8 |
8 |
use SL::DB::Employee;
|
9 |
9 |
use SL::DB::EmailJournal;
|
10 |
10 |
use SL::DB::EmailJournalAttachment;
|
|
11 |
use SL::Presenter::EmailJournal;
|
|
12 |
use SL::Presenter::Tag qw(html_tag div_tag radio_button_tag);
|
11 |
13 |
use SL::Helper::Flash;
|
12 |
14 |
use SL::Locale::String qw(t8);
|
13 |
|
use SL::System::TaskServer;
|
14 |
|
use SL::Presenter::EmailJournal;
|
15 |
15 |
|
16 |
16 |
use SL::DB::Order;
|
17 |
17 |
use SL::DB::Order::TypeData;
|
... | ... | |
25 |
25 |
use SL::DB::Manager::Customer;
|
26 |
26 |
use SL::DB::Manager::Vendor;
|
27 |
27 |
|
|
28 |
use List::MoreUtils qw(any);
|
|
29 |
|
28 |
30 |
use Rose::Object::MakeMethods::Generic
|
29 |
31 |
(
|
30 |
32 |
scalar => [ qw(entry) ],
|
... | ... | |
37 |
39 |
my %RECORD_TYPES_INFO = (
|
38 |
40 |
Order => {
|
39 |
41 |
controller => 'Order',
|
40 |
|
model => 'SL::DB::Order',
|
|
42 |
class => 'Order',
|
41 |
43 |
types => SL::DB::Order::TypeData->valid_types(),
|
42 |
44 |
},
|
43 |
45 |
DeliveryOrder => {
|
44 |
46 |
controller => 'DeliveryOrder',
|
45 |
|
model => 'SL::DB::DeliveryOrder',
|
|
47 |
class => 'DeliveryOrder',
|
46 |
48 |
types => SL::DB::DeliveryOrder::TypeData->valid_types(),
|
47 |
49 |
},
|
48 |
50 |
Reclamation => {
|
49 |
51 |
controller => 'Reclamation',
|
50 |
|
model => 'SL::DB::Reclamation',
|
|
52 |
class => 'Reclamation',
|
51 |
53 |
types => SL::DB::Reclamation::TypeData->valid_types(),
|
52 |
54 |
},
|
53 |
55 |
ArTransaction => {
|
54 |
56 |
controller => 'ar.pl',
|
55 |
|
model => 'SL::DB::Invoice',
|
|
57 |
class => 'Invoice',
|
56 |
58 |
types => [
|
57 |
59 |
'ar_transaction',
|
58 |
60 |
],
|
59 |
61 |
},
|
60 |
62 |
Invoice => {
|
61 |
63 |
controller => 'is.pl',
|
62 |
|
model => 'SL::DB::Invoice',
|
|
64 |
class => 'Invoice',
|
63 |
65 |
types => [
|
64 |
66 |
'invoice',
|
65 |
67 |
'invoice_for_advance_payment',
|
... | ... | |
72 |
74 |
},
|
73 |
75 |
ApTransaction => {
|
74 |
76 |
controller => 'ap.pl',
|
75 |
|
model => 'SL::DB::PurchaseInvoice',
|
|
77 |
class => 'PurchaseInvoice',
|
76 |
78 |
types => [
|
77 |
79 |
'ap_transaction',
|
78 |
80 |
],
|
79 |
81 |
},
|
80 |
82 |
PurchaseInvoice => {
|
81 |
83 |
controller => 'ir.pl',
|
82 |
|
model => 'SL::DB::PurchaseInvoice',
|
|
84 |
class => 'PurchaseInvoice',
|
83 |
85 |
types => [
|
84 |
86 |
'purchase_invoice',
|
85 |
87 |
'purchase_credit_note',
|
... | ... | |
93 |
95 |
} keys %RECORD_TYPES_INFO;
|
94 |
96 |
my %RECORD_TYPE_TO_MODEL =
|
95 |
97 |
map {
|
96 |
|
my $model = $RECORD_TYPES_INFO{$_}->{model};
|
97 |
|
map { $_ => $model } @{ $RECORD_TYPES_INFO{$_}->{types} }
|
|
98 |
my $class = $RECORD_TYPES_INFO{$_}->{class};
|
|
99 |
map { $_ => "SL::DB::$class" } @{ $RECORD_TYPES_INFO{$_}->{types} }
|
|
100 |
} keys %RECORD_TYPES_INFO;
|
|
101 |
my %RECORD_TYPE_TO_MANAGER =
|
|
102 |
map {
|
|
103 |
my $class = $RECORD_TYPES_INFO{$_}->{class};
|
|
104 |
map { $_ => "SL::DB::Manager::$class" } @{ $RECORD_TYPES_INFO{$_}->{types} }
|
98 |
105 |
} keys %RECORD_TYPES_INFO;
|
|
106 |
my @ALL_RECORD_TYPES = map { @{ $RECORD_TYPES_INFO{$_}->{types} } } keys %RECORD_TYPES_INFO;
|
|
107 |
|
|
108 |
# has do be done at runtime for translation to work
|
|
109 |
sub get_record_types_with_info {
|
|
110 |
# TODO: what record types can be created, which are only available in workflows?
|
|
111 |
my @record_types_with_info = ();
|
|
112 |
for my $record_class ('SL::DB::Order', 'SL::DB::DeliveryOrder', 'SL::DB::Reclamation') {
|
|
113 |
my $valid_types = "${record_class}::TypeData"->valid_types();
|
|
114 |
for my $type (@$valid_types) {
|
|
115 |
|
|
116 |
my $type_data = SL::DB::Helper::TypeDataProxy->new($record_class, $type);
|
|
117 |
push @record_types_with_info, {
|
|
118 |
record_type => $type,
|
|
119 |
customervendor => $type_data->properties('customervendor'),
|
|
120 |
text => $type_data->text('type'),
|
|
121 |
};
|
|
122 |
}
|
|
123 |
}
|
|
124 |
push @record_types_with_info, (
|
|
125 |
# invoice
|
|
126 |
{ record_type => 'invoice', customervendor => 'customer', text => t8('Invoice') },
|
|
127 |
{ record_type => 'invoice_for_advance_payment', customervendor => 'customer', text => t8('Invoice for Advance Payment')},
|
|
128 |
{ record_type => 'invoice_for_advance_payment_storno', customervendor => 'customer', text => t8('Storno Invoice for Advance Payment')},
|
|
129 |
{ record_type => 'final_invoice', customervendor => 'customer', text => t8('Final Invoice')},
|
|
130 |
{ record_type => 'invoice_storno', customervendor => 'customer', text => t8('Storno Invoice')},
|
|
131 |
{ record_type => 'credit_note', customervendor => 'customer', text => t8('Credit Note')},
|
|
132 |
{ record_type => 'credit_note_storno', customervendor => 'customer', text => t8('Storno Credit Note')},
|
|
133 |
{ record_type => 'ar_transaction', customervendor => 'customer', text => t8('AR Transaction')},
|
|
134 |
# purchase invoice
|
|
135 |
{ record_type => 'purchase_invoice', customervendor => 'vendor', text => t8('Purchase Invoice')},
|
|
136 |
{ record_type => 'purchase_credit_note', customervendor => 'vendor', text => t8('Purchase Credit Note')},
|
|
137 |
{ record_type => 'ap_transaction', customervendor => 'vendor', text => t8('AP Transaction')},
|
|
138 |
);
|
|
139 |
return @record_types_with_info;
|
|
140 |
}
|
|
141 |
|
|
142 |
sub record_types_for_customer_vendor_type {
|
|
143 |
my ($self, $customer_vendor_type) = @_;
|
|
144 |
return [ map { $_->{record_type} } grep { $_->{customervendor} eq $customer_vendor_type } $self->get_record_types_with_info ];
|
|
145 |
}
|
99 |
146 |
|
100 |
147 |
#
|
101 |
148 |
# actions
|
... | ... | |
129 |
176 |
$::form->error(t8('You do not have permission to access this entry.'));
|
130 |
177 |
}
|
131 |
178 |
|
132 |
|
# TODO: what record types can be created, which are only available in workflows?
|
133 |
|
my @record_types_with_info = ();
|
134 |
|
for my $record_class ('SL::DB::Order', 'SL::DB::DeliveryOrder', 'SL::DB::Reclamation') {
|
135 |
|
my $valid_types = "${record_class}::TypeData"->valid_types();
|
136 |
|
for my $type (@$valid_types) {
|
137 |
|
|
138 |
|
my $type_data = SL::DB::Helper::TypeDataProxy->new($record_class, $type);
|
139 |
|
push @record_types_with_info, {
|
140 |
|
record_type => $type,
|
141 |
|
customervendor => $type_data->properties('customervendor'),
|
142 |
|
text => $type_data->text('type'),
|
143 |
|
};
|
144 |
|
}
|
145 |
|
}
|
146 |
|
push @record_types_with_info, (
|
147 |
|
# invoice
|
148 |
|
{ record_type => 'ar_transaction' , customervendor => 'customer', text => t8('AR Transaction')},
|
149 |
|
{ record_type => 'invoice' , customervendor => 'customer', text => t8('Invoice') },
|
150 |
|
{ record_type => 'invoice_for_advance_payment' , customervendor => 'customer', text => t8('Invoice for Advance Payment')},
|
151 |
|
{ record_type => 'invoice_for_advance_payment_storno', customervendor => 'customer', text => t8('Storno Invoice for Advance Payment')},
|
152 |
|
{ record_type => 'final_invoice' , customervendor => 'customer', text => t8('Final Invoice')},
|
153 |
|
{ record_type => 'invoice_storno' , customervendor => 'customer', text => t8('Storno Invoice')},
|
154 |
|
{ record_type => 'credit_note' , customervendor => 'customer', text => t8('Credit Note')},
|
155 |
|
{ record_type => 'credit_note_storno' , customervendor => 'customer', text => t8('Storno Credit Note')},
|
156 |
|
# purchase invoice
|
157 |
|
{ record_type => 'ap_transaction' , customervendor => 'vendor', text => t8('AP Transaction')},
|
158 |
|
{ record_type => 'purchase_invoice' , customervendor => 'vendor', text => t8('Purchase Invoice')},
|
159 |
|
{ record_type => 'purchase_credit_note', customervendor => 'vendor', text => t8('Purchase Credit Note')},
|
160 |
|
);
|
|
179 |
my @record_types_with_info = $self->get_record_types_with_info();
|
161 |
180 |
|
162 |
181 |
my $customer_vendor = $self->find_customer_vendor_from_email($self->entry);
|
|
182 |
my $cv_type = $customer_vendor && $customer_vendor->is_vendor ? 'vendor' : 'customer';
|
|
183 |
|
|
184 |
my $record_types = $self->record_types_for_customer_vendor_type($cv_type);
|
|
185 |
my @records = $self->get_records_for_types(
|
|
186 |
$record_types,
|
|
187 |
customer_vendor_type => $cv_type,
|
|
188 |
customer_vendor_id => $customer_vendor && $customer_vendor->id,
|
|
189 |
with_closed => 0,
|
|
190 |
);
|
163 |
191 |
|
164 |
192 |
$self->setup_show_action_bar;
|
165 |
193 |
$self->render(
|
... | ... | |
168 |
196 |
CUSTOMER_VENDOR => , $customer_vendor,
|
169 |
197 |
CV_TYPE_FOUND => $customer_vendor && $customer_vendor->is_vendor ? 'vendor' : 'customer',
|
170 |
198 |
RECORD_TYPES_WITH_INFO => \@record_types_with_info,
|
|
199 |
RECORDS => \@records,
|
171 |
200 |
back_to => $back_to
|
172 |
201 |
);
|
173 |
202 |
}
|
174 |
203 |
|
|
204 |
sub get_records_for_types {
|
|
205 |
my ($self, $record_types, %params) = @_;
|
|
206 |
$record_types = [ $record_types ] unless ref $record_types eq 'ARRAY';
|
|
207 |
|
|
208 |
my $cv_type = $params{customer_vendor_type};
|
|
209 |
my $cv_id = $params{customer_vendor_id};
|
|
210 |
my $with_closed = $params{with_closed};
|
|
211 |
|
|
212 |
my @records = ();
|
|
213 |
foreach my $record_type (@$record_types) {
|
|
214 |
my $manager = $RECORD_TYPE_TO_MANAGER{$record_type};
|
|
215 |
my $model = $RECORD_TYPE_TO_MODEL{$record_type};
|
|
216 |
my %additional_where = ();
|
|
217 |
if ($cv_type && $cv_id) {
|
|
218 |
$additional_where{"${cv_type}_id"} = $cv_id;
|
|
219 |
}
|
|
220 |
unless ($with_closed) {
|
|
221 |
if (any {$_ eq 'closed' } $model->meta->columns) {
|
|
222 |
$additional_where{closed} = 0;
|
|
223 |
} elsif (any {$_ eq 'paid' } $model->meta->columns) {
|
|
224 |
$additional_where{amount} = { gt => \'paid' };
|
|
225 |
}
|
|
226 |
}
|
|
227 |
my $records_of_type = $manager->get_all(
|
|
228 |
where => [
|
|
229 |
$manager->type_filter($record_type),
|
|
230 |
%additional_where,
|
|
231 |
],
|
|
232 |
);
|
|
233 |
push @records, @$records_of_type;
|
|
234 |
}
|
|
235 |
|
|
236 |
return @records;
|
|
237 |
}
|
|
238 |
|
175 |
239 |
sub action_attachment_preview {
|
176 |
240 |
my ($self) = @_;
|
177 |
241 |
|
... | ... | |
249 |
313 |
my $customer_vendor = $::form->{customer_vendor_selection};
|
250 |
314 |
my $customer_vendor_id = $::form->{"${customer_vendor}_id"};
|
251 |
315 |
my $action = $::form->{action_selection};
|
252 |
|
my $record_type = $::form->{"${customer_vendor}_record_type_selection"};
|
253 |
|
my $record_id = $::form->{"${record_type}_id"};
|
|
316 |
my $record_type_id = $::form->{"record_type_id"};
|
|
317 |
die t8("No record is selected.") unless $record_type_id || $action eq 'create_new';
|
|
318 |
|
|
319 |
die "no 'email_journal_id' was given" unless $email_journal_id;
|
|
320 |
die "no 'customer_vendor_selection' was given" unless $customer_vendor;
|
|
321 |
die "no 'action_selection' was given" unless $action;
|
|
322 |
|
|
323 |
my ($record_type, $record_id) = split(/-/, $record_type_id);
|
254 |
324 |
|
255 |
325 |
if ($action eq 'linking') {
|
256 |
326 |
return $self->link_and_add_attachment_to_record({
|
... | ... | |
299 |
369 |
->render();
|
300 |
370 |
}
|
301 |
371 |
|
|
372 |
sub action_update_record_list {
|
|
373 |
my ($self) = @_;
|
|
374 |
$::auth->assert('email_journal');
|
|
375 |
my $customer_vendor_type = $::form->{customer_vendor_selection};
|
|
376 |
my $customer_vendor_id = $::form->{"${customer_vendor_type}_id"};
|
|
377 |
my $record_type = $::form->{"${customer_vendor_type}_record_type_selection"};
|
|
378 |
my $with_closed = $::form->{with_closed};
|
|
379 |
|
|
380 |
$record_type ||= $self->record_types_for_customer_vendor_type($customer_vendor_type);
|
|
381 |
|
|
382 |
my @records = $self->get_records_for_types(
|
|
383 |
$record_type,
|
|
384 |
customer_vendor_type => $customer_vendor_type,
|
|
385 |
customer_vendor_id => $customer_vendor_id,
|
|
386 |
with_closed => $with_closed,
|
|
387 |
);
|
|
388 |
|
|
389 |
unless (@records) {
|
|
390 |
$self->js->replaceWith('#record_list', div_tag(
|
|
391 |
html_tag('h3', t8('No records found.')),
|
|
392 |
id => 'record_list',
|
|
393 |
))->render();
|
|
394 |
return;
|
|
395 |
}
|
|
396 |
|
|
397 |
my $new_div = div_tag(
|
|
398 |
join('', map {
|
|
399 |
div_tag(
|
|
400 |
radio_button_tag('record_type_id',
|
|
401 |
value => $_->record_type . "-" . $_->id, label => $_->displayable_name,
|
|
402 |
class => "record_radio", label_class => "record_radio",
|
|
403 |
),
|
|
404 |
id => "record_$_->{id}",
|
|
405 |
)
|
|
406 |
} @records),
|
|
407 |
id => 'record_list',
|
|
408 |
);
|
|
409 |
|
|
410 |
$self->js->replaceWith('#record_list', $new_div)->render();
|
|
411 |
}
|
|
412 |
|
302 |
413 |
#
|
303 |
414 |
# filters
|
304 |
415 |
#
|
EmailJournal: Workflow: Vorschlag der passenden Belege