X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FIS.pm;h=43303e894b2c0ceb21099622a9c23aa4335dbb03;hb=b8125c17c8add08c9b84fb054f797547a853dd3a;hp=1398ed872e68e3c98b81293c4ad79e951cb19fdc;hpb=6f1b36cfb8b26f6c8540ba5f36e48b9188d9470a;p=kivitendo-erp.git diff --git a/SL/IS.pm b/SL/IS.pm index 1398ed872..43303e894 100644 --- a/SL/IS.pm +++ b/SL/IS.pm @@ -373,6 +373,12 @@ sub invoice_details { $sth->finish; } + CVar->get_non_editable_ic_cvars(form => $form, + dbh => $dbh, + row => $i, + sub_module => 'invoice', + may_converted_from => ['delivery_order_items', 'orderitems', 'invoice']); + push @{ $form->{TEMPLATE_ARRAYS}->{"ic_cvar_$_->{name}"} }, CVar->format_to_template(CVar->parse($form->{"ic_cvar_$_->{name}_$i"}, $_), $_) for @{ $ic_cvar_configs }; @@ -578,13 +584,6 @@ sub post_invoice { $form->{defaultcurrency} = $form->get_default_currency($myconfig); my $defaultcurrency = $form->{defaultcurrency}; - # Seit neuestem wird die department_id schon übergeben UND $form->department nicht mehr - # korrekt zusammengebaut. Sehr wahrscheinlich beim Umstieg auf T8 kaputt gegangen - # Ich lass den Code von 2005 erstmal noch stehen ;-) jb 03-2011 - if (!$form->{department_id}){ - ($null, $form->{department_id}) = split(/--/, $form->{department}); - } - my $all_units = AM->retrieve_units($myconfig, $form); if (!$payments_only) { @@ -633,6 +632,8 @@ sub post_invoice { $form->{amount} = {}; $form->{amount_cogs} = {}; + my @processed_invoice_ids; + foreach my $i (1 .. $form->{rowcount}) { if ($form->{type} eq "credit_note") { $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"}) * -1; @@ -653,6 +654,7 @@ sub post_invoice { if ($form->{"id_$i"}) { my $item_unit; + my $position = $i; if (defined($baseunits{$form->{"id_$i"}})) { $item_unit = $baseunits{$form->{"id_$i"}}; @@ -738,7 +740,7 @@ sub post_invoice { if ($form->{"assembly_$i"}) { # record assembly item as allocated - &process_assembly($dbh, $myconfig, $form, $form->{"id_$i"}, $baseqty); + &process_assembly($dbh, $myconfig, $form, $position, $form->{"id_$i"}, $baseqty); } else { $allocated = &cogs($dbh, $myconfig, $form, $form->{"id_$i"}, $baseqty, $basefactor, $i); @@ -753,20 +755,36 @@ sub post_invoice { $pricegroup_id *= 1; $pricegroup_id = undef if !$pricegroup_id; - my ($invoice_id) = selectfirst_array_query($form, $dbh, qq|SELECT nextval('invoiceid')|); + CVar->get_non_editable_ic_cvars(form => $form, + dbh => $dbh, + row => $i, + sub_module => 'invoice', + may_converted_from => ['delivery_order_items', 'orderitems', 'invoice']); + + if (!$form->{"invoice_id_$i"}) { + # there is no persistent id, therefore create one with all necessary constraints + my $q_invoice_id = qq|SELECT nextval('invoiceid')|; + my $h_invoice_id = prepare_query($form, $dbh, $q_invoice_id); + do_statement($form, $h_invoice_id, $q_invoice_id); + $form->{"invoice_id_$i"} = $h_invoice_id->fetchrow_array(); + my $q_create_invoice_id = qq|INSERT INTO invoice (id, trans_id, position, parts_id) values (?, ?, ?, ?)|; + do_query($form, $dbh, $q_create_invoice_id, conv_i($form->{"invoice_id_$i"}), + conv_i($form->{id}), conv_i($position), conv_i($form->{"id_$i"})); + $h_invoice_id->finish(); + } # save detail record in invoice table - $query = - qq|INSERT INTO invoice (id, trans_id, parts_id, description, longdescription, qty, - sellprice, fxsellprice, discount, allocated, assemblyitem, - unit, deliverydate, project_id, serialnumber, pricegroup_id, - ordnumber, donumber, transdate, cusordnumber, base_qty, subtotal, - marge_percent, marge_total, lastcost, - price_factor_id, price_factor, marge_price_factor) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, - (SELECT factor FROM price_factors WHERE id = ?), ?)|; - - @values = ($invoice_id, conv_i($form->{id}), conv_i($form->{"id_$i"}), + $query = <{id}), conv_i($position), conv_i($form->{"id_$i"}), $form->{"description_$i"}, $restricter->process($form->{"longdescription_$i"}), $form->{"qty_$i"}, $form->{"sellprice_$i"}, $fxsellprice, $form->{"discount_$i"}, $allocated, 'f', @@ -776,19 +794,35 @@ sub post_invoice { $form->{"cusordnumber_$i"}, $baseqty, $form->{"subtotal_$i"} ? 't' : 'f', $form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"}, $form->{"lastcost_$i"}, + $form->{"active_price_source_$i"}, $form->{"active_discount_source_$i"}, conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}), - conv_i($form->{"marge_price_factor_$i"})); + conv_i($form->{"marge_price_factor_$i"}), + conv_i($form->{"invoice_id_$i"})); do_query($form, $dbh, $query, @values); + push @processed_invoice_ids, $form->{"invoice_id_$i"}; CVar->save_custom_variables(module => 'IC', sub_module => 'invoice', - trans_id => $invoice_id, + trans_id => $form->{"invoice_id_$i"}, configs => $ic_cvar_configs, variables => $form, name_prefix => 'ic_', name_postfix => "_$i", dbh => $dbh); } + # link previous items with invoice items + foreach (qw(delivery_order_items orderitems invoice)) { + if (!$form->{useasnew} && $form->{"converted_from_${_}_id_$i"}) { + RecordLinks->create_links('dbh' => $dbh, + 'mode' => 'ids', + 'from_table' => $_, + 'from_ids' => $form->{"converted_from_${_}_id_$i"}, + 'to_table' => 'invoice', + 'to_id' => $form->{"invoice_id_$i"}, + ); + } + delete $form->{"converted_from_${_}_id_$i"}; + } } # total payments, don't move we need it here @@ -1174,15 +1208,28 @@ sub post_invoice { Common::webdav_folder($form); - # Link this record to the records it was created from. - RecordLinks->create_links('dbh' => $dbh, - 'mode' => 'ids', - 'from_table' => 'oe', - 'from_ids' => $form->{convert_from_oe_ids}, - 'to_table' => 'ar', - 'to_id' => $form->{id}, + if ($form->{convert_from_ar_ids}) { + RecordLinks->create_links('dbh' => $dbh, + 'mode' => 'ids', + 'from_table' => 'ar', + 'from_ids' => $form->{convert_from_ar_ids}, + 'to_table' => 'ar', + 'to_id' => $form->{id}, ); - delete $form->{convert_from_oe_ids}; + delete $form->{convert_from_ar_ids}; + } + + # Link this record to the records it was created from. + if ($form->{convert_from_oe_ids}) { + RecordLinks->create_links('dbh' => $dbh, + 'mode' => 'ids', + 'from_table' => 'oe', + 'from_ids' => $form->{convert_from_oe_ids}, + 'to_table' => 'ar', + 'to_id' => $form->{id}, + ); + delete $form->{convert_from_oe_ids}; + } my @convert_from_do_ids = map { $_ * 1 } grep { $_ } split m/\s+/, $form->{convert_from_do_ids}; @@ -1204,6 +1251,16 @@ sub post_invoice { 'arap_id' => $form->{id}, 'table' => 'ar',); + # search for orphaned invoice items + $query = sprintf 'SELECT id FROM invoice WHERE trans_id = ? AND NOT id IN (%s)', join ', ', ("?") x scalar @processed_invoice_ids; + @values = (conv_i($form->{id}), map { conv_i($_) } @processed_invoice_ids); + my @orphaned_ids = map { $_->{id} } selectall_hashref_query($form, $dbh, $query, @values); + if (scalar @orphaned_ids) { + # clean up invoice items + $query = sprintf 'DELETE FROM invoice WHERE id IN (%s)', join ', ', ("?") x scalar @orphaned_ids; + do_query($form, $dbh, $query, @orphaned_ids); + } + # safety check datev export if ($::instance_conf->get_datev_check_on_sales_invoice) { my $transdate = $::form->{invdate} ? DateTime->from_lxoffice($::form->{invdate}) : undef; @@ -1345,7 +1402,7 @@ sub post_payment { sub process_assembly { $main::lxdebug->enter_sub(); - my ($dbh, $myconfig, $form, $id, $totalqty) = @_; + my ($dbh, $myconfig, $form, $position, $id, $totalqty) = @_; my $query = qq|SELECT a.parts_id, a.qty, p.assembly, p.partnumber, p.description, p.unit, @@ -1366,7 +1423,7 @@ sub process_assembly { $ref->{qty} *= $totalqty; if ($ref->{assembly}) { - &process_assembly($dbh, $myconfig, $form, $ref->{parts_id}, $ref->{qty}); + &process_assembly($dbh, $myconfig, $form, $position, $ref->{parts_id}, $ref->{qty}); next; } else { if ($ref->{inventory_accno_id}) { @@ -1376,9 +1433,10 @@ sub process_assembly { # save detail record for individual assembly item in invoice table $query = - qq|INSERT INTO invoice (trans_id, description, parts_id, qty, sellprice, fxsellprice, allocated, assemblyitem, unit) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)|; - my @values = (conv_i($form->{id}), $ref->{description}, conv_i($ref->{parts_id}), $ref->{qty}, 0, 0, $allocated, 't', $ref->{unit}); + qq|INSERT INTO invoice (trans_id, position, description, parts_id, qty, sellprice, fxsellprice, allocated, assemblyitem, unit) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|; + my @values = (conv_i($form->{id}), conv_i($position), $ref->{description}, + conv_i($ref->{parts_id}), $ref->{qty}, 0, 0, $allocated, 't', $ref->{unit}); do_query($form, $dbh, $query, @values); } @@ -1525,7 +1583,6 @@ sub reverse_invoice { # delete acc_trans my @values = (conv_i($form->{id})); do_query($form, $dbh, qq|DELETE FROM acc_trans WHERE trans_id = ?|, @values); - do_query($form, $dbh, qq|DELETE FROM invoice WHERE trans_id = ?|, @values); do_query($form, $dbh, qq|DELETE FROM shipto WHERE (trans_id = ?) AND (module = 'AR')|, @values); $main::lxdebug->leave_sub(); @@ -1563,6 +1620,7 @@ sub delete_invoice { my @queries = ( qq|DELETE FROM status WHERE trans_id = ?|, qq|DELETE FROM periodic_invoices WHERE ar_id = ?|, + qq|DELETE FROM invoice WHERE trans_id = ?|, qq|DELETE FROM ar WHERE id = ?|, ); @@ -1665,8 +1723,8 @@ sub retrieve_invoice { i.id AS invoice_id, i.description, i.longdescription, i.qty, i.fxsellprice AS sellprice, i.discount, i.parts_id AS id, i.unit, i.deliverydate AS reqdate, - i.project_id, i.serialnumber, i.id AS invoice_pos, i.pricegroup_id, i.ordnumber, i.donumber, i.transdate, i.cusordnumber, i.subtotal, i.lastcost, - i.price_factor_id, i.price_factor, i.marge_price_factor, + i.project_id, i.serialnumber, i.pricegroup_id, i.ordnumber, i.donumber, i.transdate, i.cusordnumber, i.subtotal, i.lastcost, + i.price_factor_id, i.price_factor, i.marge_price_factor, i.active_price_source, i.active_discount_source, p.partnumber, p.assembly, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id, p.formel, p.listprice, pr.projectnumber, pg.partsgroup, prg.pricegroup @@ -1680,7 +1738,7 @@ sub retrieve_invoice { LEFT JOIN chart c2 ON ((SELECT tc.income_accno_id FROM taxzone_charts tc WHERE tc.taxzone_id = '$taxzone_id' and tc.buchungsgruppen_id = p.buchungsgruppen_id) = c2.id) LEFT JOIN chart c3 ON ((SELECT tc.expense_accno_id FROM taxzone_charts tc WHERE tc.taxzone_id = '$taxzone_id' and tc.buchungsgruppen_id = p.buchungsgruppen_id) = c3.id) - WHERE (i.trans_id = ?) AND NOT (i.assemblyitem = '1') ORDER BY i.id|; + WHERE (i.trans_id = ?) AND NOT (i.assemblyitem = '1') ORDER BY i.position|; $sth = prepare_execute_query($form, $dbh, $query, $id); @@ -1692,7 +1750,6 @@ sub retrieve_invoice { trans_id => $ref->{invoice_id}, ); map { $ref->{"ic_cvar_$_->{name}"} = $_->{value} } @{ $cvars }; - delete $ref->{invoice_id}; map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid)) if !$ref->{"part_inventory_accno_id"}; delete($ref->{"part_inventory_accno_id"}); @@ -2120,196 +2177,6 @@ sub retrieve_item { $main::lxdebug->leave_sub(); } -########################## -# get pricegroups from database -# build up selected pricegroup -# if an exchange rate - change price -# for each part -# -sub get_pricegroups_for_parts { - - $main::lxdebug->enter_sub(); - - my ($self, $myconfig, $form) = @_; - - my $dbh = $form->get_standard_dbh; - - $form->{"PRICES"} = {}; - - my $i = 1; - my $id = 0; - my $all_units = AM->retrieve_units($myconfig, $form); - while (($form->{"id_$i"}) or ($form->{"new_id_$i"})) { - $form->{"PRICES"}{$i} = []; - - $id = $form->{"id_$i"}; - - if (!($form->{"id_$i"}) and $form->{"new_id_$i"}) { - $id = $form->{"new_id_$i"}; - } - - my ($price, $selectedpricegroup_id) = split(/--/, $form->{"sellprice_pg_$i"}); - - my $pricegroup_old = $form->{"pricegroup_old_$i"}; - - # sellprice has format 13,0000 or 0,00000, can't check for 0 numerically - my $sellprice = $form->{"sellprice_$i"}; - my $pricegroup_id = $form->{"pricegroup_id_$i"}; - $form->{"new_pricegroup_$i"} = $selectedpricegroup_id; - $form->{"old_pricegroup_$i"} = $pricegroup_old; - - my $price_new = $form->{"price_new_$i"}; - my $price_old = $form->{"price_old_$i"}; - - if (!$form->{"unit_old_$i"}) { - # Neue Ware aus der Datenbank. In diesem Fall ist unit_$i die - # Einheit, wie sie in den Stammdaten hinterlegt wurde. - # Es sollte also angenommen werden, dass diese ausgewaehlt war. - $form->{"unit_old_$i"} = $form->{"unit_$i"}; - } - - # Die zuletzt ausgewaehlte mit der aktuell ausgewaehlten Einheit - # vergleichen und bei Unterschied den Preis entsprechend umrechnen. - $form->{"selected_unit_$i"} = $form->{"unit_$i"} unless ($form->{"selected_unit_$i"}); - - if (!$all_units->{$form->{"selected_unit_$i"}} || - ($all_units->{$form->{"selected_unit_$i"}}->{"base_unit"} ne - $all_units->{$form->{"unit_old_$i"}}->{"base_unit"})) { - # Die ausgewaehlte Einheit ist fuer diesen Artikel nicht gueltig - # (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber - # um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen. - $form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"}; - } - - my $basefactor = 1; - - if ($form->{"unit_old_$i"} ne $form->{"selected_unit_$i"}) { - if (defined($all_units->{$form->{"unit_old_$i"}}->{"factor"}) && - $all_units->{$form->{"unit_old_$i"}}->{"factor"}) { - $basefactor = $all_units->{$form->{"selected_unit_$i"}}->{"factor"} / - $all_units->{$form->{"unit_old_$i"}}->{"factor"}; - } - } - - if (!$form->{"basefactor_$i"}) { - $form->{"basefactor_$i"} = 1; - } - - my $query = - qq|SELECT - 0 as pricegroup_id, - sellprice AS default_sellprice, - '' AS pricegroup, - sellprice AS price, - 'selected' AS selected - FROM parts - WHERE id = ? - UNION ALL - SELECT - pricegroup_id, - parts.sellprice AS default_sellprice, - pricegroup.pricegroup, - price, - '' AS selected - FROM prices - LEFT JOIN parts ON parts.id = parts_id - LEFT JOIN pricegroup ON pricegroup.id = pricegroup_id - WHERE parts_id = ? - ORDER BY pricegroup|; - my @values = (conv_i($id), conv_i($id)); - my $pkq = prepare_execute_query($form, $dbh, $query, @values); - - while (my $pkr = $pkq->fetchrow_hashref('NAME_lc')) { - $pkr->{id} = $id; - $pkr->{selected} = ''; - - # if there is an exchange rate change price - if (($form->{exchangerate} * 1) != 0) { - $pkr->{price} /= $form->{exchangerate}; - } - - $pkr->{price} *= $form->{"basefactor_$i"}; - $pkr->{price} *= $basefactor; - $pkr->{price_ufmt} = $pkr->{price}; - $pkr->{price} = $form->format_amount($myconfig, $pkr->{price}, 5); - - if (!defined $selectedpricegroup_id) { - # new entries in article list, either old invoice was loaded (edit) or a new article was added - # Case A: open old invoice, no pricegroup selected - # Case B: add new article to invoice, no pricegroup selected - - # to distinguish case A and B the variable pricegroup_id_$i is used - # for new articles this variable isn't defined, for loaded articles it is - # sellprice can't be used, as it already has 0,00 set - - if ($pkr->{pricegroup_id} eq $form->{"pricegroup_id_$i"} and defined $form->{"pricegroup_id_$i"}) { - # Case A - $pkr->{selected} = ' selected'; - } elsif ($pkr->{pricegroup_id} eq $form->{customer_klass} - and not defined $form->{"pricegroup_id_$i"} - and $pkr->{price_ufmt} != 0 # only use customer pricegroup price if it has a value, else use default_sellprice - # for the case where pricegroup prices haven't been set - ) { - # Case B: use default pricegroup of customer - - $pkr->{selected} = ' selected'; # unless $form->{selected}; - # no customer pricesgroup set - if ($pkr->{price_ufmt} == $pkr->{default_sellprice}) { - - $pkr->{price} = $form->{"sellprice_$i"}; - - } else { - -# this sub should not set anything and only return. --sschoeling, 20090506 -# is this correct? put in again... -- grichardson 20110119 - $form->{"sellprice_$i"} = $pkr->{price}; - } - - } elsif ($pkr->{price_ufmt} == $pkr->{default_sellprice} and $pkr->{default_sellprice} != 0) { - $pkr->{price} = $form->{"sellprice_$i"}; - $pkr->{selected} = ' selected'; - } - } - - # existing article: pricegroup or price changed - if ($selectedpricegroup_id or $selectedpricegroup_id == 0) { - if ($selectedpricegroup_id ne $pricegroup_old) { - # pricegroup has changed - if ($pkr->{pricegroup_id} eq $selectedpricegroup_id) { - $pkr->{selected} = ' selected'; - } - } elsif ( ($form->parse_amount($myconfig, $price_new) - != $form->parse_amount($myconfig, $form->{"sellprice_$i"})) - and ($price_new ne 0) and defined $price_new) { - # sellprice has changed - # when loading existing invoices $price_new is NULL - if ($pkr->{pricegroup_id} == 0) { - $pkr->{price} = $form->{"sellprice_$i"}; - $pkr->{selected} = ' selected'; - } - } elsif ($pkr->{pricegroup_id} eq $selectedpricegroup_id) { - # neither sellprice nor pricegroup changed - $pkr->{selected} = ' selected'; - if ( ($pkr->{pricegroup_id} == 0) and ($pkr->{price} == $form->{"sellprice_$i"})) { - # $pkr->{price} = $form->{"sellprice_$i"}; - } else { - $pkr->{price} = $form->{"sellprice_$i"}; - } - } - } - push @{ $form->{PRICES}{$i} }, $pkr; - - } - $form->{"basefactor_$i"} *= $basefactor; - - $i++; - - $pkq->finish; - } - - $main::lxdebug->leave_sub(); -} - sub has_storno { $main::lxdebug->enter_sub();