summaryrefslogtreecommitdiff
path: root/LedgerSMB/CP.pm
blob: 18ab0bdecbe95aaa70216c6270afecffe91b978d (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. # http://www.ledgersmb.org/
  5. #
  6. # Copyright (C) 2006
  7. # This work contains copyrighted information from a number of sources all used
  8. # with permission.
  9. #
  10. # This file contains source code included with or based on SQL-Ledger which
  11. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  12. # under the GNU General Public License version 2 or, at your option, any later
  13. # version. For a full list including contact information of contributors,
  14. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  15. #
  16. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  17. # Copyright (C) 2003
  18. #
  19. # Author: DWS Systems Inc.
  20. # Web: http://www.sql-ledger.org
  21. #
  22. # Contributors:
  23. #
  24. #
  25. #======================================================================
  26. #
  27. # This file has undergone whitespace cleanup.
  28. #
  29. #======================================================================
  30. #
  31. # Check and receipt printing payment module backend routines
  32. # Number to text conversion routines are in
  33. # locale/{countrycode}/Num2text
  34. #
  35. #======================================================================
  36. package CP;
  37. use LedgerSMB::Sysconfig;
  38. sub new {
  39. my ( $type, $countrycode ) = @_;
  40. $self = {};
  41. use LedgerSMB::Num2text;
  42. use LedgerSMB::Locale;
  43. $self->{'locale'} = LedgerSMB::Locale->get_handle($countrycode);
  44. bless $self, $type;
  45. }
  46. sub paymentaccounts {
  47. my ( $self, $myconfig, $form ) = @_;
  48. my $dbh = $form->{dbh};
  49. my $query = qq|SELECT accno, description, link
  50. FROM chart
  51. WHERE link LIKE ?
  52. ORDER BY accno|;
  53. my $sth = $dbh->prepare($query);
  54. $sth->execute("%$form->{ARAP}%") || $form->dberror($query);
  55. $form->{PR}{ $form->{ARAP} } = ();
  56. $form->{PR}{"$form->{ARAP}_paid"} = ();
  57. while ( my $ref = $sth->fetchrow_hashref(NAME_lc) ) {
  58. foreach my $item ( split /:/, $ref->{link} ) {
  59. if ( $item eq $form->{ARAP} ) {
  60. push @{ $form->{PR}{ $form->{ARAP} } }, $ref;
  61. }
  62. if ( $item eq "$form->{ARAP}_paid" ) {
  63. push @{ $form->{PR}{"$form->{ARAP}_paid"} }, $ref;
  64. }
  65. }
  66. }
  67. $sth->finish;
  68. # get currencies and closedto
  69. $query = qq|
  70. SELECT value, (SELECT value FROM defaults
  71. WHERE setting_key = 'closedto'),
  72. current_date
  73. FROM defaults
  74. WHERE setting_key = 'curr'|;
  75. ( $form->{currencies}, $form->{closedto}, $form->{datepaid} ) =
  76. $dbh->selectrow_array($query);
  77. if ( $form->{payment} eq 'payments' ) {
  78. # get language codes
  79. $query = qq|SELECT *
  80. FROM language
  81. ORDER BY 2|;
  82. $sth = $dbh->prepare($query);
  83. $sth->execute || $self->dberror($query);
  84. $form->{all_language} = ();
  85. while ( $ref = $sth->fetchrow_hashref(NAME_lc) ) {
  86. push @{ $form->{all_language} }, $ref;
  87. }
  88. $sth->finish;
  89. $form->all_departments( $myconfig, $dbh, $form->{vc} );
  90. }
  91. $dbh->commit;
  92. }
  93. sub get_openvc {
  94. my ( $self, $myconfig, $form ) = @_;
  95. my $dbh = $form->{dbh};
  96. my $arap = ( $form->{vc} eq 'customer' ) ? 'ar' : 'ap';
  97. my $query = qq|SELECT count(*)
  98. FROM $form->{vc} ct, $arap a
  99. WHERE a.$form->{vc}_id = ct.id
  100. AND a.amount != a.paid|;
  101. my ($count) = $dbh->selectrow_array($query);
  102. my $sth;
  103. my $ref;
  104. my $i = 0;
  105. my $where = qq|WHERE a.$form->{vc}_id = ct.id
  106. AND a.amount != a.paid|;
  107. if ( $form->{ $form->{vc} } ) {
  108. my $var = $dbh->quote( $form->like( lc $form->{ $form->{vc} } ) );
  109. $where .= " AND lower(name) LIKE $var";
  110. }
  111. # build selection list
  112. $query = qq|SELECT DISTINCT ct.*
  113. FROM $form->{vc} ct, $arap a
  114. $where
  115. ORDER BY name|;
  116. $sth = $dbh->prepare($query);
  117. $sth->execute || $form->dberror($query);
  118. while ( $ref = $sth->fetchrow_hashref(NAME_lc) ) {
  119. $i++;
  120. push @{ $form->{name_list} }, $ref;
  121. }
  122. $sth->finish;
  123. $form->all_departments( $myconfig, $dbh, $form->{vc} );
  124. # get language codes
  125. $query = qq|SELECT *
  126. FROM language
  127. ORDER BY 2|;
  128. $sth = $dbh->prepare($query);
  129. $sth->execute || $self->dberror($query);
  130. $form->{all_language} = ();
  131. while ( $ref = $sth->fetchrow_hashref(NAME_lc) ) {
  132. push @{ $form->{all_language} }, $ref;
  133. }
  134. $sth->finish;
  135. # get currency for first name
  136. if ( @{ $form->{name_list} } ) {
  137. # Chris T: I don't like this but it seems safe injection-wise
  138. # Leaving it so we can change it when we go to a new system
  139. $query = qq|SELECT curr
  140. FROM $form->{vc}
  141. WHERE id = $form->{name_list}->[0]->{id}|;
  142. ( $form->{currency} ) = $dbh->selectrow_array($query);
  143. $form->{currency} ||= $form->{defaultcurrency};
  144. }
  145. $dbh->commit;
  146. $i;
  147. }
  148. sub get_openinvoices {
  149. my ( $self, $myconfig, $form ) = @_;
  150. my $null;
  151. my $department_id;
  152. # connect to database
  153. my $dbh = $form->{dbh};
  154. $vc_id = $dbh->quote( $form->{"$form->{vc}_id"} );
  155. my $where = qq|WHERE a.$form->{vc}_id = $vc_id
  156. AND a.amount != a.paid|;
  157. $curr = $dbh->quote( $form->{currency} );
  158. $where .= qq| AND a.curr = $curr| if $form->{currency};
  159. my $sortorder = "transdate, invnumber";
  160. my ($buysell);
  161. if ( $form->{vc} eq 'customer' ) {
  162. $buysell = "buy";
  163. }
  164. else {
  165. $buysell = "sell";
  166. }
  167. if ( $form->{payment} eq 'payments' ) {
  168. $where = qq|WHERE a.amount != a.paid|;
  169. $where .= qq| AND a.curr = $curr| if $form->{currency};
  170. if ( $form->{duedatefrom} ) {
  171. $where .= qq| AND a.duedate >=
  172. | . $dbh->quote( $form->{duedatefrom} );
  173. }
  174. if ( $form->{duedateto} ) {
  175. $where .=
  176. qq| AND a.duedate <= | . $dbh->quote( $form->{duedateto} );
  177. }
  178. $sortorder = "name, transdate";
  179. }
  180. ( $null, $department_id ) = split /--/, $form->{department};
  181. if ($department_id) {
  182. $where .= qq| AND a.department_id = $department_id|;
  183. }
  184. my $query = qq|SELECT a.id, a.invnumber, a.transdate, a.amount, a.paid,
  185. a.curr, c.name, a.$form->{vc}_id, c.language_code
  186. FROM $form->{arap} a
  187. JOIN $form->{vc} c ON (c.id = a.$form->{vc}_id)
  188. $where
  189. ORDER BY $sortorder|;
  190. my $sth = $dbh->prepare($query);
  191. $sth->execute || $form->dberror($query);
  192. $query = qq|SELECT s.spoolfile
  193. FROM status s
  194. WHERE s.formname = '$form->{formname}'
  195. AND s.trans_id = ?|;
  196. my $vth = $dbh->prepare($query);
  197. my $spoolfile;
  198. while ( $ref = $sth->fetchrow_hashref(NAME_lc) ) {
  199. $form->db_parse_numeric(sth=>$sth, hashref=>$ref);
  200. # if this is a foreign currency transaction get exchangerate
  201. $ref->{exchangerate} =
  202. $form->get_exchangerate( $dbh, $ref->{curr}, $ref->{transdate},
  203. $buysell )
  204. if ( $form->{currency} ne $form->{defaultcurrency} );
  205. $vth->execute( $ref->{id} );
  206. $ref->{queue} = "";
  207. while ( ($spoolfile) = $vth->fetchrow_array ) {
  208. $ref->{queued} .= "$form->{formname} $spoolfile ";
  209. }
  210. $vth->finish;
  211. $ref->{queued} =~ s/ +$//g;
  212. push @{ $form->{PR} }, $ref;
  213. }
  214. $sth->finish;
  215. $dbh->commit;
  216. }
  217. sub post_payment {
  218. my ( $self, $myconfig, $form ) = @_;
  219. # connect to database, turn AutoCommit off
  220. my $dbh = $form->{dbh};
  221. my $sth;
  222. my ($paymentaccno) = split /--/, $form->{account};
  223. # if currency ne defaultcurrency update exchangerate
  224. if ( $form->{currency} ne $form->{defaultcurrency} ) {
  225. $form->{exchangerate} =
  226. $form->parse_amount( $myconfig, $form->{exchangerate} );
  227. if ( $form->{vc} eq 'customer' ) {
  228. $form->update_exchangerate( $dbh, $form->{currency},
  229. $form->{datepaid}, $form->{exchangerate}, 0 );
  230. }
  231. else {
  232. $form->update_exchangerate( $dbh, $form->{currency},
  233. $form->{datepaid}, 0, $form->{exchangerate} );
  234. }
  235. }
  236. else {
  237. $form->{exchangerate} = 1;
  238. }
  239. my $query = qq|
  240. SELECT (SELECT value FROM defaults
  241. WHERE setting_key='fxgain_accno_id'),
  242. (SELECT value FROM defaults
  243. WHERE setting_key='fxloss_accno_id')|;
  244. my ( $fxgain_accno_id, $fxloss_accno_id ) = $dbh->selectrow_array($query);
  245. my ($buysell);
  246. if ( $form->{vc} eq 'customer' ) {
  247. $buysell = "buy";
  248. }
  249. else {
  250. $buysell = "sell";
  251. }
  252. my $ml;
  253. my $where;
  254. if ( $form->{ARAP} eq 'AR' ) {
  255. $ml = 1;
  256. $where = qq| (c.link = 'AR' OR c.link LIKE 'AR:%') |;
  257. }
  258. else {
  259. $ml = -1;
  260. $where =
  261. qq| (c.link = 'AP' OR c.link LIKE '%:AP' OR c.link LIKE '%:AP:%') |;
  262. }
  263. my $paymentamount = $form->parse_amount( $myconfig, $form->{amount} );
  264. # query to retrieve paid amount
  265. $query = qq|SELECT paid
  266. FROM $form->{arap}
  267. WHERE id = ?
  268. FOR UPDATE|;
  269. my $pth = $dbh->prepare($query) || $form->dberror($query);
  270. my %audittrail;
  271. # go through line by line
  272. for my $i ( 1 .. $form->{rowcount} ) {
  273. $form->{"paid_$i"} =
  274. $form->parse_amount( $myconfig, $form->{"paid_$i"} );
  275. $form->{"due_$i"} = $form->parse_amount( $myconfig, $form->{"due_$i"} );
  276. if ( $form->{"checked_$i"} && $form->{"paid_$i"} ) {
  277. $paymentamount -= $form->{"paid_$i"};
  278. # get exchangerate for original
  279. $query = qq|
  280. SELECT $buysell
  281. FROM exchangerate e
  282. JOIN $form->{arap} a
  283. ON (a.transdate = e.transdate)
  284. WHERE e.curr = ?
  285. AND a.id = ?|;
  286. my $sth = $dbh->prepare($query);
  287. $sth->execute( $form->{currency}, $form->{"id_$i"} );
  288. my @exchange = $sth->fetchrow_array();
  289. $form->db_parse_numeric(sth=>$sth, arrayref=>\@exchange);
  290. my $exchangerate = shift @exchange;
  291. $exchangerate = 1 unless $exchangerate;
  292. $query = qq|
  293. SELECT c.id
  294. FROM chart c
  295. JOIN acc_trans a ON (a.chart_id = c.id)
  296. WHERE $where
  297. AND a.trans_id = ?|;
  298. my $sth = $dbh->prepare($query);
  299. $sth->execute( $form->{"id_$i"} );
  300. my ($id) = $sth->fetchrow_array;
  301. $amount =
  302. $form->round_amount( $form->{"paid_$i"} * $exchangerate, 2 );
  303. # add AR/AP
  304. $query = qq|
  305. INSERT INTO acc_trans
  306. (trans_id, chart_id, transdate,
  307. amount)
  308. VALUES (?, ?,
  309. ?,
  310. ?)|;
  311. $sth = $dbh->prepare($query);
  312. $sth->execute( $form->{"id_$i"}, $id, $form->{datepaid},
  313. $amount * $ml )
  314. || $form->dberror( $query, __file__, __line__ );
  315. # add payment
  316. $query = qq|
  317. INSERT INTO acc_trans
  318. (trans_id, chart_id, transdate,
  319. amount, source, memo)
  320. VALUES (?, (SELECT id
  321. FROM chart
  322. WHERE accno = ?),
  323. ?, ?, ?, ?)|;
  324. $sth = $dbh->prepare($query);
  325. $sth->execute( $form->{"id_$i"}, $paymentaccno, $form->{datepaid},
  326. $form->{"paid_$i"} * $ml * -1,
  327. $form->{source}, $form->{memo} )
  328. || $form->dberror( $query, 'CP.pm', 444 );
  329. # add exchangerate difference if currency ne defaultcurrency
  330. $amount =
  331. $form->round_amount(
  332. $form->{"paid_$i"} * ( $form->{exchangerate} - 1 ), 2 );
  333. if ($amount) {
  334. # exchangerate difference
  335. $query = qq|
  336. INSERT INTO acc_trans
  337. (trans_id, chart_id,
  338. transdate, amount, cleared,
  339. fx_transaction, source)
  340. VALUES (?, (SELECT id
  341. FROM chart
  342. WHERE accno = ?),
  343. ?, ?, '0', '1',
  344. ?)|;
  345. $sth = $dbh->prepare($query);
  346. $sth->execute(
  347. $form->{"id_$i"}, $paymentaccno, $form->{datepaid},
  348. $amount * $ml * -1, $form->{source}
  349. ) || $form->dberror( $query, 'CP.pm', 470 );
  350. # gain/loss
  351. $amount = (
  352. $form->round_amount(
  353. $form->{"paid_$i"} * $exchangerate, 2
  354. ) - $form->round_amount(
  355. $form->{"paid_$i"} * $form->{exchangerate}, 2
  356. )
  357. ) * $ml * -1;
  358. if ($amount) {
  359. my $accno_id =
  360. ( $amount > 0 )
  361. ? $fxgain_accno_id
  362. : $fxloss_accno_id;
  363. $query = qq|
  364. INSERT INTO acc_trans
  365. (trans_id,
  366. chart_id,
  367. transdate,
  368. amount, cleared,
  369. fx_transaction)
  370. VALUES (?, ?, ?, ?, '0', '1')|;
  371. $sth = $dbh->prepare($query);
  372. $sth->execute(
  373. $form->{"id_$i"}, $accno_id,
  374. $form->{datepaid}, $amount
  375. ) || $form->dberror( $query, 'CP.pm', 506 );
  376. }
  377. }
  378. $form->{"paid_$i"} =
  379. $form->round_amount( $form->{"paid_$i"} * $exchangerate, 2 );
  380. $pth->execute( $form->{"id_$i"} ) || $form->dberror($pth->statement);
  381. ($amount) = $pth->fetchrow_array;
  382. $pth->finish;
  383. $amount += $form->{"paid_$i"};
  384. # update AR/AP transaction
  385. $query = qq|
  386. UPDATE $form->{arap}
  387. SET paid = ?,
  388. datepaid = ?
  389. WHERE id = ?|;
  390. $sth = $dbh->prepare($query);
  391. $sth->execute( $amount, $form->{datepaid}, $form->{"id_$i"} )
  392. || $form->dberror( $query, 'CP.pm', 530 );
  393. %audittrail = (
  394. tablename => $form->{arap},
  395. reference => $form->{source},
  396. formname => $form->{formname},
  397. action => 'posted',
  398. id => $form->{"id_$i"}
  399. );
  400. $form->audittrail( $dbh, "", \%audittrail );
  401. }
  402. }
  403. # record a AR/AP with a payment
  404. if ( $form->round_amount( $paymentamount, 2 ) ) {
  405. $form->{invnumber} = "";
  406. OP::overpayment( "", $myconfig, $form, $dbh, $paymentamount, $ml, 1 );
  407. }
  408. my $rc = $dbh->commit;
  409. $rc;
  410. }
  411. sub post_payments {
  412. my ( $self, $myconfig, $form ) = @_;
  413. # connect to database, turn AutoCommit off
  414. my $dbh = $form->{dbh};
  415. my $sth;
  416. my ($paymentaccno) = split /--/, $form->{account};
  417. # if currency ne defaultcurrency update exchangerate
  418. if ( $form->{currency} ne $form->{defaultcurrency} ) {
  419. $form->{exchangerate} =
  420. $form->parse_amount( $myconfig, $form->{exchangerate} );
  421. if ( $form->{vc} eq 'customer' ) {
  422. $form->update_exchangerate( $dbh, $form->{currency},
  423. $form->{datepaid}, $form->{exchangerate}, 0 );
  424. }
  425. else {
  426. $form->update_exchangerate( $dbh, $form->{currency},
  427. $form->{datepaid}, 0, $form->{exchangerate} );
  428. }
  429. }
  430. else {
  431. $form->{exchangerate} = 1;
  432. }
  433. my $query = qq|
  434. SELECT (SELECT value FROM defaults
  435. WHERE setting_key='fxgain_accno_id'),
  436. (SELECT value FROM defaults
  437. WHERE setting_key='fxloss_accno_id')|;
  438. my ( $fxgain_accno_id, $fxloss_accno_id ) = $dbh->selectrow_array($query);
  439. my ($buysell);
  440. if ( $form->{vc} eq 'customer' ) {
  441. $buysell = "buy";
  442. }
  443. else {
  444. $buysell = "sell";
  445. }
  446. my $ml;
  447. my $where;
  448. if ( $form->{ARAP} eq 'AR' ) {
  449. $ml = 1;
  450. $where = qq| (c.link = 'AR' OR c.link LIKE 'AR:%') |;
  451. }
  452. else {
  453. $ml = -1;
  454. $where =
  455. qq| (c.link = 'AP' OR c.link LIKE '%:AP' OR c.link LIKE '%:AP:%') |;
  456. }
  457. # get AR/AP account
  458. $query = qq|SELECT c.accno
  459. FROM chart c
  460. JOIN acc_trans ac ON (ac.chart_id = c.id)
  461. WHERE trans_id = ?
  462. AND $where|;
  463. my $ath = $dbh->prepare($query) || $form->dberror($query);
  464. # query to retrieve paid amount
  465. $query = qq|SELECT paid
  466. FROM $form->{arap}
  467. WHERE id = ?
  468. FOR UPDATE|;
  469. my $pth = $dbh->prepare($query) || $form->dberror($query);
  470. my %audittrail;
  471. my $overpayment = 0;
  472. my $accno_id;
  473. # go through line by line
  474. for my $i ( 1 .. $form->{rowcount} ) {
  475. $ath->execute( $form->{"id_$i"} );
  476. ( $form->{ $form->{ARAP} } ) = $ath->fetchrow_array;
  477. $ath->finish;
  478. $form->{"paid_$i"} =
  479. $form->parse_amount( $myconfig, $form->{"paid_$i"} );
  480. $form->{"due_$i"} = $form->parse_amount( $myconfig, $form->{"due_$i"} );
  481. if ( $form->{"$form->{vc}_id_$i"} ne $sameid ) {
  482. # record a AR/AP with a payment
  483. if ( $overpayment > 0 && $form->{ $form->{ARAP} } ) {
  484. $form->{invnumber} = "";
  485. OP::overpayment( "", $myconfig, $form, $dbh, $overpayment, $ml,
  486. 1 );
  487. }
  488. $overpayment = 0;
  489. $form->{"$form->{vc}_id"} = $form->{"$form->{vc}_id_$i"};
  490. for (qw(source memo)) { $form->{$_} = $form->{"${_}_$i"} }
  491. }
  492. if ( $form->{"checked_$i"} && $form->{"paid_$i"} ) {
  493. $overpayment += ( $form->{"paid_$i"} - $form->{"due_$i"} );
  494. # get exchangerate for original
  495. $query = qq|
  496. SELECT $buysell
  497. FROM exchangerate e
  498. JOIN $form->{arap} a
  499. ON (a.transdate = e.transdate)
  500. WHERE e.curr = ?
  501. AND a.id = ?|;
  502. $sth = $dbh->prepare($query);
  503. $sth->execute( $form->{currency}, $form->{"id_$i"} )
  504. || $form->dberror( $query, 'CP.pm', 671 );
  505. my ($exchangerate) = $sth->fetchrow_array;
  506. $exchangerate ||= 1;
  507. $query = qq|
  508. SELECT c.id
  509. FROM chart c
  510. JOIN acc_trans a ON (a.chart_id = c.id)
  511. WHERE $where
  512. AND a.trans_id = ?|;
  513. $sth = $dbh->prepare($query);
  514. $sth->execute( $form->{"id_$i"} );
  515. ($id) = $sth->fetchrow_array();
  516. $paid =
  517. ( $form->{"paid_$i"} > $form->{"due_$i"} )
  518. ? $form->{"due_$i"}
  519. : $form->{"paid_$i"};
  520. $amount = $form->round_amount( $paid * $exchangerate, 2 );
  521. # add AR/AP
  522. $query = qq|
  523. INSERT INTO acc_trans
  524. (trans_id, chart_id, transdate,
  525. amount)
  526. VALUES (?, ?, ?, ?)|;
  527. $sth = $dbh->prepare($query);
  528. $sth->execute( $form->{"id_$i"}, $id, $form->{datepaid},
  529. $amount * $ml )
  530. || $form->dberror( $query, 'CP.pm', 701 );
  531. $query = qq|SELECT id
  532. FROM chart
  533. WHERE accno = ?|;
  534. $sth = $dbh->prepare($query);
  535. $sth->execute($paymentaccno);
  536. ($accno_id) = $sth->fetchrow_array;
  537. # add payment
  538. $query = qq|
  539. INSERT INTO acc_trans
  540. (trans_id, chart_id, transdate,
  541. amount, source, memo)
  542. VALUES (?, ?, ?, ?, ?, ?)|;
  543. $sth = $dbh->prepare($query);
  544. $sth->execute(
  545. $form->{"id_$i"}, $accno_id, $form->{datepaid},
  546. $paid * $ml * -1, $form->{source}, $form->{memo}
  547. ) || $form->dberror( $query, 'CP.pm', 723 );
  548. # add exchangerate difference if currency ne defaultcurrency
  549. $amount =
  550. $form->round_amount(
  551. $paid * ( $form->{exchangerate} - 1 ) * $ml * -1, 2 );
  552. if ($amount) {
  553. # exchangerate difference
  554. $query = qq|
  555. INSERT INTO acc_trans
  556. (trans_id, chart_id,
  557. transdate,
  558. amount, source)
  559. VALUES (?, ?, ?, ?, ?)|;
  560. $sth = $dbh->prepare($query);
  561. $sth->execute(
  562. $form->{"id_$i"}, $accno_id, $form->{datepaid},
  563. $amount, $form->{source}
  564. ) || $form->dberror( $query, 'CP.pm', 748 );
  565. # gain/loss
  566. $amount =
  567. ( $form->round_amount( $paid * $exchangerate, 2 ) -
  568. $form->round_amount( $paid * $form->{exchangerate}, 2 ) )
  569. * $ml * -1;
  570. if ($amount) {
  571. $accno_id =
  572. ( $amount > 0 )
  573. ? $fxgain_accno_id
  574. : $fxloss_accno_id;
  575. $query = qq|
  576. INSERT INTO acc_trans
  577. (trans_id,
  578. chart_id,
  579. transdate,
  580. amount,
  581. fx_transaction)
  582. VALUES (?, ?, ?, ?, '1')|;
  583. $sth = $dbh->prepare($query);
  584. $sth->execute(
  585. $form->{"id_$i"}, $accno_id,
  586. $form->{datepaid}, $amount
  587. ) || $form->dberror( $query, 'CP.pm', 775 );
  588. }
  589. }
  590. $paid = $form->round_amount( $paid * $exchangerate, 2 );
  591. $pth->execute( $form->{"id_$i"} ) || $form->dberror($pth->statement);
  592. ($amount) = $pth->fetchrow_array;
  593. $pth->finish;
  594. $amount += $paid;
  595. # update AR/AP transaction
  596. $query = qq|
  597. UPDATE $form->{arap}
  598. SET paid = ?,
  599. datepaid = ?
  600. WHERE id = ?|;
  601. $sth = $dbh->prepare($query);
  602. $sth->execute( $amount, $form->{datepaid}, $form->{"id_$i"} )
  603. || $form->dberror( $query, 'CP.pm', 796 );
  604. %audittrail = (
  605. tablename => $form->{arap},
  606. reference => $form->{source},
  607. formname => $form->{formname},
  608. action => 'posted',
  609. id => $form->{"id_$i"}
  610. );
  611. $form->audittrail( $dbh, "", \%audittrail );
  612. }
  613. $sameid = $form->{"$form->{vc}_id_$i"};
  614. }
  615. # record a AR/AP with a payment
  616. if ( $overpayment > 0 && $form->{ $form->{ARAP} } ) {
  617. $form->{invnumber} = "";
  618. OP::overpayment( "", $myconfig, $form, $dbh, $overpayment, $ml, 1 );
  619. }
  620. my $rc = $dbh->commit;
  621. $rc;
  622. }
  623. 1;