]> wagnertech.de Git - mfinanz.git/blobdiff - SL/DB/Invoice.pm
kivitendo 3.9.2-0.2
[mfinanz.git] / SL / DB / Invoice.pm
index d1ce5be87df83af642bc799f0c3ae1385c43210f..f882438cdd02c35b5960618f67eb34acf0fc3da7 100644 (file)
@@ -5,7 +5,7 @@ use strict;
 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);
@@ -16,11 +16,11 @@ use SL::DB::Helper::LinkedRecords;
 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 => {
@@ -77,6 +77,7 @@ __PACKAGE__->attr_html('notes');
 __PACKAGE__->attr_sorted('items');
 
 __PACKAGE__->before_save('_before_save_set_invnumber');
+__PACKAGE__->after_save('_after_save_link_records');
 
 # hooks
 
@@ -88,11 +89,26 @@ sub _before_save_set_invnumber {
   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
@@ -137,6 +153,17 @@ sub closed {
   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) = @_;
 
@@ -218,6 +245,15 @@ sub new_from {
   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;
@@ -236,11 +272,14 @@ sub new_from {
                                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};
@@ -360,7 +399,9 @@ sub add_ar_amount_row {
   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,
@@ -549,6 +590,12 @@ sub invoice_type {
   return 'invoice';
 }
 
+sub is_credit_note {
+  my ($self) = @_;
+
+  return $self->invoice_type eq 'credit_note' ? 1 : undef;
+}
+
 sub displayable_state {
   my $self = shift;
 
@@ -626,6 +673,12 @@ sub effective_tax_point {
   return $self->tax_point || $self->deliverydate || $self->transdate;
 }
 
+sub netamount_base_currency {
+  my ($self) = @_;
+
+  return $self->netamount; # already matches base currency
+}
+
 1;
 
 __END__