X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FIS.pm;h=9474b18e087bb25c4cf9ca34f2f463ffbbb82431;hb=844a541e0d8f59644540413f675e8f07cd154cf6;hp=21bf15f74e970b23c12c588eec21b07cea2da448;hpb=ce36e8eb8fe64b4ec7134503956e3e99018862f9;p=kivitendo-erp.git diff --git a/SL/IS.pm b/SL/IS.pm index 21bf15f74..9474b18e0 100644 --- a/SL/IS.pm +++ b/SL/IS.pm @@ -171,7 +171,7 @@ sub invoice_details { push @arrays, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs }; push @arrays, map { "project_cvar_$_->{name}" } @{ $project_cvar_configs }; - my @tax_arrays = qw(taxbase tax taxdescription taxrate taxnumber); + my @tax_arrays = qw(taxbase tax taxdescription taxrate taxnumber tax_id); my @payment_arrays = qw(payment paymentaccount paymentdate paymentsource paymentmemo); @@ -442,9 +442,9 @@ sub invoice_details { my $sortorder = ""; if ($form->{groupitems}) { $sortorder = - qq|ORDER BY pg.partsgroup, a.oid|; + qq|ORDER BY pg.partsgroup, a.position|; } else { - $sortorder = qq|ORDER BY a.oid|; + $sortorder = qq|ORDER BY a.position|; } my $query = @@ -505,10 +505,25 @@ sub invoice_details { push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100)); push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate_nofmt} }, $form->{"${item}_rate"} * 100); push(@{ $form->{TEMPLATE_ARRAYS}->{taxnumber} }, $form->{"${item}_taxnumber"}); + push(@{ $form->{TEMPLATE_ARRAYS}->{tax_id} }, $form->{"${item}_tax_id"}); + + # taxnumber (= accno) is used for grouping the amounts of the various taxes and as a prefix in form + + # This code used to assume that at most one tax entry can point to the same + # chart_id, even though chart_id does not have a unique constraint! + + # This chart_id was then looked up via its accno, which is the key that is + # used to group the different taxes by for a record + + # As we now also store the tax_id we can use that to look up the tax + # instead, this is only done here to get the (translated) taxdescription. + + if ( $form->{"${item}_tax_id"} ) { + my $tax_obj = SL::DB::Manager::Tax->find_by(id => $form->{"${item}_tax_id"}) or die "Can't find tax with id " . $form->{"${item}_tax_id"}; + my $description = $tax_obj ? $tax_obj->translated_attribute('taxdescription', $form->{language_id}, 0) : ''; + push(@{ $form->{TEMPLATE_ARRAYS}->{taxdescription} }, $description . q{ } . 100 * $form->{"${item}_rate"} . q{%}); + } - my $tax_obj = SL::DB::Manager::Tax->find_by(taxnumber => $form->{"${item}_taxnumber"}); - my $description = $tax_obj ? $tax_obj->translated_attribute('taxdescription', $form->{language_id}, 0) : ''; - push(@{ $form->{TEMPLATE_ARRAYS}->{taxdescription} }, $description . q{ } . 100 * $form->{"${item}_rate"} . q{%}); } for my $i (1 .. $form->{paidaccounts}) { @@ -562,20 +577,6 @@ sub invoice_details { $main::lxdebug->leave_sub(); } -sub project_description { - $main::lxdebug->enter_sub(); - - my ($self, $dbh, $id) = @_; - my $form = \%main::form; - - my $query = qq|SELECT description FROM project WHERE id = ?|; - my ($description) = selectrow_query($form, $dbh, $query, conv_i($id)); - - $main::lxdebug->leave_sub(); - - return $_; -} - sub customer_details { $main::lxdebug->enter_sub(); @@ -682,18 +683,19 @@ sub customer_details { } sub post_invoice { - my ($self, $myconfig, $form, $provided_dbh, $payments_only) = @_; + my ($self, $myconfig, $form, $provided_dbh, %params) = @_; $main::lxdebug->enter_sub(); - my $rc = SL::DB->client->with_transaction(\&_post_invoice, $self, $myconfig, $form, $provided_dbh, $payments_only); + my $rc = SL::DB->client->with_transaction(\&_post_invoice, $self, $myconfig, $form, $provided_dbh, %params); $::lxdebug->leave_sub; return $rc; } sub _post_invoice { - my ($self, $myconfig, $form, $provided_dbh, $payments_only) = @_; + my ($self, $myconfig, $form, $provided_dbh, %params) = @_; + my $payments_only = $params{payments_only}; my $dbh = $provided_dbh || SL::DB->client->dbh; my $restricter = SL::HTML::Restrict->create; @@ -1035,7 +1037,7 @@ SQL $project_id = conv_i($form->{"globalproject_id"}); # entsprechend auch beim Bestimmen des Steuerschlüssels in Taxkey.pm berücksichtigen - my $taxdate = $form->{deliverydate} ? $form->{deliverydate} : $form->{invdate}; + my $taxdate = $form->{tax_point} ||$form->{deliverydate} || $form->{invdate}; foreach my $trans_id (keys %{ $form->{amount_cogs} }) { foreach my $accno (keys %{ $form->{amount_cogs}{$trans_id} }) { @@ -1144,6 +1146,8 @@ SQL } } + my %already_cleared = %{ $params{already_cleared} // {} }; + # record payments and offsetting AR if (!$form->{storno}) { for my $i (1 .. $form->{paidaccounts}) { @@ -1173,9 +1177,16 @@ SQL # record AR $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate} + $diff, 2); + my $new_cleared = !$form->{"acc_trans_id_$i"} ? 'f' + : !$already_cleared{$form->{"acc_trans_id_$i"}} ? 'f' + : $already_cleared{$form->{"acc_trans_id_$i"}}->{amount} != $form->{"paid_$i"} * -1 ? 'f' + : $already_cleared{$form->{"acc_trans_id_$i"}}->{accno} != $accno ? 'f' + : $already_cleared{$form->{"acc_trans_id_$i"}}->{cleared} ? 't' + : 'f'; + if ($form->{amount}{ $form->{id} }{ $form->{AR} } != 0) { $query = - qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, tax_id, taxkey, project_id, chart_link) + qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, tax_id, taxkey, project_id, cleared, chart_link) VALUES (?, (SELECT id FROM chart WHERE accno = ?), ?, ?, (SELECT tax_id FROM taxkeys @@ -1191,9 +1202,9 @@ SQL WHERE accno = ?) AND startdate <= ? ORDER BY startdate DESC LIMIT 1), - ?, + ?, ?, (SELECT link FROM chart WHERE accno = ?))|; - @values = (conv_i($form->{"id"}), $form->{AR}, $amount, $form->{"datepaid_$i"}, $form->{AR}, conv_date($taxdate), $form->{AR}, conv_date($taxdate), $project_id, $form->{AR}); + @values = (conv_i($form->{"id"}), $form->{AR}, $amount, $form->{"datepaid_$i"}, $form->{AR}, conv_date($taxdate), $form->{AR}, conv_date($taxdate), $project_id, $new_cleared, $form->{AR}); do_query($form, $dbh, $query, @values); } @@ -1202,7 +1213,7 @@ SQL my $gldate = (conv_date($form->{"gldate_$i"}))? conv_date($form->{"gldate_$i"}) : conv_date($form->current_date($myconfig)); $query = - qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, gldate, source, memo, tax_id, taxkey, project_id, chart_link) + qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, gldate, source, memo, tax_id, taxkey, project_id, cleared, chart_link) VALUES (?, (SELECT id FROM chart WHERE accno = ?), ?, ?, ?, ?, ?, (SELECT tax_id FROM taxkeys @@ -1218,10 +1229,10 @@ SQL WHERE accno = ?) AND startdate <= ? ORDER BY startdate DESC LIMIT 1), - ?, + ?, ?, (SELECT link FROM chart WHERE accno = ?))|; @values = (conv_i($form->{"id"}), $accno, $form->{"paid_$i"}, $form->{"datepaid_$i"}, - $gldate, $form->{"source_$i"}, $form->{"memo_$i"}, $accno, conv_date($taxdate), $accno, conv_date($taxdate), $project_id, $accno); + $gldate, $form->{"source_$i"}, $form->{"memo_$i"}, $accno, conv_date($taxdate), $accno, conv_date($taxdate), $project_id, $new_cleared, $accno); do_query($form, $dbh, $query, @values); # exchangerate difference @@ -1301,13 +1312,13 @@ SQL $query = qq|UPDATE ar set invnumber = ?, ordnumber = ?, quonumber = ?, cusordnumber = ?, - transdate = ?, orddate = ?, quodate = ?, customer_id = ?, + transdate = ?, orddate = ?, quodate = ?, tax_point = ?, customer_id = ?, amount = ?, netamount = ?, paid = ?, duedate = ?, deliverydate = ?, invoice = ?, shippingpoint = ?, shipvia = ?, notes = ?, intnotes = ?, currency_id = (SELECT id FROM currencies WHERE name = ?), department_id = ?, payment_id = ?, taxincluded = ?, - type = ?, language_id = ?, taxzone_id = ?, shipto_id = ?, + type = ?, language_id = ?, taxzone_id = ?, shipto_id = ?, billing_address_id = ?, employee_id = ?, salesman_id = ?, storno_id = ?, storno = ?, cp_id = ?, marge_total = ?, marge_percent = ?, globalproject_id = ?, delivery_customer_id = ?, @@ -1316,12 +1327,12 @@ SQL delivery_term_id = ? WHERE id = ?|; @values = ( $form->{"invnumber"}, $form->{"ordnumber"}, $form->{"quonumber"}, $form->{"cusordnumber"}, - conv_date($form->{"invdate"}), conv_date($form->{"orddate"}), conv_date($form->{"quodate"}), conv_i($form->{"customer_id"}), + conv_date($form->{"invdate"}), conv_date($form->{"orddate"}), conv_date($form->{"quodate"}), conv_date($form->{tax_point}), conv_i($form->{"customer_id"}), $amount, $netamount, $form->{"paid"}, conv_date($form->{"duedate"}), conv_date($form->{"deliverydate"}), '1', $form->{"shippingpoint"}, $form->{"shipvia"}, $restricter->process($form->{"notes"}), $form->{"intnotes"}, $form->{"currency"}, conv_i($form->{"department_id"}), conv_i($form->{"payment_id"}), $form->{"taxincluded"} ? 't' : 'f', - $form->{"type"}, conv_i($form->{"language_id"}), conv_i($form->{"taxzone_id"}), conv_i($form->{"shipto_id"}), + $form->{"type"}, conv_i($form->{"language_id"}), conv_i($form->{"taxzone_id"}), conv_i($form->{"shipto_id"}), conv_i($form->{billing_address_id}), conv_i($form->{"employee_id"}), conv_i($form->{"salesman_id"}), conv_i($form->{storno_id}), $form->{"storno"} ? 't' : 'f', conv_i($form->{"cp_id"}), 1 * $form->{marge_total} , 1 * $form->{marge_percent}, conv_i($form->{"globalproject_id"}), conv_i($form->{"delivery_customer_id"}), @@ -1430,6 +1441,21 @@ SQL } } + # update shop status + my $invoice = SL::DB::Invoice->new( id => $form->{id} )->load; + my @linked_shop_orders = $invoice->linked_records( + from => 'ShopOrder', + via => ['DeliveryOrder','Order',], + ); + #do update + my $shop_order = $linked_shop_orders[0][0]; + if ( $shop_order ) { + require SL::Shop; + my $shop_config = SL::DB::Manager::Shop->get_first( query => [ id => $shop_order->shop_id ] ); + my $shop = SL::Shop->new( config => $shop_config ); + $shop->connector->set_orderstatus($shop_order->shop_trans_id, "completed"); + } + return 1; } @@ -1440,7 +1466,7 @@ sub transfer_out { my (@errors, @transfers); - # do nothing, if transfer default is not requeseted at all + # do nothing, if transfer default is not requested at all if (!$::instance_conf->get_transfer_default) { $::lxdebug->leave_sub; return \@errors; @@ -1450,26 +1476,56 @@ sub transfer_out { foreach my $i (1 .. $form->{rowcount}) { next if !$form->{"id_$i"}; - my ($err, $wh_id, $bin_id) = _determine_wh_and_bin($dbh, $::instance_conf, - $form->{"id_$i"}, - $form->{"qty_$i"}, - $form->{"unit_$i"}); - if (!@{ $err } && $wh_id && $bin_id) { - push @transfers, { - 'parts_id' => $form->{"id_$i"}, - 'qty' => $form->{"qty_$i"}, - 'unit' => $form->{"unit_$i"}, - 'transfer_type' => 'shipped', - 'src_warehouse_id' => $wh_id, - 'src_bin_id' => $bin_id, - 'project_id' => $form->{"project_id_$i"}, - 'invoice_id' => $form->{"invoice_id_$i"}, - 'comment' => $::locale->text("Default transfer invoice"), - }; - } + my ($err, $qty, $wh_id, $bin_id, $chargenumber); + + if ($::instance_conf->get_sales_serial_eq_charge && $form->{"serialnumber_$i"}) { + my @serials = split(" ", $form->{"serialnumber_$i"}); + if (scalar @serials != $form->{"qty_$i"}) { + push @errors, $::locale->text("Cannot transfer #1 qty with #2 serial number(s)", $form->{"qty_$i"}, scalar @serials); + last; + } + foreach my $serial (@serials) { + ($qty, $wh_id, $bin_id, $chargenumber) = WH->get_wh_and_bin_for_charge(chargenumber => $serial); + if (!$qty) { + push @errors, $::locale->text("Not enough in stock for the serial number #1", $serial); + last; + } + push @transfers, { + 'parts_id' => $form->{"id_$i"}, + 'qty' => 1, + 'unit' => $form->{"unit_$i"}, + 'transfer_type' => 'shipped', + 'src_warehouse_id' => $wh_id, + 'src_bin_id' => $bin_id, + 'chargenumber' => $chargenumber, + 'project_id' => $form->{"project_id_$i"}, + 'invoice_id' => $form->{"invoice_id_$i"}, + 'comment' => $::locale->text("Default transfer invoice with charge number"), + }; + } + $err = []; # error handling uses @errors direct + } else { + ($err, $wh_id, $bin_id) = _determine_wh_and_bin($dbh, $::instance_conf, + $form->{"id_$i"}, + $form->{"qty_$i"}, + $form->{"unit_$i"}); + if (!@{ $err } && $wh_id && $bin_id) { + push @transfers, { + 'parts_id' => $form->{"id_$i"}, + 'qty' => $form->{"qty_$i"}, + 'unit' => $form->{"unit_$i"}, + 'transfer_type' => 'shipped', + 'src_warehouse_id' => $wh_id, + 'src_bin_id' => $bin_id, + 'project_id' => $form->{"project_id_$i"}, + 'invoice_id' => $form->{"invoice_id_$i"}, + 'comment' => $::locale->text("Default transfer invoice"), + }; + } + } push @errors, @{ $err }; - } + } # end form rowcount if (!@errors) { WH->transfer(@transfers); @@ -1620,6 +1676,15 @@ sub _post_payment { $old_form = save_form(); + $query = <{id}); + # Delete all entries in acc_trans from prior payments. if (SL::DB::Default->get->payments_changeable != 0) { $self->_delete_payments($form, $dbh); @@ -1666,7 +1731,7 @@ sub _post_payment { ($form->{AR}) = selectfirst_array_query($form, $dbh, $query, conv_i($form->{id})); # Post the new payments. - $self->post_invoice($myconfig, $form, $dbh, 1); + $self->post_invoice($myconfig, $form, $dbh, payments_only => 1, already_cleared => \%already_cleared); restore_form($old_form); @@ -1962,9 +2027,10 @@ sub _retrieve_invoice { qq|SELECT a.invnumber, a.ordnumber, a.quonumber, a.cusordnumber, a.orddate, a.quodate, a.globalproject_id, - a.transdate AS invdate, a.deliverydate, a.paid, a.storno, a.storno_id, a.gldate, + a.transdate AS invdate, a.deliverydate, a.tax_point, a.paid, a.storno, a.storno_id, a.gldate, a.shippingpoint, a.shipvia, a.notes, a.intnotes, a.taxzone_id, a.duedate, a.taxincluded, (SELECT cu.name FROM currencies cu WHERE cu.id=a.currency_id) AS currency, a.shipto_id, a.cp_id, + a.billing_address_id, a.employee_id, a.salesman_id, a.payment_id, a.mtime, a.itime, a.language_id, a.delivery_customer_id, a.delivery_vendor_id, a.type, @@ -2005,7 +2071,8 @@ sub _retrieve_invoice { $sth->finish; map { $form->{$_} =~ s/ +$//g } qw(printed emailed queued); - my $transdate = $form->{deliverydate} ? $dbh->quote($form->{deliverydate}) + my $transdate = $form->{tax_point} ? $dbh->quote($form->{tax_point}) + : $form->{deliverydate} ? $dbh->quote($form->{deliverydate}) : $form->{invdate} ? $dbh->quote($form->{invdate}) : "current_date"; @@ -2064,7 +2131,8 @@ sub _retrieve_invoice { # get tax rates and description my $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno}; $query = - qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber FROM tax t + qq|SELECT c.accno, t.taxdescription, t.rate, t.id as tax_id, c.accno as 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 @@ -2086,7 +2154,8 @@ sub _retrieve_invoice { if (!($form->{taxaccounts} =~ /\Q$ptr->{accno}\E/)) { $form->{"$ptr->{accno}_rate"} = $ptr->{rate}; $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription}; - $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; + $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; # don't use this anymore + $form->{"$ptr->{accno}_tax_id"} = $ptr->{tax_id}; $form->{taxaccounts} .= "$ptr->{accno} "; } @@ -2150,6 +2219,10 @@ sub get_customer { c.street, c.zipcode, c.city, c.country, c.notes AS intnotes, c.pricegroup_id as customer_pricegroup_id, c.taxzone_id, c.salesman_id, cu.name AS curr, c.taxincluded_checked, c.direct_debit, + (SELECT aba.id + FROM additional_billing_addresses aba + WHERE aba.default_address + LIMIT 1) AS default_billing_address_id, b.discount AS tradediscount, b.description AS business FROM customer c LEFT JOIN business b ON (b.id = c.business_id) @@ -2388,7 +2461,7 @@ sub retrieve_item { # get tax rates and description my $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno}; $query = - qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber + qq|SELECT c.accno, t.taxdescription, t.id as tax_id, t.rate, c.accno as taxnumber FROM tax t LEFT JOIN chart c ON (c.id = t.chart_id) WHERE t.id in @@ -2417,6 +2490,7 @@ sub retrieve_item { $form->{"$ptr->{accno}_rate"} = $ptr->{rate}; $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription}; $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber}; + $form->{"$ptr->{accno}_tax_id"} = $ptr->{tax_id}; $form->{taxaccounts} .= "$ptr->{accno} "; }