2 |
2 |
|
3 |
3 |
use strict;
|
4 |
4 |
|
|
5 |
use DateTime::Format::Strptime;
|
|
6 |
|
5 |
7 |
use SL::DB::MetaSetup::RecordTemplate;
|
6 |
8 |
use SL::DB::Manager::RecordTemplate;
|
7 |
9 |
|
... | ... | |
17 |
19 |
|
18 |
20 |
sub items { goto &record_template_items; }
|
19 |
21 |
|
|
22 |
sub _replace_variables {
|
|
23 |
my ($self, %params) = @_;
|
|
24 |
|
|
25 |
foreach my $sub (@{ $params{fields} }) {
|
|
26 |
my $value = $params{object}->$sub;
|
|
27 |
next if ($value // '') eq '';
|
|
28 |
|
|
29 |
$value =~ s{ <\% ([a-z0-9_]+) ( \s+ format \s*=\s* (.*?) \s* )? \%> }{
|
|
30 |
my ($key, $format) = ($1, $3);
|
|
31 |
my $new_value;
|
|
32 |
|
|
33 |
if (!$params{variables}->{$key}) {
|
|
34 |
$new_value = '';
|
|
35 |
|
|
36 |
} elsif ($format) {
|
|
37 |
$new_value = DateTime::Format::Strptime->new(
|
|
38 |
pattern => $format,
|
|
39 |
locale => 'de_DE',
|
|
40 |
time_zone => 'local',
|
|
41 |
)->format_datetime($params{variables}->{$key}->[0]);
|
|
42 |
|
|
43 |
} else {
|
|
44 |
$new_value = $params{variables}->{$1}->[1]->($params{variables}->{$1}->[0]);
|
|
45 |
}
|
|
46 |
|
|
47 |
$new_value;
|
|
48 |
|
|
49 |
}eigx;
|
|
50 |
|
|
51 |
$params{object}->$sub($value);
|
|
52 |
}
|
|
53 |
}
|
|
54 |
|
|
55 |
sub _generate_variables {
|
|
56 |
my ($self, $reference_date) = @_;
|
|
57 |
|
|
58 |
$reference_date //= DateTime->today_local;
|
|
59 |
my @month_names = (
|
|
60 |
$::locale->text('January'), $::locale->text('February'), $::locale->text('March'), $::locale->text('April'), $::locale->text('May'), $::locale->text('June'),
|
|
61 |
$::locale->text('July'), $::locale->text('August'), $::locale->text('September'), $::locale->text('October'), $::locale->text('November'), $::locale->text('December'),
|
|
62 |
);
|
|
63 |
|
|
64 |
my $variables = {
|
|
65 |
current_quarter => [ $reference_date->clone->truncate(to => 'month'), sub { $_[0]->quarter } ],
|
|
66 |
previous_quarter => [ $reference_date->clone->truncate(to => 'month')->subtract(months => 3), sub { $_[0]->quarter } ],
|
|
67 |
next_quarter => [ $reference_date->clone->truncate(to => 'month')->add( months => 3), sub { $_[0]->quarter } ],
|
|
68 |
|
|
69 |
current_month => [ $reference_date->clone->truncate(to => 'month'), sub { $_[0]->month } ],
|
|
70 |
previous_month => [ $reference_date->clone->truncate(to => 'month')->subtract(months => 1), sub { $_[0]->month } ],
|
|
71 |
next_month => [ $reference_date->clone->truncate(to => 'month')->add( months => 1), sub { $_[0]->month } ],
|
|
72 |
|
|
73 |
current_month_long => [ $reference_date->clone->truncate(to => 'month'), sub { $month_names[ $_[0]->month - 1 ] } ],
|
|
74 |
previous_month_long => [ $reference_date->clone->truncate(to => 'month')->subtract(months => 1), sub { $month_names[ $_[0]->month - 1 ] } ],
|
|
75 |
next_month_long => [ $reference_date->clone->truncate(to => 'month')->add( months => 1), sub { $month_names[ $_[0]->month - 1 ] } ],
|
|
76 |
|
|
77 |
current_year => [ $reference_date->clone->truncate(to => 'year'), sub { $_[0]->year } ],
|
|
78 |
previous_year => [ $reference_date->clone->truncate(to => 'year')->subtract(years => 1), sub { $_[0]->year } ],
|
|
79 |
next_year => [ $reference_date->clone->truncate(to => 'year')->add( years => 1), sub { $_[0]->year } ],
|
|
80 |
|
|
81 |
reference_date => [ $reference_date->clone, sub { $::locale->format_date(\%::myconfig, $_[0]) } ],
|
|
82 |
};
|
|
83 |
|
|
84 |
return $variables;
|
|
85 |
}
|
|
86 |
|
|
87 |
sub _text_column_names {
|
|
88 |
my ($self, $object) = @_;
|
|
89 |
return map { $_->name } grep { ref($_) =~ m{::Text} } @{ $object->meta->columns };
|
|
90 |
}
|
|
91 |
|
|
92 |
sub substitute_variables {
|
|
93 |
my ($self, $reference_date) = @_;
|
|
94 |
|
|
95 |
my $variables = $self->_generate_variables($reference_date);
|
|
96 |
my @text_columns = $self->_text_column_names($self);
|
|
97 |
|
|
98 |
$self->_replace_variables(
|
|
99 |
object => $self,
|
|
100 |
variables => $variables,
|
|
101 |
fields => \@text_columns,
|
|
102 |
);
|
|
103 |
|
|
104 |
@text_columns = $self->_text_column_names(SL::DB::RecordTemplateItem->new);
|
|
105 |
|
|
106 |
foreach my $item (@{ $self->items }) {
|
|
107 |
$self->_replace_variables(
|
|
108 |
object => $item,
|
|
109 |
variables => $variables,
|
|
110 |
fields => \@text_columns,
|
|
111 |
);
|
|
112 |
}
|
|
113 |
}
|
|
114 |
|
20 |
115 |
1;
|
|
116 |
__END__
|
|
117 |
|
|
118 |
=pod
|
|
119 |
|
|
120 |
=encoding utf8
|
|
121 |
|
|
122 |
=head1 NAME
|
|
123 |
|
|
124 |
SL::DB::RecordTemplate — Templates for accounts receivable
|
|
125 |
transactions, accounts payable transactions and generic ledger
|
|
126 |
transactiona
|
|
127 |
|
|
128 |
=head1 FUNCTIONS
|
|
129 |
|
|
130 |
=over 4
|
|
131 |
|
|
132 |
=item C<items>
|
|
133 |
|
|
134 |
An alias for C<record_template_items>.
|
|
135 |
|
|
136 |
=item C<substitute_variables> C<[$reference_date]>
|
|
137 |
|
|
138 |
Texts in record templates can contain placeholders. This function
|
|
139 |
replaces those placeholders by their actual value. Placeholders use
|
|
140 |
the syntax C<E<lt>%variableE<gt>> or C<E<lt>%variable format=…E<gt>>
|
|
141 |
for a custom format (see L<DateTime::Format::Strptime> for available
|
|
142 |
formatting characters).
|
|
143 |
|
|
144 |
The variables are calculated based on C<$reference_date> which must be
|
|
145 |
an instance of L<DateTime> if given. If left out, it defaults to the
|
|
146 |
current day.
|
|
147 |
|
|
148 |
Supported variables are:
|
|
149 |
|
|
150 |
=over 2
|
|
151 |
|
|
152 |
=item * C<current_quarter>, C<previous_quarter>, C<next_quarter> — the
|
|
153 |
quarter as a number between 1 and 4 inclusively
|
|
154 |
|
|
155 |
=item * C<current_month>, C<previous_month>, C<next_month> — the
|
|
156 |
month as a number between 1 and 12 inclusively
|
|
157 |
|
|
158 |
=item * C<current_month_long>, C<previous_month_long>,
|
|
159 |
C<next_month_long> — the month's name (e.g. C<August>).
|
|
160 |
|
|
161 |
=item * C<current_year>, C<previous_year>, C<next_year> — the
|
|
162 |
year (e.g. C<2017>)
|
|
163 |
|
|
164 |
=item * C<reference_date> — the reference date in the user's date style
|
|
165 |
(e.g. C<27.11.2017>)
|
|
166 |
|
|
167 |
=back
|
|
168 |
|
|
169 |
=back
|
|
170 |
|
|
171 |
=head1 AUTHOR
|
|
172 |
|
|
173 |
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
|
|
174 |
|
|
175 |
=cut
|
Belegvorlagen: Variablen in Texten nutzen können
Unterstützt werden fast die gleichen Variablen wie beim Erzeugen
wiederkehrender Rechnungen.