/doc/tips/convert_mediawiki_to_ikiwiki/

nk rel='alternate' title='Atom feed' href='https://source.jones.dk/ledger-smb/atom/LedgerSMB/AA.pm?h=1.2.17+jones' type='application/atom+xml'/>
summaryrefslogtreecommitdiff
path: root/LedgerSMB/AA.pm
blob: fcf5782a188117ae1202ec3e8b87b7888a295b67 (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. # http://www.ledgersmb.org/
  5. # Copyright (C) 2006
  6. # This work contains copyrighted information from a number of sources all used
  7. # with permission.
  8. #
  9. # This file contains source code included with or based on SQL-Ledger which
  10. # is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
  11. # under the GNU General Public License version 2 or, at your option, any later
  12. # version. For a full list including contact information of contributors,
  13. # maintainers, and copyright holders, see the CONTRIBUTORS file.
  14. #
  15. # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
  16. # Copyright (C) 2006
  17. #
  18. # Author: DWS Systems Inc.
  19. # Web: http://www.sql-ledger.org
  20. #
  21. # Contributors:
  22. #
  23. #
  24. # See COPYRIGHT file for copyright information
  25. #======================================================================
  26. #
  27. # This file has undergone whitespace cleanup.
  28. #
  29. #======================================================================
  30. #
  31. # AR/AP backend routines
  32. # common routines
  33. #
  34. #======================================================================
  35. package AA;
  36. use LedgerSMB::Sysconfig;
  37. sub post_transaction {
  38. my ($self, $myconfig, $form) = @_;
  39. # connect to database
  40. my $dbh = $form->{dbh};
  41. my $query;
  42. my $sth;
  43. my $null;
  44. ($null, $form->{department_id}) = split(/--/, $form->{department});
  45. $form->{department_id} *= 1;
  46. my $ml = 1;
  47. my $table = 'ar';
  48. my $buysell = 'buy';
  49. my $ARAP = 'AR';
  50. my $invnumber = "sinumber";
  51. my $keepcleared;
  52. if ($form->{vc} eq 'vendor') {
  53. $table = 'ap';
  54. $buysell = 'sell';
  55. $ARAP = 'AP';
  56. $ml = -1;
  57. $invnumber = "vinumber";
  58. }
  59. if ($form->{currency} eq $form->{defaultcurrency}) {
  60. $form->{exchangerate} = 1;
  61. } else {
  62. $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, $buysell);
  63. $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
  64. }
  65. my @taxaccounts = split / /, $form->{taxaccounts};
  66. my $tax = 0;
  67. my $fxtax = 0;
  68. my $amount;
  69. my $diff;
  70. my %tax = ();
  71. my $accno;
  72. # add taxes
  73. foreach $accno (@taxaccounts) {
  74. $fxtax += $tax{fxamount}{$accno} = $form->parse_amount($myconfig, $form->{"tax_$accno"});
  75. $tax += $tax{fxamount}{$accno};
  76. push @{ $form->{acc_trans}{taxes} }, {
  77. accno => $accno,
  78. amount => $tax{fxamount}{$accno},
  79. project_id => 'NULL',
  80. fx_transaction => 0 };
  81. $amount = $tax{fxamount}{$accno} * $form->{exchangerate};
  82. $tax{amount}{$accno} = $form->round_amount($amount - $diff, 2);
  83. $diff = $tax{amount}{$accno} - ($amount - $diff);
  84. $amount = $tax{amount}{$accno} - $tax{fxamount}{$accno};
  85. $tax += $amount;
  86. if ($form->{currency} ne $form->{defaultcurrency}) {
  87. push @{ $form->{acc_trans}{taxes} }, {
  88. accno => $accno,
  89. amount => $amount,
  90. project_id => 'NULL',
  91. fx_transaction => 1 };
  92. }
  93. }
  94. my %amount = ();
  95. my $fxinvamount = 0;
  96. for (1 .. $form->{rowcount}) {
  97. $fxinvamount += $amount{fxamount}{$_} = $form->parse_amount($myconfig, $form->{"amount_$_"})
  98. }
  99. $form->{taxincluded} *= 1;
  100. my $i;
  101. my $project_id;
  102. my $cleared = 0;
  103. $diff = 0;
  104. # deduct tax from amounts if tax included
  105. for $i (1 .. $form->{rowcount}) {
  106. if ($amount{fxamount}{$i}) {
  107. if ($form->{taxincluded}) {
  108. $amount = ($fxinvamount) ? $fxtax * $amount{fxamount}{$i} / $fxinvamount : 0;
  109. $amount{fxamount}{$i} -= $amount;
  110. }
  111. # multiply by exchangerate
  112. $amount = $amount{fxamount}{$i} * $form->{exchangerate};
  113. $amount{amount}{$i} = $form->round_amount($amount - $diff, 2);
  114. $diff = $amount{amount}{$i} - ($amount - $diff);
  115. ($null, $project_id) = split /--/, $form->{"projectnumber_$i"};
  116. $project_id ||= 'NULL';
  117. ($accno) = split /--/, $form->{"${ARAP}_amount_$i"};
  118. if ($keepcleared) {
  119. $cleared = ($form->{"cleared_$i"}) ? 1 : 0;
  120. }
  121. push @{ $form->{acc_trans}{lineitems} }, {
  122. accno => $accno,
  123. amount => $amount{fxamount}{$i},
  124. project_id => $project_id,
  125. description => $form->{"description_$i"},
  126. cleared => $cleared,
  127. fx_transaction => 0 };
  128. if ($form->{currency} ne $form->{defaultcurrency}) {
  129. $amount = $amount{amount}{$i} - $amount{fxamount}{$i};
  130. push @{ $form->{acc_trans}{lineitems} }, {
  131. accno => $accno,
  132. amount => $amount,
  133. project_id => $project_id,
  134. description => $form->{"description_$i"},
  135. cleared => $cleared,
  136. fx_transaction => 1 };
  137. }
  138. }
  139. }
  140. my $invnetamount = 0;
  141. for (@{ $form->{acc_trans}{lineitems} }) { $invnetamount += $_->{amount} }
  142. my $invamount = $invnetamount + $tax;
  143. # adjust paidaccounts if there is no date in the last row
  144. $form->{paidaccounts}--
  145. unless ($form->{"datepaid_$form->{paidaccounts}"});
  146. if ($form->{vc} ne "customer"){
  147. $form->{vc} = "vendor";
  148. }
  149. my $paid = 0;
  150. my $fxamount;
  151. $diff = 0;
  152. # add payments
  153. for $i (1 .. $form->{paidaccounts}) {
  154. $fxamount = $form->parse_amount($myconfig, $form->{"paid_$i"});
  155. if ($fxamount) {
  156. $paid += $fxamount;
  157. $paidamount = $fxamount * $form->{exchangerate};
  158. $amount = $form->round_amount($paidamount - $diff, 2);
  159. $diff = $amount - ($paidamount - $diff);
  160. $form->{datepaid} = $form->{"datepaid_$i"};
  161. $paid{fxamount}{$i} = $fxamount;
  162. $paid{amount}{$i} = $amount;
  163. }
  164. }
  165. $fxinvamount += $fxtax unless $form->{taxincluded};
  166. $fxinvamount = $form->round_amount($fxinvamount, 2);
  167. $invamount = $form->round_amount($invamount, 2);
  168. $paid = $form->round_amount($paid, 2);
  169. $paid = ($fxinvamount == $paid)
  170. ? $invamount
  171. : $form->round_amount($paid * $form->{exchangerate}, 2);
  172. $query = q|
  173. SELECT (SELECT value FROM defaults
  174. WHERE setting_key = 'fxgain_accno_id'),
  175. (SELECT value FROM defaults
  176. WHERE setting_key = 'fxloss_accno_id')|;
  177. my ($fxgain_accno_id, $fxloss_accno_id) = $dbh->selectrow_array($query);
  178. ($null, $form->{employee_id}) = split /--/, $form->{employee};
  179. unless ($form->{employee_id}) {
  180. ($form->{employee}, $form->{employee_id}) =
  181. $form->get_employee($dbh);
  182. }
  183. # check if id really exists
  184. if ($form->{id}) {
  185. my $id = $dbh->quote($form->{id});
  186. $keepcleared = 1;
  187. $query = qq|
  188. SELECT id
  189. FROM $table
  190. WHERE id = $id|;
  191. if ($dbh->selectrow_array($query)) {
  192. # delete detail records
  193. $query = qq|
  194. DELETE FROM acc_trans
  195. WHERE trans_id = $id|;
  196. $dbh->do($query) || $form->dberror($query);
  197. }
  198. } else {
  199. my $uid = localtime;
  200. $uid .= "$$";
  201. $query = qq|
  202. INSERT INTO $table (invnumber)
  203. VALUES ('$uid')|;
  204. $dbh->do($query) || $form->dberror($query);
  205. $query = qq|
  206. SELECT id FROM $table
  207. WHERE invnumber = '$uid'|;
  208. ($form->{id}) = $dbh->selectrow_array($query);
  209. }
  210. # record last payment date in ar/ap table
  211. $form->{datepaid} = $form->{transdate} unless $form->{datepaid};
  212. my $datepaid = ($paid) ? qq|'$form->{datepaid}'| : 'NULL';
  213. $form->{invnumber} = $form->update_defaults($myconfig, $invnumber) unless $form->{invnumber};
  214. $query = qq|
  215. UPDATE $table
  216. SET invnumber = ?,
  217. ordnumber = ?,
  218. transdate = ?,
  219. $form->{vc}_id = ?,
  220. taxincluded = ?,
  221. amount = ?,
  222. duedate = ?,
  223. paid = ?,
  224. datepaid = ?,
  225. netamount = ?,
  226. curr = ?,
  227. notes = ?,
  228. department_id = ?,
  229. employee_id = ?,
  230. ponumber = ?
  231. WHERE id = ?
  232. |;
  233. my @queryargs = ($form->{invnumber}, $form->{ordnumber},
  234. $form->{transdate}, $form->{"$form->{vc}_id"},
  235. $form->{taxincluded}, $invamount, $form->{duedate}, $paid,
  236. $datepaid, $invnetamout, $form->{currency}, $form->{notes},
  237. $form->{department_id}, $form->{employee_id},
  238. $form->{ponumber}, $form->{id});
  239. $dbh->prepare($query)->execute(@queryargs) || $form->dberror($query);
  240. @queries = $form->run_custom_queries($table, 'INSERT');
  241. # update exchangerate
  242. my $buy = $form->{exchangerate};
  243. my $sell = 0;
  244. if ($form->{vc} eq 'vendor') {
  245. $buy = 0;
  246. $sell = $form->{exchangerate};
  247. }
  248. if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
  249. $form->update_exchangerate(
  250. $dbh, $form->{currency}, $form->{transdate},
  251. $buy, $sell);
  252. }
  253. my $ref;
  254. # add individual transactions
  255. foreach $ref (@{ $form->{acc_trans}{lineitems} }) {
  256. # insert detail records in acc_trans
  257. if ($ref->{amount}) {
  258. $query = qq|
  259. INSERT INTO acc_trans
  260. (trans_id, chart_id, amount,
  261. transdate, project_id, memo,
  262. fx_transaction, cleared)
  263. VALUES (?, (SELECT id FROM chart
  264. WHERE accno = ?),
  265. ?, ?, ?, ?, ?, ?)|;
  266. @queryargs = ($form->{id}, $ref->{accno},
  267. $ref->{amount} * $ml, $form->{transdate},
  268. $ref->{project_id}, $ref->{description},
  269. $ref->{fx_transaction}, $ref->{cleared});
  270. $dbh->prepare($query)->execute(@queryargs)
  271. || $form->dberror($query);
  272. }
  273. }
  274. # save taxes
  275. foreach $ref (@{ $form->{acc_trans}{taxes} }) {
  276. if ($ref->{amount}) {
  277. $query = qq|
  278. INSERT INTO acc_trans
  279. (trans_id, chart_id, amount,
  280. transdate, fx_transaction)
  281. VALUES (?, (SELECT id FROM chart
  282. WHERE accno = ?),
  283. ?, ?, ?)|;
  284. @queryargs = ($form->{id}, $ref->{accno},
  285. $ref->{amount} * $ml, $form->{transdate},
  286. $ref->{fx_transaction});
  287. $dbh->prepare($query)->execute(@queryargs)
  288. || $form->dberror($query);
  289. }
  290. }
  291. my $arap;
  292. # record ar/ap
  293. if (($arap = $invamount)) {
  294. ($accno) = split /--/, $form->{$ARAP};
  295. $query = qq|
  296. INSERT INTO acc_trans
  297. (trans_id, chart_id, amount, transdate)
  298. VALUES (?, (SELECT id FROM chart
  299. WHERE accno = '?'),
  300. ? * -1 * $ml, ?)|;
  301. @queryargs = ($form->{id}, $accno, $invamount,
  302. $form->{transdate});
  303. $dbh->prepare($query)->execute(@queryargs)
  304. || $form->dberror($query);
  305. }
  306. # if there is no amount force ar/ap
  307. if ($fxinvamount == 0) {
  308. $arap = 1;
  309. }
  310. my $exchangerate;
  311. # add paid transactions
  312. for $i (1 .. $form->{paidaccounts}) {
  313. if ($paid{fxamount}{$i}) {
  314. ($accno) = split(/--/, $form->{"${ARAP}_paid_$i"});
  315. $form->{"datepaid_$i"} = $form->{transdate} unless ($form->{"datepaid_$i"});
  316. $exchangerate = 0;
  317. if ($form->{currency} eq $form->{defaultcurrency}) {
  318. $form->{"exchangerate_$i"} = 1;
  319. } else {
  320. $exchangerate = $form->check_exchangerate(
  321. $myconfig, $form->{currency},
  322. $form->{"datepaid_$i"}, $buysell);
  323. $form->{"exchangerate_$i"} = ($exchangerate)
  324. ? $exchangerate
  325. : $form->parse_amount(
  326. $myconfig,
  327. $form->{"exchangerate_$i"});
  328. }
  329. # if there is no amount
  330. if ($fxinvamount == 0) {
  331. $form->{exchangerate} =
  332. $form->{"exchangerate_$i"};
  333. }
  334. # ar/ap amount
  335. if ($arap) {
  336. ($accno) = split /--/, $form->{$ARAP};
  337. # add ar/ap
  338. $query = qq|
  339. INSERT INTO acc_trans
  340. (trans_id, chart_id,
  341. amount,transdate)
  342. VALUES (?, (SELECT id FROM chart
  343. WHERE accno = ?),
  344. ? * $ml, ?)|;
  345. @queryargs = ($form->{id}, $paid{amount}{$i},
  346. $form->{"datepaid_$i"});
  347. $dbh->prepare($query)->execute(@queryargs)
  348. || $form->dberror($query);
  349. }
  350. $arap = $paid{amount}{$i};
  351. # add payment
  352. if ($paid{fxamount}{$i}) {
  353. ($accno) = split /--/, $form->{"${ARAP}_paid_$i"};
  354. my $cleared = ($form->{"cleared_$i"}) ? 1 : 0;
  355. $amount = $paid{fxamount}{$i};
  356. $query = qq|
  357. INSERT INTO acc_trans
  358. (trans_id, chart_id, amount,
  359. transdate, source, memo,
  360. cleared)
  361. VALUES (?, (SELECT id FROM chart
  362. WHERE accno = ?),
  363. ? * -1 * $ml, ?, ?, ?, ?)|;
  364. @queryargs = ($form->{id}, $accno, $amount,
  365. $form->{"datepaid_$i"},
  366. $form->{"source_$i"},
  367. $form->{"memo_$i"},
  368. $cleared);
  369. $dbh->prepare($query)->execute(@queryargs)
  370. || $form->dberror($query);
  371. if ($form->{currency}
  372. ne $form->{defaultcurrency}) {
  373. # exchangerate gain/loss
  374. $amount = ($form->round_amount(
  375. $paid{fxamount}{$i}
  376. * $form->{exchangerate},2) -
  377. $form->round_amount(
  378. $paid{fxamount}{$i}
  379. * $form->{"exchangerate_$i"},
  380. 2)) * -1;
  381. if ($amount) {
  382. my $accno_id = (($amount * $ml) > 0) ? $fxgain_accno_id : $fxloss_accno_id;
  383. $query = qq|
  384. INSERT INTO acc_trans
  385. (trans_id,
  386. chart_id,
  387. amount,
  388. transdate,
  389. fx_transaction,
  390. cleared)
  391. VALUES (?, ?,
  392. ? * $ml,
  393. ?, '1', ?)|;
  394. @queryargs = ($form->{id},
  395. $accno_id, $amount,
  396. $form->{"datepaid_$i"},
  397. $cleared);
  398. $sth = $dbh->prepare($query);
  399. $sth->execute(@queryargs)
  400. ||
  401. $form->dberror($query);
  402. }
  403. # exchangerate difference
  404. $amount = $paid{amount}{$i} - $paid{fxamount}{$i} + $amount;
  405. $query = qq|
  406. INSERT INTO acc_trans
  407. (trans_id, chart_id,
  408. amount,
  409. transdate,
  410. fx_transaction,
  411. cleared, source)
  412. VALUES (?, (SELECT id
  413. FROM chart
  414. WHERE accno
  415. = ?),
  416. ? * -1 * $ml, ?,
  417. '1', ?, ?)|;
  418. @queryargs = ($form->{id}, $accno,
  419. $amount, $form->{"datepaid_$i"},
  420. $cleared, $form->{"source_$i"});
  421. $sth = $dbh->prepare($query) ;
  422. $sth->execute(@queryargs)