summaryrefslogtreecommitdiff
path: root/LedgerSMB/PE.pm
blob: 604e62e7677465406a1769c107429fa26106330a (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. # This file has NOT undergone whitespace cleanup.
  27. #
  28. #======================================================================
  29. #
  30. # Project module
  31. # also used for partsgroups
  32. #
  33. #======================================================================
  34. package PE;
  35. sub projects {
  36. my ($self, $myconfig, $form) = @_;
  37. # connect to database
  38. my $dbh = $form->dbconnect($myconfig);
  39. $form->{sort} = "projectnumber" unless $form->{sort};
  40. my @a = ($form->{sort});
  41. my %ordinal = ( projectnumber => 2,
  42. description => 3,
  43. startdate => 4,
  44. enddate => 5,
  45. );
  46. my $sortorder = $form->sort_order(\@a, \%ordinal);
  47. my $query;
  48. my $where = "WHERE 1=1";
  49. $query = qq|SELECT pr.*, c.name
  50. FROM project pr
  51. LEFT JOIN customer c ON (c.id = pr.customer_id)|;
  52. if ($form->{type} eq 'job') {
  53. $where .= qq| AND pr.id NOT IN (SELECT DISTINCT id
  54. FROM parts
  55. WHERE project_id > 0)|;
  56. }
  57. my $var;
  58. if ($form->{projectnumber} ne "") {
  59. $var = $form->like(lc $form->{projectnumber});
  60. $where .= " AND lower(pr.projectnumber) LIKE '$var'";
  61. }
  62. if ($form->{description} ne "") {
  63. $var = $form->like(lc $form->{description});
  64. $where .= " AND lower(pr.description) LIKE '$var'";
  65. }
  66. ($form->{startdatefrom}, $form->{startdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
  67. if ($form->{startdatefrom}) {
  68. $where .= " AND (pr.startdate IS NULL OR pr.startdate >= '$form->{startdatefrom}')";
  69. }
  70. if ($form->{startdateto}) {
  71. $where .= " AND (pr.startdate IS NULL OR pr.startdate <= '$form->{startdateto}')";
  72. }
  73. if ($form->{status} eq 'orphaned') {
  74. $where .= qq| AND pr.id NOT IN (SELECT DISTINCT project_id
  75. FROM acc_trans
  76. WHERE project_id > 0
  77. UNION
  78. SELECT DISTINCT project_id
  79. FROM invoice
  80. WHERE project_id > 0
  81. UNION
  82. SELECT DISTINCT project_id
  83. FROM orderitems
  84. WHERE project_id > 0
  85. UNION
  86. SELECT DISTINCT project_id
  87. FROM jcitems
  88. WHERE project_id > 0)
  89. |;
  90. }
  91. if ($form->{status} eq 'active') {
  92. $where .= qq| AND (pr.enddate IS NULL OR pr.enddate >= current_date)|;
  93. }
  94. if ($form->{status} eq 'inactive') {
  95. $where .= qq| AND pr.enddate <= current_date|;
  96. }
  97. $query .= qq|
  98. $where
  99. ORDER BY $sortorder|;
  100. $sth = $dbh->prepare($query);
  101. $sth->execute || $form->dberror($query);
  102. my $i = 0;
  103. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  104. push @{ $form->{all_project} }, $ref;
  105. $i++;
  106. }
  107. $sth->finish;
  108. $dbh->disconnect;
  109. $i;
  110. }
  111. sub get_project {
  112. my ($self, $myconfig, $form) = @_;
  113. # connect to database
  114. my $dbh = $form->dbconnect($myconfig);
  115. my $query;
  116. my $sth;
  117. my $ref;
  118. my $where;
  119. if ($form->{id}) {
  120. $where = "WHERE pr.id = $form->{id}" if $form->{id};
  121. $query = qq|SELECT pr.*,
  122. c.name AS customer
  123. FROM project pr
  124. LEFT JOIN customer c ON (c.id = pr.customer_id)
  125. $where|;
  126. $sth = $dbh->prepare($query);
  127. $sth->execute || $form->dberror($query);
  128. $ref = $sth->fetchrow_hashref(NAME_lc);
  129. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  130. $sth->finish;
  131. # check if it is orphaned
  132. $query = qq|SELECT count(*)
  133. FROM acc_trans
  134. WHERE project_id = $form->{id}
  135. UNION
  136. SELECT count(*)
  137. FROM invoice
  138. WHERE project_id = $form->{id}
  139. UNION
  140. SELECT count(*)
  141. FROM orderitems
  142. WHERE project_id = $form->{id}
  143. UNION
  144. SELECT count(*)
  145. FROM jcitems
  146. WHERE project_id = $form->{id}
  147. |;
  148. $sth = $dbh->prepare($query);
  149. $sth->execute || $form->dberror($query);
  150. my $count;
  151. while (($count) = $sth->fetchrow_array) {
  152. $form->{orphaned} += $count;
  153. }
  154. $sth->finish;
  155. $form->{orphaned} = !$form->{orphaned};
  156. }
  157. PE->get_customer($myconfig, $form, $dbh);
  158. $form->run_custom_queries('project', 'SELECT');
  159. $dbh->disconnect;
  160. }
  161. sub save_project {
  162. my ($self, $myconfig, $form) = @_;
  163. # connect to database
  164. my $dbh = $form->dbconnect($myconfig);
  165. $form->{customer_id} ||= 'NULL';
  166. $form->{projectnumber} = $form->update_defaults($myconfig, "projectnumber", $dbh) unless $form->{projectnumber};
  167. if ($form->{id}) {
  168. $query = qq|UPDATE project SET
  169. projectnumber = |.$dbh->quote($form->{projectnumber}).qq|,
  170. description = |.$dbh->quote($form->{description}).qq|,
  171. startdate = |.$form->dbquote($form->{startdate}, SQL_DATE).qq|,
  172. enddate = |.$form->dbquote($form->{enddate}, SQL_DATE).qq|,
  173. customer_id = $form->{customer_id}
  174. WHERE id = $form->{id}|;
  175. } else {
  176. $query = qq|INSERT INTO project
  177. (projectnumber, description, startdate, enddate, customer_id)
  178. VALUES (|
  179. .$dbh->quote($form->{projectnumber}).qq|, |
  180. .$dbh->quote($form->{description}).qq|, |
  181. .$form->dbquote($form->{startdate}, SQL_DATE).qq|, |
  182. .$form->dbquote($form->{enddate}, SQL_DATE).qq|,
  183. $form->{customer_id}
  184. )|;
  185. }
  186. $dbh->do($query) || $form->dberror($query);
  187. $form->run_custom_queries('project', 'UPDATE');
  188. $dbh->disconnect;
  189. }
  190. sub list_stock {
  191. my ($self, $myconfig, $form) = @_;
  192. # connect to database
  193. my $dbh = $form->dbconnect($myconfig);
  194. my $var;
  195. my $where = "1 = 1";
  196. if ($form->{status} eq 'active') {
  197. $where = qq|(pr.enddate IS NULL
  198. OR pr.enddate >= current_date)
  199. AND pr.completed < pr.production|;
  200. }
  201. if ($form->{status} eq 'inactive') {
  202. $where = qq|pr.completed = pr.production|;
  203. }
  204. if ($form->{projectnumber}) {
  205. $var = $form->like(lc $form->{projectnumber});
  206. $where .= " AND lower(pr.projectnumber) LIKE '$var'";
  207. }
  208. if ($form->{description}) {
  209. $var = $form->like(lc $form->{description});
  210. $where .= " AND lower(pr.description) LIKE '$var'";
  211. }
  212. $form->{sort} = "projectnumber" unless $form->{sort};
  213. my @a = ($form->{sort});
  214. my %ordinal = ( projectnumber => 2,
  215. description => 3
  216. );
  217. my $sortorder = $form->sort_order(\@a, \%ordinal);
  218. my $query = qq|SELECT pr.*, p.partnumber
  219. FROM project pr
  220. JOIN parts p ON (p.id = pr.parts_id)
  221. WHERE $where
  222. ORDER BY $sortorder|;
  223. $sth = $dbh->prepare($query);
  224. $sth->execute || $form->dberror($query);
  225. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  226. push @{ $form->{all_project} }, $ref;
  227. }
  228. $sth->finish;
  229. $query = qq|SELECT current_date FROM defaults|;
  230. ($form->{stockingdate}) = $dbh->selectrow_array($query) if !$form->{stockingdate};
  231. $dbh->disconnect;
  232. }
  233. sub jobs {
  234. my ($self, $myconfig, $form) = @_;
  235. # connect to database
  236. my $dbh = $form->dbconnect($myconfig);
  237. $form->{sort} = "projectnumber" unless $form->{sort};
  238. my @a = ($form->{sort});
  239. my %ordinal = ( projectnumber => 2,
  240. description => 3,
  241. startdate => 4,
  242. );
  243. my $sortorder = $form->sort_order(\@a, \%ordinal);
  244. my $query = qq|SELECT pr.*, p.partnumber, p.onhand, c.name
  245. FROM project pr
  246. JOIN parts p ON (p.id = pr.parts_id)
  247. LEFT JOIN customer c ON (c.id = pr.customer_id)
  248. WHERE 1=1|;
  249. if ($form->{projectnumber} ne "") {
  250. $var = $form->like(lc $form->{projectnumber});
  251. $query .= " AND lower(pr.projectnumber) LIKE '$var'";
  252. }
  253. if ($form->{description} ne "") {
  254. $var = $form->like(lc $form->{description});
  255. $query .= " AND lower(pr.description) LIKE '$var'";
  256. }
  257. ($form->{startdatefrom}, $form->{startdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
  258. if ($form->{startdatefrom}) {
  259. $query .= " AND pr.startdate >= '$form->{startdatefrom}'";
  260. }
  261. if ($form->{startdateto}) {
  262. $query .= " AND pr.startdate <= '$form->{startdateto}'";
  263. }
  264. if ($form->{status} eq 'active') {
  265. $query .= qq| AND NOT pr.production = pr.completed|;
  266. }
  267. if ($form->{status} eq 'inactive') {
  268. $query .= qq| AND pr.production = pr.completed|;
  269. }
  270. if ($form->{status} eq 'orphaned') {
  271. $query .= qq| AND pr.completed = 0
  272. AND (pr.id NOT IN SELECT DISTINCT project_id
  273. FROM invoice
  274. WHERE project_id > 0)
  275. UNION
  276. SELECT DISTINCT project_id
  277. FROM orderitems
  278. WHERE project_id > 0
  279. SELECT DISTINCT project_id
  280. FROM jcitems
  281. WHERE project_id > 0
  282. )|;
  283. }
  284. $query .= qq|
  285. ORDER BY $sortorder|;
  286. $sth = $dbh->prepare($query);
  287. $sth->execute || $form->dberror($query);
  288. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  289. push @{ $form->{all_project} }, $ref;
  290. }
  291. $sth->finish;
  292. $dbh->disconnect;
  293. }
  294. sub get_job {
  295. my ($self, $myconfig, $form) = @_;
  296. # connect to database
  297. my $dbh = $form->dbconnect($myconfig);
  298. my $query;
  299. my $sth;
  300. my $ref;
  301. if ($form->{id}) {
  302. $query = qq|SELECT weightunit
  303. FROM defaults|;
  304. ($form->{weightunit}) = $dbh->selectrow_array($query);
  305. $query = qq|SELECT pr.*,
  306. p.partnumber, p.description AS partdescription, p.unit, p.listprice,
  307. p.sellprice, p.priceupdate, p.weight, p.notes, p.bin,
  308. p.partsgroup_id,
  309. ch.accno AS income_accno, ch.description AS income_description,
  310. pr.customer_id, c.name AS customer,
  311. pg.partsgroup
  312. FROM project pr
  313. LEFT JOIN parts p ON (p.id = pr.parts_id)
  314. LEFT JOIN chart ch ON (ch.id = p.income_accno_id)
  315. LEFT JOIN customer c ON (c.id = pr.customer_id)
  316. LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
  317. WHERE pr.id = $form->{id}|;
  318. } else {
  319. $query = qq|SELECT weightunit, current_date AS startdate FROM defaults|;
  320. }
  321. $sth = $dbh->prepare($query);
  322. $sth->execute || $form->dberror($query);
  323. $ref = $sth->fetchrow_hashref(NAME_lc);
  324. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  325. $sth->finish;
  326. if ($form->{id}) {
  327. # check if it is orphaned
  328. $query = qq|SELECT count(*)
  329. FROM invoice
  330. WHERE project_id = $form->{id}
  331. UNION
  332. SELECT count(*)
  333. FROM orderitems
  334. WHERE project_id = $form->{id}
  335. UNION
  336. SELECT count(*)
  337. FROM jcitems
  338. WHERE project_id = $form->{id}
  339. |;
  340. $sth = $dbh->prepare($query);
  341. $sth->execute || $form->dberror($query);
  342. my $count;
  343. while (($count) = $sth->fetchrow_array) {
  344. $form->{orphaned} += $count;
  345. }
  346. $sth->finish;
  347. }
  348. $form->{orphaned} = !$form->{orphaned};
  349. $query = qq|SELECT accno, description, link
  350. FROM chart
  351. WHERE link LIKE '%IC%'
  352. ORDER BY accno|;
  353. $sth = $dbh->prepare($query);
  354. $sth->execute || $form->dberror($query);
  355. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  356. for (split /:/, $ref->{link}) {
  357. if (/IC/) {
  358. push @{ $form->{IC_links}{$_} }, { accno => $ref->{accno},
  359. description => $ref->{description} };
  360. }
  361. }
  362. }
  363. $sth->finish;
  364. if ($form->{id}) {
  365. $query = qq|SELECT ch.accno
  366. FROM parts p
  367. JOIN partstax pt ON (pt.parts_id = p.id)
  368. JOIN chart ch ON (pt.chart_id = ch.id)
  369. WHERE p.id = $form->{id}|;
  370. $sth = $dbh->prepare($query);
  371. $sth->execute || $form->dberror($query);
  372. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  373. $form->{amount}{$ref->{accno}} = $ref->{accno};
  374. }
  375. $sth->finish;
  376. }
  377. PE->get_customer($myconfig, $form, $dbh);
  378. $dbh->disconnect;
  379. }
  380. sub get_customer {
  381. my ($self, $myconfig, $form, $dbh) = @_;
  382. my $disconnect = 0;
  383. if (! $dbh) {
  384. $dbh = $form->dbconnect($myconfig);
  385. $disconnect = 1;
  386. }
  387. my $query;
  388. my $sth;
  389. my $ref;
  390. if (! $form->{startdate}) {
  391. $query = qq|SELECT current_date FROM defaults|;
  392. ($form->{startdate}) = $dbh->selectrow_array($query);
  393. }
  394. my $where = qq|(startdate >= '$form->{startdate}' OR startdate IS NULL OR enddate IS NULL)|;
  395. if ($form->{enddate}) {
  396. $where .= qq| AND (enddate >= '$form->{enddate}' OR enddate IS NULL)|;
  397. } else {
  398. $where .= qq| AND (enddate >= current_date OR enddate IS NULL)|;
  399. }
  400. $query = qq|SELECT count(*)
  401. FROM customer
  402. WHERE $where|;
  403. my ($count) = $dbh->selectrow_array($query);
  404. if ($count < $myconfig->{vclimit}) {
  405. $query = qq|SELECT id, name
  406. FROM customer
  407. WHERE $where|;
  408. if ($form->{customer_id}) {
  409. $query .= qq|
  410. UNION SELECT id,name
  411. FROM customer
  412. WHERE id = $form->{customer_id}|;
  413. }
  414. $query .= qq|
  415. ORDER BY name|;
  416. $sth = $dbh->prepare($query);
  417. $sth->execute || $form->dberror($query);
  418. @{ $form->{all_customer} } = ();
  419. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  420. push @{ $form->{all_customer} }, $ref;
  421. }
  422. $sth->finish;
  423. }
  424. $dbh->disconnect if $disconnect;
  425. }
  426. sub save_job {
  427. my ($self, $myconfig, $form) = @_;
  428. # connect to database
  429. my $dbh = $form->dbconnect_noauto($myconfig);
  430. my ($income_accno) = split /--/, $form->{IC_income};
  431. my ($partsgroup, $partsgroup_id) = split /--/, $form->{partsgroup};
  432. $partsgroup_id ||= 'NULL';
  433. if ($form->{id}) {
  434. $query = qq|SELECT id FROM project
  435. WHERE id = $form->{id}|;
  436. ($form->{id}) = $dbh->selectrow_array($query);
  437. }
  438. if (!$form->{id}) {
  439. my $uid = localtime;
  440. $uid .= "$$";
  441. $query = qq|INSERT INTO project (projectnumber)
  442. VALUES ('$uid')|;
  443. $dbh->do($query) || $form->dberror($query);
  444. $query = qq|SELECT id FROM project
  445. WHERE projectnumber = '$uid'|;
  446. ($form->{id}) = $dbh->selectrow_array($query);
  447. }
  448. $form->{projectnumber} = $form->update_defaults($myconfig, "projectnumber", $dbh) unless $form->{projectnumber};
  449. $query = qq|UPDATE project SET
  450. projectnumber = |.$dbh->quote($form->{projectnumber}).qq|,
  451. description = |.$dbh->quote($form->{description}).qq|,
  452. startdate = |.$form->dbquote($form->{startdate}, SQL_DATE).qq|,
  453. enddate = |.$form->dbquote($form->{enddate}, SQL_DATE).qq|,
  454. parts_id = $form->{id},
  455. production = |.$form->parse_amount($myconfig, $form->{production}).qq|,
  456. customer_id = $form->{customer_id}
  457. WHERE id = $form->{id}|;
  458. $dbh->do($query) || $form->dberror($query);
  459. #### add/edit assembly
  460. $query = qq|SELECT id FROM parts
  461. WHERE id = $form->{id}|;
  462. my ($id) = $dbh->selectrow_array($query);
  463. if (!$id) {
  464. $query = qq|INSERT INTO parts (id)
  465. VALUES ($form->{id})|;
  466. $dbh->do($query) || $form->dberror($query);
  467. }
  468. my $partnumber = ($form->{partnumber}) ? $form->{partnumber} : $form->{projectnumber};
  469. $query = qq|UPDATE parts SET
  470. partnumber = |.$dbh->quote($partnumber).qq|,
  471. description = |.$dbh->quote($form->{partdescription}).qq|,
  472. priceupdate = |.$form->dbquote($form->{priceupdate}, SQL_DATE).qq|,
  473. listprice = |.$form->parse_amount($myconfig, $form->{listprice}).qq|,
  474. sellprice = |.$form->parse_amount($myconfig, $form->{sellprice}).qq|,
  475. weight = |.$form->parse_amount($myconfig, $form->{weight}).qq|,
  476. bin = '$form->{bin}',
  477. unit = |.$dbh->quote($form->{unit}).qq|,
  478. notes = |.$dbh->quote($form->{notes}).qq|,
  479. income_accno_id = (SELECT id FROM chart
  480. WHERE accno = '$income_accno'),
  481. partsgroup_id = $partsgroup_id,
  482. assembly = '1',
  483. obsolete = '1',
  484. project_id = $form->{id}
  485. WHERE id = $form->{id}|;
  486. $dbh->do($query) || $form->dberror($query);
  487. $query = qq|DELETE FROM partstax
  488. WHERE parts_id = $form->{id}|;
  489. $dbh->do($query) || $form->dberror($query);
  490. for (split / /, $form->{taxaccounts}) {
  491. if ($form->{"IC_tax_$_"}) {
  492. $query = qq|INSERT INTO partstax (parts_id, chart_id)
  493. VALUES ($form->{id},
  494. (SELECT id
  495. FROM chart
  496. WHERE accno = '$_'))|;
  497. $dbh->do($query) || $form->dberror($query);
  498. }
  499. }
  500. $dbh->commit;
  501. $dbh->disconnect;
  502. }
  503. sub stock_assembly {
  504. my ($self, $myconfig, $form) = @_;
  505. # connect to database
  506. my $dbh = $form->dbconnect_noauto($myconfig);
  507. my $ref;
  508. my $query = qq|SELECT *
  509. FROM project
  510. WHERE id = ?|;
  511. my $sth = $dbh->prepare($query) || $form->dberror($query);
  512. $query = qq|SELECT COUNT(*)
  513. FROM parts
  514. WHERE project_id = ?|;
  515. my $rvh = $dbh->prepare($query) || $form->dberror($query);
  516. if (! $form->{stockingdate}) {
  517. $query = qq|SELECT current_date FROM defaults|;
  518. ($form->{stockingdate}) = $dbh->selectrow_array($query);
  519. }
  520. $query = qq|SELECT *
  521. FROM parts
  522. WHERE id = ?|;
  523. my $pth = $dbh->prepare($query) || $form->dberror($query);
  524. $query = qq|SELECT j.*, p.lastcost FROM jcitems j
  525. JOIN parts p ON (p.id = j.parts_id)
  526. WHERE j.project_id = ?
  527. AND j.checkedin <= '$form->{stockingdate}'
  528. ORDER BY parts_id|;
  529. my $jth = $dbh->prepare($query) || $form->dberror($query);
  530. $query = qq|INSERT INTO assembly (id, parts_id, qty, bom, adj)
  531. VALUES (?, ?, ?, '0', '0')|;
  532. my $ath = $dbh->prepare($query) || $form->dberror($query);
  533. my $i = 0;
  534. my $sold;
  535. my $ship;
  536. while (1) {
  537. $i++;
  538. last unless $form->{"id_$i"};
  539. $stock = $form->parse_amount($myconfig, $form->{"stock_$i"});
  540. if ($stock) {
  541. $sth->execute($form->{"id_$i"});
  542. $ref = $sth->fetchrow_hashref(NAME_lc);
  543. if ($stock > ($ref->{production} - $ref->{completed})) {
  544. $stock = $ref->{production} - $ref->{completed};
  545. }
  546. if (($stock * -1) > $ref->{completed}) {
  547. $stock = $ref->{completed} * -1;
  548. }
  549. $pth->execute($form->{"id_$i"});
  550. $pref = $pth->fetchrow_hashref(NAME_lc);
  551. my %assembly = ();
  552. my $lastcost = 0;
  553. my $sellprice = 0;
  554. my $listprice = 0;
  555. $jth->execute($form->{"id_$i"});
  556. while ($jref = $jth->fetchrow_hashref(NAME_lc)) {
  557. $assembly{qty}{$jref->{parts_id}} += ($jref->{qty} - $jref->{allocated});
  558. $assembly{parts_id}{$jref->{parts_id}} = $jref->{parts_id};
  559. $assembly{jcitems}{$jref->{id}} = $jref->{id};
  560. $lastcost += $form->round_amount(($jref->{lastcost} * ($jref->{qty} - $jref->{allocated})), 2);
  561. $sellprice += $form->round_amount(($jref->{sellprice} * ($jref->{qty} - $jref->{allocated})), 2);
  562. $listprice += $form->round_amount(($jref->{listprice} * ($jref->{qty} - $jref->{allocated})), 2);
  563. }
  564. $jth->finish;
  565. $uid = localtime;
  566. $uid .= "$$";
  567. $query = qq|INSERT INTO parts (partnumber)
  568. VALUES ('$uid')|;
  569. $dbh->do($query) || $form->dberror($query);
  570. $query = qq|SELECT id
  571. FROM parts
  572. WHERE partnumber = '$uid'|;
  573. ($uid) = $dbh->selectrow_array($query);
  574. $lastcost = $form->round_amount($lastcost / $stock, 2);
  575. $sellprice = ($pref->{sellprice}) ? $pref->{sellprice} : $form->round_amount($sellprice / $stock, 2);
  576. $listprice = ($pref->{listprice}) ? $pref->{listprice} : $form->round_amount($listprice / $stock, 2);
  577. $rvh->execute($form->{"id_$i"});
  578. my ($rev) = $rvh->fetchrow_array;
  579. $rvh->finish;
  580. $query = qq|UPDATE parts SET
  581. partnumber = '$pref->{partnumber}-$rev',
  582. description = '$pref->{partdescription}',
  583. priceupdate = '$form->{stockingdate}',
  584. unit = '$pref->{unit}',
  585. listprice = $listprice,
  586. sellprice = $sellprice,
  587. lastcost = $lastcost,
  588. weight = $pref->{weight},
  589. onhand = $stock,
  590. notes = '$pref->{notes}',
  591. assembly = '1',
  592. income_accno_id = $pref->{income_accno_id},
  593. bin = '$pref->{bin}',
  594. project_id = $form->{"id_$i"}
  595. WHERE id = $uid|;
  596. $dbh->do($query) || $form->dberror($query);
  597. $query = qq|INSERT INTO partstax (parts_id, chart_id)
  598. SELECT '$uid', chart_id FROM partstax
  599. WHERE parts_id = $pref->{id}|;
  600. $dbh->do($query) || $form->dberror($query);
  601. $pth->finish;
  602. for (keys %{$assembly{parts_id}}) {
  603. if ($assembly{qty}{$_}) {
  604. $ath->execute($uid, $assembly{parts_id}{$_}, $form->round_amount($assembly{qty}{$_} / $stock, 4));
  605. $ath->finish;
  606. }
  607. }
  608. $form->update_balance($dbh,
  609. "project",
  610. "completed",
  611. qq|id = $form->{"id_$i"}|,
  612. $stock);
  613. $query = qq|UPDATE jcitems SET
  614. allocated = qty
  615. WHERE allocated != qty
  616. AND checkedin <= '$form->{stockingdate}'
  617. AND project_id = $form->{"id_$i"}|;
  618. $dbh->do($query) || $form->dberror($query);
  619. $sth->finish;
  620. }
  621. }
  622. my $rc = $dbh->commit;
  623. $dbh->disconnect;
  624. $rc;
  625. }
  626. sub delete_project {
  627. my ($self, $myconfig, $form) = @_;
  628. # connect to database
  629. my $dbh = $form->dbconnect_noauto($myconfig);
  630. $query = qq|DELETE FROM project
  631. WHERE id = $form->{id}|;
  632. $dbh->do($query) || $form->dberror($query);
  633. $query = qq|DELETE FROM translation
  634. WHERE trans_id = $form->{id}|;
  635. $dbh->do($query) || $form->dberror($query);
  636. my $rc = $dbh->commit;
  637. $dbh->disconnect;
  638. $rc;
  639. }
  640. sub delete_partsgroup {
  641. my ($self, $myconfig, $form) = @_;
  642. # connect to database
  643. my $dbh = $form->dbconnect_noauto($myconfig);
  644. $query = qq|DELETE FROM partsgroup
  645. WHERE id = $form->{id}|;
  646. $dbh->do($query) || $form->dberror($query);
  647. $query = qq|DELETE FROM translation
  648. WHERE trans_id = $form->{id}|;
  649. $dbh->do($query) || $form->dberror($query);
  650. my $rc = $dbh->commit;
  651. $dbh->disconnect;
  652. $rc;
  653. }
  654. sub delete_pricegroup {
  655. my ($self, $myconfig, $form) = @_;
  656. # connect to database
  657. my $dbh = $form->dbconnect_noauto($myconfig);
  658. $query = qq|DELETE FROM pricegroup
  659. WHERE id = $form->{id}|;
  660. $dbh->do($query) || $form->dberror($query);
  661. my $rc = $dbh->commit;
  662. $dbh->disconnect;
  663. $rc;
  664. }
  665. sub delete_job {
  666. my ($self, $myconfig, $form) = @_;
  667. # connect to database
  668. my $dbh = $form->dbconnect_noauto($myconfig);
  669. my %audittrail = ( tablename => 'project',
  670. reference => $form->{id},
  671. formname => $form->{type},
  672. action => 'deleted',
  673. id => $form->{id} );
  674. $form->audittrail($dbh, "", \%audittrail);
  675. my $query = qq|DELETE FROM project
  676. WHERE id = $form->{id}|;
  677. $dbh->do($query) || $form->dberror($query);
  678. $query = qq|DELETE FROM translation
  679. WHERE trans_id = $form->{id}|;
  680. $dbh->do($query) || $form->dberror($query);
  681. # delete all the assemblies
  682. $query = qq|DELETE FROM assembly a
  683. JOIN parts p ON (a.id = p.id)
  684. WHERE p.project_id = $form->{id}|;
  685. $dbh->do($query) || $form->dberror($query);
  686. $query = qq|DELETE FROM parts
  687. WHERE project_id = $form->{id}|;
  688. $dbh->do($query) || $form->dberror($query);
  689. my $rc = $dbh->commit;
  690. $dbh->disconnect;
  691. $rc;
  692. }
  693. sub partsgroups {
  694. my ($self, $myconfig, $form) = @_;
  695. my $var;
  696. # connect to database
  697. my $dbh = $form->dbconnect($myconfig);
  698. $form->{sort} = "partsgroup" unless $form->{partsgroup};
  699. my @a = (partsgroup);
  700. my $sortorder = $form->sort_order(\@a);
  701. my $query = qq|SELECT g.*
  702. FROM partsgroup g|;
  703. my $where = "1 = 1";
  704. if ($form->{partsgroup} ne "") {
  705. $var = $form->like(lc $form->{partsgroup});
  706. $where .= " AND lower(partsgroup) LIKE '$var'";
  707. }
  708. $query .= qq|
  709. WHERE $where
  710. ORDER BY $sortorder|;
  711. if ($form->{status} eq 'orphaned') {
  712. $query = qq|SELECT g.*
  713. FROM partsgroup g
  714. LEFT JOIN parts p ON (p.partsgroup_id = g.id)
  715. WHERE $where
  716. EXCEPT
  717. SELECT g.*
  718. FROM partsgroup g
  719. JOIN parts p ON (p.partsgroup_id = g.id)
  720. WHERE $where
  721. ORDER BY $sortorder|;
  722. }
  723. $sth = $dbh->prepare($query);
  724. $sth->execute || $form->dberror($query);
  725. my $i = 0;
  726. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  727. push @{ $form->{item_list} }, $ref;
  728. $i++;
  729. }
  730. $sth->finish;
  731. $dbh->disconnect;
  732. $i;
  733. }
  734. sub save_partsgroup {
  735. my ($self, $myconfig, $form) = @_;
  736. # connect to database
  737. my $dbh = $form->dbconnect($myconfig);
  738. if ($form->{id}) {
  739. $query = qq|UPDATE partsgroup SET
  740. partsgroup = |.$dbh->quote($form->{partsgroup}).qq|
  741. WHERE id = $form->{id}|;
  742. } else {
  743. $query = qq|INSERT INTO partsgroup
  744. (partsgroup)
  745. VALUES (|.$dbh->quote($form->{partsgroup}).qq|)|;
  746. }
  747. $dbh->do($query) || $form->dberror($query);
  748. $dbh->disconnect;
  749. }
  750. sub get_partsgroup {
  751. my ($self, $myconfig, $form) = @_;
  752. # connect to database
  753. my $dbh = $form->dbconnect($myconfig);
  754. my $query = qq|SELECT *
  755. FROM partsgroup
  756. WHERE id = $form->{id}|;
  757. my $sth = $dbh->prepare($query);
  758. $sth->execute || $form->dberror($query);
  759. my $ref = $sth->fetchrow_hashref(NAME_lc);
  760. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  761. $sth->finish;
  762. # check if it is orphaned
  763. $query = qq|SELECT count(*)
  764. FROM parts
  765. WHERE partsgroup_id = $form->{id}|;
  766. $sth = $dbh->prepare($query);
  767. $sth->execute || $form->dberror($query);
  768. ($form->{orphaned}) = $sth->fetchrow_array;
  769. $form->{orphaned} = !$form->{orphaned};
  770. $sth->finish;
  771. $dbh->disconnect;
  772. }
  773. sub pricegroups {
  774. my ($self, $myconfig, $form) = @_;
  775. my $var;
  776. # connect to database
  777. my $dbh = $form->dbconnect($myconfig);
  778. $form->{sort} = "pricegroup" unless $form->{sort};
  779. my @a = (pricegroup);
  780. my $sortorder = $form->sort_order(\@a);
  781. my $query = qq|SELECT g.*
  782. FROM pricegroup g|;
  783. my $where = "1 = 1";
  784. if ($form->{pricegroup} ne "") {
  785. $var = $form->like(lc $form->{pricegroup});
  786. $where .= " AND lower(pricegroup) LIKE '$var'";
  787. }
  788. $query .= qq|
  789. WHERE $where
  790. ORDER BY $sortorder|;
  791. if ($form->{status} eq 'orphaned') {
  792. $query = qq|SELECT g.*
  793. FROM pricegroup g
  794. WHERE $where
  795. AND g.id NOT IN (SELECT DISTINCT pricegroup_id
  796. FROM partscustomer
  797. WHERE pricegroup_id > 0)
  798. ORDER BY $sortorder|;
  799. }
  800. $sth = $dbh->prepare($query);
  801. $sth->execute || $form->dberror($query);
  802. my $i = 0;
  803. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  804. push @{ $form->{item_list} }, $ref;
  805. $i++;
  806. }
  807. $sth->finish;
  808. $dbh->disconnect;
  809. $i;
  810. }
  811. sub save_pricegroup {
  812. my ($self, $myconfig, $form) = @_;
  813. # connect to database
  814. my $dbh = $form->dbconnect($myconfig);
  815. if ($form->{id}) {
  816. $query = qq|UPDATE pricegroup SET
  817. pricegroup = |.$dbh->quote($form->{pricegroup}).qq|
  818. WHERE id = $form->{id}|;
  819. } else {
  820. $query = qq|INSERT INTO pricegroup
  821. (pricegroup)
  822. VALUES (|.$dbh->quote($form->{pricegroup}).qq|)|;
  823. }
  824. $dbh->do($query) || $form->dberror($query);
  825. $dbh->disconnect;
  826. }
  827. sub get_pricegroup {
  828. my ($self, $myconfig, $form) = @_;
  829. # connect to database
  830. my $dbh = $form->dbconnect($myconfig);
  831. my $query = qq|SELECT *
  832. FROM pricegroup
  833. WHERE id = $form->{id}|;
  834. my $sth = $dbh->prepare($query);
  835. $sth->execute || $form->dberror($query);
  836. my $ref = $sth->fetchrow_hashref(NAME_lc);
  837. for (keys %$ref) { $form->{$_} = $ref->{$_} }
  838. $sth->finish;
  839. # check if it is orphaned
  840. $query = qq|SELECT count(*)
  841. FROM partscustomer
  842. WHERE pricegroup_id = $form->{id}|;
  843. $sth = $dbh->prepare($query);
  844. $sth->execute || $form->dberror($query);
  845. ($form->{orphaned}) = $sth->fetchrow_array;
  846. $form->{orphaned} = !$form->{orphaned};
  847. $sth->finish;
  848. $dbh->disconnect;
  849. }
  850. sub description_translations {
  851. my ($self, $myconfig, $form) = @_;
  852. my $where = "1 = 1";
  853. my $var;
  854. my $ref;
  855. for (qw(partnumber description)) {
  856. if ($form->{$_}) {
  857. $var = $form->like(lc $form->{$_});
  858. $where .= " AND lower(p.$_) LIKE '$var'";
  859. }
  860. }
  861. $where .= " AND p.obsolete = '0'";
  862. $where .= " AND p.id = $form->{id}" if $form->{id};
  863. # connect to database
  864. my $dbh = $form->dbconnect($myconfig);
  865. my %ordinal = ( 'partnumber' => 2,
  866. 'description' => 3
  867. );
  868. my @a = qw(partnumber description);
  869. my $sortorder = $form->sort_order(\@a, \%ordinal);
  870. my $query = qq|SELECT l.description AS language, t.description AS translation,
  871. l.code
  872. FROM translation t
  873. JOIN language l ON (l.code = t.language_code)
  874. WHERE trans_id = ?
  875. ORDER BY 1|;
  876. my $tth = $dbh->prepare($query);
  877. $query = qq|SELECT p.id, p.partnumber, p.description
  878. FROM parts p
  879. WHERE $where
  880. ORDER BY $sortorder|;
  881. my $sth = $dbh->prepare($query);
  882. $sth->execute || $form->dberror($query);
  883. my $tra;
  884. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  885. push @{ $form->{translations} }, $ref;
  886. # get translations for description
  887. $tth->execute($ref->{id}) || $form->dberror;
  888. while ($tra = $tth->fetchrow_hashref(NAME_lc)) {
  889. $form->{trans_id} = $ref->{id};
  890. $tra->{id} = $ref->{id};
  891. push @{ $form->{translations} }, $tra;
  892. }
  893. $tth->finish;
  894. }
  895. $sth->finish;
  896. &get_language("", $dbh, $form) if $form->{id};
  897. $dbh->disconnect;
  898. }
  899. sub partsgroup_translations {
  900. my ($self, $myconfig, $form) = @_;
  901. my $where = "1 = 1";
  902. my $ref;
  903. my $var;
  904. if ($form->{description}) {
  905. $var = $form->like(lc $form->{description});
  906. $where .= " AND lower(p.partsgroup) LIKE '$var'";
  907. }
  908. $where .= " AND p.id = $form->{id}" if $form->{id};
  909. # connect to database
  910. my $dbh = $form->dbconnect($myconfig);
  911. my $query = qq|SELECT l.description AS language, t.description AS translation,
  912. l.code
  913. FROM translation t
  914. JOIN language l ON (l.code = t.language_code)
  915. WHERE trans_id = ?
  916. ORDER BY 1|;
  917. my $tth = $dbh->prepare($query);
  918. $form->sort_order();
  919. $query = qq|SELECT p.id, p.partsgroup AS description
  920. FROM partsgroup p
  921. WHERE $where
  922. ORDER BY 2 $form->{direction}|;
  923. my $sth = $dbh->prepare($query);
  924. $sth->execute || $form->dberror($query);
  925. my $tra;
  926. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  927. push @{ $form->{translations} }, $ref;
  928. # get translations for partsgroup
  929. $tth->execute($ref->{id}) || $form->dberror;
  930. while ($tra = $tth->fetchrow_hashref(NAME_lc)) {
  931. $form->{trans_id} = $ref->{id};
  932. push @{ $form->{translations} }, $tra;
  933. }
  934. $tth->finish;
  935. }
  936. $sth->finish;
  937. &get_language("", $dbh, $form) if $form->{id};
  938. $dbh->disconnect;
  939. }
  940. sub project_translations {
  941. my ($self, $myconfig, $form) = @_;
  942. my $where = "1 = 1";
  943. my $var;
  944. my $ref;
  945. for (qw(projectnumber description)) {
  946. if ($form->{$_}) {
  947. $var = $form->like(lc $form->{$_});
  948. $where .= " AND lower(p.$_) LIKE '$var'";
  949. }
  950. }
  951. $where .= " AND p.id = $form->{id}" if $form->{id};
  952. # connect to database
  953. my $dbh = $form->dbconnect($myconfig);
  954. my %ordinal = ( 'projectnumber' => 2,
  955. 'description' => 3
  956. );
  957. my @a = qw(projectnumber description);
  958. my $sortorder = $form->sort_order(\@a, \%ordinal);
  959. my $query = qq|SELECT l.description AS language, t.description AS translation,
  960. l.code
  961. FROM translation t
  962. JOIN language l ON (l.code = t.language_code)
  963. WHERE trans_id = ?
  964. ORDER BY 1|;
  965. my $tth = $dbh->prepare($query);
  966. $query = qq|SELECT p.id, p.projectnumber, p.description
  967. FROM project p
  968. WHERE $where
  969. ORDER BY $sortorder|;
  970. my $sth = $dbh->prepare($query);
  971. $sth->execute || $form->dberror($query);
  972. my $tra;
  973. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  974. push @{ $form->{translations} }, $ref;
  975. # get translations for description
  976. $tth->execute($ref->{id}) || $form->dberror;
  977. while ($tra = $tth->fetchrow_hashref(NAME_lc)) {
  978. $form->{trans_id} = $ref->{id};
  979. $tra->{id} = $ref->{id};
  980. push @{ $form->{translations} }, $tra;
  981. }
  982. $tth->finish;
  983. }
  984. $sth->finish;
  985. &get_language("", $dbh, $form) if $form->{id};
  986. $dbh->disconnect;
  987. }
  988. sub get_language {
  989. my ($self, $dbh, $form) = @_;
  990. # get language
  991. my $query = qq|SELECT *
  992. FROM language
  993. ORDER BY 2|;
  994. my $sth = $dbh->prepare($query);
  995. $sth->execute || $form->dberror($query);
  996. while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
  997. push @{ $form->{all_language} }, $ref;
  998. }
  999. $sth->finish;
  1000. }
  1001. sub save_translation {
  1002. my ($self, $myconfig, $form) = @_;
  1003. # connect to database
  1004. my $dbh = $form->dbconnect_noauto($myconfig);
  1005. my $query = qq|DELETE FROM translation
  1006. WHERE trans_id = $form->{id}|;
  1007. $dbh->do($query) || $form->dberror($query);
  1008. $query = qq|INSERT INTO translation (trans_id, language_code, description)
  1009. VALUES ($form->{id}, ?, ?)|;
  1010. my $sth = $dbh->prepare($query) || $form->dberror($query);
  1011. foreach my $i (1 .. $form->{translation_rows}) {
  1012. if ($form->{"language_code_$i"} ne "") {
  1013. $sth->execute($form->{"language_code_$i"}, $form->{"translation_$i"});
  1014. $sth->finish;
  1015. }
  1016. }
  1017. $dbh->commit;
  1018. $dbh->disconnect;
  1019. }
  1020. sub delete_translation {
  1021. my ($self, $myconfig, $form) = @_;
  1022. # connect to database
  1023. my $dbh = $form->dbconnect($myconfig);
  1024. my $query = qq|DELETE FROM translation
  1025. WHERE trans_id = $form->{id}|;
  1026. $dbh->do($query) || $form->dberror($query);
  1027. $dbh->disconnect;
  1028. }
  1029. sub project_sales_order {
  1030. my ($self, $myconfig, $form) = @_;
  1031. # connect to database
  1032. my $dbh = $form->dbconnect($myconfig);
  1033. my $query = qq|SELECT current_date FROM defaults|;
  1034. my ($transdate) = $dbh->selectrow_array($query);
  1035. $form->all_years($myconfig, $dbh);
  1036. $form->all_projects($myconfig, $dbh, $transdate);
  1037. $form->all_employees($myconfig, $dbh, $transdate);
  1038. $dbh->disconnect;
  1039. }
  1040. sub get_jcitems {
  1041. my ($self, $myconfig, $form) = @_;
  1042. # connect to database
  1043. my $dbh = $form->dbconnect($myconfig);
  1044. my $null;
  1045. my $var;
  1046. my $where;
  1047. if ($form->{projectnumber}) {
  1048. ($null, $var) = split /--/, $form->{projectnumber};
  1049. $where .= " AND j.project_id = $var";
  1050. }
  1051. if ($form->{employee}) {
  1052. ($null, $var) = split /--/, $form->{employee};
  1053. $where .= " AND j.employee_id = $var";
  1054. }
  1055. ($form->{transdatefrom}, $form->{transdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month};
  1056. if ($form->{transdatefrom}) {
  1057. $where .= " AND j.checkedin >= '$form->{transdatefrom}'";
  1058. }
  1059. if ($form->{transdateto}) {
  1060. $where .= " AND j.checkedout <= (date '$form->{transdateto}' + interval '1 days')";
  1061. }
  1062. my $query;
  1063. my $ref;
  1064. $query = qq|SELECT j.id, j.description, j.qty - j.allocated AS qty,
  1065. j.sellprice, j.parts_id, pr.$form->{vc}_id, j.project_id,
  1066. j.checkedin::date AS transdate, j.notes,
  1067. c.name AS $form->{vc}, pr.projectnumber, p.partnumber
  1068. FROM jcitems j
  1069. JOIN project pr ON (pr.id = j.project_id)
  1070. JOIN employee e ON (e.id = j.employee_id)
  1071. JOIN parts p ON (p.id = j.parts_id)
  1072. LEFT JOIN $form->{vc} c ON (c.id = pr.$form->{vc}_id)
  1073. WHERE pr.parts_id IS NULL
  1074. AND j.allocated != j.qty
  1075. $where
  1076. ORDER BY pr.projectnumber, c.name, j.checkedin::date|;
  1077. if ($form->{summary}) {
  1078. $query =~ s/j\.description/p\.description/;
  1079. $query =~ s/c\.name,/c\.name, j\.parts_id, /;
  1080. }
  1081. $sth = $dbh->prepare($query);
  1082. $sth->execute || $form->dberror($query);
  1083. # tax accounts
  1084. $query = qq|SELECT c.accno
  1085. FROM chart c
  1086. JOIN partstax pt ON (pt.chart_id = c.id)
  1087. WHERE pt.parts_id = ?|;
  1088. my $tth = $dbh->prepare($query) || $form->dberror($query);
  1089. my $ptref;
  1090. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  1091. $tth->execute($ref->{parts_id});
  1092. $ref->{taxaccounts} = "";
  1093. while ($ptref = $tth->fetchrow_hashref(NAME_lc)) {
  1094. $ref->{taxaccounts} .= "$ptref->{accno} ";
  1095. }
  1096. $tth->finish;
  1097. chop $ref->{taxaccounts};
  1098. $ref->{amount} = $ref->{sellprice} * $ref->{qty};
  1099. push @{ $form->{jcitems} }, $ref;
  1100. }
  1101. $sth->finish;
  1102. $query = qq|SELECT curr
  1103. FROM defaults|;
  1104. ($form->{currency}) = $dbh->selectrow_array($query);
  1105. $form->{currency} =~ s/:.*//;
  1106. $form->{defaultcurrency} = $form->{currency};
  1107. $query = qq|SELECT c.accno, t.rate
  1108. FROM tax t
  1109. JOIN chart c ON (c.id = t.chart_id)|;
  1110. $sth = $dbh->prepare($query);
  1111. $sth->execute || $form->dberror($query);
  1112. while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
  1113. $form->{taxaccounts} .= "$ref->{accno} ";
  1114. $form->{"$ref->{accno}_rate"} = $ref->{rate};
  1115. }
  1116. chop $form->{taxaccounts};
  1117. $sth->finish;
  1118. $dbh->disconnect;
  1119. }
  1120. sub allocate_projectitems {
  1121. my ($self, $myconfig, $form) = @_;
  1122. # connect to database
  1123. my $dbh = $form->dbconnect_noauto($myconfig);
  1124. for my $i (1 .. $form->{rowcount}) {
  1125. for (split / /, $form->{"jcitems_$i"}) {
  1126. my ($id, $qty) = split /:/, $_;
  1127. $form->update_balance($dbh,
  1128. 'jcitems',
  1129. 'allocated',
  1130. "id = $id",
  1131. $qty);
  1132. }
  1133. }
  1134. $rc = $dbh->commit;
  1135. $dbh->disconnect;
  1136. $rc;
  1137. }
  1138. 1;