|
package SL::Controller::Reclamation;
|
|
|
|
use strict;
|
|
use parent qw(SL::Controller::Base);
|
|
|
|
use SL::Helper::Flash qw(flash_later);
|
|
use SL::Presenter::Tag qw(select_tag hidden_tag div_tag);
|
|
use SL::Presenter::ReclamationFilter qw(filter);
|
|
use SL::Locale::String qw(t8);
|
|
use SL::SessionFile::Random;
|
|
use SL::PriceSource;
|
|
use SL::ReportGenerator;
|
|
use SL::Controller::Helper::ReportGenerator;
|
|
use SL::Webdav;
|
|
use SL::File;
|
|
use SL::MIME;
|
|
use SL::YAML;
|
|
use SL::DB::History;
|
|
use SL::DB::Reclamation;
|
|
use SL::DB::ReclamationItem;
|
|
use SL::DB::Default;
|
|
use SL::DB::Printer;
|
|
use SL::DB::Language;
|
|
use SL::DB::RecordLink;
|
|
use SL::DB::Shipto;
|
|
use SL::DB::Translation;
|
|
use SL::DB::ValidityToken;
|
|
use SL::DB::EmailJournal;
|
|
use SL::DB::Helper::RecordLink qw(set_record_link_conversions RECORD_ID RECORD_TYPE_REF RECORD_ITEM_ID RECORD_ITEM_TYPE_REF);
|
|
use SL::DB::Helper::TypeDataProxy;
|
|
use SL::DB::Helper::Record qw(get_object_name_from_type get_class_from_type);
|
|
|
|
use SL::Helper::CreatePDF qw(:all);
|
|
use SL::Helper::PrintOptions;
|
|
use SL::Helper::UserPreferences::PositionsScrollbar;
|
|
use SL::Helper::UserPreferences::UpdatePositions;
|
|
|
|
use SL::Controller::Helper::GetModels;
|
|
|
|
use SL::DB::Order;
|
|
use SL::DB::DeliveryOrder;
|
|
use SL::DB::Invoice;
|
|
use SL::Model::Record;
|
|
use SL::DB::Order::TypeData qw(:types);
|
|
use SL::DB::DeliveryOrder::TypeData qw(:types);
|
|
use SL::DB::Reclamation::TypeData qw(:types);
|
|
|
|
use List::Util qw(first sum0);
|
|
use List::UtilsBy qw(sort_by uniq_by);
|
|
use List::MoreUtils qw(any none pairwise first_index);
|
|
use English qw(-no_match_vars);
|
|
use File::Spec;
|
|
use Cwd;
|
|
use Sort::Naturally;
|
|
|
|
use Rose::Object::MakeMethods::Generic
|
|
(
|
|
scalar => [ qw(item_ids_to_delete is_custom_shipto_to_delete) ],
|
|
'scalar --get_set_init' => [qw(
|
|
all_price_factors cv models p part_picker_classification_ids reclamation
|
|
search_cvpartnumber show_update_button type valid_types type_data
|
|
)],
|
|
);
|
|
|
|
|
|
# safety
|
|
__PACKAGE__->run_before('check_auth');
|
|
|
|
__PACKAGE__->run_before('recalc',
|
|
only => [qw(
|
|
save save_as_new print preview_pdf send_email
|
|
save_and_show_email_dialog
|
|
save_and_new_record
|
|
save_and_credit_note
|
|
)]);
|
|
|
|
__PACKAGE__->run_before('get_unalterable_data',
|
|
only => [qw(
|
|
save save_as_new print preview_pdf send_email
|
|
save_and_show_email_dialog
|
|
save_and_new_record
|
|
save_and_credit_note
|
|
)]);
|
|
|
|
#
|
|
# actions
|
|
#
|
|
|
|
# add a new reclamation
|
|
sub action_add {
|
|
my ($self) = @_;
|
|
|
|
$self->reclamation(SL::Model::Record->update_after_new($self->reclamation));
|
|
|
|
$self->pre_render();
|
|
|
|
if (!$::form->{form_validity_token}) {
|
|
$::form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_RECLAMATION_SAVE())->token;
|
|
}
|
|
|
|
$self->render(
|
|
'reclamation/form',
|
|
title => $self->type_data->text('add'),
|
|
%{$self->{template_args}},
|
|
);
|
|
}
|
|
|
|
sub action_add_from_record {
|
|
my ($self) = @_;
|
|
my $from_type = $::form->{from_type};
|
|
my $from_id = $::form->{from_id};
|
|
|
|
die "No 'from_type' was given." unless ($from_type);
|
|
die "No 'from_id' was given." unless ($from_id);
|
|
|
|
my %flags = ();
|
|
if (defined($::form->{from_item_ids})) {
|
|
my %use_item = map { $_ => 1 } @{$::form->{from_item_ids}};
|
|
$flags{item_filter} = sub {
|
|
my ($item) = @_;
|
|
return %use_item{$item->{RECORD_ITEM_ID()}};
|
|
}
|
|
}
|
|
|
|
my $record = SL::Model::Record->get_record($from_type, $from_id);
|
|
my $reclamation = SL::Model::Record->new_from_workflow($record, $self->type, %flags);
|
|
$self->reclamation($reclamation);
|
|
|
|
if ($record->type eq SALES_RECLAMATION_TYPE()) { # check for direct delivery
|
|
# copy shipto in custom shipto (custom shipto will be copied by new_from() in case)
|
|
if ($::form->{use_shipto}) {
|
|
my $custom_shipto = $record->shipto->clone('SL::DB::Reclamation');
|
|
$self->reclamation->custom_shipto($custom_shipto) if $custom_shipto;
|
|
} else {
|
|
# remove any custom shipto if not wanted
|
|
$self->reclamation->custom_shipto(SL::DB::Shipto->new(module => 'RC', custom_variables => []));
|
|
}
|
|
}
|
|
|
|
$self->reinit_after_new_reclamation();
|
|
|
|
if (!$::form->{form_validity_token}) {
|
|
$::form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_RECLAMATION_SAVE())->token;
|
|
}
|
|
|
|
$self->render(
|
|
'reclamation/form',
|
|
title => $self->type_data->text('add'),
|
|
%{$self->{template_args}},
|
|
);
|
|
}
|
|
|
|
sub action_add_from_email_journal {
|
|
my ($self) = @_;
|
|
die "No 'email_journal_id' was given." unless ($::form->{email_journal_id});
|
|
|
|
$self->action_add();
|
|
}
|
|
|
|
sub action_edit_with_email_journal_workflow {
|
|
my ($self) = @_;
|
|
die "No 'email_journal_id' was given." unless ($::form->{email_journal_id});
|
|
$::form->{workflow_email_journal_id} = delete $::form->{email_journal_id};
|
|
$::form->{workflow_email_attachment_id} = delete $::form->{email_attachment_id};
|
|
$::form->{workflow_email_callback} = delete $::form->{callback};
|
|
|
|
$self->action_edit();
|
|
}
|
|
|
|
# edit an existing reclamation
|
|
sub action_edit {
|
|
my ($self) = @_;
|
|
|
|
unless ($::form->{id}) {
|
|
$self->js->flash('error', t8("Can't edit unsaved reclamation. No 'id' was given."));
|
|
return $self->js->render();
|
|
}
|
|
|
|
$self->load_reclamation;
|
|
|
|
$self->recalc();
|
|
$self->pre_render();
|
|
|
|
$self->render(
|
|
'reclamation/form',
|
|
title => $self->type_data->text('edit'),
|
|
%{$self->{template_args}},
|
|
);
|
|
}
|
|
|
|
# delete the reclamation
|
|
sub action_delete {
|
|
my ($self) = @_;
|
|
|
|
|
|
SL::Model::Record->delete($self->reclamation);
|
|
flash_later('info', $self->type_data->text('delete'));
|
|
|
|
my @redirect_params = (
|
|
action => 'add',
|
|
type => $self->type,
|
|
);
|
|
|
|
$self->redirect_to(@redirect_params);
|
|
}
|
|
|
|
# save the reclamation
|
|
sub action_save {
|
|
my ($self) = @_;
|
|
|
|
$self->save();
|
|
|
|
flash_later('info', t8('The reclamation has been saved'));
|
|
|
|
my @redirect_params;
|
|
if ($::form->{back_to_caller}) {
|
|
@redirect_params = $::form->{callback} ? ($::form->{callback})
|
|
: (controller => 'LoginScreen', action => 'user_login');
|
|
} else {
|
|
@redirect_params = (
|
|
action => 'edit',
|
|
type => $self->type,
|
|
id => $self->reclamation->id,
|
|
callback => $::form->{callback},
|
|
);
|
|
}
|
|
|
|
$self->redirect_to(@redirect_params);
|
|
}
|
|
|
|
sub action_list {
|
|
my ($self) = @_;
|
|
|
|
$self->_setup_search_action_bar;
|
|
$self->prepare_report;
|
|
$self->report_generator_list_objects(
|
|
report => $self->{report},
|
|
objects => $self->models->get,
|
|
options => {
|
|
action_bar_additional_submit_values => {
|
|
type => $self->type,
|
|
},
|
|
},
|
|
);
|
|
}
|
|
|
|
# save the reclamation as new document an open it for edit
|
|
sub action_save_as_new {
|
|
my ($self) = @_;
|
|
|
|
my $reclamation = $self->reclamation;
|
|
|
|
if (!$reclamation->id) {
|
|
$self->js->flash('error', t8('This object has not been saved yet.'));
|
|
return $self->js->render();
|
|
}
|
|
|
|
my $saved_reclamation = SL::DB::Reclamation->new(id => $reclamation->id)->load;
|
|
|
|
# Create new record from current one
|
|
my $new_reclamation = SL::Model::Record->clone_for_save_as_new($saved_reclamation, $reclamation);
|
|
$self->reclamation($new_reclamation);
|
|
|
|
if (!$::form->{form_validity_token}) {
|
|
$::form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_RECLAMATION_SAVE())->token;
|
|
}
|
|
|
|
# save
|
|
$self->action_save();
|
|
}
|
|
|
|
# print the reclamation
|
|
#
|
|
# This is called if "print" is pressed in the print dialog.
|
|
# If PDF creation was requested and succeeded, the pdf is offered for download
|
|
# via send_file (which uses ajax in this case).
|
|
sub action_print {
|
|
my ($self) = @_;
|
|
|
|
$self->save();
|
|
|
|
$self->js_reset_reclamation_and_item_ids_after_save;
|
|
|
|
my $format = $::form->{print_options}->{format};
|
|
my $media = $::form->{print_options}->{media};
|
|
my $formname = $::form->{print_options}->{formname};
|
|
my $copies = $::form->{print_options}->{copies};
|
|
my $groupitems = $::form->{print_options}->{groupitems};
|
|
my $printer_id = $::form->{print_options}->{printer_id};
|
|
|
|
# only pdf and opendocument by now
|
|
if (none { $format eq $_ } qw(pdf opendocument opendocument_pdf)) {
|
|
return $self->js->flash('error', t8('Format \'#1\' is not supported yet/anymore.', $format))->render;
|
|
}
|
|
|
|
# only screen or printer by now
|
|
if (none { $media eq $_ } qw(screen printer)) {
|
|
return $self->js->flash('error', t8('Media \'#1\' is not supported yet/anymore.', $media))->render;
|
|
}
|
|
|
|
# create a form for generate_attachment_filename
|
|
$form->{format} = 'pdf';
|
|
$form->{cp_id} = $self->reclamation->contact->cp_id if $self->reclamation->contact;
|
|
|
|
my $email_form;
|
|
$email_form->{to} = $self->reclamation->contact->cp_email if $self->reclamation->contact;
|
|
$email_form->{to} ||= $self->reclamation->customervendor->email;
|
|
$email_form->{cc} = $self->reclamation->customervendor->cc;
|
|
$email_form->{bcc} = join ', ', grep $_, $self->reclamation->customervendor-> |