2f62bd9ac5790fb8b8b059918c6c2341bd31433f
[kivitendo-erp.git] / PaymentTerm.pm
1 package SL::DB::PaymentTerm;
2
3 use strict;
4
5 use List::Util qw(max);
6
7 use SL::DB::MetaSetup::PaymentTerm;
8 use SL::DB::Manager::PaymentTerm;
9 use SL::DB::Helper::ActsAsList;
10 use SL::DB::Helper::TranslatedAttributes;
11
12 __PACKAGE__->meta->initialize;
13
14 sub validate {
15   my ($self) = @_;
16
17   my @errors;
18   push @errors, $::locale->text('The description is missing.')      if !$self->description;
19   push @errors, $::locale->text('The long description is missing.') if !$self->description_long;
20
21   return @errors;
22 }
23
24 sub calc_date {
25   my ($self, %params) = @_;
26
27   my $reference_date  = $params{reference_date} || DateTime->today_local;
28   $reference_date     = DateTime->from_kivitendo($reference_date) unless ref($reference_date) eq 'DateTime';
29
30   if (!$self->auto_calculation) {
31     my $due_date = $params{due_date} || $reference_date;
32     $due_date    = DateTime->from_kivitendo($due_date) unless ref($due_date) eq 'DateTime';
33
34     return max $due_date, $reference_date;
35   }
36
37   my $terms           = ($params{terms} // 'net') eq 'discount' ? 'terms_skonto' : 'terms_netto';
38   my $date            = $reference_date->clone->add(days => $self->$terms);
39
40   my $dow             = $date->day_of_week;
41   $date               = $date->add(days => 8 - $dow) if $dow > 5;
42
43   return $date;
44 }
45
46 1;
47 __END__
48
49 =pod
50
51 =encoding utf8
52
53 =head1 NAME
54
55 SL::DB::PaymentTerm - Rose model for the payment_terms table
56
57 =head1 SYNOPSIS
58
59   my $terms             = SL::DB::PaymentTerm->new(id => $::form->{payment_id})->load;
60   my $due_date_net      = $terms->calc_date(terms => 'net');      # uses terms_netto
61   my $due_date_discount = $terms->calc_date(terms => 'discount'); # uses terms_skonto
62
63   # Calculate due date taking the existing invoice date and the due
64   # date entered by the user into account:
65   my $due_date = $terms->calc_date(
66     reference_date => $::form->{invdate},
67     due_date       => $::form->{duedate},
68   );
69
70 =head1 FUNCTIONS
71
72 =over 4
73
74 =item C<calc_date [%params]>
75
76 Calculates and returns a due date as an instance of L<DateTime> by
77 adding one of C<$self>'s terms fields if automatic calculation is on;
78 otherwise returns the currently-set due date (which must be provided)
79 or the reference date, whichever is later.
80
81 Note that for automatic calculation the resulting date will be the
82 following Monday if the result falls on a weekend.
83
84 C<%params> can contain the following parameters:
85
86 =over 4
87
88 =item C<reference_date>
89
90 The reference date from which the due date will be calculated. Can be
91 either an instance of L<DateTime> or a scalar in which case the scalar
92 is parsed via L<DateTime/from_kivitendo>.
93
94 Defaults to the current date if unset.
95
96 =item C<due_date>
97
98 A currently set due date. If automatic calculation is off then this
99 date will be returned if it is provided and greater than or equal to
100 the C<reference_date>. Otherwise the reference date will be returned.
101
102 =item C<terms>
103
104 Can be either C<net> or C<discount>. For C<net> the number of days to
105 add to the reference date are C<$self-E<gt>terms_netto>. For
106 C<discount> C<$self-E<gt>terms_skonto> is used.
107
108 Defaults to C<net> if unset.
109
110 =back
111
112 =item C<validate>
113
114 Validates before saving and returns an array of human-readable error
115 messages in case of an error.
116
117 =back
118
119 =head1 BUGS
120
121 Nothing here yet.
122
123 =head1 AUTHOR
124
125 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
126
127 =cut