use Carp;
use List::Util qw(first sum);
-use Rose::DB::Object::Helpers qw(has_loaded_related forget_related);
+use Rose::DB::Object::Helpers qw(has_loaded_related forget_related as_tree strip);
use SL::DB::MetaSetup::Invoice;
use SL::DB::Manager::Invoice;
use SL::DB::Helper::Payment qw(:ALL);
use SL::DB::Helper::PDF_A;
use SL::DB::Helper::PriceTaxCalculator;
use SL::DB::Helper::PriceUpdater;
+use SL::DB::Helper::RecordLink qw(RECORD_ID RECORD_TYPE_REF RECORD_ITEM_ID RECORD_ITEM_TYPE_REF);
use SL::DB::Helper::SalesPurchaseInvoice;
use SL::DB::Helper::TransNumberGenerator;
-use SL::DB::Helper::ZUGFeRD;
+use SL::DB::Helper::ZUGFeRD qw(:CREATE);
use SL::Locale::String qw(t8);
-use SL::DB::CustomVariable;
__PACKAGE__->meta->add_relationship(
invoiceitems => {
__PACKAGE__->attr_sorted('items');
__PACKAGE__->before_save('_before_save_set_invnumber');
+__PACKAGE__->after_save('_after_save_link_records');
# hooks
return 1;
}
+sub _after_save_link_records {
+ my ($self) = @_;
+
+ my @allowed_record_sources = qw(SL::DB::Reclamation SL::DB::Order SL::DB::DeliveryOrder);
+ my @allowed_item_sources = qw(SL::DB::ReclamationItem SL::DB::OrderItem SL::DB::DeliveryOrderItem);
+
+ SL::DB::Helper::RecordLink::link_records(
+ $self,
+ \@allowed_record_sources,
+ \@allowed_item_sources,
+ close_source_quotations => 1,
+ );
+}
+
# methods
sub items { goto &invoiceitems; }
sub add_items { goto &add_invoiceitems; }
sub record_number { goto &invnumber; };
+sub record_type { goto &invoice_type; };
sub is_sales {
# For compatibility with Order, DeliveryOrder
return $self->paid >= $self->amount;
}
+sub convert_to_reclamation {
+ my ($self, %params) = @_;
+ $params{destination_type} = $self->is_sales ? 'sales_reclamation'
+ : 'purchase_reclamation';
+
+ require SL::DB::Reclamation;
+ my $reclamation = SL::DB::Reclamation->new_from($self, %params);
+
+ return $reclamation;
+}
+
sub _clone_orderitem_delivery_order_item_cvar {
my ($cvar) = @_;
my $items = delete($params{items}) || $source->items_sorted;
my %item_parents;
+ if ($params{honor_recurring_billing_mode}) {
+ $items = [
+ grep { !$_->can('recurring_billing_mode')
+ || ($_->recurring_billing_mode eq 'always')
+ || (($_->recurring_billing_mode eq 'once') && !$_->recurring_billing_invoice_id)
+ } @{ $items }
+ ];
+ }
+
my @items = map {
my $source_item = $_;
my $source_item_id = $_->$item_parent_id_column;
donumber => ref($item_parent) eq 'SL::DB::DeliveryOrder' ? $item_parent->donumber : $source_item->can('donumber') ? $source_item->donumber : '',
);
- $current_invoice_item->{"converted_from_orderitems_id"} = $_->{id} if ref($item_parent) eq 'SL::DB::Order';
- $current_invoice_item->{"converted_from_delivery_order_items_id"} = $_->{id} if ref($item_parent) eq 'SL::DB::DeliveryOrder';
+ $current_invoice_item->{RECORD_ITEM_ID()} = $_->{id};
+ $current_invoice_item->{RECORD_ITEM_TYPE_REF()} = ref $source_item;
$current_invoice_item;
} @{ $items };
+ $invoice->{RECORD_ID()} = $source->id;
+ $invoice->{RECORD_TYPE_REF()} = ref $source;
+
@items = grep { $params{item_filter}->($_) } @items if $params{item_filter};
@items = grep { $_->qty * 1 } @items if $params{skip_items_zero_qty};
@items = grep { $_->qty >=0 } @items if $params{skip_items_negative_qty};
if ( $tax and $tax->rate != 0 ) {
($netamount, $taxamount) = Form->calculate_tax($params{amount}, $tax->rate, $self->taxincluded, $roundplaces);
};
- next unless $netamount; # netamount mustn't be zero
+
+ return unless $netamount; # netamount mustn't be zero
+
my $sign = $self->customer_id ? 1 : -1;
my $acc = SL::DB::AccTransaction->new(
amount => $netamount * $sign,
return 'invoice';
}
+sub is_credit_note {
+ my ($self) = @_;
+
+ return $self->invoice_type eq 'credit_note' ? 1 : undef;
+}
+
sub displayable_state {
my $self = shift;
return $self->tax_point || $self->deliverydate || $self->transdate;
}
+sub netamount_base_currency {
+ my ($self) = @_;
+
+ return $self->netamount; # already matches base currency
+}
+
1;
__END__