use strict;
+use Carp;
use List::Util qw(first);
use SL::DB::MetaSetup::Invoice;
use SL::DB::Manager::Invoice;
use SL::DB::Helper::LinkedRecords;
use SL::DB::Helper::PriceTaxCalculator;
+use SL::DB::Helper::TransNumberGenerator;
+use SL::DB::Employee;
__PACKAGE__->meta->add_relationship(
invoiceitems => {
with_objects => [ 'part' ]
}
},
+ payment_term => {
+ type => 'one to one',
+ class => 'SL::DB::PaymentTerm',
+ column_map => { payment_id => 'id' },
+ },
);
__PACKAGE__->meta->initialize;
return $self->paid >= $self->amount;
}
+sub new_from {
+ my ($class, $source, %params) = @_;
+
+ croak("Unsupported source object type '" . ref($source) . "'") unless ref($source) =~ m/^ SL::DB:: (?: Order | DeliveryOrder ) $/x;
+ croak("Cannot create invoices for purchase records") unless $source->customer_id;
+
+ my $terms = $source->can('payment_id') && $source->payment_id ? $source->payment_term->terms_netto : 0;
+
+ my %args = ( map({ ( $_ => $source->$_ ) } qw(customer_id taxincluded shippingpoint shipvia notes intnotes curr salesman_id cusordnumber ordnumber quonumber
+ department_id cp_id language_id payment_id delivery_customer_id delivery_vendor_id taxzone_id shipto_id
+ globalproject_id transaction_description)),
+ transdate => DateTime->today_local,
+ gldate => DateTime->today_local,
+ duedate => DateTime->today_local->add(days => $terms * 1),
+ invoice => 1,
+ type => 'invoice',
+ storno => 0,
+ paid => 0,
+ employee_id => (SL::DB::Manager::Employee->current || SL::DB::Employee->new(id => $source->employee_id))->id,
+ );
+
+ if ($source->type =~ /_order$/) {
+ $args{deliverydate} = $source->reqdate;
+ $args{orddate} = $source->transdate;
+ } else {
+ $args{quodate} = $source->transdate;
+ }
+
+ my $invoice = $class->new(%args, %params);
+
+ my @items = map {
+ my $source_item = $_;
+ SL::DB::InvoiceItem->new(map({ ( $_ => $source_item->$_ ) }
+ qw(parts_id description qty sellprice discount project_id
+ serialnumber pricegroup_id ordnumber transdate cusordnumber unit
+ base_qty subtotal longdescription lastcost price_factor_id)),
+ deliverydate => $source_item->reqdate,
+ fxsellprice => $source_item->sellprice,);
+ } @{ $source->items };
+
+ $invoice->invoiceitems(\@items);
+
+ return $invoice;
+}
+
sub post {
my ($self, %params) = @_;
- $self->db->do_transaction(sub {
- 1; # dummy instruction for Emacs ;)
+ croak("Missing parameter 'ar_id'") unless $params{ar_id};
+ my $worker = sub {
my %data = $self->calculate_prices_and_taxes;
$self->_post_create_assemblyitem_entries($data{assembly_items});
-
+ $self->create_trans_number;
$self->save;
$self->_post_add_acctrans($data{amounts_cogs});
$self->_post_add_acctrans($data{amounts});
$self->_post_add_acctrans($data{taxes});
+ $self->_post_add_acctrans({ $params{ar_id} => $self->amount * -1 });
+
$self->_post_update_allocated($data{allocated});
+ };
+
+ if ($self->db->in_transaction) {
+ $worker->();
+ } elsif (!$self->db->do_transaction($worker)) {
+ $::lxdebug->message(0, "convert_to_invoice failed: " . join("\n", (split(/\n/, $self->db->error))[0..2]));
+ return undef;
+ }
- die;
- });
+ return $self;
}
sub _post_add_acctrans {
chart_id => $chart_id,
amount => $spec->{amount},
taxkey => $spec->{taxkey},
- project_id => $self->project_id,
+ project_id => $self->globalproject_id,
transdate => $self->transdate)->save;
}
}
my ($self, $allocated) = @_;
while (my ($invoice_id, $diff) = each %{ $allocated }) {
- SL::DB::Manager::InvoiceItem->update_all(set => { allocated => { sql => [ 'allocated + ?', $diff ] } },
+ SL::DB::Manager::InvoiceItem->update_all(set => { allocated => { sql => "allocated + $diff" } },
where => [ id => $invoice_id ]);
}
}