X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FIC.pm;h=a2703b64f656fc8e93e6326afbb6eba81f41eae1;hb=d0810c4289d895acfb8cf477125c6796c51945e3;hp=b8815cc59605fc904b7159d606d99f697be47b81;hpb=07b34c6ddd71bfeca5266b9045069769c1cdb01f;p=kivitendo-erp.git diff --git a/SL/IC.pm b/SL/IC.pm index b8815cc59..a2703b64f 100644 --- a/SL/IC.pm +++ b/SL/IC.pm @@ -34,6 +34,8 @@ package IC; use Data::Dumper; +use SL::DBUtils; + sub get_part { $main::lxdebug->enter_sub(); @@ -52,9 +54,10 @@ sub get_part { LEFT JOIN chart c2 ON (p.income_accno_id = c2.id) LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id) LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) - WHERE p.id = $form->{id}|; + WHERE p.id = ? |; + my @vars = ($form->{id}); my $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); + $sth->execute(@vars) || $form->dberror("$query (" . join(', ', @vars) . ")"); my $ref = $sth->fetchrow_hashref(NAME_lc); # copy to $form variables @@ -77,12 +80,12 @@ sub get_part { FROM parts p JOIN assembly a ON (a.parts_id = p.id) LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) - WHERE a.id = $form->{id} - ORDER BY $oid{$myconfig->{dbdriver}}|; - + WHERE a.id = ? + ORDER BY ?|; + @vars = ($form->{id}, $oid{$myconfig->{dbdriver}}); $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); - + $sth->execute(@vars) || $form->dberror("$query (" . join(', ', @vars) . ")"); + $form->{assembly_rows} = 0; while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { $form->{assembly_rows}++; @@ -104,11 +107,12 @@ sub get_part { # get prices $query = qq|SELECT p.parts_id, p.pricegroup_id, p.price, (SELECT pg.pricegroup FROM pricegroup pg WHERE pg.id=p.pricegroup_id) AS pricegroup FROM prices p - WHERE parts_id = $form->{id} + WHERE parts_id = ? ORDER by pricegroup|; + @vars = ($form->{id}); $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); + $sth->execute(@vars) || $form->dberror("$query (" . join(', ', @vars) . ")"); @pricegroups = (); @pricegroups_not_used = (); @@ -163,7 +167,7 @@ sub get_part { $form->{"price_$i"} = $form->format_amount($myconfig, $form->{"price_$i"}, 5); $form->{"pricegroup_id_$i"} = "$name->{id}"; - $form->{"pricegroup_$i"} = "$name->{pricegroup}\n"; + $form->{"pricegroup_$i"} = "$name->{pricegroup}"; $i++; } } @@ -176,10 +180,10 @@ sub get_part { # get makes if ($form->{makemodel}) { $query = qq|SELECT m.make, m.model FROM makemodel m - WHERE m.parts_id = $form->{id}|; - + WHERE m.parts_id = ?|; + @vars = ($form->{id}); $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); + $sth->execute(@vars) || $form->dberror("$query (" . join(', ', @vars) . ")"); my $i = 1; while (($form->{"make_$i"}, $form->{"model_$i"}) = $sth->fetchrow_array) @@ -192,6 +196,17 @@ sub get_part { } } + # get translations + $form->{language_values} = ""; + $query = qq|SELECT language_id, translation FROM translation WHERE parts_id = ?|; + @vars = ($form->{id}); + $trq = $dbh->prepare($query); + $trq->execute(@vars) || $form->dberror("$query (" . join(', ', @vars) . ")"); + while ($tr = $trq->fetchrow_hashref(NAME_lc)) { + $form->{language_values} .= "---+++---".$tr->{language_id}."--++--".$tr->{translation}; + } + $trq->finish; + # now get accno for taxes $query = qq|SELECT c.accno FROM chart c, partstax pt @@ -226,6 +241,18 @@ sub get_part { $form->{orphaned} = !$form->{orphaned}; $sth->finish; + $form->{"unit_changeable"} = 1; + foreach my $table (qw(invoice assembly orderitems inventory license)) { + $query = "SELECT COUNT(*) FROM $table WHERE parts_id = ?"; + my ($count) = $dbh->selectrow_array($query, undef, $form->{"id"}); + $form->dberror($query . " (" . $form->{"id"} . ")") if ($dbh->err); + + if ($count) { + $form->{"unit_changeable"} = 0; + last; + } + } + $dbh->disconnect; $main::lxdebug->leave_sub(); @@ -235,8 +262,8 @@ sub get_pricegroups { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; - my $dbh = $form->dbconnect($myconfig); - my $i = 1; + my $dbh = $form->dbconnect($myconfig); + my $i = 1; my @pricegroups_not_used = (); # get pricegroups @@ -263,7 +290,7 @@ sub get_pricegroups { $form->{"price_$i"} = $form->format_amount($myconfig, $form->{"price_$i"}, 5); $form->{"pricegroup_id_$i"} = "$name->{id}"; - $form->{"pricegroup_$i"} = "$name->{pricegroup}\n"; + $form->{"pricegroup_$i"} = "$name->{pricegroup}"; $i++; } } @@ -276,19 +303,35 @@ sub get_pricegroups { $main::lxdebug->leave_sub(); } - -sub save { +sub retrieve_buchungsgruppen { $main::lxdebug->enter_sub(); my ($self, $myconfig, $form) = @_; - if ($form->{eur} && ($form->{item} ne 'service')) { - $form->{IC} = $form->{IC_expense}; + my ($query, $sth); + + my $dbh = $form->dbconnect($myconfig); + + # get buchungsgruppen + $query = qq|SELECT id, description + FROM buchungsgruppen + ORDER BY sortkey|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + $form->{BUCHUNGSGRUPPEN} = []; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push(@{ $form->{BUCHUNGSGRUPPEN} }, $ref); } + $sth->finish; + + $main::lxdebug->leave_sub(); +} - ($form->{inventory_accno}) = split(/--/, $form->{IC}); - ($form->{expense_accno}) = split(/--/, $form->{IC_expense}); - ($form->{income_accno}) = split(/--/, $form->{IC_income}); +sub save { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; # connect to database, turn off AutoCommit my $dbh = $form->dbconnect_noauto($myconfig); @@ -322,6 +365,9 @@ sub save { $form->{onhand} *= 1; $form->{ve} *= 1; $form->{ge} *= 1; + $form->{buchungsgruppen_id} *= 1; + $form->{not_discountable} *= 1; + $form->{payment_id} *= 1; my ($query, $sth); @@ -373,6 +419,11 @@ sub save { WHERE parts_id = $form->{id}|; $dbh->do($query) || $form->dberror($query); + # delete translations + $query = qq|DELETE FROM translation + WHERE parts_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + } else { my $uid = rand() . time; $uid .= $form->{login}; @@ -402,10 +453,10 @@ sub save { $form->{orphaned} = 1; $form->{onhand} = $form->{stock} if $form->{item} eq 'assembly'; - if ($form->{partnumber} eq "" && $form->{inventory_accno} eq "") { + if ($form->{partnumber} eq "" && $form->{"item"} eq "service") { $form->{partnumber} = $form->update_defaults($myconfig, "servicenumber"); } - if ($form->{partnumber} eq "" && $form->{inventory_accno} ne "") { + if ($form->{partnumber} eq "" && $form->{"item"} ne "service") { $form->{partnumber} = $form->update_defaults($myconfig, "articlenumber"); } @@ -416,6 +467,30 @@ sub save { ($partsgroup, $partsgroup_id) = split /--/, $form->{partsgroup}; } + my ($subq_inventory, $subq_expense, $subq_income); + if ($form->{"item"} eq "part") { + $subq_inventory = + qq|(SELECT bg.inventory_accno_id | . + qq| FROM buchungsgruppen bg | . + qq| WHERE bg.id = | . $dbh->quote($form->{"buchungsgruppen_id"}) . qq|)|; + } else { + $subq_inventory = "NULL"; + } + + if ($form->{"item"} ne "assembly") { + $subq_expense = + qq|(SELECT bg.expense_accno_id_0 | . + qq| FROM buchungsgruppen bg | . + qq| WHERE bg.id = | . $dbh->quote($form->{"buchungsgruppen_id"}) . qq|)|; + } else { + $subq_expense = "NULL"; + } + + $subq_income = + qq|(SELECT bg.income_accno_id_0 | . + qq| FROM buchungsgruppen bg | . + qq| WHERE bg.id = | . $dbh->quote($form->{"buchungsgruppen_id"}) . qq|)|; + $query = qq|UPDATE parts SET partnumber = '$form->{partnumber}', description = '$form->{description}', @@ -429,38 +504,58 @@ sub save { priceupdate = $form->{priceupdate}, unit = '$form->{unit}', notes = '$form->{notes}', + formel = '$form->{formel}', rop = $form->{rop}, bin = '$form->{bin}', - inventory_accno_id = (SELECT c.id FROM chart c - WHERE c.accno = '$form->{inventory_accno}'), - income_accno_id = (SELECT c.id FROM chart c - WHERE c.accno = '$form->{income_accno}'), - expense_accno_id = (SELECT c.id FROM chart c - WHERE c.accno = '$form->{expense_accno}'), + buchungsgruppen_id = '$form->{buchungsgruppen_id}', + payment_id = '$form->{payment_id}', + inventory_accno_id = $subq_inventory, + income_accno_id = $subq_income, + expense_accno_id = $subq_expense, obsolete = '$form->{obsolete}', image = '$form->{image}', drawing = '$form->{drawing}', shop = '$form->{shop}', ve = '$form->{ve}', gv = '$form->{gv}', + ean = '$form->{ean}', + not_discountable = '$form->{not_discountable}', microfiche = '$form->{microfiche}', partsgroup_id = $partsgroup_id WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); + # delete translation records + $query = qq|DELETE FROM translation + WHERE parts_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + + if ($form->{language_values} ne "") { + split /---\+\+\+---/,$form->{language_values}; + foreach $item (@_) { + my ($language_id, $translation, $longdescription) = split /--\+\+--/, $item; + if ($translation ne "") { + $query = qq|INSERT into translation (parts_id, language_id, translation, longdescription) VALUES + ($form->{id}, $language_id, | . $dbh->quote($translation) . qq|, | . $dbh->quote($longdescription) . qq| )|; + $dbh->do($query) || $form->dberror($query); + } + } + } # delete price records $query = qq|DELETE FROM prices WHERE parts_id = $form->{id}|; $dbh->do($query) || $form->dberror($query); - # insert price records only if different to sellprice for my $i (1 .. $form->{price_rows}) { if ($form->{"price_$i"} eq "0") { - $form->{"price_$i"} = $form->{sellprice}; + $form->{"price_$i"} = $form->{sellprice}; } - if (( $form->{"price_$i"} - || $form->{"klass_$i"} - || $form->{"pricegroup_id_$i"}) and $form->{"price_$i"} != $form->{sellprice}) { + if ( + ( $form->{"price_$i"} + || $form->{"klass_$i"} + || $form->{"pricegroup_id_$i"}) + and $form->{"price_$i"} != $form->{sellprice} + ) { $klass = $form->parse_amount($myconfig, $form->{"klass_$i"}); $price = $form->parse_amount($myconfig, $form->{"price_$i"}); $pricegroup_id = @@ -715,6 +810,11 @@ sub delete { # connect to database, turn off AutoCommit my $dbh = $form->dbconnect_noauto($myconfig); + # first delete prices of pricegroup + my $query = qq|DELETE FROM prices + WHERE parts_id = $form->{id}|; + $dbh->do($query) || $form->dberror($query); + my $query = qq|DELETE FROM parts WHERE id = $form->{id}|; $dbh->do($query) || $form->dberror($query); @@ -822,14 +922,10 @@ sub all_parts { my $group; my $limit; - foreach my $item (qw(partnumber drawing microfiche make model)) { + foreach my $item (qw(partnumber drawing microfiche)) { if ($form->{$item}) { $var = $form->like(lc $form->{$item}); - - # make will build later Bugfix 145 - if ($item ne 'make') { - $where .= " AND lower(p.$item) LIKE '$var'"; - } + $where .= " AND lower(p.$item) LIKE '$var'"; } } @@ -854,6 +950,11 @@ sub all_parts { } } + if ($form->{ean}) { + $var = $form->like(lc $form->{ean}); + $where .= " AND lower(ean) LIKE '$var'"; + } + if ($form->{searchitems} eq 'part') { $where .= " AND p.inventory_accno_id > 0"; } @@ -934,7 +1035,7 @@ sub all_parts { my $sortorder = $form->{sort}; $sortorder .= $form->{desc}; - $sortorder = $form->{sort} unless $sortorder; + $sortorder = $form->{sort} if $form->{sort}; my $query = ""; @@ -997,7 +1098,7 @@ sub all_parts { p.priceupdate, p.image, p.drawing, p.microfiche, pg.partsgroup, a.invnumber, a.ordnumber, a.quonumber, i.trans_id, - ct.name|; + ct.name, i.deliverydate|; if ($form->{bought}) { $query = qq| @@ -1041,13 +1142,14 @@ sub all_parts { $ordwhere .= " AND lower(oi.description) LIKE '$var'"; } - $flds = qq|p.id, p.partnumber, oi.description, oi.serialnumber AS serialnumber, + $flds = + qq|p.id, p.partnumber, oi.description, oi.serialnumber AS serialnumber, oi.qty AS onhand, oi.unit, p.bin, oi.sellprice, p.listprice, p.lastcost, p.rop, p.weight, p.priceupdate, p.image, p.drawing, p.microfiche, pg.partsgroup, '' AS invnumber, o.ordnumber, o.quonumber, oi.trans_id, - ct.name|; + ct.name, NULL AS deliverydate|; if ($form->{ordered}) { $query .= qq|$union @@ -1067,13 +1169,14 @@ sub all_parts { } if ($form->{onorder}) { - $flds = qq|p.id, p.partnumber, oi.description, oi.serialnumber AS serialnumber, + $flds = + qq|p.id, p.partnumber, oi.description, oi.serialnumber AS serialnumber, oi.qty * -1 AS onhand, oi.unit, p.bin, oi.sellprice, p.listprice, p.lastcost, p.rop, p.weight, p.priceupdate, p.image, p.drawing, p.microfiche, pg.partsgroup, '' AS invnumber, o.ordnumber, o.quonumber, oi.trans_id, - ct.name|; + ct.name, NULL AS deliverydate|; $query .= qq|$union SELECT $flds, 'oe' AS module, 'purchase_order' AS type, @@ -1104,13 +1207,14 @@ sub all_parts { $quowhere .= " AND lower(oi.description) LIKE '$var'"; } - $flds = qq|p.id, p.partnumber, oi.description, oi.serialnumber AS serialnumber, + $flds = + qq|p.id, p.partnumber, oi.description, oi.serialnumber AS serialnumber, oi.qty AS onhand, oi.unit, p.bin, oi.sellprice, p.listprice, p.lastcost, p.rop, p.weight, p.priceupdate, p.image, p.drawing, p.microfiche, pg.partsgroup, '' AS invnumber, o.ordnumber, o.quonumber, oi.trans_id, - ct.name|; + ct.name, NULL AS deliverydate|; if ($form->{quoted}) { $query .= qq|$union @@ -1130,13 +1234,14 @@ sub all_parts { } if ($form->{rfq}) { - $flds = qq|p.id, p.partnumber, oi.description, oi.serialnumber AS serialnumber, + $flds = + qq|p.id, p.partnumber, oi.description, oi.serialnumber AS serialnumber, oi.qty * -1 AS onhand, oi.unit, p.bin, oi.sellprice, p.listprice, p.lastcost, p.rop, p.weight, p.priceupdate, p.image, p.drawing, p.microfiche, pg.partsgroup, '' AS invnumber, o.ordnumber, o.quonumber, oi.trans_id, - ct.name|; + ct.name, NULL AS deliverydate|; $query .= qq|$union SELECT $flds, 'oe' AS module, 'request_quotation' AS type, @@ -1200,6 +1305,171 @@ sub all_parts { $main::lxdebug->leave_sub(); } +sub update_prices { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + my $where = '1 = 1'; + my $var; + + my $group; + my $limit; + + foreach my $item (qw(partnumber drawing microfiche make model)) { + if ($form->{$item}) { + $var = $form->like(lc $form->{$item}); + + # make will build later Bugfix 145 + if ($item ne 'make') { + $where .= " AND lower(p.$item) LIKE '$var'"; + } + } + } + + # special case for description + if ($form->{description}) { + unless ( $form->{bought} + || $form->{sold} + || $form->{onorder} + || $form->{ordered} + || $form->{rfq} + || $form->{quoted}) { + $var = $form->like(lc $form->{description}); + $where .= " AND lower(p.description) LIKE '$var'"; + } + } + + # special case for serialnumber + if ($form->{l_serialnumber}) { + if ($form->{serialnumber}) { + $var = $form->like(lc $form->{serialnumber}); + $where .= " AND lower(serialnumber) LIKE '$var'"; + } + } + + + # items which were never bought, sold or on an order + if ($form->{itemstatus} eq 'orphaned') { + $form->{onhand} = $form->{short} = 0; + $form->{bought} = $form->{sold} = 0; + $form->{onorder} = $form->{ordered} = 0; + $form->{rfq} = $form->{quoted} = 0; + + $form->{transdatefrom} = $form->{transdateto} = ""; + + $where .= " AND p.onhand = 0 + AND p.id NOT IN (SELECT p.id FROM parts p, invoice i + WHERE p.id = i.parts_id) + AND p.id NOT IN (SELECT p.id FROM parts p, assembly a + WHERE p.id = a.parts_id) + AND p.id NOT IN (SELECT p.id FROM parts p, orderitems o + WHERE p.id = o.parts_id)"; + } + + if ($form->{itemstatus} eq 'active') { + $where .= " AND p.obsolete = '0'"; + } + if ($form->{itemstatus} eq 'obsolete') { + $where .= " AND p.obsolete = '1'"; + $form->{onhand} = $form->{short} = 0; + } + if ($form->{itemstatus} eq 'onhand') { + $where .= " AND p.onhand > 0"; + } + if ($form->{itemstatus} eq 'short') { + $where .= " AND p.onhand < p.rop"; + } + if ($form->{make}) { + $var = $form->like(lc $form->{make}); + $where .= " AND p.id IN (SELECT DISTINCT ON (m.parts_id) m.parts_id + FROM makemodel m WHERE lower(m.make) LIKE '$var')"; + } + if ($form->{model}) { + $var = $form->like(lc $form->{model}); + $where .= " AND p.id IN (SELECT DISTINCT ON (m.parts_id) m.parts_id + FROM makemodel m WHERE lower(m.model) LIKE '$var')"; + } + if ($form->{partsgroup}) { + $var = $form->like(lc $form->{partsgroup}); + $where .= " AND lower(pg.partsgroup) LIKE '$var'"; + } + + + # connect to database + my $dbh = $form->dbconnect_noauto($myconfig); + + if ($form->{"sellprice"} ne "") { + my $update = ""; + my $faktor = $form->parse_amount($myconfig,$form->{"sellprice"}); + if ($form->{"sellprice_type"} eq "percent") { + my $faktor = $form->parse_amount($myconfig,$form->{"sellprice"})/100 +1; + $update = "sellprice* $faktor"; + } else { + $update = "sellprice+$faktor"; + } + + $query = qq|UPDATE parts set sellprice=$update WHERE id IN (SELECT p.id + FROM parts p + LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) + WHERE $where)|; + $dbh->do($query); + } + + if ($form->{"listprice"} ne "") { + my $update = ""; + my $faktor = $form->parse_amount($myconfig,$form->{"listprice"}); + if ($form->{"listprice_type"} eq "percent") { + my $faktor = $form->parse_amount($myconfig,$form->{"sellprice"})/100 +1; + $update = "listprice* $faktor"; + } else { + $update = "listprice+$faktor"; + } + + $query = qq|UPDATE parts set listprice=$update WHERE id IN (SELECT p.id + FROM parts p + LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) + WHERE $where)|; + + $dbh->do($query); + } + + + + + for my $i (1 .. $form->{price_rows}) { + + my $query = ""; + + + if ($form->{"price_$i"} ne "") { + my $update = ""; + my $faktor = $form->parse_amount($myconfig,$form->{"price_$i"}); + if ($form->{"pricegroup_type_$i"} eq "percent") { + my $faktor = $form->parse_amount($myconfig,$form->{"sellprice"})/100 +1; + $update = "price* $faktor"; + } else { + $update = "price+$faktor"; + } + + $query = qq|UPDATE prices set price=$update WHERE parts_id IN (SELECT p.id + FROM parts p + LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) + WHERE $where) AND pricegroup_id=$form->{"pricegroup_id_$i"}|; + + $dbh->do($query); + } + } + + + + my $rc= $dbh->commit; + $dbh->disconnect; + $main::lxdebug->leave_sub(); + + return $rc; +} + sub create_links { $main::lxdebug->enter_sub(); @@ -1235,6 +1505,7 @@ sub create_links { { accno => $ref->{accno}, description => $ref->{description}, selected => "selected" }; + $form->{"${key}_default"} = "$ref->{accno}--$ref->{description}"; } else { push @{ $form->{"${module}_links"}{$key} }, { accno => $ref->{accno}, @@ -1246,22 +1517,36 @@ sub create_links { } $sth->finish; - if ($form->{id}) { - $query = qq|SELECT weightunit - FROM defaults|; - $sth = $dbh->prepare($query); - $sth->execute || $form->dberror($query); + # get buchungsgruppen + $query = qq|SELECT id, description + FROM buchungsgruppen|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); - ($form->{weightunit}) = $sth->fetchrow_array; - $sth->finish; + $form->{BUCHUNGSGRUPPEN} = []; + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $form->{BUCHUNGSGRUPPEN} }, $ref; + } + $sth->finish; - } else { - $query = qq|SELECT weightunit, current_date - FROM defaults|; + # get payment terms + $query = qq|SELECT id, description + FROM payment_terms + ORDER BY sortkey|; + $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while ($ref = $sth->fetchrow_hashref(NAME_lc)) { + push @{ $self->{payment_terms} }, $ref; + } + $sth->finish; + + if (!$form->{id}) { + $query = qq|SELECT current_date FROM defaults|; $sth = $dbh->prepare($query); $sth->execute || $form->dberror($query); - ($form->{weightunit}, $form->{priceupdate}) = $sth->fetchrow_array; + ($form->{priceupdate}) = $sth->fetchrow_array; $sth->finish; } @@ -1425,4 +1710,182 @@ sub retrieve_item { $main::lxdebug->leave_sub(); } +sub retrieve_languages { + $main::lxdebug->enter_sub(); + + my ($self, $myconfig, $form) = @_; + + # connect to database + my $dbh = $form->dbconnect($myconfig); + + if ($form->{id}) { + $where .= "tr.parts_id=$form->{id}"; + } + + + if ($form->{language_values} ne "") { + $query = qq|SELECT l.id, l.description, tr.translation, tr.longdescription + FROM language l LEFT OUTER JOIN translation tr ON (tr.language_id=l.id AND $where)|; + } else { + $query = qq|SELECT l.id, l.description + FROM language l|; + } + my $sth = $dbh->prepare($query); + $sth->execute || $form->dberror($query); + + while (my $ref = $sth->fetchrow_hashref(NAME_lc)) { + push(@{$languages}, $ref); + } + $sth->finish; + + $dbh->disconnect; + + $main::lxdebug->leave_sub(); + return $languages; + +} + +sub follow_account_chain { + $main::lxdebug->enter_sub(2); + + my ($self, $form, $dbh, $transdate, $accno_id, $accno) = @_; + + my @visited_accno_ids = ($accno_id); + + my ($query, $sth); + + $query = + "SELECT c.new_chart_id, date($transdate) >= c.valid_from AS is_valid, " . + " cnew.accno " . + "FROM chart c " . + "LEFT JOIN chart cnew ON c.new_chart_id = cnew.id " . + "WHERE (c.id = ?) AND NOT c.new_chart_id ISNULL AND (c.new_chart_id > 0)"; + $sth = $dbh->prepare($query); + + while (1) { + $sth->execute($accno_id) || $form->dberror($query . " ($accno_id)"); + $ref = $sth->fetchrow_hashref(); + last unless ($ref && $ref->{"is_valid"} && + !grep({ $_ == $ref->{"new_chart_id"} } @visited_accno_ids)); + $accno_id = $ref->{"new_chart_id"}; + $accno = $ref->{"accno"}; + push(@visited_accno_ids, $accno_id); + } + + $main::lxdebug->leave_sub(2); + + return ($accno_id, $accno); +} + +sub retrieve_accounts { + $main::lxdebug->enter_sub(2); + + my ($self, $myconfig, $form, $parts_id, $index, $copy_accnos) = @_; + + my ($query, $sth, $dbh); + + $form->{"taxzone_id"} *= 1; + + $dbh = $form->dbconnect($myconfig); + + my $transdate = ""; + if ($form->{type} eq "invoice") { + if (($form->{vc} eq "vendor") || !$form->{deliverydate}) { + $transdate = $form->{invdate}; + } else { + $transdate = $form->{deliverydate}; + } + } elsif ($form->{type} eq "credit_note") { + $transdate = $form->{invdate}; + } else { + $transdate = $form->{transdate}; + } + + if ($transdate eq "") { + $transdate = "current_date"; + } else { + $transdate = $dbh->quote($transdate); + } + + $query = + "SELECT " . + " p.inventory_accno_id AS is_part, " . + " bg.inventory_accno_id, " . + " bg.income_accno_id_$form->{taxzone_id} AS income_accno_id, " . + " bg.expense_accno_id_$form->{taxzone_id} AS expense_accno_id, " . + " c1.accno AS inventory_accno, " . + " c2.accno AS income_accno, " . + " c3.accno AS expense_accno " . + "FROM parts p " . + "LEFT JOIN buchungsgruppen bg ON p.buchungsgruppen_id = bg.id " . + "LEFT JOIN chart c1 ON bg.inventory_accno_id = c1.id " . + "LEFT JOIN chart c2 ON bg.income_accno_id_$form->{taxzone_id} = c2.id " . + "LEFT JOIN chart c3 ON bg.expense_accno_id_$form->{taxzone_id} = c3.id " . + "WHERE p.id = ?"; + $sth = $dbh->prepare($query); + $sth->execute($parts_id) || $form->dberror($query . " ($parts_id)"); + my $ref = $sth->fetchrow_hashref(); + $sth->finish(); + +# $main::lxdebug->message(0, "q $query"); + + if (!$ref) { + $dbh->disconnect(); + return $main::lxdebug->leave_sub(2); + } + + $ref->{"inventory_accno_id"} = undef unless ($ref->{"is_part"}); + + my %accounts; + foreach my $type (qw(inventory income expense)) { + next unless ($ref->{"${type}_accno_id"}); + ($accounts{"${type}_accno_id"}, $accounts{"${type}_accno"}) = + $self->follow_account_chain($form, $dbh, $transdate, + $ref->{"${type}_accno_id"}, + $ref->{"${type}_accno"}); + } + + map({ $form->{"${_}_accno_$index"} = $accounts{"${_}_accno"} } + qw(inventory income expense)); + + my $inc_exp = $form->{"vc"} eq "customer" ? "income" : "expense"; + my $accno_id = $accounts{"${inc_exp}_accno_id"}; + + $query = + "SELECT c.accno, t.taxdescription AS description, t.rate, t.taxnumber " . + "FROM tax t " . + "LEFT JOIN chart c ON c.id = t.chart_id " . + "WHERE t.id IN " . + " (SELECT tk.tax_id " . + " FROM taxkeys tk " . + " WHERE tk.chart_id = ? AND startdate <= " . quote_db_date($transdate) . + " ORDER BY startdate DESC LIMIT 1) "; + @vars = ($accno_id); + $sth = $dbh->prepare($query); + $sth->execute(@vars) || $form->dberror("$query (" . join(', ', @vars) . ")"); + $ref = $sth->fetchrow_hashref(); + $sth->finish(); + $dbh->disconnect(); + + unless ($ref) { + $main::lxdebug->leave_sub(2); + return; + } + + $form->{"taxaccounts_$index"} = $ref->{"accno"}; + if ($form->{"taxaccounts"} !~ /$ref->{accno}/) { + $form->{"taxaccounts"} .= "$ref->{accno} "; + } + map({ $form->{"$ref->{accno}_${_}"} = $ref->{$_}; } + qw(rate description taxnumber)); + +# $main::lxdebug->message(0, "formvars: rate " . $form->{"$ref->{accno}_rate"} . +# " description " . $form->{"$ref->{accno}_description"} . +# " taxnumber " . $form->{"$ref->{accno}_taxnumber"} . +# " || taxaccounts_$index " . $form->{"taxaccounts_$index"} . +# " || taxaccounts " . $form->{"taxaccounts"}); + + $main::lxdebug->leave_sub(2); +} + 1;