summaryrefslogtreecommitdiff
path: root/LedgerSMB/AM.pm
blob: a5ebc53b13662b1a8cc5c696d826c4149501e693 (plain)
  1. #=====================================================================
  2. # LedgerSMB
  3. # Small Medium Business Accounting software
  4. #
  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) 2000
  17. #
  18. # Author: DWS Systems Inc.
  19. # Web: http://www.sql-ledger.org
  20. #
  21. # Contributors: Jim Rawlings <jim@your-dba.com>
  22. #
  23. #======================================================================
  24. #
  25. # This file has undergone whitespace cleanup.
  26. #
  27. #======================================================================
  28. #
  29. # Administration module
  30. # Chart of Accounts
  31. # template routines
  32. # preferences
  33. #
  34. #======================================================================
  35. package AM;
  36. sub get_account {
  37. my ($self, $myconfig, $form) = @_;
  38. # connect to database
  39. my $dbh = $form->dbconnect($myconfig);
  40. my $query = qq|SELECT accno, description, charttype, gifi_accno,
  41. category, link, contra
  42. FROM chart
  43. WHERE id = $form->{id}|;
  44. my $sth = $dbh->prepare($query);
  45. $sth->execute || $form->dberror($query);
  46. my $ref = $sth->fetchrow_hashref(NAME_lc);
  47. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  48. $sth->finish;
  49. # get default accounts
  50. $query = qq|SELECT inventory_accno_id, income_accno_id, expense_accno_id,
  51. fxgain_accno_id, fxloss_accno_id
  52. FROM defaults|;
  53. $sth = $dbh->prepare($query);
  54. $sth->execute || $form->dberror($query);
  55. $ref = $sth->fetchrow_hashref(NAME_lc);
  56. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  57. $sth->finish;
  58. # check if we have any transactions
  59. $query = qq|SELECT trans_id FROM acc_trans
  60. WHERE chart_id = $form->{id}|;
  61. ($form->{orphaned}) = $dbh->selectrow_array($query);
  62. $form->{orphaned} = !$form->{orphaned};
  63. $dbh->disconnect;
  64. }
  65. sub save_account {
  66. my ($self, $myconfig, $form) = @_;
  67. # connect to database, turn off AutoCommit
  68. my $dbh = $form->dbconnect_noauto($myconfig);
  69. $form->{link} = "";
  70. foreach my $item ($form->{AR},
  71. $form->{AR_amount},
  72. $form->{AR_tax},
  73. $form->{AR_paid},
  74. $form->{AP},
  75. $form->{AP_amount},
  76. $form->{AP_tax},
  77. $form->{AP_paid},
  78. $form->{IC},
  79. $form->{IC_income},
  80. $form->{IC_sale},
  81. $form->{IC_expense},
  82. $form->{IC_cogs},
  83. $form->{IC_taxpart},
  84. $form->{IC_taxservice}) {
  85. $form->{link} .= "${item}:" if ($item);
  86. }
  87. chop $form->{link};
  88. # strip blanks from accno
  89. for (qw(accno gifi_accno)) { $form->{$_} =~ s/( |')//g }
  90. foreach my $item (qw(accno gifi_accno description)) {
  91. $form->{$item} =~ s/-(-+)/-/g;
  92. $form->{$item} =~ s/ ( )+/ /g;
  93. }
  94. my $query;
  95. my $sth;
  96. $form->{contra} *= 1;
  97. # if we have an id then replace the old record
  98. if ($form->{id}) {
  99. $query = qq|UPDATE chart SET accno = '$form->{accno}',
  100. description = |.$dbh->quote($form->{description}).qq|,
  101. charttype = '$form->{charttype}',
  102. gifi_accno = '$form->{gifi_accno}',
  103. category = '$form->{category}',
  104. link = '$form->{link}',
  105. contra = '$form->{contra}'
  106. WHERE id = $form->{id}|;
  107. } else {
  108. $query = qq|INSERT INTO chart (accno, description, charttype,
  109. gifi_accno, category, link, contra)
  110. VALUES ('$form->{accno}',|
  111. .$dbh->quote($form->{description}).qq|,
  112. '$form->{charttype}', '$form->{gifi_accno}',
  113. '$form->{category}', '$form->{link}', '$form->{contra}')|;
  114. }
  115. $dbh->do($query) || $form->dberror($query);
  116. $chart_id = $form->{id};
  117. if (! $form->{id}) {
  118. # get id from chart
  119. $query = qq|SELECT id
  120. FROM chart
  121. WHERE accno = '$form->{accno}'|;
  122. ($chart_id) = $dbh->selectrow_array($query);
  123. }
  124. if ($form->{IC_taxpart} || $form->{IC_taxservice} || $form->{AR_tax} || $form->{AP_tax}) {
  125. # add account if it doesn't exist in tax
  126. $query = qq|SELECT chart_id
  127. FROM tax
  128. WHERE chart_id = $chart_id|;
  129. my ($tax_id) = $dbh->selectrow_array($query);
  130. # add tax if it doesn't exist
  131. unless ($tax_id) {
  132. $query = qq|INSERT INTO tax (chart_id, rate)
  133. VALUES ($chart_id, 0)|;
  134. $dbh->do($query) || $form->dberror($query);
  135. }
  136. } else {
  137. # remove tax
  138. if ($form->{id}) {
  139. $query = qq|DELETE FROM tax
  140. WHERE chart_id = $form->{id}|;
  141. $dbh->do($query) || $form->dberror($query);
  142. }
  143. }
  144. # commit
  145. my $rc = $dbh->commit;
  146. $dbh->disconnect;
  147. $rc;
  148. }
  149. sub delete_account {
  150. my ($self, $myconfig, $form) = @_;
  151. # connect to database, turn off AutoCommit
  152. my $dbh = $form->dbconnect_noauto($myconfig);
  153. ## needs fixing (SELECT *...)
  154. my $query = qq|SELECT *
  155. FROM acc_trans
  156. WHERE chart_id = $form->{id}|;
  157. if ($dbh->selectrow_array($query)) {
  158. $dbh->disconnect;
  159. return;
  160. }
  161. # delete chart of account record
  162. $query = qq|DELETE FROM chart
  163. WHERE id = $form->{id}|;
  164. $dbh->do($query) || $form->dberror($query);
  165. # set inventory_accno_id, income_accno_id, expense_accno_id to defaults
  166. $query = qq|UPDATE parts
  167. SET inventory_accno_id = (SELECT inventory_accno_id
  168. FROM defaults)
  169. WHERE inventory_accno_id = $form->{id}|;
  170. $dbh->do($query) || $form->dberror($query);
  171. $query = qq|UPDATE parts
  172. SET income_accno_id = (SELECT income_accno_id
  173. FROM defaults)
  174. WHERE income_accno_id = $form->{id}|;
  175. $dbh->do($query) || $form->dberror($query);
  176. $query = qq|UPDATE parts
  177. SET expense_accno_id = (SELECT expense_accno_id
  178. FROM defaults)
  179. WHERE expense_accno_id = $form->{id}|;
  180. $dbh->do($query) || $form->dberror($query);
  181. foreach my $table (qw(partstax customertax vendortax tax)) {
  182. $query = qq|DELETE FROM $table
  183. WHERE chart_id = $form->{id}|;
  184. $dbh->do($query) || $form->dberror($query);
  185. }
  186. # commit and redirect
  187. my $rc = $dbh->commit;
  188. $dbh->disconnect;
  189. $rc;
  190. }
  191. sub gifi_accounts {
  192. my ($self, $myconfig, $form) = @_;
  193. # connect to database
  194. my $dbh = $form->dbconnect($myconfig);
  195. my $query = qq|SELECT accno, description
  196. FROM gifi
  197. ORDER BY accno|;
  198. $sth = $dbh->prepare($query);
  199. $sth->execute || $form->dberror($query);
  200. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  201. push @{ $form->{ALL} }, $ref;
  202. }
  203. $sth->finish;
  204. $dbh->disconnect;
  205. }
  206. sub get_gifi {
  207. my ($self, $myconfig, $form) = @_;
  208. # connect to database
  209. my $dbh = $form->dbconnect($myconfig);
  210. my $query = qq|SELECT accno, description
  211. FROM gifi
  212. WHERE accno = '$form->{accno}'|;
  213. ($form->{accno}, $form->{description}) = $dbh->selectrow_array($query);
  214. # check for transactions ## needs fixing (SELECT *...)
  215. $query = qq|SELECT *
  216. FROM acc_trans a
  217. JOIN chart c ON (a.chart_id = c.id)
  218. JOIN gifi g ON (c.gifi_accno = g.accno)
  219. WHERE g.accno = '$form->{accno}'|;
  220. ($form->{orphaned}) = $dbh->selectrow_array($query);
  221. $form->{orphaned} = !$form->{orphaned};
  222. $dbh->disconnect;
  223. }
  224. sub save_gifi {
  225. my ($self, $myconfig, $form) = @_;
  226. # connect to database
  227. my $dbh = $form->dbconnect($myconfig);
  228. $form->{accno} =~ s/( |')//g;
  229. foreach my $item (qw(accno description)) {
  230. $form->{$item} =~ s/-(-+)/-/g;
  231. $form->{$item} =~ s/ ( )+/ /g;
  232. }
  233. # id is the old account number!
  234. if ($form->{id}) {
  235. $query = qq|UPDATE gifi
  236. SET accno = '$form->{accno}',
  237. description = |.$dbh->quote($form->{description}).qq|
  238. WHERE accno = '$form->{id}'|;
  239. } else {
  240. $query = qq|INSERT INTO gifi (accno, description)
  241. VALUES ('$form->{accno}',|
  242. .$dbh->quote($form->{description}).qq|)|;
  243. }
  244. $dbh->do($query) || $form->dberror;
  245. $dbh->disconnect;
  246. }
  247. sub delete_gifi {
  248. my ($self, $myconfig, $form) = @_;
  249. # connect to database
  250. my $dbh = $form->dbconnect($myconfig);
  251. # id is the old account number!
  252. $query = qq|DELETE FROM gifi
  253. WHERE accno = '$form->{id}'|;
  254. $dbh->do($query) || $form->dberror($query);
  255. $dbh->disconnect;
  256. }
  257. sub warehouses {
  258. my ($self, $myconfig, $form) = @_;
  259. # connect to database
  260. my $dbh = $form->dbconnect($myconfig);
  261. $form->sort_order();
  262. my $query = qq|SELECT id, description
  263. FROM warehouse
  264. ORDER BY description $form->{direction}|;
  265. $sth = $dbh->prepare($query);
  266. $sth->execute || $form->dberror($query);
  267. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  268. push @{ $form->{ALL} }, $ref;
  269. }
  270. $sth->finish;
  271. $dbh->disconnect;
  272. }
  273. sub get_warehouse {
  274. my ($self, $myconfig, $form) = @_;
  275. # connect to database
  276. my $dbh = $form->dbconnect($myconfig);
  277. my $query = qq|SELECT description
  278. FROM warehouse
  279. WHERE id = $form->{id}|;
  280. ($form->{description}) = $dbh->selectrow_array($query);
  281. # see if it is in use
  282. $query = qq|SELECT * FROM inventory
  283. WHERE warehouse_id = $form->{id}|;
  284. ($form->{orphaned}) = $dbh->selectrow_array($query);
  285. $form->{orphaned} = !$form->{orphaned};
  286. $dbh->disconnect;
  287. }
  288. sub save_warehouse {
  289. my ($self, $myconfig, $form) = @_;
  290. # connect to database
  291. my $dbh = $form->dbconnect($myconfig);
  292. $form->{description} =~ s/-(-)+/-/g;
  293. $form->{description} =~ s/ ( )+/ /g;
  294. if ($form->{id}) {
  295. $query = qq|UPDATE warehouse
  296. SET description = |.$dbh->quote($form->{description}).qq|
  297. WHERE id = $form->{id}|;
  298. } else {
  299. $query = qq|INSERT INTO warehouse (description)
  300. VALUES (|.$dbh->quote($form->{description}).qq|)|;
  301. }
  302. $dbh->do($query) || $form->dberror($query);
  303. $dbh->disconnect;
  304. }
  305. sub delete_warehouse {
  306. my ($self, $myconfig, $form) = @_;
  307. # connect to database
  308. my $dbh = $form->dbconnect($myconfig);
  309. $query = qq|DELETE FROM warehouse
  310. WHERE id = $form->{id}|;
  311. $dbh->do($query) || $form->dberror($query);
  312. $dbh->disconnect;
  313. }
  314. sub departments {
  315. my ($self, $myconfig, $form) = @_;
  316. # connect to database
  317. my $dbh = $form->dbconnect($myconfig);
  318. $form->sort_order();
  319. my $query = qq|SELECT id, description, role
  320. FROM department
  321. ORDER BY description $form->{direction}|;
  322. $sth = $dbh->prepare($query);
  323. $sth->execute || $form->dberror($query);
  324. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  325. push @{ $form->{ALL} }, $ref;
  326. }
  327. $sth->finish;
  328. $dbh->disconnect;
  329. }
  330. sub get_department {
  331. my ($self, $myconfig, $form) = @_;
  332. # connect to database
  333. my $dbh = $form->dbconnect($myconfig);
  334. my $query = qq|SELECT description, role
  335. FROM department
  336. WHERE id = $form->{id}|;
  337. ($form->{description}, $form->{role}) = $dbh->selectrow_array($query);
  338. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  339. # see if it is in use ## needs fixing (SELECT * ...)
  340. $query = qq|SELECT *
  341. FROM dpt_trans
  342. WHERE department_id = $form->{id}|;
  343. ($form->{orphaned}) = $dbh->selectrow_array($query);
  344. $form->{orphaned} = !$form->{orphaned};
  345. $dbh->disconnect;
  346. }
  347. sub save_department {
  348. my ($self, $myconfig, $form) = @_;
  349. # connect to database
  350. my $dbh = $form->dbconnect($myconfig);
  351. $form->{description} =~ s/-(-)+/-/g;
  352. $form->{description} =~ s/ ( )+/ /g;
  353. if ($form->{id}) {
  354. $query = qq|UPDATE department
  355. SET description = |.$dbh->quote($form->{description}).qq|,
  356. role = '$form->{role}'
  357. WHERE id = $form->{id}|;
  358. } else {
  359. $query = qq|INSERT INTO department (description, role)
  360. VALUES (| .$dbh->quote($form->{description}).qq|, '$form->{role}')|;
  361. }
  362. $dbh->do($query) || $form->dberror($query);
  363. $dbh->disconnect;
  364. }
  365. sub delete_department {
  366. my ($self, $myconfig, $form) = @_;
  367. # connect to database
  368. my $dbh = $form->dbconnect($myconfig);
  369. $query = qq|DELETE FROM department
  370. WHERE id = $form->{id}|;
  371. $dbh->do($query);
  372. $dbh->disconnect;
  373. }
  374. sub business {
  375. my ($self, $myconfig, $form) = @_;
  376. # connect to database
  377. my $dbh = $form->dbconnect($myconfig);
  378. $form->sort_order();
  379. my $query = qq|SELECT id, description, discount
  380. FROM business
  381. ORDER BY description $form->{direction}|;
  382. $sth = $dbh->prepare($query);
  383. $sth->execute || $form->dberror($query);
  384. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  385. push @{ $form->{ALL} }, $ref;
  386. }
  387. $sth->finish;
  388. $dbh->disconnect;
  389. }
  390. sub get_business {
  391. my ($self, $myconfig, $form) = @_;
  392. # connect to database
  393. my $dbh = $form->dbconnect($myconfig);
  394. my $query = qq|SELECT description, discount
  395. FROM business
  396. WHERE id = $form->{id}|;
  397. ($form->{description}, $form->{discount}) = $dbh->selectrow_array($query);
  398. $dbh->disconnect;
  399. }
  400. sub save_business {
  401. my ($self, $myconfig, $form) = @_;
  402. # connect to database
  403. my $dbh = $form->dbconnect($myconfig);
  404. $form->{description} =~ s/-(-)+/-/g;
  405. $form->{description} =~ s/ ( )+/ /g;
  406. $form->{discount} /= 100;
  407. if ($form->{id}) {
  408. $query = qq|UPDATE business
  409. SET description = |.$dbh->quote($form->{description}).qq|,
  410. discount = $form->{discount}
  411. WHERE id = $form->{id}|;
  412. } else {
  413. $query = qq|INSERT INTO business (description, discount)
  414. VALUES (| .$dbh->quote($form->{description}).qq|, $form->{discount})|;
  415. }
  416. $dbh->do($query) || $form->dberror($query);
  417. $dbh->disconnect;
  418. }
  419. sub delete_business {
  420. my ($self, $myconfig, $form) = @_;
  421. # connect to database
  422. my $dbh = $form->dbconnect($myconfig);
  423. $query = qq|DELETE FROM business
  424. WHERE id = $form->{id}|;
  425. $dbh->do($query) || $form->dberror($query);
  426. $dbh->disconnect;
  427. }
  428. sub sic {
  429. my ($self, $myconfig, $form) = @_;
  430. # connect to database
  431. my $dbh = $form->dbconnect($myconfig);
  432. $form->{sort} = "code" unless $form->{sort};
  433. my @a = qw(code description);
  434. my %ordinal = ( code => 1,
  435. description => 3 );
  436. my $sortorder = $form->sort_order(\@a, \%ordinal);
  437. my $query = qq|SELECT code, sictype, description
  438. FROM sic
  439. ORDER BY $sortorder|;
  440. $sth = $dbh->prepare($query);
  441. $sth->execute || $form->dberror($query);
  442. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  443. push @{ $form->{ALL} }, $ref;
  444. }
  445. $sth->finish;
  446. $dbh->disconnect;
  447. }
  448. sub get_sic {
  449. my ($self, $myconfig, $form) = @_;
  450. # connect to database
  451. my $dbh = $form->dbconnect($myconfig);
  452. my $query = qq|SELECT code, sictype, description
  453. FROM sic
  454. WHERE code = |.$dbh->quote($form->{code});
  455. my $sth = $dbh->prepare($query);
  456. $sth->execute || $form->dberror($query);
  457. my $ref = $sth->fetchrow_hashref(NAME_lc);
  458. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  459. $sth->finish;
  460. $dbh->disconnect;
  461. }
  462. sub save_sic {
  463. my ($self, $myconfig, $form) = @_;
  464. # connect to database
  465. my $dbh = $form->dbconnect($myconfig);
  466. foreach my $item (qw(code description)) {
  467. $form->{$item} =~ s/-(-)+/-/g;
  468. }
  469. # if there is an id
  470. if ($form->{id}) {
  471. $query = qq|UPDATE sic
  472. SET code = |.$dbh->quote($form->{code}).qq|,
  473. sictype = '$form->{sictype}',
  474. description = |.$dbh->quote($form->{description}).qq|
  475. WHERE code = |.$dbh->quote($form->{id});
  476. } else {
  477. $query = qq|INSERT INTO sic (code, sictype, description)
  478. VALUES (|.$dbh->quote($form->{code}).qq|,
  479. '$form->{sictype}',|
  480. .$dbh->quote($form->{description}).qq|)|;
  481. }
  482. $dbh->do($query) || $form->dberror($query);
  483. $dbh->disconnect;
  484. }
  485. sub delete_sic {
  486. my ($self, $myconfig, $form) = @_;
  487. # connect to database
  488. my $dbh = $form->dbconnect($myconfig);
  489. $query = qq|DELETE FROM sic
  490. WHERE code = |.$dbh->quote($form->{code});
  491. $dbh->do($query);
  492. $dbh->disconnect;
  493. }
  494. sub language {
  495. my ($self, $myconfig, $form) = @_;
  496. # connect to database
  497. my $dbh = $form->dbconnect($myconfig);
  498. $form->{sort} = "code" unless $form->{sort};
  499. my @a = qw(code description);
  500. my %ordinal = ( code => 1,
  501. description => 2 );
  502. my $sortorder = $form->sort_order(\@a, \%ordinal);
  503. my $query = qq|SELECT code, description
  504. FROM language
  505. ORDER BY $sortorder|;
  506. $sth = $dbh->prepare($query);
  507. $sth->execute || $form->dberror($query);
  508. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  509. push @{ $form->{ALL} }, $ref;
  510. }
  511. $sth->finish;
  512. $dbh->disconnect;
  513. }
  514. sub get_language {
  515. my ($self, $myconfig, $form) = @_;
  516. # connect to database
  517. my $dbh = $form->dbconnect($myconfig);
  518. ## needs fixing (SELECT *...)
  519. my $query = qq|SELECT *
  520. FROM language
  521. WHERE code = |.$dbh->quote($form->{code});
  522. my $sth = $dbh->prepare($query);
  523. $sth->execute || $form->dberror($query);
  524. my $ref = $sth->fetchrow_hashref(NAME_lc);
  525. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  526. $sth->finish;
  527. $dbh->disconnect;
  528. }
  529. sub save_language {
  530. my ($self, $myconfig, $form) = @_;
  531. # connect to database
  532. my $dbh = $form->dbconnect($myconfig);
  533. $form->{code} =~ s/ //g;
  534. foreach my $item (qw(code description)) {
  535. $form->{$item} =~ s/-(-)+/-/g;
  536. $form->{$item} =~ s/ ( )+/-/g;
  537. }
  538. # if there is an id
  539. if ($form->{id}) {
  540. $query = qq|UPDATE language
  541. SET code = |.$dbh->quote($form->{code}).qq|,
  542. description = |.$dbh->quote($form->{description}).qq|
  543. WHERE code = |.$dbh->quote($form->{id});
  544. } else {
  545. $query = qq|INSERT INTO language (code, description)
  546. VALUES (|.$dbh->quote($form->{code}).qq|,|
  547. .$dbh->quote($form->{description}).qq|)|;
  548. }
  549. $dbh->do($query) || $form->dberror($query);
  550. $dbh->disconnect;
  551. }
  552. sub delete_language {
  553. my ($self, $myconfig, $form) = @_;
  554. # connect to database
  555. my $dbh = $form->dbconnect($myconfig);
  556. $query = qq|DELETE FROM language
  557. WHERE code = |.$dbh->quote($form->{code});
  558. $dbh->do($query) || $form->dberror($query);
  559. $dbh->disconnect;
  560. }
  561. sub recurring_transactions {
  562. my ($self, $myconfig, $form) = @_;
  563. my $dbh = $form->dbconnect($myconfig);
  564. my $query = qq|SELECT curr FROM defaults|;
  565. my ($defaultcurrency) = $dbh->selectrow_array($query);
  566. $defaultcurrency =~ s/:.*//g;
  567. $form->{sort} ||= "nextdate";
  568. my @a = ($form->{sort});
  569. my $sortorder = $form->sort_order(\@a);
  570. $query = qq|SELECT 'ar' AS module, 'ar' AS transaction, a.invoice,
  571. n.name AS description, a.amount,
  572. s.*, se.formname AS recurringemail,
  573. sp.formname AS recurringprint,
  574. s.nextdate - current_date AS overdue, 'customer' AS vc,
  575. ex.buy AS exchangerate, a.curr,
  576. (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired
  577. FROM recurring s
  578. JOIN ar a ON (a.id = s.id)
  579. JOIN customer n ON (n.id = a.customer_id)
  580. LEFT JOIN recurringemail se ON (se.id = s.id)
  581. LEFT JOIN recurringprint sp ON (sp.id = s.id)
  582. LEFT JOIN exchangerate ex ON (ex.curr = a.curr AND a.transdate = ex.transdate)
  583. UNION
  584. SELECT 'ap' AS module, 'ap' AS transaction, a.invoice,
  585. n.name AS description, a.amount,
  586. s.*, se.formname AS recurringemail,
  587. sp.formname AS recurringprint,
  588. s.nextdate - current_date AS overdue, 'vendor' AS vc,
  589. ex.sell AS exchangerate, a.curr,
  590. (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired
  591. FROM recurring s
  592. JOIN ap a ON (a.id = s.id)
  593. JOIN vendor n ON (n.id = a.vendor_id)
  594. LEFT JOIN recurringemail se ON (se.id = s.id)
  595. LEFT JOIN recurringprint sp ON (sp.id = s.id)
  596. LEFT JOIN exchangerate ex ON (ex.curr = a.curr AND a.transdate = ex.transdate)
  597. UNION
  598. SELECT 'gl' AS module, 'gl' AS transaction, FALSE AS invoice,
  599. a.description, (SELECT SUM(ac.amount)
  600. FROM acc_trans ac
  601. WHERE ac.trans_id = a.id
  602. AND ac.amount > 0) AS amount,
  603. s.*, se.formname AS recurringemail,
  604. sp.formname AS recurringprint,
  605. s.nextdate - current_date AS overdue, '' AS vc,
  606. '1' AS exchangerate, '$defaultcurrency' AS curr,
  607. (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired
  608. FROM recurring s
  609. JOIN gl a ON (a.id = s.id)
  610. LEFT JOIN recurringemail se ON (se.id = s.id)
  611. LEFT JOIN recurringprint sp ON (sp.id = s.id)
  612. UNION
  613. SELECT 'oe' AS module, 'so' AS transaction, FALSE AS invoice,
  614. n.name AS description, a.amount,
  615. s.*, se.formname AS recurringemail,
  616. sp.formname AS recurringprint,
  617. s.nextdate - current_date AS overdue, 'customer' AS vc,
  618. ex.buy AS exchangerate, a.curr,
  619. (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired
  620. FROM recurring s
  621. JOIN oe a ON (a.id = s.id)
  622. JOIN customer n ON (n.id = a.customer_id)
  623. LEFT JOIN recurringemail se ON (se.id = s.id)
  624. LEFT JOIN recurringprint sp ON (sp.id = s.id)
  625. LEFT JOIN exchangerate ex ON (ex.curr = a.curr AND a.transdate = ex.transdate)
  626. WHERE a.quotation = '0'
  627. UNION
  628. SELECT 'oe' AS module, 'po' AS transaction, FALSE AS invoice,
  629. n.name AS description, a.amount,
  630. s.*, se.formname AS recurringemail,
  631. sp.formname AS recurringprint,
  632. s.nextdate - current_date AS overdue, 'vendor' AS vc,
  633. ex.sell AS exchangerate, a.curr,
  634. (s.nextdate IS NULL OR s.nextdate > s.enddate) AS expired
  635. FROM recurring s
  636. JOIN oe a ON (a.id = s.id)
  637. JOIN vendor n ON (n.id = a.vendor_id)
  638. LEFT JOIN recurringemail se ON (se.id = s.id)
  639. LEFT JOIN recurringprint sp ON (sp.id = s.id)
  640. LEFT JOIN exchangerate ex ON (ex.curr = a.curr AND a.transdate = ex.transdate)
  641. WHERE a.quotation = '0'
  642. ORDER BY $sortorder|;
  643. my $sth = $dbh->prepare($query);
  644. $sth->execute || $form->dberror($query);
  645. my $id;
  646. my $transaction;
  647. my %e = ();
  648. my %p = ();
  649. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  650. $ref->{exchangerate} ||= 1;
  651. if ($ref->{id} != $id) {
  652. if (%e) {
  653. $form->{transactions}{$transaction}->[$i]->{recurringemail} = "";
  654. for (keys %e) { $form->{transactions}{$transaction}->[$i]->{recurringemail} .= "${_}:" }
  655. chop $form->{transactions}{$transaction}->[$i]->{recurringemail};
  656. }
  657. if (%p) {
  658. $form->{transactions}{$transaction}->[$i]->{recurringprint} = "";
  659. for (keys %p) { $form->{transactions}{$transaction}->[$i]->{recurringprint} .= "${_}:" }
  660. chop $form->{transactions}{$transaction}->[$i]->{recurringprint};
  661. }
  662. %e = ();
  663. %p = ();
  664. push @{ $form->{transactions}{$ref->{transaction}} }, $ref;
  665. $id = $ref->{id};
  666. $i = $#{ $form->{transactions}{$ref->{transaction}} };
  667. }
  668. $transaction = $ref->{transaction};
  669. $e{$ref->{recurringemail}} = 1 if $ref->{recurringemail};
  670. $p{$ref->{recurringprint}} = 1 if $ref->{recurringprint};
  671. }
  672. $sth->finish;
  673. # this is for the last row
  674. if (%e) {
  675. $form->{transactions}{$transaction}->[$i]->{recurringemail} = "";
  676. for (keys %e) { $form->{transactions}{$transaction}->[$i]->{recurringemail} .= "${_}:" }
  677. chop $form->{transactions}{$transaction}->[$i]->{recurringemail};
  678. }
  679. if (%p) {
  680. $form->{transactions}{$transaction}->[$i]->{recurringprint} = "";
  681. for (keys %p) { $form->{transactions}{$transaction}->[$i]->{recurringprint} .= "${_}:" }
  682. chop $form->{transactions}{$transaction}->[$i]->{recurringprint};
  683. }
  684. $dbh->disconnect;
  685. }
  686. sub recurring_details {
  687. my ($self, $myconfig, $form, $id) = @_;
  688. my $dbh = $form->dbconnect($myconfig);
  689. my $query = qq|SELECT s.*, ar.id AS arid, ar.invoice AS arinvoice,
  690. ap.id AS apid, ap.invoice AS apinvoice,
  691. ar.duedate - ar.transdate AS overdue,
  692. ar.datepaid - ar.transdate AS paid,
  693. oe.reqdate - oe.transdate AS req,
  694. oe.id AS oeid, oe.customer_id, oe.vendor_id
  695. FROM recurring s
  696. LEFT JOIN ar ON (ar.id = s.id)
  697. LEFT JOIN ap ON (ap.id = s.id)
  698. LEFT JOIN oe ON (oe.id = s.id)
  699. WHERE s.id = $id|;
  700. my $sth = $dbh->prepare($query);
  701. $sth->execute || $form->dberror($query);
  702. my $ref = $sth->fetchrow_hashref(NAME_lc);
  703. $form->{vc} = "customer" if $ref->{customer_id};
  704. $form->{vc} = "vendor" if $ref->{vendor_id};
  705. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  706. $sth->finish;
  707. $form->{invoice} = ($form->{arid} && $form->{arinvoice});
  708. $form->{invoice} = ($form->{apid} && $form->{apinvoice}) unless $form->{invoice};
  709. $query = qq|SELECT *
  710. FROM recurringemail
  711. WHERE id = $id|;
  712. $sth = $dbh->prepare($query);
  713. $sth->execute || $form->dberror($query);
  714. $form->{recurringemail} = "";
  715. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  716. $form->{recurringemail} .= "$ref->{formname}:$ref->{format}:";
  717. $form->{message} = $ref->{message};
  718. }
  719. $sth->finish;
  720. $query = qq|SELECT *
  721. FROM recurringprint
  722. WHERE id = $id|;
  723. $sth = $dbh->prepare($query);
  724. $sth->execute || $form->dberror($query);
  725. $form->{recurringprint} = "";
  726. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  727. $form->{recurringprint} .= "$ref->{formname}:$ref->{format}:$ref->{printer}:";
  728. }
  729. $sth->finish;
  730. chop $form->{recurringemail};
  731. chop $form->{recurringprint};
  732. for (qw(arinvoice apinvoice)) { delete $form->{$_} }
  733. $dbh->disconnect;
  734. }
  735. sub update_recurring {
  736. my ($self, $myconfig, $form, $id) = @_;
  737. my $dbh = $form->dbconnect($myconfig);
  738. my $query = qq|SELECT nextdate, repeat, unit
  739. FROM recurring
  740. WHERE id = $id|;
  741. my ($nextdate, $repeat, $unit) = $dbh->selectrow_array($query);
  742. my %advance = ( 'Pg' => "(date '$nextdate' + interval '$repeat $unit')",
  743. 'DB2' => qq|(date ('$nextdate') + "$repeat $unit")|,);
  744. $interval{Oracle} = $interval{PgPP} = $interval{Pg};
  745. # check if it is the last date
  746. $query = qq|SELECT $advance{$myconfig->{dbdriver}} > enddate
  747. FROM recurring
  748. WHERE id = $id|;
  749. my ($last_repeat) = $dbh->selectrow_array($query);
  750. if ($last_repeat) {
  751. $advance{$myconfig->{dbdriver}} = "NULL";
  752. }
  753. $query = qq|UPDATE recurring
  754. SET nextdate = $advance{$myconfig->{dbdriver}}
  755. WHERE id = $id|;
  756. $dbh->do($query) || $form->dberror($query);
  757. $dbh->disconnect;
  758. }
  759. sub load_template {
  760. my ($self, $form) = @_;
  761. open(TEMPLATE, "$form->{file}") or $form->error("$form->{file} : $!");
  762. while (<TEMPLATE>) {
  763. $form->{body} .= $_;
  764. }
  765. close(TEMPLATE);
  766. }
  767. sub save_template {
  768. my ($self, $form) = @_;
  769. open(TEMPLATE, ">$form->{file}") or $form->error("$form->{file} : $!");
  770. # strip
  771. $form->{body} =~ s/\r//g;
  772. print TEMPLATE $form->{body};
  773. close(TEMPLATE);
  774. }
  775. sub save_preferences {
  776. my ($self, $myconfig, $form, $memberfile, $userspath) = @_;
  777. # connect to database
  778. my $dbh = $form->dbconnect($myconfig);
  779. # update name
  780. my $query = qq|UPDATE employee
  781. SET name = |.$dbh->quote($form->{name}).qq|,
  782. role = '$form->{role}'
  783. WHERE login = '$form->{login}'|;
  784. $dbh->do($query) || $form->dberror($query);
  785. # get default currency
  786. $query = qq|SELECT curr, businessnumber
  787. FROM defaults|;
  788. ($form->{currency}, $form->{businessnumber}) = $dbh->selectrow_array($query);
  789. $form->{currency} =~ s/:.*//;
  790. $dbh->disconnect;
  791. my $myconfig = new User "$memberfile", "$form->{login}";
  792. foreach my $item (keys %$form) {
  793. $myconfig->{$item} = $form->{$item};
  794. }
  795. $myconfig->{password} = $form->{new_password} if ($form->{old_password} ne $form->{new_password});
  796. $myconfig->save_member($memberfile, $userspath);
  797. 1;
  798. }
  799. sub save_defaults {
  800. my ($self, $myconfig, $form) = @_;
  801. for (qw(IC IC_income IC_expense FX_gain FX_loss)) { ($form->{$_}) = split /--/, $form->{$_} }
  802. my @a;
  803. $form->{curr} =~ s/ //g;
  804. for (split /:/, $form->{curr}) { push(@a, uc pack "A3", $_) if $_ }
  805. $form->{curr} = join ':', @a;
  806. # connect to database
  807. my $dbh = $form->dbconnect_noauto($myconfig);
  808. # save defaults
  809. my $query = qq|UPDATE defaults
  810. SET inventory_accno_id = (SELECT id
  811. FROM chart
  812. WHERE accno = '$form->{IC}'),
  813. income_accno_id = (SELECT id
  814. FROM chart
  815. WHERE accno = '$form->{IC_income}'),
  816. expense_accno_id = (SELECT id
  817. FROM chart
  818. WHERE accno = '$form->{IC_expense}'),
  819. fxgain_accno_id = (SELECT id
  820. FROM chart
  821. WHERE accno = '$form->{FX_gain}'),
  822. fxloss_accno_id = (SELECT id
  823. FROM chart
  824. WHERE accno = '$form->{FX_loss}'),
  825. glnumber = '$form->{glnumber}',
  826. sinumber = '$form->{sinumber}',
  827. vinumber = '$form->{vinumber}',
  828. sonumber = '$form->{sonumber}',
  829. ponumber = '$form->{ponumber}',
  830. sqnumber = '$form->{sqnumber}',
  831. rfqnumber = '$form->{rfqnumber}',
  832. partnumber = '$form->{partnumber}',
  833. employeenumber = '$form->{employeenumber}',
  834. customernumber = '$form->{customernumber}',
  835. vendornumber = '$form->{vendornumber}',
  836. projectnumber = '$form->{projectnumber}',
  837. yearend = '$form->{yearend}',
  838. curr = '$form->{curr}',
  839. weightunit = |.$dbh->quote($form->{weightunit}).qq|,
  840. businessnumber = |.$dbh->quote($form->{businessnumber});
  841. $dbh->do($query) || $form->dberror($query);
  842. my $rc = $dbh->commit;
  843. $dbh->disconnect;
  844. $rc;
  845. }
  846. sub defaultaccounts {
  847. my ($self, $myconfig, $form) = @_;
  848. # connect to database
  849. my $dbh = $form->dbconnect($myconfig);
  850. # get defaults from defaults table
  851. my $query = qq|SELECT * FROM defaults|;
  852. my $sth = $dbh->prepare($query);
  853. $sth->execute || $form->dberror($query);
  854. my $ref = $sth->fetchrow_hashref(NAME_lc);
  855. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  856. $form->{defaults}{IC} = $form->{inventory_accno_id};
  857. $form->{defaults}{IC_income} = $form->{income_accno_id};
  858. $form->{defaults}{IC_sale} = $form->{income_accno_id};
  859. $form->{defaults}{IC_expense} = $form->{expense_accno_id};
  860. $form->{defaults}{IC_cogs} = $form->{expense_accno_id};
  861. $form->{defaults}{FX_gain} = $form->{fxgain_accno_id};
  862. $form->{defaults}{FX_loss} = $form->{fxloss_accno_id};
  863. $sth->finish;
  864. $query = qq|SELECT id, accno, description, link
  865. FROM chart
  866. WHERE link LIKE '%IC%'
  867. ORDER BY accno|;
  868. $sth = $dbh->prepare($query);
  869. $sth->execute || $form->dberror($query);
  870. my $nkey;
  871. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  872. foreach my $key (split(/:/, $ref->{link})) {
  873. if ($key =~ /IC/) {
  874. $nkey = $key;
  875. if ($key =~ /cogs/) {
  876. $nkey = "IC_expense";
  877. }
  878. if ($key =~ /sale/) {
  879. $nkey = "IC_income";
  880. }
  881. %{ $form->{accno}{$nkey}{$ref->{accno}} } = ( id => $ref->{id},
  882. description => $ref->{description} );
  883. }
  884. }
  885. }
  886. $sth->finish;
  887. $query = qq|SELECT id, accno, description
  888. FROM chart
  889. WHERE (category = 'I' OR category = 'E')
  890. AND charttype = 'A'
  891. ORDER BY accno|;
  892. $sth = $dbh->prepare($query);
  893. $sth->execute || $form->dberror($query);
  894. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  895. %{ $form->{accno}{FX_gain}{$ref->{accno}} } = ( id => $ref->{id},
  896. description => $ref->{description} );
  897. %{ $form->{accno}{FX_loss}{$ref->{accno}} } = ( id => $ref->{id},
  898. description => $ref->{description} );
  899. }
  900. $sth->finish;
  901. $dbh->disconnect;
  902. }
  903. sub taxes {
  904. my ($self, $myconfig, $form) = @_;
  905. # connect to database
  906. my $dbh = $form->dbconnect($myconfig);
  907. my $query = qq|SELECT c.id, c.accno, c.description,
  908. t.rate * 100 AS rate, t.taxnumber, t.validto
  909. FROM chart c
  910. JOIN tax t ON (c.id = t.chart_id)
  911. ORDER BY 3, 6|;
  912. my $sth = $dbh->prepare($query);
  913. $sth->execute || $form->dberror($query);
  914. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  915. push @{ $form->{taxrates} }, $ref;
  916. }
  917. $sth->finish;
  918. $dbh->disconnect;
  919. }
  920. sub save_taxes {
  921. my ($self, $myconfig, $form) = @_;
  922. # connect to database
  923. my $dbh = $form->dbconnect_noauto($myconfig);
  924. my $query = qq|DELETE FROM tax|;
  925. $dbh->do($query) || $form->dberror($query);
  926. foreach my $item (split / /, $form->{taxaccounts}) {
  927. my ($chart_id, $i) = split /_/, $item;
  928. my $rate = $form->parse_amount($myconfig, $form->{"taxrate_$i"}) / 100;
  929. $query = qq|INSERT INTO tax (chart_id, rate, taxnumber, validto)
  930. VALUES ($chart_id, $rate, |
  931. .$dbh->quote($form->{"taxnumber_$i"}).qq|, |
  932. .$form->dbquote($form->{"validto_$i"}, SQL_DATE)
  933. .qq|)|;
  934. $dbh->do($query) || $form->dberror($query);
  935. }
  936. my $rc = $dbh->commit;
  937. $dbh->disconnect;
  938. $rc;
  939. }
  940. sub backup {
  941. my ($self, $myconfig, $form, $userspath, $gzip) = @_;
  942. my $mail;
  943. my $err;
  944. my @t = localtime(time);
  945. $t[4]++;
  946. $t[5] += 1900;
  947. $t[3] = substr("0$t[3]", -2);
  948. $t[4] = substr("0$t[4]", -2);
  949. my $boundary = time;
  950. my $tmpfile = "$userspath/$boundary.$myconfig->{dbname}-$form->{dbversion}-$t[5]$t[4]$t[3].sql";
  951. my $out = $form->{OUT};
  952. $form->{OUT} = ">$tmpfile";
  953. open(OUT, "$form->{OUT}") or $form->error("$form->{OUT} : $!");
  954. # get sequences, functions and triggers
  955. my @tables = ();
  956. my @sequences = ();
  957. my @functions = ();
  958. my @triggers = ();
  959. my @schema = ();
  960. # get dbversion from -tables.sql
  961. my $file = "$myconfig->{dbdriver}-tables.sql";
  962. open(FH, "sql/$file") or $form->error("sql/$file : $!");
  963. my @a = <FH>;
  964. close(FH);
  965. @dbversion = grep /defaults \(version\)/, @a;
  966. $dbversion = "@dbversion";
  967. $dbversion =~ /(\d+\.\d+\.\d+)/;
  968. $dbversion = User::calc_version($1);
  969. opendir SQLDIR, "sql/." or $form->error($!);
  970. @a = grep /$myconfig->{dbdriver}-upgrade-.*?\.sql$/, readdir SQLDIR;
  971. closedir SQLDIR;
  972. my $mindb;
  973. my $maxdb;
  974. foreach my $line (@a) {
  975. $upgradescript = $line;
  976. $line =~ s/(^$myconfig->{dbdriver}-upgrade-|\.sql$)//g;
  977. ($mindb, $maxdb) = split /-/, $line;
  978. $mindb = User::calc_version($mindb);
  979. next if $mindb < $dbversion;
  980. $maxdb = User::calc_version($maxdb);
  981. $upgradescripts{$maxdb} = $upgradescript;
  982. }
  983. $upgradescripts{$dbversion} = "$myconfig->{dbdriver}-tables.sql";
  984. $upgradescripts{functions} = "$myconfig->{dbdriver}-functions.sql";
  985. if (-f "sql/$myconfig->{dbdriver}-custom_tables.sql") {
  986. $upgradescripts{customtables} = "$myconfig->{dbdriver}-custom_tables.sql";
  987. }
  988. if (-f "sql/$myconfig->{dbdriver}-custom_functions.sql") {
  989. $upgradescripts{customfunctions} = "$myconfig->{dbdriver}-custom_functions.sql";
  990. }
  991. foreach my $key (sort keys %upgradescripts) {
  992. $file = $upgradescripts{$key};
  993. open(FH, "sql/$file") or $form->error("sql/$file : $!");
  994. push @schema, qq|-- $file\n|;
  995. while (<FH>) {
  996. if (/create table (\w+)/i) {
  997. push @tables, $1;
  998. }
  999. if (/create sequence (\w+)/i) {
  1000. push @sequences, $1;
  1001. next;
  1002. }
  1003. if (/end function/i) {
  1004. push @functions, $_;
  1005. $function = 0;
  1006. $temp = 0;
  1007. next;
  1008. }
  1009. if (/create function /i) {
  1010. $function = 1;
  1011. }
  1012. if ($function) {
  1013. push @functions, $_;
  1014. next;
  1015. }
  1016. if (/end trigger/i) {
  1017. push @triggers, $_;
  1018. $trigger = 0;
  1019. next;
  1020. }
  1021. if (/create trigger/i) {
  1022. $trigger = 1;
  1023. }
  1024. if ($trigger) {
  1025. push @triggers, $_;
  1026. next;
  1027. }
  1028. push @schema, $_ if $_ !~ /^(insert|--)/i;
  1029. }
  1030. close(FH);
  1031. }
  1032. # connect to database
  1033. my $dbh = $form->dbconnect($myconfig);
  1034. my $today = scalar localtime;
  1035. $myconfig->{dbhost} = 'localhost' unless $myconfig->{dbhost};
  1036. print OUT qq|-- LedgerSMB Backup
  1037. -- Dataset: $myconfig->{dbname}
  1038. -- Version: $form->{dbversion}
  1039. -- Host: $myconfig->{dbhost}
  1040. -- Login: $form->{login}
  1041. -- User: $myconfig->{name}
  1042. -- Date: $today
  1043. --
  1044. |;
  1045. @tables = grep !/^temp/, @tables;
  1046. # drop tables and sequences
  1047. for (@tables) { print OUT qq|DROP TABLE $_;\n| }
  1048. print OUT "--\n";
  1049. # triggers and index files are dropped with the tables
  1050. # drop functions
  1051. foreach $item (@functions) {
  1052. if ($item =~ /create function (.*\))/i) {
  1053. print OUT qq|DROP FUNCTION $1;\n|;
  1054. }
  1055. }
  1056. # create sequences
  1057. foreach $item (@sequences) {
  1058. if ($myconfig->{dbdriver} eq 'DB2') {
  1059. $query = qq|SELECT NEXTVAL FOR $item FROM sysibm.sysdummy1|;
  1060. } else {
  1061. $query = qq|SELECT last_value FROM $item|;
  1062. }
  1063. my ($id) = $dbh->selectrow_array($query);
  1064. if ($myconfig->{dbdriver} eq 'DB2') {
  1065. print OUT qq|DROP SEQUENCE $item RESTRICT
  1066. CREATE SEQUENCE $item AS INTEGER START WITH $id INCREMENT BY 1 MAXVALUE 2147483647 MINVALUE 1 CACHE 5;\n|;
  1067. } else {
  1068. if ($myconfig->{dbdriver} eq 'Pg') {
  1069. print OUT qq|CREATE SEQUENCE $item;
  1070. SELECT SETVAL('$item', $id, FALSE);\n|;
  1071. } else {
  1072. print OUT qq|DROP SEQUENCE $item
  1073. CREATE SEQUENCE $item START $id;\n|;
  1074. }
  1075. }
  1076. }
  1077. print OUT "--\n";
  1078. # add schema
  1079. print OUT @schema;
  1080. print OUT "\n";
  1081. print OUT qq|-- set options
  1082. $myconfig->{dboptions};
  1083. --
  1084. |;
  1085. my $query;
  1086. my $sth;
  1087. my @arr;
  1088. my $fields;
  1089. foreach $table (@tables) {
  1090. $query = qq|SELECT * FROM $table|;
  1091. $sth = $dbh->prepare($query);
  1092. $sth->execute || $form->dberror($query);
  1093. $query = qq|INSERT INTO $table (|;
  1094. $query .= join ',', (map { $sth->{NAME}->[$_] } (0 .. $sth->{NUM_OF_FIELDS} - 1));
  1095. $query .= qq|) VALUES|;
  1096. while (@arr = $sth->fetchrow_array) {
  1097. $fields = "(";
  1098. $fields .= join ',', map { $dbh->quote($_) } @arr;
  1099. $fields .= ")";
  1100. print OUT qq|$query $fields;\n|;
  1101. }
  1102. $sth->finish;
  1103. }
  1104. print OUT "--\n";
  1105. # functions
  1106. for (@functions) { print OUT $_ }
  1107. # triggers
  1108. for (@triggers) { print OUT $_ }
  1109. # add the index files
  1110. open(FH, "sql/$myconfig->{dbdriver}-indices.sql");
  1111. @a = <FH>;
  1112. close(FH);
  1113. print OUT @a;
  1114. close(OUT);
  1115. $dbh->disconnect;
  1116. # compress backup if gzip defined
  1117. my $suffix = "";
  1118. if ($gzip) {
  1119. my @args = split / /, $gzip;
  1120. my @s = @args;
  1121. push @args, "$tmpfile";
  1122. system(@args) == 0 or $form->error("$args[0] : $?");
  1123. shift @s;
  1124. my %s = @s;
  1125. $suffix = ${-S} || ".gz";
  1126. $tmpfile .= $suffix;
  1127. }
  1128. if ($form->{media} eq 'email') {
  1129. use LedgerSMB::Mailer;
  1130. $mail = new Mailer;
  1131. $mail->{to} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
  1132. $mail->{from} = qq|"$myconfig->{name}" <$myconfig->{email}>|;
  1133. $mail->{subject} = "LedgerSMB Backup / $myconfig->{dbname}-$form->{dbversion}-$t[5]$t[4]$t[3].sql$suffix";
  1134. @{ $mail->{attachments} } = ($tmpfile);
  1135. $mail->{version} = $form->{version};
  1136. $mail->{fileid} = "$boundary.";
  1137. $myconfig->{signature} =~ s/\\n/\n/g;
  1138. $mail->{message} = "-- \n$myconfig->{signature}";
  1139. $err = $mail->send($out);
  1140. }
  1141. if ($form->{media} eq 'file') {
  1142. open(IN, "$tmpfile") or $form->error("$tmpfile : $!");
  1143. open(OUT, ">-") or $form->error("STDOUT : $!");
  1144. print OUT qq|Content-Type: application/file;
  1145. Content-Disposition: attachment; filename="$myconfig->{dbname}-$form->{dbversion}-$t[5]$t[4]$t[3].sql$suffix"
  1146. |;
  1147. binmode(IN);
  1148. binmode(OUT);
  1149. while (<IN>) {
  1150. print OUT $_;
  1151. }
  1152. close(IN);
  1153. close(OUT);
  1154. }
  1155. unlink "$tmpfile";
  1156. }
  1157. sub closedto {
  1158. my ($self, $myconfig, $form) = @_;
  1159. my $dbh = $form->dbconnect($myconfig);
  1160. my $query = qq|SELECT closedto, revtrans, audittrail
  1161. FROM defaults|;
  1162. ($form->{closedto}, $form->{revtrans}, $form->{audittrail}) = $dbh->selectrow_array($query);
  1163. $dbh->disconnect;
  1164. }
  1165. sub closebooks {
  1166. my ($self, $myconfig, $form) = @_;
  1167. my $dbh = $form->dbconnect_noauto($myconfig);
  1168. my $query = qq|UPDATE defaults SET|;
  1169. if ($form->{revtrans}) {
  1170. $query .= qq| revtrans = '1'|;
  1171. } else {
  1172. $query .= qq| revtrans = '0'|;
  1173. }
  1174. $query .= qq|, closedto = |.$form->dbquote($form->{closedto}, SQL_DATE);
  1175. if ($form->{audittrail}) {
  1176. $query .= qq|, audittrail = '1'|;
  1177. } else {
  1178. $query .= qq|, audittrail = '0'|;
  1179. }
  1180. # set close in defaults
  1181. $dbh->do($query) || $form->dberror($query);
  1182. if ($form->{removeaudittrail}) {
  1183. $query = qq|DELETE FROM audittrail
  1184. WHERE transdate < '$form->{removeaudittrail}'|;
  1185. $dbh->do($query) || $form->dberror($query);
  1186. }
  1187. $dbh->commit;
  1188. $dbh->disconnect;
  1189. }
  1190. sub earningsaccounts {
  1191. my ($self, $myconfig, $form) = @_;
  1192. my ($query, $sth, $ref);
  1193. # connect to database
  1194. my $dbh = $form->dbconnect($myconfig);
  1195. # get chart of accounts
  1196. $query = qq|SELECT accno,description
  1197. FROM chart
  1198. WHERE charttype = 'A'
  1199. AND category = 'Q'
  1200. ORDER BY accno|;
  1201. $sth = $dbh->prepare($query);
  1202. $sth->execute || $form->dberror($query);
  1203. $form->{chart} = "";
  1204. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  1205. push @{ $form->{chart} }, $ref;
  1206. }
  1207. $sth->finish;
  1208. $dbh->disconnect;
  1209. }
  1210. sub post_yearend {
  1211. my ($self, $myconfig, $form) = @_;
  1212. # connect to database, turn off AutoCommit
  1213. my $dbh = $form->dbconnect_noauto($myconfig);
  1214. my $query;
  1215. my $uid = localtime;
  1216. $uid .= "$$";
  1217. $query = qq|INSERT INTO gl (reference, employee_id)
  1218. VALUES ('$uid', (SELECT id FROM employee
  1219. WHERE login = '$form->{login}'))|;
  1220. $dbh->do($query) || $form->dberror($query);
  1221. $query = qq|SELECT id
  1222. FROM gl
  1223. WHERE reference = '$uid'|;
  1224. ($form->{id}) = $dbh->selectrow_array($query);
  1225. $query = qq|UPDATE gl
  1226. SET reference = |.$dbh->quote($form->{reference}).qq|,
  1227. description = |.$dbh->quote($form->{description}).qq|,
  1228. notes = |.$dbh->quote($form->{notes}).qq|,
  1229. transdate = '$form->{transdate}',
  1230. department_id = 0
  1231. WHERE id = $form->{id}|;
  1232. $dbh->do($query) || $form->dberror($query);
  1233. my $amount;
  1234. my $accno;
  1235. # insert acc_trans transactions
  1236. for my $i (1 .. $form->{rowcount}) {
  1237. # extract accno
  1238. ($accno) = split(/--/, $form->{"accno_$i"});
  1239. $amount = 0;
  1240. if ($form->{"credit_$i"}) {
  1241. $amount = $form->{"credit_$i"};
  1242. }
  1243. if ($form->{"debit_$i"}) {
  1244. $amount = $form->{"debit_$i"} * -1;
  1245. }
  1246. # if there is an amount, add the record
  1247. if ($amount) {
  1248. $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, source)
  1249. VALUES ($form->{id}, (SELECT id
  1250. FROM chart
  1251. WHERE accno = '$accno'),
  1252. $amount, '$form->{transdate}', |
  1253. .$dbh->quote($form->{reference}).qq|)|;
  1254. $dbh->do($query) || $form->dberror($query);
  1255. }
  1256. }
  1257. $query = qq|INSERT INTO yearend (trans_id, transdate)
  1258. VALUES ($form->{id}, '$form->{transdate}')|;
  1259. $dbh->do($query) || $form->dberror($query);
  1260. my %audittrail = ( tablename => 'gl',
  1261. reference => $form->{reference},
  1262. formname => 'yearend',
  1263. action => 'posted',
  1264. id => $form->{id} );
  1265. $form->audittrail($dbh, "", \%audittrail);
  1266. # commit and redirect
  1267. my $rc = $dbh->commit;
  1268. $dbh->disconnect;
  1269. $rc;
  1270. }
  1271. 1;