diff options
Diffstat (limited to 'LedgerSMB/PE.pm')
-rwxr-xr-x | LedgerSMB/PE.pm | 1499 |
1 files changed, 1499 insertions, 0 deletions
diff --git a/LedgerSMB/PE.pm b/LedgerSMB/PE.pm new file mode 100755 index 00000000..d85f4cc3 --- /dev/null +++ b/LedgerSMB/PE.pm @@ -0,0 +1,1499 @@ +#===================================================================== +# LedgerSMB +# Small Medium Business Accounting software +# +# See COPYRIGHT file for copyright information +#====================================================================== +# +# This file has NOT undergone whitespace cleanup. +# +#====================================================================== +# +# Project module +# also used for partsgroups +# +#====================================================================== + +package PE; + + +sub projects { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{sort} = "projectnumber" unless $form->{sort}; + my @a = ($form->{sort}); + my %ordinal = ( projectnumber => 2, + description => 3, + startdate => 4, + enddate => 5, + ); + my $sortorder = $form->sort_order(\@a, \%ordinal); + + my $query; + my $where = "WHERE 1=1"; + + $query = qq|SELECT pr.*, c.name + FROM project pr + LEFT JOIN customer c ON (c.id = pr.customer_id)|; + + if ($form->{type} eq 'job') { + $where .= qq| AND pr.id NOT IN (SELECT DISTINCT id + FROM parts + WHERE project_id > 0)|; + } + + my $var; + if ($form->{projectnumber} ne "") { + $var = $form->like(lc $form->{projectnumber}); + $where .= " AND lower(pr.projectnumber) LIKE '$var'"; + } + if ($form->{description} ne "") { + $var = $form->like(lc $form->{description}); + $where .= " AND lower(pr.description) LIKE '$var'"; + } + + ($form->{startdatefrom}, $form->{startdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month}; + + if ($form->{startdatefrom}) { + $where .= " AND (pr.startdate IS NULL OR pr.startdate >= '$form->{startdatefrom}')"; + } + if ($form->{startdateto}) { + $where .= " AND (pr.startdate IS NULL OR pr.startdate <= '$form->{startdateto}')"; + } + + if ($form->{status} eq 'orphaned') { + $where .= qq| AND pr.id NOT IN (SELECT DISTINCT project_id + FROM acc_trans + WHERE project_id > 0 + UNION + SELECT DISTINCT project_id + FROM invoice + WHERE project_id > 0 + UNION + SELECT DISTINCT project_id + FROM orderitems + WHERE project_id > 0 + UNION + SELECT DISTINCT project_id + FROM jcitems + WHERE project_id > 0) + |; + + } + if ($form->{status} eq 'active') { + $where .= qq| AND (pr.enddate IS NULL OR pr.enddate >= current_date)|; + } + if ($form->{status} eq 'inactive') { + $where .= qq| AND pr.enddate <= current_date|; + } + + $query .= qq| + $where + ORDER BY $sortorder|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $i = 0; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{all_project} }, $ref; + $i++; + } + + $sth->finish; + $dbh->disconnect; + + $i; + +} + + +sub get_project { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query; + my $sth; + my $ref; + my $where; + + if ($form->{id}) { + + $where = "WHERE pr.id = $form->{id}" if $form->{id}; + + $query = qq|SELECT pr.*, + c.name AS customer + FROM project pr + LEFT JOIN customer c ON (c.id = pr.customer_id) + $where|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + + for (keys %$ref) { $form->{$_} = $ref->{$_} } + + $sth->finish; + + # check if it is orphaned + $query = qq|SELECT count(*) + FROM acc_trans + WHERE project_id = $form->{id} + UNION + SELECT count(*) + FROM invoice + WHERE project_id = $form->{id} + UNION + SELECT count(*) + FROM orderitems + WHERE project_id = $form->{id} + UNION + SELECT count(*) + FROM jcitems + WHERE project_id = $form->{id} + |; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $count; + while (($count) = $sth->fetchrow_array) { + $form->{orphaned} += $count; + } + $sth->finish; + $form->{orphaned} = !$form->{orphaned}; + } + + PE->get_customer($myconfig, $form, $dbh); + + $dbh->disconnect; + +} + + +sub save_project { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{customer_id} ||= 'NULL'; + + $form->{projectnumber} = $form->update_defaults($myconfig, "projectnumber", $dbh) unless $form->{projectnumber}; + + if ($form->{id}) { + + $query = qq|UPDATE project SET + projectnumber = |.$dbh->quote($form->{projectnumber}).qq|, + description = |.$dbh->quote($form->{description}).qq|, + startdate = |.$form->dbquote($form->{startdate}, SQL_DATE).qq|, + enddate = |.$form->dbquote($form->{enddate}, SQL_DATE).qq|, + customer_id = $form->{customer_id} + WHERE id = $form->{id}|; + } else { + + $query = qq|INSERT INTO project + (projectnumber, description, startdate, enddate, customer_id) + VALUES (| + .$dbh->quote($form->{projectnumber}).qq|, | + .$dbh->quote($form->{description}).qq|, | + .$form->dbquote($form->{startdate}, SQL_DATE).qq|, | + .$form->dbquote($form->{enddate}, SQL_DATE).qq|, + $form->{customer_id} + )|; + } + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + +} + + +sub list_stock { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $var; + my $where = "1 = 1"; + + if ($form->{status} eq 'active') { + $where = qq|(pr.enddate IS NULL + OR pr.enddate >= current_date) + AND pr.completed < pr.production|; + } + if ($form->{status} eq 'inactive') { + $where = qq|pr.completed = pr.production|; + } + + if ($form->{projectnumber}) { + $var = $form->like(lc $form->{projectnumber}); + $where .= " AND lower(pr.projectnumber) LIKE '$var'"; + } + + if ($form->{description}) { + $var = $form->like(lc $form->{description}); + $where .= " AND lower(pr.description) LIKE '$var'"; + } + + $form->{sort} = "projectnumber" unless $form->{sort}; + my @a = ($form->{sort}); + my %ordinal = ( projectnumber => 2, + description => 3 + ); + my $sortorder = $form->sort_order(\@a, \%ordinal); + + my $query = qq|SELECT pr.*, p.partnumber + FROM project pr + JOIN parts p ON (p.id = pr.parts_id) + WHERE $where + ORDER BY $sortorder|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{all_project} }, $ref; + } + $sth->finish; + + $query = qq|SELECT current_date FROM defaults|; + ($form->{stockingdate}) = $dbh->selectrow_array($query) if !$form->{stockingdate}; + + $dbh->disconnect; + +} + + +sub jobs { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{sort} = "projectnumber" unless $form->{sort}; + my @a = ($form->{sort}); + my %ordinal = ( projectnumber => 2, + description => 3, + startdate => 4, + ); + my $sortorder = $form->sort_order(\@a, \%ordinal); + + my $query = qq|SELECT pr.*, p.partnumber, p.onhand, c.name + FROM project pr + JOIN parts p ON (p.id = pr.parts_id) + LEFT JOIN customer c ON (c.id = pr.customer_id) + WHERE 1=1|; + + if ($form->{projectnumber} ne "") { + $var = $form->like(lc $form->{projectnumber}); + $query .= " AND lower(pr.projectnumber) LIKE '$var'"; + } + if ($form->{description} ne "") { + $var = $form->like(lc $form->{description}); + $query .= " AND lower(pr.description) LIKE '$var'"; + } + + ($form->{startdatefrom}, $form->{startdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month}; + + if ($form->{startdatefrom}) { + $query .= " AND pr.startdate >= '$form->{startdatefrom}'"; + } + if ($form->{startdateto}) { + $query .= " AND pr.startdate <= '$form->{startdateto}'"; + } + + if ($form->{status} eq 'active') { + $query .= qq| AND NOT pr.production = pr.completed|; + } + if ($form->{status} eq 'inactive') { + $query .= qq| AND pr.production = pr.completed|; + } + if ($form->{status} eq 'orphaned') { + $query .= qq| AND pr.completed = 0 + AND (pr.id NOT IN SELECT DISTINCT project_id + FROM invoice + WHERE project_id > 0) + UNION + SELECT DISTINCT project_id + FROM orderitems + WHERE project_id > 0 + SELECT DISTINCT project_id + FROM jcitems + WHERE project_id > 0 + )|; + } + + $query .= qq| + ORDER BY $sortorder|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{all_project} }, $ref; + } + + $sth->finish; + + $dbh->disconnect; + +} + + +sub get_job { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query; + my $sth; + my $ref; + + if ($form->{id}) { + $query = qq|SELECT weightunit + FROM defaults|; + ($form->{weightunit}) = $dbh->selectrow_array($query); + + $query = qq|SELECT pr.*, + p.partnumber, p.description AS partdescription, p.unit, p.listprice, + p.sellprice, p.priceupdate, p.weight, p.notes, p.bin, + p.partsgroup_id, + ch.accno AS income_accno, ch.description AS income_description, + pr.customer_id, c.name AS customer, + pg.partsgroup + FROM project pr + LEFT JOIN parts p ON (p.id = pr.parts_id) + LEFT JOIN chart ch ON (ch.id = p.income_accno_id) + LEFT JOIN customer c ON (c.id = pr.customer_id) + LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id) + WHERE pr.id = $form->{id}|; + } else { + $query = qq|SELECT weightunit, current_date AS startdate FROM defaults|; + } + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $ref = $sth->fetchrow_hashref(NAME_lc); + + for (keys %$ref) { $form->{$_} = $ref->{$_} } + + $sth->finish; + + if ($form->{id}) { + # check if it is orphaned + $query = qq|SELECT count(*) + FROM invoice + WHERE project_id = $form->{id} + UNION + SELECT count(*) + FROM orderitems + WHERE project_id = $form->{id} + UNION + SELECT count(*) + FROM jcitems + WHERE project_id = $form->{id} + |; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $count; + while (($count) = $sth->fetchrow_array) { + $form->{orphaned} += $count; + } + $sth->finish; + + } + + $form->{orphaned} = !$form->{orphaned}; + + $query = qq|SELECT accno, description, link + FROM chart + WHERE link LIKE '%IC%' + ORDER BY accno|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + for (split /:/, $ref->{link}) { + if (/IC/) { + push @{ $form->{IC_links}{$_} }, { accno => $ref->{accno}, + description => $ref->{description} }; + } + } + } + $sth->finish; + + if ($form->{id}) { + $query = qq|SELECT ch.accno + FROM parts p + JOIN partstax pt ON (pt.parts_id = p.id) + JOIN chart ch ON (pt.chart_id = ch.id) + WHERE p.id = $form->{id}|; + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + $form->{amount}{$ref->{accno}} = $ref->{accno}; + } + $sth->finish; + } + + PE->get_customer($myconfig, $form, $dbh); + + $dbh->disconnect; + +} + + +sub get_customer { + my ($self, $myconfig, $form, $dbh) = @_; + + my $disconnect = 0; + + if (! $dbh) { + $dbh = $form->dbconnect($myconfig); + $disconnect = 1; + } + + my $query; + my $sth; + my $ref; + + if (! $form->{startdate}) { + $query = qq|SELECT current_date FROM defaults|; + ($form->{startdate}) = $dbh->selectrow_array($query); + } + + my $where = qq|(startdate >= '$form->{startdate}' OR startdate IS NULL OR enddate IS NULL)|; + + if ($form->{enddate}) { + $where .= qq| AND (enddate >= '$form->{enddate}' OR enddate IS NULL)|; + } else { + $where .= qq| AND (enddate >= current_date OR enddate IS NULL)|; + } + + $query = qq|SELECT count(*) + FROM customer + WHERE $where|; + my ($count) = $dbh->selectrow_array($query); + + if ($count < $myconfig->{vclimit}) { + $query = qq|SELECT id, name + FROM customer + WHERE $where|; + + if ($form->{customer_id}) { + $query .= qq| + UNION SELECT id,name + FROM customer + WHERE id = $form->{customer_id}|; + } + + $query .= qq| + ORDER BY name|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + @{ $form->{all_customer} } = (); + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{all_customer} }, $ref; + } + $sth->finish; + } + + $dbh->disconnect if $disconnect; + +} + + +sub save_job { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + my ($income_accno) = split /--/, $form->{IC_income}; + + my ($partsgroup, $partsgroup_id) = split /--/, $form->{partsgroup}; + $partsgroup_id ||= 'NULL'; + + if ($form->{id}) { + $query = qq|SELECT id FROM project + WHERE id = $form->{id}|; + ($form->{id}) = $dbh->selectrow_array($query); + } + + if (!$form->{id}) { + my $uid = localtime; + $uid .= "$$"; + + $query = qq|INSERT INTO project (projectnumber) + VALUES ('$uid')|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|SELECT id FROM project + WHERE projectnumber = '$uid'|; + ($form->{id}) = $dbh->selectrow_array($query); + } + + $form->{projectnumber} = $form->update_defaults($myconfig, "projectnumber", $dbh) unless $form->{projectnumber}; + + $query = qq|UPDATE project SET + projectnumber = |.$dbh->quote($form->{projectnumber}).qq|, + description = |.$dbh->quote($form->{description}).qq|, + startdate = |.$form->dbquote($form->{startdate}, SQL_DATE).qq|, + enddate = |.$form->dbquote($form->{enddate}, SQL_DATE).qq|, + parts_id = $form->{id}, + production = |.$form->parse_amount($myconfig, $form->{production}).qq|, + customer_id = $form->{customer_id} + WHERE id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + + #### add/edit assembly + $query = qq|SELECT id FROM parts + WHERE id = $form->{id}|; + my ($id) = $dbh->selectrow_array($query); + + if (!$id) { + $query = qq|INSERT INTO parts (id) + VALUES ($form->{id})|; + $dbh->do($query) || $form->dberror($query); + } + + my $partnumber = ($form->{partnumber}) ? $form->{partnumber} : $form->{projectnumber}; + + $query = qq|UPDATE parts SET + partnumber = |.$dbh->quote($partnumber).qq|, + description = |.$dbh->quote($form->{partdescription}).qq|, + priceupdate = |.$form->dbquote($form->{priceupdate}, SQL_DATE).qq|, + listprice = |.$form->parse_amount($myconfig, $form->{listprice}).qq|, + sellprice = |.$form->parse_amount($myconfig, $form->{sellprice}).qq|, + weight = |.$form->parse_amount($myconfig, $form->{weight}).qq|, + bin = '$form->{bin}', + unit = |.$dbh->quote($form->{unit}).qq|, + notes = |.$dbh->quote($form->{notes}).qq|, + income_accno_id = (SELECT id FROM chart + WHERE accno = '$income_accno'), + partsgroup_id = $partsgroup_id, + assembly = '1', + obsolete = '1', + project_id = $form->{id} + WHERE id = $form->{id}|; + + $dbh->do($query) || $form->dberror($query); + + $query = qq|DELETE FROM partstax + WHERE parts_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + for (split / /, $form->{taxaccounts}) { + if ($form->{"IC_tax_$_"}) { + $query = qq|INSERT INTO partstax (parts_id, chart_id) + VALUES ($form->{id}, + (SELECT id + FROM chart + WHERE accno = '$_'))|; + $dbh->do($query) || $form->dberror($query); + } + } + + $dbh->commit; + $dbh->disconnect; + +} + + +sub stock_assembly { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + my $ref; + + my $query = qq|SELECT * + FROM project + WHERE id = ?|; + my $sth = $dbh->prepare($query) || $form->dberror($query); + + $query = qq|SELECT COUNT(*) + FROM parts + WHERE project_id = ?|; + my $rvh = $dbh->prepare($query) || $form->dberror($query); + + if (! $form->{stockingdate}) { + $query = qq|SELECT current_date FROM defaults|; + ($form->{stockingdate}) = $dbh->selectrow_array($query); + } + + $query = qq|SELECT * + FROM parts + WHERE id = ?|; + my $pth = $dbh->prepare($query) || $form->dberror($query); + + $query = qq|SELECT j.*, p.lastcost FROM jcitems j + JOIN parts p ON (p.id = j.parts_id) + WHERE j.project_id = ? + AND j.checkedin <= '$form->{stockingdate}' + ORDER BY parts_id|; + my $jth = $dbh->prepare($query) || $form->dberror($query); + + $query = qq|INSERT INTO assembly (id, parts_id, qty, bom, adj) + VALUES (?, ?, ?, '0', '0')|; + my $ath = $dbh->prepare($query) || $form->dberror($query); + + my $i = 0; + my $sold; + my $ship; + + while (1) { + $i++; + last unless $form->{"id_$i"}; + + $stock = $form->parse_amount($myconfig, $form->{"stock_$i"}); + + if ($stock) { + $sth->execute($form->{"id_$i"}); + $ref = $sth->fetchrow_hashref(NAME_lc); + + if ($stock > ($ref->{production} - $ref->{completed})) { + $stock = $ref->{production} - $ref->{completed}; + } + if (($stock * -1) > $ref->{completed}) { + $stock = $ref->{completed} * -1; + } + + $pth->execute($form->{"id_$i"}); + $pref = $pth->fetchrow_hashref(NAME_lc); + + my %assembly = (); + my $lastcost = 0; + my $sellprice = 0; + my $listprice = 0; + + $jth->execute($form->{"id_$i"}); + while ($jref = $jth->fetchrow_hashref(NAME_lc)) { + $assembly{qty}{$jref->{parts_id}} += ($jref->{qty} - $jref->{allocated}); + $assembly{parts_id}{$jref->{parts_id}} = $jref->{parts_id}; + $assembly{jcitems}{$jref->{id}} = $jref->{id}; + $lastcost += $form->round_amount(($jref->{lastcost} * ($jref->{qty} - $jref->{allocated})), 2); + $sellprice += $form->round_amount(($jref->{sellprice} * ($jref->{qty} - $jref->{allocated})), 2); + $listprice += $form->round_amount(($jref->{listprice} * ($jref->{qty} - $jref->{allocated})), 2); + } + $jth->finish; + + $uid = localtime; + $uid .= "$$"; + + $query = qq|INSERT INTO parts (partnumber) + VALUES ('$uid')|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|SELECT id + FROM parts + WHERE partnumber = '$uid'|; + ($uid) = $dbh->selectrow_array($query); + + $lastcost = $form->round_amount($lastcost / $stock, 2); + $sellprice = ($pref->{sellprice}) ? $pref->{sellprice} : $form->round_amount($sellprice / $stock, 2); + $listprice = ($pref->{listprice}) ? $pref->{listprice} : $form->round_amount($listprice / $stock, 2); + + $rvh->execute($form->{"id_$i"}); + my ($rev) = $rvh->fetchrow_array; + $rvh->finish; + + $query = qq|UPDATE parts SET + partnumber = '$pref->{partnumber}-$rev', + description = '$pref->{partdescription}', + priceupdate = '$form->{stockingdate}', + unit = '$pref->{unit}', + listprice = $listprice, + sellprice = $sellprice, + lastcost = $lastcost, + weight = $pref->{weight}, + onhand = $stock, + notes = '$pref->{notes}', + assembly = '1', + income_accno_id = $pref->{income_accno_id}, + bin = '$pref->{bin}', + project_id = $form->{"id_$i"} + WHERE id = $uid|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|INSERT INTO partstax (parts_id, chart_id) + SELECT '$uid', chart_id FROM partstax + WHERE parts_id = $pref->{id}|; + $dbh->do($query) || $form->dberror($query); + + + $pth->finish; + + for (keys %{$assembly{parts_id}}) { + if ($assembly{qty}{$_}) { + $ath->execute($uid, $assembly{parts_id}{$_}, $form->round_amount($assembly{qty}{$_} / $stock, 4)); + $ath->finish; + } + } + + $form->update_balance($dbh, + "project", + "completed", + qq|id = $form->{"id_$i"}|, + $stock); + + $query = qq|UPDATE jcitems SET + allocated = qty + WHERE allocated != qty + AND checkedin <= '$form->{stockingdate}' + AND project_id = $form->{"id_$i"}|; + $dbh->do($query) || $form->dberror($query); + + $sth->finish; + + } + + } + + my $rc = $dbh->commit; + $dbh->disconnect; + + $rc; + +} + + +sub delete_project { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + $query = qq|DELETE FROM project + WHERE id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|DELETE FROM translation + WHERE trans_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + my $rc = $dbh->commit; + $dbh->disconnect; + + $rc; + +} + + +sub delete_partsgroup { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + $query = qq|DELETE FROM partsgroup + WHERE id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|DELETE FROM translation + WHERE trans_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + my $rc = $dbh->commit; + $dbh->disconnect; + + $rc; + +} + + +sub delete_pricegroup { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + $query = qq|DELETE FROM pricegroup + WHERE id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + my $rc = $dbh->commit; + $dbh->disconnect; + + $rc; + +} + + +sub delete_job { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + my %audittrail = ( tablename => 'project', + reference => $form->{id}, + formname => $form->{type}, + action => 'deleted', + id => $form->{id} ); + + $form->audittrail($dbh, "", \%audittrail); + + my $query = qq|DELETE FROM project + WHERE id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|DELETE FROM translation + WHERE trans_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + # delete all the assemblies + $query = qq|DELETE FROM assembly a + JOIN parts p ON (a.id = p.id) + WHERE p.project_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|DELETE FROM parts + WHERE project_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + my $rc = $dbh->commit; + $dbh->disconnect; + + $rc; + +} + + +sub partsgroups { + my ($self, $myconfig, $form) = @_; + + my $var; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{sort} = "partsgroup" unless $form->{partsgroup}; + my @a = (partsgroup); + my $sortorder = $form->sort_order(\@a); + + my $query = qq|SELECT g.* + FROM partsgroup g|; + + my $where = "1 = 1"; + + if ($form->{partsgroup} ne "") { + $var = $form->like(lc $form->{partsgroup}); + $where .= " AND lower(partsgroup) LIKE '$var'"; + } + $query .= qq| + WHERE $where + ORDER BY $sortorder|; + + if ($form->{status} eq 'orphaned') { + $query = qq|SELECT g.* + FROM partsgroup g + LEFT JOIN parts p ON (p.partsgroup_id = g.id) + WHERE $where + EXCEPT + SELECT g.* + FROM partsgroup g + JOIN parts p ON (p.partsgroup_id = g.id) + WHERE $where + ORDER BY $sortorder|; + } + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $i = 0; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{item_list} }, $ref; + $i++; + } + + $sth->finish; + $dbh->disconnect; + + $i; + +} + + +sub save_partsgroup { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + if ($form->{id}) { + $query = qq|UPDATE partsgroup SET + partsgroup = |.$dbh->quote($form->{partsgroup}).qq| + WHERE id = $form->{id}|; + } else { + $query = qq|INSERT INTO partsgroup + (partsgroup) + VALUES (|.$dbh->quote($form->{partsgroup}).qq|)|; + } + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + +} + + +sub get_partsgroup { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT * + FROM partsgroup + WHERE id = $form->{id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + for (keys %$ref) { $form->{$_} = $ref->{$_} } + + $sth->finish; + + # check if it is orphaned + $query = qq|SELECT count(*) + FROM parts + WHERE partsgroup_id = $form->{id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + ($form->{orphaned}) = $sth->fetchrow_array; + $form->{orphaned} = !$form->{orphaned}; + + $sth->finish; + + $dbh->disconnect; + +} + + +sub pricegroups { + my ($self, $myconfig, $form) = @_; + + my $var; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + $form->{sort} = "pricegroup" unless $form->{sort}; + my @a = (pricegroup); + my $sortorder = $form->sort_order(\@a); + + my $query = qq|SELECT g.* + FROM pricegroup g|; + + my $where = "1 = 1"; + + if ($form->{pricegroup} ne "") { + $var = $form->like(lc $form->{pricegroup}); + $where .= " AND lower(pricegroup) LIKE '$var'"; + } + $query .= qq| + WHERE $where + ORDER BY $sortorder|; + + if ($form->{status} eq 'orphaned') { + $query = qq|SELECT g.* + FROM pricegroup g + WHERE $where + AND g.id NOT IN (SELECT DISTINCT pricegroup_id + FROM partscustomer + WHERE pricegroup_id > 0) + ORDER BY $sortorder|; + } + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $i = 0; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{item_list} }, $ref; + $i++; + } + + $sth->finish; + $dbh->disconnect; + + $i; + +} + + +sub save_pricegroup { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + if ($form->{id}) { + $query = qq|UPDATE pricegroup SET + pricegroup = |.$dbh->quote($form->{pricegroup}).qq| + WHERE id = $form->{id}|; + } else { + $query = qq|INSERT INTO pricegroup + (pricegroup) + VALUES (|.$dbh->quote($form->{pricegroup}).qq|)|; + } + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + +} + + +sub get_pricegroup { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT * + FROM pricegroup + WHERE id = $form->{id}|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $ref = $sth->fetchrow_hashref(NAME_lc); + + for (keys %$ref) { $form->{$_} = $ref->{$_} } + + $sth->finish; + + # check if it is orphaned + $query = qq|SELECT count(*) + FROM partscustomer + WHERE pricegroup_id = $form->{id}|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + ($form->{orphaned}) = $sth->fetchrow_array; + $form->{orphaned} = !$form->{orphaned}; + + $sth->finish; + + $dbh->disconnect; + +} + + +sub description_translations { + my ($self, $myconfig, $form) = @_; + + my $where = "1 = 1"; + my $var; + my $ref; + + for (qw(partnumber description)) { + if ($form->{$_}) { + $var = $form->like(lc $form->{$_}); + $where .= " AND lower(p.$_) LIKE '$var'"; + } + } + + $where .= " AND p.obsolete = '0'"; + $where .= " AND p.id = $form->{id}" if $form->{id}; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my %ordinal = ( 'partnumber' => 2, + 'description' => 3 + ); + + my @a = qw(partnumber description); + my $sortorder = $form->sort_order(\@a, \%ordinal); + + my $query = qq|SELECT l.description AS language, t.description AS translation, + l.code + FROM translation t + JOIN language l ON (l.code = t.language_code) + WHERE trans_id = ? + ORDER BY 1|; + my $tth = $dbh->prepare($query); + + $query = qq|SELECT p.id, p.partnumber, p.description + FROM parts p + WHERE $where + ORDER BY $sortorder|; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $tra; + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{translations} }, $ref; + + # get translations for description + $tth->execute($ref->{id}) || $form->dberror; + + while ($tra = $tth->fetchrow_hashref(NAME_lc)) { + $form->{trans_id} = $ref->{id}; + $tra->{id} = $ref->{id}; + push @{ $form->{translations} }, $tra; + } + $tth->finish; + + } + $sth->finish; + + &get_language("", $dbh, $form) if $form->{id}; + + $dbh->disconnect; + +} + + +sub partsgroup_translations { + my ($self, $myconfig, $form) = @_; + + my $where = "1 = 1"; + my $ref; + my $var; + + if ($form->{description}) { + $var = $form->like(lc $form->{description}); + $where .= " AND lower(p.partsgroup) LIKE '$var'"; + } + $where .= " AND p.id = $form->{id}" if $form->{id}; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT l.description AS language, t.description AS translation, + l.code + FROM translation t + JOIN language l ON (l.code = t.language_code) + WHERE trans_id = ? + ORDER BY 1|; + my $tth = $dbh->prepare($query); + + $form->sort_order(); + + $query = qq|SELECT p.id, p.partsgroup AS description + FROM partsgroup p + WHERE $where + ORDER BY 2 $form->{direction}|; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $tra; + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{translations} }, $ref; + + # get translations for partsgroup + $tth->execute($ref->{id}) || $form->dberror; + + while ($tra = $tth->fetchrow_hashref(NAME_lc)) { + $form->{trans_id} = $ref->{id}; + push @{ $form->{translations} }, $tra; + } + $tth->finish; + + } + $sth->finish; + + &get_language("", $dbh, $form) if $form->{id}; + + $dbh->disconnect; + +} + + +sub project_translations { + my ($self, $myconfig, $form) = @_; + + my $where = "1 = 1"; + my $var; + my $ref; + + for (qw(projectnumber description)) { + if ($form->{$_}) { + $var = $form->like(lc $form->{$_}); + $where .= " AND lower(p.$_) LIKE '$var'"; + } + } + + $where .= " AND p.id = $form->{id}" if $form->{id}; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my %ordinal = ( 'projectnumber' => 2, + 'description' => 3 + ); + + my @a = qw(projectnumber description); + my $sortorder = $form->sort_order(\@a, \%ordinal); + + my $query = qq|SELECT l.description AS language, t.description AS translation, + l.code + FROM translation t + JOIN language l ON (l.code = t.language_code) + WHERE trans_id = ? + ORDER BY 1|; + my $tth = $dbh->prepare($query); + + $query = qq|SELECT p.id, p.projectnumber, p.description + FROM project p + WHERE $where + ORDER BY $sortorder|; + + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + my $tra; + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{translations} }, $ref; + + # get translations for description + $tth->execute($ref->{id}) || $form->dberror; + + while ($tra = $tth->fetchrow_hashref(NAME_lc)) { + $form->{trans_id} = $ref->{id}; + $tra->{id} = $ref->{id}; + push @{ $form->{translations} }, $tra; + } + $tth->finish; + + } + $sth->finish; + + &get_language("", $dbh, $form) if $form->{id}; + + $dbh->disconnect; + +} + + +sub get_language { + my ($self, $dbh, $form) = @_; + + # get language + my $query = qq|SELECT * + FROM language + ORDER BY 2|; + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{all_language} }, $ref; + } + $sth->finish; + +} + + +sub save_translation { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + my $query = qq|DELETE FROM translation + WHERE trans_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $query = qq|INSERT INTO translation (trans_id, language_code, description) + VALUES ($form->{id}, ?, ?)|; + my $sth = $dbh->prepare($query) || $form->dberror($query); + + foreach my $i (1 .. $form->{translation_rows}) { + if ($form->{"language_code_$i"} ne "") { + $sth->execute($form->{"language_code_$i"}, $form->{"translation_$i"}); + $sth->finish; + } + } + $dbh->commit; + $dbh->disconnect; + +} + + +sub delete_translation { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|DELETE FROM translation + WHERE trans_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + $dbh->disconnect; + +} + + +sub project_sales_order { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $query = qq|SELECT current_date FROM defaults|; + my ($transdate) = $dbh->selectrow_array($query); + + $form->all_years($myconfig, $dbh); + + $form->all_projects($myconfig, $dbh, $transdate); + + $form->all_employees($myconfig, $dbh, $transdate); + + $dbh->disconnect; + +} + + +sub get_jcitems { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + my $null; + my $var; + my $where; + + if ($form->{projectnumber}) { + ($null, $var) = split /--/, $form->{projectnumber}; + $where .= " AND j.project_id = $var"; + } + + if ($form->{employee}) { + ($null, $var) = split /--/, $form->{employee}; + $where .= " AND j.employee_id = $var"; + } + + ($form->{transdatefrom}, $form->{transdateto}) = $form->from_to($form->{year}, $form->{month}, $form->{interval}) if $form->{year} && $form->{month}; + + if ($form->{transdatefrom}) { + $where .= " AND j.checkedin >= '$form->{transdatefrom}'"; + } + if ($form->{transdateto}) { + $where .= " AND j.checkedout <= (date '$form->{transdateto}' + interval '1 days')"; + } + + my $query; + my $ref; + + $query = qq|SELECT j.id, j.description, j.qty - j.allocated AS qty, + j.sellprice, j.parts_id, pr.$form->{vc}_id, j.project_id, + j.checkedin::date AS transdate, j.notes, + c.name AS $form->{vc}, pr.projectnumber, p.partnumber + FROM jcitems j + JOIN project pr ON (pr.id = j.project_id) + JOIN employee e ON (e.id = j.employee_id) + JOIN parts p ON (p.id = j.parts_id) + LEFT JOIN $form->{vc} c ON (c.id = pr.$form->{vc}_id) + WHERE pr.parts_id IS NULL + AND j.allocated != j.qty + $where + ORDER BY pr.projectnumber, c.name, j.checkedin::date|; + + if ($form->{summary}) { + $query =~ s/j\.description/p\.description/; + $query =~ s/c\.name,/c\.name, j\.parts_id, /; + } + + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + # tax accounts + $query = qq|SELECT c.accno + FROM chart c + JOIN partstax pt ON (pt.chart_id = c.id) + WHERE pt.parts_id = ?|; + my $tth = $dbh->prepare($query) || $form->dberror($query); + my $ptref; + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + + $tth->execute($ref->{parts_id}); + $ref->{taxaccounts} = ""; + while ($ptref = $tth->fetchrow_hashref(NAME_lc)) { + $ref->{taxaccounts} .= "$ptref->{accno} "; + } + $tth->finish; + chop $ref->{taxaccounts}; + + $ref->{amount} = $ref->{sellprice} * $ref->{qty}; + + push @{ $form->{jcitems} }, $ref; + } + + $sth->finish; + + $query = qq|SELECT curr + FROM defaults|; + ($form->{currency}) = $dbh->selectrow_array($query); + $form->{currency} =~ s/:.*//; + $form->{defaultcurrency} = $form->{currency}; + + $query = qq|SELECT c.accno, t.rate + FROM tax t + JOIN chart c ON (c.id = t.chart_id)|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + $form->{taxaccounts} .= "$ref->{accno} "; + $form->{"$ref->{accno}_rate"} = $ref->{rate}; + } + chop $form->{taxaccounts}; + $sth->finish; + + $dbh->disconnect; + +} + + +sub allocate_projectitems { + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + for my $i (1 .. $form->{rowcount}) { + for (split / /, $form->{"jcitems_$i"}) { + my ($id, $qty) = split /:/, $_; + $form->update_balance($dbh, + 'jcitems', + 'allocated', + "id = $id", + $qty); + } + } + + $rc = $dbh->commit; + $dbh->disconnect; + + $rc; + +} + + +1; + |