summaryrefslogtreecommitdiff
path: root/LedgerSMB/CP.pm
blob: a7a2f0d0619e2a55ebe172925362f687b1d0f773 (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}) = $dbh->selectrow_array($query);
  76. if ($form->{payment} eq 'payments') {
  77. # get language codes
  78. $query = qq|SELECT *
  79. FROM language
  80. ORDER BY 2|;
  81. $sth = $dbh->prepare($query);
  82. $sth->execute || $self->dberror($query);
  83. $form->{all_language} = ();
  84. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  85. push @{ $form->{all_language} }, $ref;
  86. }
  87. $sth->finish;
  88. $form->all_departments($myconfig, $dbh, $form->{vc});
  89. }
  90. $dbh->commit;
  91. }
  92. sub get_openvc {
  93. my ($self, $myconfig, $form) = @_;
  94. my $dbh = $form->{dbh};
  95. my $arap = ($form->{vc} eq 'customer') ? 'ar' : 'ap';
  96. my $query = qq|SELECT count(*)
  97. FROM $form->{vc} ct, $arap a
  98. WHERE a.$form->{vc}_id = ct.id
  99. AND a.amount != a.paid|;
  100. my ($count) = $dbh->selectrow_array($query);
  101. my $sth;
  102. my $ref;
  103. my $i = 0;
  104. my $where = qq|WHERE a.$form->{vc}_id = ct.id
  105. AND a.amount != a.paid|;
  106. if ($form->{$form->{vc}}) {
  107. my $var = $dbh->quote($form->like(lc $form->{$form->{vc}}));
  108. $where .= " AND lower(name) LIKE $var";
  109. }
  110. # build selection list
  111. $query = qq|SELECT DISTINCT ct.*
  112. FROM $form->{vc} ct, $arap a
  113. $where
  114. ORDER BY name|;
  115. $sth = $dbh->prepare($query);
  116. $sth->execute || $form->dberror($query);
  117. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  118. $i++;
  119. push @{ $form->{name_list} }, $ref;
  120. }
  121. $sth->finish;
  122. $form->all_departments($myconfig, $dbh, $form->{vc});
  123. # get language codes
  124. $query = qq|SELECT *
  125. FROM language
  126. ORDER BY 2|;
  127. $sth = $dbh->prepare($query);
  128. $sth->execute || $self->dberror($query);
  129. $form->{all_language} = ();
  130. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  131. push @{ $form->{all_language} }, $ref;
  132. }
  133. $sth->finish;
  134. # get currency for first name
  135. if (@{ $form->{name_list} }) {
  136. # Chris T: I don't like this but it seems safe injection-wise
  137. # Leaving it so we can change it when we go to a new system
  138. $query = qq|SELECT curr
  139. FROM $form->{vc}
  140. WHERE id = $form->{name_list}->[0]->{id}|;
  141. ($form->{currency}) = $dbh->selectrow_array($query);
  142. $form->{currency} ||= $form->{defaultcurrency};
  143. }
  144. $dbh->commit;
  145. $i;
  146. }
  147. sub get_openinvoices {
  148. my ($self, $myconfig, $form) = @_;
  149. my $null;
  150. my $department_id;
  151. # connect to database
  152. my $dbh = $form->{dbh};
  153. $vc_id = $dbh->quote($form->{"$form->{vc}_id"});
  154. my $where = qq|WHERE a.$form->{vc}_id = $vc_id
  155. AND a.amount != a.paid|;
  156. $curr = $dbh->quote($form->{curr});
  157. $where .= qq| AND a.curr = $curr| if $form->{currency};
  158. my $sortorder = "transdate, invnumber";
  159. my ($buysell);
  160. if ($form->{vc} eq 'customer') {
  161. $buysell = "buy";
  162. } else {
  163. $buysell = "sell";
  164. }
  165. if ($form->{payment} eq 'payments') {
  166. $where = qq|WHERE a.amount != a.paid|;
  167. $where .= qq| AND a.curr = $curr| if $form->{currency};
  168. if ($form->{duedatefrom}) {
  169. $where .= qq| AND a.duedate >=
  170. |.$dbh->quote($form->{duedatefrom});
  171. }
  172. if ($form->{duedateto}) {
  173. $where .= qq| AND a.duedate <= |.
  174. $dbh->quote($form->{duedateto});
  175. }
  176. $sortorder = "name, transdate";
  177. }
  178. ($null, $department_id) = split /--/, $form->{department};
  179. if ($department_id) {
  180. $where .= qq| AND a.department_id = $department_id|;
  181. }
  182. my $query = qq|SELECT a.id, a.invnumber, a.transdate, a.amount, a.paid,
  183. a.curr, c.name, a.$form->{vc}_id, c.language_code
  184. FROM $form->{arap} a
  185. JOIN $form->{vc} c ON (c.id = a.$form->{vc}_id)
  186. $where
  187. ORDER BY $sortorder|;
  188. my $sth = $dbh->prepare($query);
  189. $sth->execute || $form->dberror($query);
  190. $query = qq|SELECT s.spoolfile
  191. FROM status s
  192. WHERE s.formname = '$form->{formname}'
  193. AND s.trans_id = ?|;
  194. my $vth = $dbh->prepare($query);
  195. my $spoolfile;
  196. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  197. # if this is a foreign currency transaction get exchangerate
  198. $ref->{exchangerate} =
  199. $form->get_exchangerate($dbh,
  200. $ref->{curr},
  201. $ref->{transdate},
  202. $buysell)
  203. if ($form->{currency}
  204. 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} = $form->parse_amount($myconfig, $form->{exchangerate});
  226. if ($form->{vc} eq 'customer') {
  227. $form->update_exchangerate($dbh, $form->{currency}, $form->{datepaid}, $form->{exchangerate}, 0);
  228. } else {
  229. $form->update_exchangerate($dbh, $form->{currency}, $form->{datepaid}, 0, $form->{exchangerate});
  230. }
  231. } else {
  232. $form->{exchangerate} = 1;
  233. }
  234. my $query = qq|
  235. SELECT (SELECT value FROM defaults
  236. WHERE setting_key='fxgain_accno_id'),
  237. (SELECT value FROM defaults
  238. WHERE setting_key='fxloss_accno_id'|;
  239. my ($fxgain_accno_id, $fxloss_accno_id) = $dbh->selectrow_array($query);
  240. my ($buysell);
  241. if ($form->{vc} eq 'customer') {
  242. $buysell = "buy";
  243. } else {
  244. $buysell = "sell";
  245. }
  246. my $ml;
  247. my $where;
  248. if ($form->{ARAP} eq 'AR') {
  249. $ml = 1;
  250. $where = qq| (c.link = 'AR' OR c.link LIKE 'AR:%') |;
  251. } else {
  252. $ml = -1;
  253. $where = qq| (c.link = 'AP' OR c.link LIKE '%:AP' OR c.link LIKE '%:AP:%') |;
  254. }
  255. my $paymentamount = $form->parse_amount($myconfig, $form->{amount});
  256. # query to retrieve paid amount
  257. $query = qq|SELECT paid
  258. FROM $form->{arap}
  259. WHERE id = ?
  260. FOR UPDATE|;
  261. my $pth = $dbh->prepare($query) || $form->dberror($query);
  262. my %audittrail;
  263. # go through line by line
  264. for my $i (1 .. $form->{rowcount}) {
  265. $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
  266. $form->{"due_$i"} = $form->parse_amount($myconfig, $form->{"due_$i"});
  267. if ($form->{"checked_$i"} && $form->{"paid_$i"}) {
  268. $paymentamount -= $form->{"paid_$i"};
  269. # get exchangerate for original
  270. $query = qq|
  271. SELECT $buysell
  272. FROM exchangerate e
  273. JOIN $form->{arap} a
  274. ON (a.transdate = e.transdate)
  275. WHERE e.curr = ?
  276. AND a.id = ?|;
  277. my $sth = $dbh->prepare($query);
  278. $sth->execute($form->{currency}, $form->{"id_$i"});
  279. my ($exchangerate) = $sth->fetchrow_array();
  280. $exchangerate = 1 unless $exchangerate;
  281. $query = qq|
  282. SELECT c.id
  283. FROM chart c
  284. JOIN acc_trans a ON (a.chart_id = c.id)
  285. WHERE $where
  286. AND a.trans_id = ?|;
  287. my $sth = $dbh->prepare($query);
  288. $sth->execute($form->{"id_$i"});
  289. my ($id) = $dbh->selectrow_array($query);
  290. $amount =
  291. $form->round_amount(
  292. $form->{"paid_$i"} * $exchangerate, 2);
  293. # add AR/AP
  294. $query = qq|
  295. INSERT INTO acc_trans
  296. (trans_id, chart_id, transdate,
  297. amount)
  298. VALUES (?, ?,
  299. ?,
  300. ? * ?)|;
  301. $sth = $dbh->prepare($query);
  302. $sth->execute($form->{"id_$i"}, $id,
  303. $form->{date_paid}, $amount, $ml)
  304. || $form->dberror($query, 'CP.pm', 427);
  305. # add payment
  306. $query = qq|
  307. INSERT INTO acc_trans
  308. (trans_id, chart_id, transdate,
  309. amount, source, memo)
  310. VALUES (?, (SELECT id
  311. FROM chart
  312. WHERE accno = ?),
  313. ?, ? * ? * -1, ?, ?)|;
  314. $sth = $dbh->prepare($query);
  315. $sth->execute(
  316. $form->{"id_$i"}, $paymentaccno,
  317. $form->{datepaid}, $form->{"paid_$i"}, $ml,
  318. $form->{source}, $form->{memo})
  319. || $form->dberror(
  320. $query, 'CP.pm', 444);
  321. # add exchangerate difference if currency ne defaultcurrency
  322. $amount = $form->round_amount(
  323. $form->{"paid_$i"} *
  324. ($form->{exchangerate} - 1),
  325. 2);
  326. if ($amount) {
  327. # exchangerate difference
  328. $query = qq|
  329. INSERT INTO acc_trans
  330. (trans_id, chart_id,
  331. transdate, amount, cleared,
  332. fx_transaction, source)
  333. VALUES (?, (SELECT id
  334. FROM chart
  335. WHERE accno = ?),
  336. ?, ? * ? * -1, '0', '1',
  337. ?)|;
  338. $sth = $dbh->prepare($query);
  339. $sth->execute(
  340. $form->{"id_$i"}, $paymentaccno,
  341. $form->{datepaid}, $amount, $ml,
  342. $form->{source})
  343. || $form->dberror(
  344. $query, 'CP.pm', 470);
  345. # gain/loss
  346. $amount =
  347. ($form->round_amount(
  348. $form->{"paid_$i"} *
  349. $exchangerate,
  350. 2) -
  351. $form->round_amount(
  352. $form->{"paid_$i"} *
  353. $form->{exchangerate},
  354. 2))
  355. * $ml * -1;
  356. if ($amount) {
  357. my $accno_id =
  358. ($amount > 0)
  359. ? $fxgain_accno_id
  360. : $fxloss_accno_id;
  361. $query = qq|
  362. INSERT INTO acc_trans
  363. (trans_id,
  364. chart_id,
  365. transdate,
  366. amount, cleared,
  367. fx_transaction)
  368. VALUES (?, ?, ?, ?, '0', '1')|;
  369. $sth = $dbh->prepare($query);
  370. $sth->execute(
  371. $form->{"id_$i"}, $accno_id,
  372. $form->{datepaid}, $amount)
  373. || $form->dberror(
  374. $query,
  375. 'CP.pm',
  376. 506);
  377. }
  378. }
  379. $form->{"paid_$i"} =
  380. $form->round_amount(
  381. $form->{"paid_$i"} * $exchangerate, 2);
  382. $pth->execute($form->{"id_$i"}) || $form->dberror;
  383. ($amount) = $pth->fetchrow_array;
  384. $pth->finish;
  385. $amount += $form->{"paid_$i"};
  386. # update AR/AP transaction
  387. $query = qq|
  388. UPDATE $form->{arap}
  389. SET paid = $amount,
  390. datepaid = '$form->{datepaid}'
  391. WHERE id = $form->{"id_$i"}|;
  392. $sth = $dbh->prepare($query);
  393. $sth->execute(
  394. $amount, $$form->{datepaid}, $form->{"id_$i"})
  395. || $form->dberror($query, 'CP.pm',
  396. 530);
  397. %audittrail = (
  398. tablename => $form->{arap},
  399. reference => $form->{source},
  400. formname => $form->{formname},
  401. action => 'posted',
  402. id => $form->{"id_$i"} );
  403. $form->audittrail($dbh, "", \%audittrail);
  404. }
  405. }
  406. # record a AR/AP with a payment
  407. if ($form->round_amount($paymentamount, 2)) {
  408. $form->{invnumber} = "";
  409. OP::overpayment("", $myconfig, $form, $dbh, $paymentamount, $ml, 1);
  410. }
  411. my $rc = $dbh->commit;
  412. $rc;
  413. }
  414. sub post_payments {
  415. my ($self, $myconfig, $form) = @_;
  416. # connect to database, turn AutoCommit off
  417. my $dbh = $form->{dbh};
  418. my $sth;
  419. my ($paymentaccno) = split /--/, $form->{account};
  420. # if currency ne defaultcurrency update exchangerate
  421. if ($form->{currency} ne $form->{defaultcurrency}) {
  422. $form->{exchangerate} = $form->parse_amount($myconfig, $form->{exchangerate});
  423. if ($form->{vc} eq 'customer') {
  424. $form->update_exchangerate($dbh, $form->{currency}, $form->{datepaid}, $form->{exchangerate}, 0);
  425. } else {
  426. $form->update_exchangerate($dbh, $form->{currency}, $form->{datepaid}, 0, $form->{exchangerate});
  427. }
  428. } else {
  429. $form->{exchangerate} = 1;
  430. }
  431. my $query = qq|
  432. SELECT (SELECT value FROM defaults
  433. WHERE setting_key='fxgain_accno_id'),
  434. (SELECT value FROM defaults
  435. WHERE setting_key='fxloss_accno_id'|;
  436. my ($fxgain_accno_id, $fxloss_accno_id) = $dbh->selectrow_array($query);
  437. my ($buysell);
  438. if ($form->{vc} eq 'customer') {
  439. $buysell = "buy";
  440. } else {
  441. $buysell = "sell";
  442. }
  443. my $ml;
  444. my $where;
  445. if ($form->{ARAP} eq 'AR') {
  446. $ml = 1;
  447. $where = qq| (c.link = 'AR' OR c.link LIKE 'AR:%') |;
  448. } else {
  449. $ml = -1;
  450. $where = qq| (c.link = 'AP' OR c.link LIKE '%:AP' OR c.link LIKE '%:AP:%') |;
  451. }
  452. # get AR/AP account
  453. $query = qq|SELECT c.accno
  454. FROM chart c
  455. JOIN acc_trans ac ON (ac.chart_id = c.id)
  456. WHERE trans_id = ?
  457. AND $where|;
  458. my $ath = $dbh->prepare($query) || $form->dberror($query);
  459. # query to retrieve paid amount
  460. $query = qq|SELECT paid
  461. FROM $form->{arap}
  462. WHERE id = ?
  463. FOR UPDATE|;
  464. my $pth = $dbh->prepare($query) || $form->dberror($query);
  465. my %audittrail;
  466. my $overpayment = 0;
  467. my $accno_id;
  468. # go through line by line
  469. for my $i (1 .. $form->{rowcount}) {
  470. $ath->execute($form->{"id_$i"});
  471. ($form->{$form->{ARAP}}) = $ath->fetchrow_array;
  472. $ath->finish;
  473. $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
  474. $form->{"due_$i"} = $form->parse_amount($myconfig, $form->{"due_$i"});
  475. if ($form->{"$form->{vc}_id_$i"} ne $sameid) {
  476. # record a AR/AP with a payment
  477. if ($overpayment > 0 && $form->{$form->{ARAP}}) {
  478. $form->{invnumber} = "";
  479. OP::overpayment("", $myconfig, $form, $dbh, $overpayment, $ml, 1);
  480. }
  481. $overpayment = 0;
  482. $form->{"$form->{vc}_id"} = $form->{"$form->{vc}_id_$i"};
  483. for (qw(source memo)) { $form->{$_} = $form->{"${_}_$i"} }
  484. }
  485. if ($form->{"checked_$i"} && $form->{"paid_$i"}) {
  486. $overpayment += ($form->{"paid_$i"} - $form->{"due_$i"});
  487. # get exchangerate for original
  488. $query = qq|
  489. SELECT $buysell
  490. FROM exchangerate e
  491. JOIN $form->{arap} a
  492. ON (a.transdate = e.transdate)
  493. WHERE e.curr = ?
  494. AND a.id = ?|;
  495. $sth = $sbh->prepare($query);
  496. $sth->execute($form->{currency}, $form->{"id_$i"})
  497. || $form->dberror($query, 'CP.pm', 671);
  498. my ($exchangerate) = $dbh->selectrow_array($query);
  499. $exchangerate ||= 1;
  500. $query = qq|
  501. SELECT c.id
  502. FROM chart c
  503. JOIN acc_trans a ON (a.chart_id = c.id)
  504. WHERE $where
  505. AND a.trans_id = $form->{"id_$i"}|;
  506. $sth = $dbh->prepare($query);
  507. $sth->execute($form->{"id_$i"});
  508. $paid = ($form->{"paid_$i"} > $form->{"due_$i"}) ? $form->{"due_$i"} : $form->{"paid_$i"};
  509. $amount = $form->round_amount($paid * $exchangerate, 2);
  510. # add AR/AP
  511. $query = qq|
  512. INSERT INTO acc_trans
  513. (trans_id, chart_id, transdate,
  514. amount)
  515. VALUES (?, ?, ?, ? * ?)|;
  516. $sth = $dbh->prepare($query);
  517. $sth->execute(
  518. $form->{"id_$i"}, $id, $form->{datepaid},
  519. $amount, $ml)
  520. || $form->dberror($query, 'CP.pm',
  521. 701);
  522. $query = qq|SELECT id
  523. FROM chart
  524. WHERE accno = ?|;
  525. $sth = $dbh->prepare($query);
  526. $sth->execute($paymentaccno);
  527. ($accno_id) = $sth->fetchrow_array($query);
  528. # add payment
  529. $query = qq|
  530. INSERT INTO acc_trans
  531. (trans_id, chart_id, transdate,
  532. amount, source, memo)
  533. VALUES (?, ?, ?, ? * ? * -1, ?, ?)|;
  534. $sth = $dbh->prepare($query);
  535. $sth->execute(
  536. $form->{"id_$i"}, $accno_id, $form->{datepaid},
  537. $paid, $ml, $form->{source}, $form->{memo})
  538. || $form->dberror($query, 'CP.pm',
  539. 723);
  540. # add exchangerate difference if currency ne defaultcurrency
  541. $amount =
  542. $form->round_amount(
  543. $paid * ($form->{exchangerate} - 1)
  544. * $ml * -1,
  545. 2);
  546. if ($amount) {
  547. # exchangerate difference
  548. $query = qq|
  549. INSERT INTO acc_trans
  550. (trans_id, chart_id,
  551. transdate,
  552. amount, source)
  553. VALUES (?, ?, ?, ?, ?)|;
  554. $sth = $dbh->prepare($query);
  555. $sth->execute(
  556. $form->{"id_$i"}, $accno_id,
  557. $form->{datepaid}, $amount,
  558. $form->{source})
  559. || $form->dberror(
  560. $query, 'CP.pm', 748);
  561. # gain/loss
  562. $amount = ($form->round_amount($paid * $exchangerate,2) - $form->round_amount($paid * $form->{exchangerate},2)) * $ml * -1;
  563. if ($amount) {
  564. $accno_id =
  565. ($amount > 0)
  566. ? $fxgain_accno_id
  567. : $fxloss_accno_id;
  568. $query = qq|
  569. INSERT INTO acc_trans
  570. (trans_id,
  571. chart_id,
  572. transdate,
  573. amount,
  574. fx_transaction)
  575. VALUES (?, ?, ?, ?, '1')|;
  576. $sth = $dbh->prepare($query);
  577. $sth->execute(
  578. $form->{"id_$i"}, $accno_id,
  579. $form->{datepaid}, $amount)
  580. || $form->dberror(
  581. $query,
  582. 'CP.pm', 775);
  583. }
  584. }
  585. $paid = $form->round_amount($paid * $exchangerate, 2);
  586. $pth->execute($form->{"id_$i"}) || $form->dberror;
  587. ($amount) = $pth->fetchrow_array;
  588. $pth->finish;
  589. $amount += $paid;
  590. # update AR/AP transaction
  591. $query = qq|
  592. UPDATE $form->{arap}
  593. SET paid = $amount,
  594. datepaid = '$form->{datepaid}'
  595. WHERE id = $form->{"id_$i"}|;
  596. $sth = $dbh->prepare($query);
  597. $sth->execute(
  598. $amount, $form->{datepaid}, $form->{"id_$i"})
  599. || $form->dberror($query, 'CP.pm',
  600. 796);
  601. %audittrail = ( tablename => $form->{arap},
  602. reference => $form->{source},
  603. formname => $form->{formname},
  604. action => 'posted',
  605. id => $form->{"id_$i"} );
  606. $form->audittrail($dbh, "", \%audittrail);
  607. }
  608. $sameid = $form->{"$form->{vc}_id_$i"};
  609. }
  610. # record a AR/AP with a payment
  611. if ($overpayment > 0 && $form->{$form->{ARAP}}) {
  612. $form->{invnumber} = "";
  613. OP::overpayment("", $myconfig, $form, $dbh, $overpayment, $ml, 1);
  614. }
  615. my $rc = $dbh->commit;
  616. $rc;
  617. }
  618. 1;