Revision 72e545d6
Von Bernd Bleßmann vor etwa 3 Jahren hinzugefügt
SL/Controller/Order.pm | ||
---|---|---|
__PACKAGE__->run_before('check_auth');
|
||
|
||
__PACKAGE__->run_before('recalc',
|
||
only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_invoice_for_advance_payment save_and_ap_transaction
|
||
only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_invoice_for_advance_payment save_and_final_invoice save_and_ap_transaction
|
||
print send_email) ]);
|
||
|
||
__PACKAGE__->run_before('get_unalterable_data',
|
||
only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_invoice_for_advance_payment save_and_ap_transaction
|
||
only => [ qw(save save_as_new save_and_delivery_order save_and_invoice save_and_invoice_for_advance_payment save_and_final_invoice save_and_ap_transaction
|
||
print send_email) ]);
|
||
|
||
#
|
||
... | ... | |
);
|
||
}
|
||
|
||
sub action_save_and_final_invoice {
|
||
my ($self) = @_;
|
||
|
||
$self->save_and_redirect_to(
|
||
controller => 'oe.pl',
|
||
action => 'oe_invoice_from_order',
|
||
new_invoice_type => 'final_invoice',
|
||
);
|
||
}
|
||
|
||
# workflow from sales order to sales quotation
|
||
sub action_sales_quotation {
|
||
$_[0]->workflow_sales_or_request_for_quotation();
|
||
... | ... | |
$has_invoice_for_advance_payment = any {'SL::DB::Invoice' eq ref $_ && "invoice_for_advance_payment" eq $_->type} @$lr;
|
||
}
|
||
|
||
my $has_final_invoice;
|
||
if ($self->order->id && $self->type eq sales_order_type()) {
|
||
my $lr = $self->order->linked_records(direction => 'to', to => ['Invoice']);
|
||
$has_final_invoice = any {'SL::DB::Invoice' eq ref $_ && "final_invoice" eq $_->type} @$lr;
|
||
}
|
||
|
||
for my $bar ($::request->layout->get('actionbar')) {
|
||
$bar->add(
|
||
combobox => [
|
||
... | ... | |
],
|
||
],
|
||
action => [
|
||
t8('Save and Invoice for Advance Payment'),
|
||
($has_invoice_for_advance_payment ? t8('Save and Further Invoice for Advance Payment') : t8('Save and Invoice for Advance Payment')),
|
||
call => [ 'kivi.Order.save', 'save_and_invoice_for_advance_payment', $::instance_conf->get_order_warn_duplicate_parts ],
|
||
checks => [ 'kivi.Order.check_save_active_periodic_invoices',
|
||
@req_trans_cost_art, @req_cusordnumber,
|
||
],
|
||
disabled => $has_invoice_for_advance_payment ? t8('This order has already an invoice for advanced payment.')
|
||
: undef,
|
||
disabled => $has_final_invoice ? t8('This order has already a final invoice.')
|
||
: undef,
|
||
only_if => (any { $self->type eq $_ } (sales_order_type())),
|
||
],
|
||
action => [
|
||
t8('Save and Final Invoice'),
|
||
call => [ 'kivi.Order.save', 'save_and_final_invoice', $::instance_conf->get_order_warn_duplicate_parts ],
|
||
checks => [ 'kivi.Order.check_save_active_periodic_invoices',
|
||
@req_trans_cost_art, @req_cusordnumber,
|
||
],
|
||
disabled => $has_final_invoice ? t8('This order has already a final invoice.')
|
||
: undef,
|
||
only_if => (any { $self->type eq $_ } (sales_order_type())) && $has_invoice_for_advance_payment,
|
||
],
|
||
action => [
|
||
t8('Save and AP Transaction'),
|
||
call => [ 'kivi.Order.save', 'save_and_ap_transaction', $::instance_conf->get_order_warn_duplicate_parts ],
|
SL/IS.pm | ||
---|---|---|
$form->{username} = $myconfig->{name};
|
||
$form->{$_} = $form->format_amount($myconfig, $form->{$_}, 2) for @separate_totals;
|
||
|
||
foreach my $invoice_for_advance_payment (@{$self->_get_invoices_for_advance_payment($form->{convert_from_ar_ids} || $form->{id})}) {
|
||
my $id_for_iap = $form->{convert_from_oe_ids} || $form->{convert_from_ar_ids} || $form->{id};
|
||
my $from_order = !!$form->{convert_from_oe_ids};
|
||
foreach my $invoice_for_advance_payment (@{$self->_get_invoices_for_advance_payment($id_for_iap, $from_order)}) {
|
||
# Collect VAT of invoices for advance payment.
|
||
# Set sellprices to fxsellprices for items, because
|
||
# the PriceTaxCalculator sets fxsellprice from sellprice before calculating.
|
||
... | ... | |
|
||
my $iap_amounts;
|
||
if ($form->{type} eq 'final_invoice') {
|
||
my $invoices_for_advance_payment = $self->_get_invoices_for_advance_payment($form->{convert_from_ar_ids} || $form->{id});
|
||
my $id_for_iap = $form->{convert_from_oe_ids} || $form->{convert_from_ar_ids} || $form->{id};
|
||
my $from_order = !!$form->{convert_from_oe_ids};
|
||
my $invoices_for_advance_payment = $self->_get_invoices_for_advance_payment($id_for_iap, $from_order);
|
||
if (scalar @$invoices_for_advance_payment > 0) {
|
||
# reverse booking for invoices for advance payment
|
||
foreach my $invoice_for_advance_payment (@$invoices_for_advance_payment) {
|
||
... | ... | |
}
|
||
|
||
sub _get_invoices_for_advance_payment {
|
||
my ($self, $id) = @_;
|
||
my ($self, $id, $id_is_from_order) = @_;
|
||
|
||
return [] if !$id;
|
||
|
||
my $invoice_obj = SL::DB::Invoice->new(id => $id*1)->load;
|
||
my $links = $invoice_obj->linked_records(direction => 'from', from => ['Invoice'], recursive => 1);
|
||
# Search all related invoices for advance payment.
|
||
# Case 1:
|
||
# (order) -> invoice for adv. payment 1 -> invoice for adv. payment 2 -> invoice for adv. payment 3 -> final invoice
|
||
#
|
||
# Case 2:
|
||
# order -> invoice for adv. payment 1
|
||
# | |`-> invoice for adv. payment 2
|
||
# | `--> invoice for adv. payment 3
|
||
# `----> final invoice
|
||
#
|
||
# The id is currently that from the last invoice for adv. payment (3 in this example),
|
||
# that from the final invoice or that from the order.
|
||
|
||
my $invoice_obj;
|
||
my $order_obj;
|
||
my $links;
|
||
|
||
if (!$id_is_from_order) {
|
||
$invoice_obj = SL::DB::Invoice->load_cached($id*1);
|
||
$links = $invoice_obj->linked_records(direction => 'from', from => ['Order']);
|
||
$order_obj = $links->[0];
|
||
} else {
|
||
$order_obj = SL::DB::Order->load_cached($id*1);
|
||
}
|
||
|
||
if ($order_obj) {
|
||
$links = $order_obj ->linked_records(direction => 'to', to => ['Invoice']);
|
||
} else {
|
||
$links = $invoice_obj->linked_records(direction => 'from', from => ['Invoice'], recursive => 1);
|
||
}
|
||
|
||
my @related_invoices = grep {'SL::DB::Invoice' eq ref $_ && "invoice_for_advance_payment" eq $_->type} @$links;
|
||
|
||
push @related_invoices, $invoice_obj if "invoice_for_advance_payment" eq $invoice_obj->type;
|
||
push @related_invoices, $invoice_obj if !$order_obj && "invoice_for_advance_payment" eq $invoice_obj->type;
|
||
|
||
return \@related_invoices;
|
||
}
|
||
... | ... | |
|
||
# if we delete a final invoice, the reverse bookings for the clearing account in the invoice for advance payment
|
||
# must be deleted as well
|
||
my $invoices_for_advance_payment = $self->_get_invoices_for_advance_payment($form->{convert_from_ar_ids} || $form->{id});
|
||
my $invoices_for_advance_payment = $self->_get_invoices_for_advance_payment($form->{id});
|
||
|
||
# Todo: allow only if invoice for advance payment is not paid.
|
||
# die if any { $_->paid } for @$invoices_for_advance_payment;
|
bin/mozilla/is.pl | ||
---|---|---|
$has_final_invoice = any {'SL::DB::Invoice' eq ref $_ && "final_invoice" eq $_->invoice_type} @$lr;
|
||
}
|
||
|
||
my $is_invoice_for_advance_payment_from_order;
|
||
if ($form->{id} && $form->{type} eq "invoice_for_advance_payment") {
|
||
my $invoice_obj = SL::DB::Invoice->load_cached($form->{id});
|
||
my $lr = $invoice_obj->linked_records(direction => 'from', from => ['Order']);
|
||
$is_invoice_for_advance_payment_from_order = scalar @$lr >= 1;
|
||
}
|
||
|
||
for my $bar ($::request->layout->get('actionbar')) {
|
||
$bar->add(
|
||
action => [
|
||
... | ... | |
: !$form->{id} ? t8('This invoice has not been posted yet.')
|
||
: $has_further_invoice_for_advance_payment ? t8('This invoice has already a further invoice for advanced payment.')
|
||
: $has_final_invoice ? t8('This invoice has already a final invoice.')
|
||
: $is_invoice_for_advance_payment_from_order ? t8('This invoice was added from an order. See there.')
|
||
: undef,
|
||
only_if => $form->{type} eq "invoice_for_advance_payment",
|
||
],
|
||
... | ... | |
: !$form->{id} ? t8('This invoice has not been posted yet.')
|
||
: $has_further_invoice_for_advance_payment ? t8('This invoice has a further invoice for advanced payment.')
|
||
: $has_final_invoice ? t8('This invoice has already a final invoice.')
|
||
: $is_invoice_for_advance_payment_from_order ? t8('This invoice was added from an order. See there.')
|
||
: undef,
|
||
only_if => $form->{type} eq "invoice_for_advance_payment",
|
||
],
|
||
... | ... | |
|
||
$main::auth->assert('invoice_edit');
|
||
|
||
# search all related invoices for advance payment
|
||
#
|
||
# (order) -> invoice for adv. payment 1 -> invoice for adv. payment 2 -> invoice for adv. payment 3 -> final invoice
|
||
#
|
||
# we are currently in the last invoice for adv. payment (3 in this example)
|
||
my $related_invoices = IS->_get_invoices_for_advance_payment($form->{id});
|
||
|
||
delete @{ $form }{qw(printed emailed queued invnumber invdate exchangerate forex deliverydate datepaid_1 gldate_1 acc_trans_id_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno locked)};
|
bin/mozilla/oe.pl | ||
---|---|---|
$::dispatcher->end_request;
|
||
}
|
||
|
||
_oe_remove_delivered_or_billed_rows(id => $form->{id}, type => 'billed');
|
||
_oe_remove_delivered_or_billed_rows(id => $form->{id}, type => 'billed') if $form->{new_invoice_type} ne 'final_invoice';
|
||
|
||
$form->{cp_id} *= 1;
|
||
|
||
... | ... | |
|
||
if ( $form->{type} eq 'sales_order'
|
||
|| $form->{type} eq 'sales_quotation') {
|
||
$form->{title} = ($form->{new_invoice_type} eq 'invoice_for_advance_payment')
|
||
? $locale->text('Add Invoice for Advance Payment')
|
||
$form->{title} = ($form->{new_invoice_type} eq 'invoice_for_advance_payment') ? $locale->text('Add Invoice for Advance Payment')
|
||
: ($form->{new_invoice_type} eq 'final_invoice') ? $locale->text('Add Final Invoice')
|
||
: $locale->text('Add Sales Invoice');
|
||
$form->{script} = 'is.pl';
|
||
$script = "is";
|
Auch abrufbar als: Unified diff
Anzahlungs-Rg.: Workflow vom Auftrag: alle Anzahlugns-Rg. und Schluss-Rg.
Wird der Workflow vom Auftrag aus begonnen, so werden alle Anzahlungs- und
die Schlussrechnung vom Auftrag aus gemacht.
Der Einstieg über eine Anzahlungs-Rg. und dann der Workflow
"weitere Anzahlungs-Rg." (...) und hieraus Schluss-Rg. bleibt bestehen.