Revision 5bae603d
Von Tamino Steinert vor mehr als 1 Jahr hinzugefügt
SL/Controller/DeliveryOrder.pm | ||
---|---|---|
# make new order from given orders
|
||
my @multi_orders = map { SL::DB::DeliveryOrder->new(id => $_)->load } @multi_ids;
|
||
$self->{converted_from_oe_id} = join ' ', map { $_->id } @multi_orders;
|
||
my $target_type = "sales_delivery_order";
|
||
my $target_type = SALES_DELIVERY_ORDER_TYPE();
|
||
my $delivery_order = SL::Model::Record->new_from_workflow_multi(\@multi_orders, $target_type, sort_sources_by => 'transdate');
|
||
$self->order($delivery_order);
|
||
|
SL/Controller/Order.pm | ||
---|---|---|
use SL::DB::Helper::RecordLink qw(set_record_link_conversions);
|
||
use SL::DB::Helper::TypeDataProxy;
|
||
use SL::Model::Record;
|
||
use SL::DB::Order::TypeData qw(:types);
|
||
use SL::DB::Reclamation::TypeData qw(:types);
|
||
|
||
use SL::Helper::CreatePDF qw(:all);
|
||
use SL::Helper::PrintOptions;
|
||
... | ... | |
|
||
my $reclamation = SL::DB::Reclamation->new(id => $::form->{from_id})->load;
|
||
my %params;
|
||
my $target_type = $reclamation->is_sales ? 'sales_order'
|
||
: 'purchase_order';
|
||
my $target_type = $reclamation->is_sales ? SALES_ORDER_TYPE()
|
||
: PURCHASE_ORDER_TYPE();
|
||
my $order = SL::Model::Record->new_from_workflow($reclamation, $target_type);
|
||
$self->{converted_from_reclamation_id} = $::form->{from_id};
|
||
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
SL::Model::Record->delete($self->order);
|
||
my $text = $self->type eq sales_order_intake_type() ? $::locale->text('The order intake has been deleted')
|
||
: $self->type eq sales_order_type() ? $::locale->text('The order confirmation has been deleted')
|
||
: $self->type eq purchase_order_type() ? $::locale->text('The order has been deleted')
|
||
: $self->type eq sales_quotation_type() ? $::locale->text('The quotation has been deleted')
|
||
: $self->type eq request_quotation_type() ? $::locale->text('The rfq has been deleted')
|
||
: $self->type eq purchase_quotation_intake_type() ? $::locale->text('The quotation intake has been deleted')
|
||
my $text = $self->type eq SALES_ORDER_INTAKE_TYPE() ? $::locale->text('The order intake has been deleted')
|
||
: $self->type eq SALES_ORDER_TYPE() ? $::locale->text('The order confirmation has been deleted')
|
||
: $self->type eq PURCHASE_ORDER_TYPE() ? $::locale->text('The order has been deleted')
|
||
: $self->type eq SALES_QUOTATION_TYPE() ? $::locale->text('The quotation has been deleted')
|
||
: $self->type eq REQUEST_QUOTATION_TYPE() ? $::locale->text('The rfq has been deleted')
|
||
: $self->type eq PURCHASE_QUOTATION_INTAKE_TYPE() ? $::locale->text('The quotation intake has been deleted')
|
||
: '';
|
||
flash_later('info', $text);
|
||
|
||
... | ... | |
|
||
$self->save();
|
||
|
||
my $text = $self->type eq sales_order_intake_type() ? $::locale->text('The order intake has been saved')
|
||
: $self->type eq sales_order_type() ? $::locale->text('The order confirmation has been saved')
|
||
: $self->type eq purchase_order_type() ? $::locale->text('The order has been saved')
|
||
: $self->type eq sales_quotation_type() ? $::locale->text('The quotation has been saved')
|
||
: $self->type eq request_quotation_type() ? $::locale->text('The rfq has been saved')
|
||
: $self->type eq purchase_quotation_intake_type() ? $::locale->text('The quotation intake has been saved')
|
||
my $text = $self->type eq SALES_ORDER_INTAKE_TYPE() ? $::locale->text('The order intake has been saved')
|
||
: $self->type eq SALES_ORDER_TYPE() ? $::locale->text('The order confirmation has been saved')
|
||
: $self->type eq PURCHASE_ORDER_TYPE() ? $::locale->text('The order has been saved')
|
||
: $self->type eq SALES_QUOTATION_TYPE() ? $::locale->text('The quotation has been saved')
|
||
: $self->type eq REQUEST_QUOTATION_TYPE() ? $::locale->text('The rfq has been saved')
|
||
: $self->type eq PURCHASE_QUOTATION_INTAKE_TYPE() ? $::locale->text('The quotation intake has been saved')
|
||
: '';
|
||
flash_later('info', $text);
|
||
|
||
... | ... | |
$config ||= SL::DB::Manager::PeriodicInvoicesConfig->find_by(oe_id => $::form->{id}) if $::form->{id};
|
||
|
||
my $has_active_periodic_invoices =
|
||
$self->type eq sales_order_type()
|
||
$self->type eq SALES_ORDER_TYPE()
|
||
&& $config
|
||
&& $config->active
|
||
&& (!$config->end_date || ($config->end_date > DateTime->today_local))
|
||
... | ... | |
# can't use save_and_redirect_to, because id is set!
|
||
$self->save();
|
||
|
||
my $to_type = $self->order->is_sales ? 'sales_reclamation'
|
||
: 'purchase_reclamation';
|
||
my $to_type = $self->order->is_sales ? SALES_RECLAMATION_TYPE()
|
||
: PURCHASE_RECLAMATION_TYPE();
|
||
$self->redirect_to(
|
||
controller => 'Reclamation',
|
||
action => 'add_from_order',
|
||
... | ... | |
my $destination_type = $::form->{to_type} ? $::form->{to_type} : '';
|
||
|
||
my $from_side = $self->order->is_sales ? 'sales' : 'purchase';
|
||
my $to_side = (any { $destination_type eq $_ } (sales_order_intake_type(), sales_order_type(), sales_quotation_type())) ? 'sales' : 'purchase';
|
||
my $to_side = (any { $destination_type eq $_ } (SALES_ORDER_INTAKE_TYPE(), SALES_ORDER_TYPE(), SALES_QUOTATION_TYPE())) ? 'sales' : 'purchase';
|
||
|
||
# check for direct delivery
|
||
# copy shipto in custom shipto (custom shipto will be copied by new_from() in case)
|
||
... | ... | |
$self->order(SL::DB::Order->new_from($self->order, destination_type => $destination_type));
|
||
|
||
# no linked records to quotations from the same side (sales -> sales or purchase -> purchase)
|
||
if ( (any { $destination_type eq $_ } (sales_quotation_type(), request_quotation_type()))
|
||
if ( (any { $destination_type eq $_ } (SALES_QUOTATION_TYPE(), REQUEST_QUOTATION_TYPE()))
|
||
&& $from_side eq $to_side) {
|
||
delete $::form->{id};
|
||
delete $::form->{$_} for qw(converted_from_oe_id converted_from_orderitems_ids);
|
||
... | ... | |
#
|
||
|
||
sub init_valid_types {
|
||
[ sales_order_intake_type(), sales_order_type(), purchase_order_type(), sales_quotation_type(), request_quotation_type(), purchase_quotation_intake_type() ];
|
||
$_[0]->type_data->valid_types;
|
||
}
|
||
|
||
sub init_type {
|
||
... | ... | |
sub init_cv {
|
||
my ($self) = @_;
|
||
|
||
my $cv = (any { $self->type eq $_ } (sales_order_intake_type(), sales_order_type(), sales_quotation_type())) ? 'customer'
|
||
: (any { $self->type eq $_ } (purchase_order_type(), request_quotation_type(), purchase_quotation_intake_type())) ? 'vendor'
|
||
my $cv = (any { $self->type eq $_ } (SALES_ORDER_INTAKE_TYPE(), SALES_ORDER_TYPE(), SALES_QUOTATION_TYPE())) ? 'customer'
|
||
: (any { $self->type eq $_ } (PURCHASE_ORDER_TYPE(), REQUEST_QUOTATION_TYPE(), PURCHASE_QUOTATION_INTAKE_TYPE())) ? 'vendor'
|
||
: die "Not a valid type for order";
|
||
|
||
return $cv;
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
my $right_for = { map { $_ => $_.'_edit' . ' | ' . $_.'_view' } @{$self->valid_types} };
|
||
$right_for->{ sales_order_intake_type() } = 'sales_order_edit | sales_order_view';
|
||
$right_for->{ purchase_quotation_intake_type() } = 'request_quotation_edit | request_quotation_view';
|
||
$right_for->{ SALES_ORDER_INTAKE_TYPE() } = 'sales_order_edit | sales_order_view';
|
||
$right_for->{ PURCHASE_QUOTATION_INTAKE_TYPE() } = 'request_quotation_edit | request_quotation_view';
|
||
|
||
my $right = $right_for->{ $self->type };
|
||
$right ||= 'DOES_NOT_EXIST';
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
my $right_for = { map { $_ => $_.'_edit' } @{$self->valid_types} };
|
||
$right_for->{ sales_order_intake_type() } = 'sales_order_edit';
|
||
$right_for->{ purchase_quotation_intake_type() } = 'request_quotation_edit';
|
||
$right_for->{ SALES_ORDER_INTAKE_TYPE() } = 'sales_order_edit';
|
||
$right_for->{ PURCHASE_QUOTATION_INTAKE_TYPE() } = 'request_quotation_edit';
|
||
|
||
my $right = $right_for->{ $self->type };
|
||
$right ||= 'DOES_NOT_EXIST';
|
||
... | ... | |
my $order;
|
||
$order = SL::DB::Order->new(id => $::form->{id})->load(with => [ 'orderitems', 'orderitems.part' ]) if $::form->{id};
|
||
$order ||= SL::DB::Order->new(orderitems => [],
|
||
quotation => (any { $self->type eq $_ } (sales_quotation_type(), request_quotation_type(), purchase_quotation_intake_type())),
|
||
intake => (any { $self->type eq $_ } (sales_order_intake_type(), purchase_quotation_intake_type())),
|
||
quotation => (any { $self->type eq $_ } (SALES_QUOTATION_TYPE(), REQUEST_QUOTATION_TYPE(), PURCHASE_QUOTATION_INTAKE_TYPE())),
|
||
intake => (any { $self->type eq $_ } (SALES_ORDER_INTAKE_TYPE(), PURCHASE_QUOTATION_INTAKE_TYPE())),
|
||
currency_id => $::instance_conf->get_currency_id(),);
|
||
|
||
my $cv_id_method = $self->cv . '_id';
|
||
... | ... | |
$item->active_discount_source($price_source->discount_from_source($item->active_discount_source));
|
||
}
|
||
|
||
if (any { $self->type eq $_ } (sales_order_intake_type(), sales_order_type(), purchase_order_type())) {
|
||
if (any { $self->type eq $_ } (SALES_ORDER_INTAKE_TYPE(), SALES_ORDER_TYPE(), PURCHASE_ORDER_TYPE())) {
|
||
# Calculate shipped qtys here to prevent calling calculate for every item via the items method.
|
||
# Do not use write_to_objects to prevent order->delivered to be set, because this should be
|
||
# the value from db, which can be set manually or is set when linked delivery orders are saved.
|
||
... | ... | |
} } @all_objects;
|
||
}
|
||
|
||
if ( (any { $self->type eq $_ } (sales_quotation_type(), sales_order_intake_type(), sales_order_type()))
|
||
if ( (any { $self->type eq $_ } (SALES_QUOTATION_TYPE(), SALES_ORDER_INTAKE_TYPE(), SALES_ORDER_TYPE()))
|
||
&& $::instance_conf->get_transport_cost_reminder_article_number_id ) {
|
||
$self->{template_args}->{transport_cost_reminder_article} = SL::DB::Part->new(id => $::instance_conf->get_transport_cost_reminder_article_number_id)->load;
|
||
}
|
||
... | ... | |
sub setup_edit_action_bar {
|
||
my ($self, %params) = @_;
|
||
|
||
my $deletion_allowed = (any { $self->type eq $_ } (sales_quotation_type(), request_quotation_type(), purchase_quotation_intake_type()))
|
||
|| (($self->type eq sales_order_type()) && $::instance_conf->get_sales_order_show_delete)
|
||
|| (($self->type eq sales_order_intake_type()) && $::instance_conf->get_sales_order_show_delete)
|
||
|| (($self->type eq purchase_order_type()) && $::instance_conf->get_purchase_order_show_delete);
|
||
my $deletion_allowed = (any { $self->type eq $_ } (SALES_QUOTATION_TYPE(), REQUEST_QUOTATION_TYPE(), PURCHASE_QUOTATION_INTAKE_TYPE()))
|
||
|| (($self->type eq SALES_ORDER_TYPE()) && $::instance_conf->get_sales_order_show_delete)
|
||
|| (($self->type eq SALES_ORDER_INTAKE_TYPE()) && $::instance_conf->get_sales_order_show_delete)
|
||
|| (($self->type eq PURCHASE_ORDER_TYPE()) && $::instance_conf->get_purchase_order_show_delete);
|
||
|
||
my @req_trans_cost_art = qw(kivi.Order.check_transport_cost_article_presence) x!!$::instance_conf->get_transport_cost_reminder_article_number_id;
|
||
my @req_cusordnumber = qw(kivi.Order.check_cusordnumber_presence) x(( any {$self->type eq $_} (sales_order_intake_type(), sales_order_type()) ) && $::instance_conf->get_order_warn_no_cusordnumber);
|
||
my @req_cusordnumber = qw(kivi.Order.check_cusordnumber_presence) x(( any {$self->type eq $_} (SALES_ORDER_INTAKE_TYPE(), SALES_ORDER_TYPE()) ) && $::instance_conf->get_order_warn_no_cusordnumber);
|
||
|
||
my $has_invoice_for_advance_payment;
|
||
if ($self->order->id && $self->type eq sales_order_type()) {
|
||
if ($self->order->id && $self->type eq SALES_ORDER_TYPE()) {
|
||
my $lr = $self->order->linked_records(direction => 'to', to => ['Invoice']);
|
||
$has_invoice_for_advance_payment = any {'SL::DB::Invoice' eq ref $_ && "invoice_for_advance_payment" eq $_->type} @$lr;
|
||
}
|
||
|
||
my $has_final_invoice;
|
||
if ($self->order->id && $self->type eq sales_order_type()) {
|
||
if ($self->order->id && $self->type eq SALES_ORDER_TYPE()) {
|
||
my $lr = $self->order->linked_records(direction => 'to', to => ['Invoice']);
|
||
$has_final_invoice = any {'SL::DB::Invoice' eq ref $_ && "final_invoice" eq $_->type} @$lr;
|
||
}
|
||
|
||
my $right_for = { map { $_ => $_.'_edit' } @{$self->valid_types} };
|
||
$right_for->{ sales_order_intake_type() } = 'sales_order_edit';
|
||
$right_for->{ purchase_quotation_intake_type() } = 'request_quotation_edit';
|
||
$right_for->{ SALES_ORDER_INTAKE_TYPE() } = 'sales_order_edit';
|
||
$right_for->{ PURCHASE_QUOTATION_INTAKE_TYPE() } = 'request_quotation_edit';
|
||
my $right = $right_for->{ $self->type };
|
||
$right ||= 'DOES_NOT_EXIST';
|
||
my $may_edit_create = $::auth->assert($right, 'may fail');
|
||
... | ... | |
],
|
||
action => [
|
||
t8('Save and Quotation'),
|
||
call => [ 'kivi.submit_ajax_form', $self->url_for(action => "save_and_order_workflow", to_type => sales_quotation_type()), '#order_form' ],
|
||
call => [ 'kivi.submit_ajax_form', $self->url_for(action => "save_and_order_workflow", to_type => SALES_QUOTATION_TYPE()), '#order_form' ],
|
||
checks => [ @req_trans_cost_art, @req_cusordnumber ],
|
||
only_if => (any { $self->type eq $_ } (sales_order_intake_type(), sales_order_type(), request_quotation_type(), purchase_quotation_intake_type())),
|
||
only_if => (any { $self->type eq $_ } (SALES_ORDER_INTAKE_TYPE(), SALES_ORDER_TYPE(), REQUEST_QUOTATION_TYPE(), PURCHASE_QUOTATION_INTAKE_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
action => [
|
||
t8('Save and RFQ'),
|
||
call => [ 'kivi.Order.purchase_check_for_direct_delivery', { to_type => request_quotation_type() } ],
|
||
only_if => (any { $self->type eq $_ } (sales_order_intake_type(), sales_order_type(), sales_quotation_type(), purchase_order_type())),
|
||
call => [ 'kivi.Order.purchase_check_for_direct_delivery', { to_type => REQUEST_QUOTATION_TYPE() } ],
|
||
only_if => (any { $self->type eq $_ } (SALES_ORDER_INTAKE_TYPE(), SALES_ORDER_TYPE(), SALES_QUOTATION_TYPE(), PURCHASE_ORDER_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
action => [
|
||
t8('Save and Purchase Quotation Intake'),
|
||
call => [ 'kivi.submit_ajax_form', $self->url_for(action => "save_and_order_workflow", to_type => purchase_quotation_intake_type()), '#order_form' ],
|
||
only_if => (any { $self->type eq $_ } (request_quotation_type())),
|
||
call => [ 'kivi.submit_ajax_form', $self->url_for(action => "save_and_order_workflow", to_type => PURCHASE_QUOTATION_INTAKE_TYPE()), '#order_form' ],
|
||
only_if => (any { $self->type eq $_ } (REQUEST_QUOTATION_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
action => [
|
||
t8('Save and Sales Order Intake'),
|
||
call => [ 'kivi.submit_ajax_form', $self->url_for(action => "save_and_order_workflow", to_type => sales_order_intake_type()), '#order_form' ],
|
||
only_if => (any { $self->type eq $_ } (sales_quotation_type())),
|
||
call => [ 'kivi.submit_ajax_form', $self->url_for(action => "save_and_order_workflow", to_type => SALES_ORDER_INTAKE_TYPE()), '#order_form' ],
|
||
only_if => (any { $self->type eq $_ } (SALES_QUOTATION_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
action => [
|
||
t8('Save and Sales Order Confirmation'),
|
||
call => [ 'kivi.submit_ajax_form', $self->url_for(action => "save_and_order_workflow", to_type => sales_order_type()), '#order_form' ],
|
||
call => [ 'kivi.submit_ajax_form', $self->url_for(action => "save_and_order_workflow", to_type => SALES_ORDER_TYPE()), '#order_form' ],
|
||
checks => [ @req_trans_cost_art ],
|
||
only_if => (any { $self->type eq $_ } (sales_quotation_type(), sales_order_intake_type(), request_quotation_type(), purchase_order_type(), purchase_quotation_intake_type())),
|
||
only_if => (any { $self->type eq $_ } (SALES_QUOTATION_TYPE(), SALES_ORDER_INTAKE_TYPE(), REQUEST_QUOTATION_TYPE(), PURCHASE_ORDER_TYPE(), PURCHASE_QUOTATION_INTAKE_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
action => [
|
||
t8('Save and Purchase Order'),
|
||
call => [ 'kivi.Order.purchase_check_for_direct_delivery', { to_type => purchase_order_type() } ],
|
||
call => [ 'kivi.Order.purchase_check_for_direct_delivery', { to_type => PURCHASE_ORDER_TYPE() } ],
|
||
checks => [ @req_trans_cost_art, @req_cusordnumber ],
|
||
only_if => (any { $self->type eq $_ } (sales_order_intake_type(), sales_order_type(), request_quotation_type(), purchase_quotation_intake_type())),
|
||
only_if => (any { $self->type eq $_ } (SALES_ORDER_INTAKE_TYPE(), SALES_ORDER_TYPE(), REQUEST_QUOTATION_TYPE(), PURCHASE_QUOTATION_INTAKE_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
action => [
|
||
... | ... | |
checks => [ 'kivi.Order.check_save_active_periodic_invoices',
|
||
@req_trans_cost_art, @req_cusordnumber,
|
||
],
|
||
only_if => (any { $self->type eq $_ } (sales_order_type(), purchase_order_type())),
|
||
only_if => (any { $self->type eq $_ } (SALES_ORDER_TYPE(), PURCHASE_ORDER_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
action => [
|
||
... | ... | |
checks => [ 'kivi.Order.check_save_active_periodic_invoices',
|
||
@req_trans_cost_art, @req_cusordnumber,
|
||
],
|
||
only_if => (any { $self->type eq $_ } (purchase_order_type())),
|
||
only_if => (any { $self->type eq $_ } (PURCHASE_ORDER_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
action => [
|
||
... | ... | |
call => [ 'kivi.Order.save', { action => 'save_and_reclamation',
|
||
warn_on_duplicates => $::instance_conf->get_order_warn_duplicate_parts },
|
||
],
|
||
only_if => (any { $self->type eq $_ } (sales_order_type(), purchase_order_type()))
|
||
only_if => (any { $self->type eq $_ } (SALES_ORDER_TYPE(), PURCHASE_ORDER_TYPE()))
|
||
],
|
||
action => [
|
||
t8('Save and Invoice'),
|
||
... | ... | |
@req_trans_cost_art, @req_cusordnumber,
|
||
],
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
not_if => (any { $self->type eq $_ } (sales_order_intake_type(), purchase_quotation_intake_type())),
|
||
not_if => (any { $self->type eq $_ } (SALES_ORDER_INTAKE_TYPE(), PURCHASE_QUOTATION_INTAKE_TYPE())),
|
||
],
|
||
action => [
|
||
($has_invoice_for_advance_payment ? t8('Save and Further Invoice for Advance Payment') : t8('Save and Invoice for Advance Payment')),
|
||
... | ... | |
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
|
||
: $has_final_invoice ? t8('This order has already a final invoice.')
|
||
: undef,
|
||
only_if => (any { $self->type eq $_ } (sales_order_type())),
|
||
only_if => (any { $self->type eq $_ } (SALES_ORDER_TYPE())),
|
||
],
|
||
action => [
|
||
t8('Save and Final Invoice'),
|
||
... | ... | |
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
|
||
: $has_final_invoice ? t8('This order has already a final invoice.')
|
||
: undef,
|
||
only_if => (any { $self->type eq $_ } (sales_order_type())) && $has_invoice_for_advance_payment,
|
||
only_if => (any { $self->type eq $_ } (SALES_ORDER_TYPE())) && $has_invoice_for_advance_payment,
|
||
],
|
||
action => [
|
||
t8('Save and AP Transaction'),
|
||
call => [ 'kivi.Order.save', { action => 'save_and_ap_transaction',
|
||
warn_on_duplicates => $::instance_conf->get_order_warn_duplicate_parts },
|
||
],
|
||
only_if => (any { $self->type eq $_ } (purchase_order_type())),
|
||
only_if => (any { $self->type eq $_ } (PURCHASE_ORDER_TYPE())),
|
||
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
|
||
],
|
||
|
||
... | ... | |
sub get_periodic_invoices_status {
|
||
my ($self, $config) = @_;
|
||
|
||
return if $self->type ne sales_order_type();
|
||
return if $self->type ne SALES_ORDER_TYPE();
|
||
return t8('not configured') if !$config;
|
||
|
||
my $active = ('HASH' eq ref $config) ? $config->{active}
|
||
... | ... | |
# $::locale->text("Edit Purchase Quotation Intake");
|
||
|
||
$action = ucfirst(lc($action));
|
||
return $self->type eq sales_order_intake_type() ? $::locale->text("$action Sales Order Intake")
|
||
: $self->type eq sales_order_type() ? $::locale->text("$action Sales Order")
|
||
: $self->type eq purchase_order_type() ? $::locale->text("$action Purchase Order")
|
||
: $self->type eq sales_quotation_type() ? $::locale->text("$action Quotation")
|
||
: $self->type eq request_quotation_type() ? $::locale->text("$action Request for Quotation")
|
||
: $self->type eq purchase_quotation_intake_type() ? $::locale->text("$action Purchase Quotation Intake")
|
||
return $self->type eq SALES_ORDER_INTAKE_TYPE() ? $::locale->text("$action Sales Order Intake")
|
||
: $self->type eq SALES_ORDER_TYPE() ? $::locale->text("$action Sales Order")
|
||
: $self->type eq PURCHASE_ORDER_TYPE() ? $::locale->text("$action Purchase Order")
|
||
: $self->type eq SALES_QUOTATION_TYPE() ? $::locale->text("$action Quotation")
|
||
: $self->type eq REQUEST_QUOTATION_TYPE() ? $::locale->text("$action Request for Quotation")
|
||
: $self->type eq PURCHASE_QUOTATION_INTAKE_TYPE() ? $::locale->text("$action Purchase Quotation Intake")
|
||
: '';
|
||
}
|
||
|
||
... | ... | |
return ($price_src, $discount_src);
|
||
}
|
||
|
||
sub sales_order_intake_type {
|
||
'sales_order_intake';
|
||
}
|
||
|
||
sub sales_order_type {
|
||
'sales_order';
|
||
}
|
||
|
||
sub purchase_order_type {
|
||
'purchase_order';
|
||
}
|
||
|
||
sub sales_quotation_type {
|
||
'sales_quotation';
|
||
}
|
||
|
||
sub request_quotation_type {
|
||
'request_quotation';
|
||
}
|
||
|
||
sub purchase_quotation_intake_type {
|
||
'purchase_quotation_intake';
|
||
}
|
||
|
||
sub nr_key {
|
||
return $_[0]->type eq sales_order_intake_type() ? 'ordnumber'
|
||
: $_[0]->type eq sales_order_type() ? 'ordnumber'
|
||
: $_[0]->type eq purchase_order_type() ? 'ordnumber'
|
||
: $_[0]->type eq sales_quotation_type() ? 'quonumber'
|
||
: $_[0]->type eq request_quotation_type() ? 'quonumber'
|
||
: $_[0]->type eq purchase_quotation_intake_type() ? 'quonumber'
|
||
return $_[0]->type eq SALES_ORDER_INTAKE_TYPE() ? 'ordnumber'
|
||
: $_[0]->type eq SALES_ORDER_TYPE() ? 'ordnumber'
|
||
: $_[0]->type eq PURCHASE_ORDER_TYPE() ? 'ordnumber'
|
||
: $_[0]->type eq SALES_QUOTATION_TYPE() ? 'quonumber'
|
||
: $_[0]->type eq REQUEST_QUOTATION_TYPE() ? 'quonumber'
|
||
: $_[0]->type eq PURCHASE_QUOTATION_INTAKE_TYPE() ? 'quonumber'
|
||
: '';
|
||
}
|
||
|
||
... | ... | |
|
||
$self->save();
|
||
|
||
my $text = $self->type eq sales_order_intake_type() ? $::locale->text('The order intake has been saved')
|
||
: $self->type eq sales_order_type() ? $::locale->text('The order confirmation has been saved')
|
||
: $self->type eq purchase_order_type() ? $::locale->text('The order has been saved')
|
||
: $self->type eq sales_quotation_type() ? $::locale->text('The quotation has been saved')
|
||
: $self->type eq request_quotation_type() ? $::locale->text('The rfq has been saved')
|
||
: $self->type eq purchase_quotation_intake_type() ? $::locale->text('The quotation intake has been saved')
|
||
my $text = $self->type eq SALES_ORDER_INTAKE_TYPE() ? $::locale->text('The order intake has been saved')
|
||
: $self->type eq SALES_ORDER_TYPE() ? $::locale->text('The order confirmation has been saved')
|
||
: $self->type eq PURCHASE_ORDER_TYPE() ? $::locale->text('The order has been saved')
|
||
: $self->type eq SALES_QUOTATION_TYPE() ? $::locale->text('The quotation has been saved')
|
||
: $self->type eq REQUEST_QUOTATION_TYPE() ? $::locale->text('The rfq has been saved')
|
||
: $self->type eq PURCHASE_QUOTATION_INTAKE_TYPE() ? $::locale->text('The quotation intake has been saved')
|
||
: '';
|
||
flash_later('info', $text);
|
||
|
SL/Controller/Reclamation.pm | ||
---|---|---|
use SL::DB::DeliveryOrder;
|
||
use SL::DB::Invoice;
|
||
use SL::Model::Record;
|
||
use SL::DB::Order::TypeData qw(:types);
|
||
use SL::DB::Reclamation::TypeData qw(:types);
|
||
|
||
use List::Util qw(first sum0);
|
||
use List::UtilsBy qw(sort_by uniq_by);
|
||
... | ... | |
}
|
||
|
||
my $order = SL::DB::Order->new(id => $::form->{from_id})->load;
|
||
my $target_type = $order->is_sales ? 'sales_reclamation'
|
||
: 'purchase_reclamation';
|
||
my $target_type = $order->is_sales ? SALES_RECLAMATION_TYPE()
|
||
: PURCHASE_RECLAMATION_TYPE();
|
||
my $reclamation = SL::Model::Record->new_from_workflow($order, $target_type);
|
||
|
||
$self->reclamation($reclamation);
|
||
... | ... | |
}
|
||
|
||
my $delivery_order = SL::DB::DeliveryOrder->new(id => $::form->{from_id})->load;
|
||
my $target_type = $delivery_order->is_sales ? 'sales_reclamation'
|
||
: 'purchase_reclamation';
|
||
my $target_type = $delivery_order->is_sales ? SALES_RECLAMATION_TYPE()
|
||
: PURCHASE_RECLAMATION_TYPE();
|
||
my $reclamation = SL::Model::Record->new_from_workflow($delivery_order, $target_type);
|
||
|
||
$self->reclamation($reclamation);
|
||
... | ... | |
}
|
||
|
||
my $invoice = SL::DB::Invoice->new(id => $::form->{from_id})->load;
|
||
my $target_type = 'sales_reclamation';
|
||
my $target_type = SALES_RECLAMATION_TYPE();
|
||
my $reclamation = SL::Model::Record->new_from_workflow($invoice, $target_type);
|
||
|
||
$self->reclamation($reclamation);
|
||
... | ... | |
require SL::DB::PurchaseInvoice;
|
||
my $invoice = SL::DB::PurchaseInvoice->new(id => $::form->{from_id})->load;
|
||
$invoice->{type} = $invoice->invoice_type; #can't add type → invoice_type in SL/DB/PurchaseInvoice
|
||
my $target_type = 'purchase_reclamation';
|
||
my $target_type = PURCHASE_RECLAMATION_TYPE();
|
||
my $reclamation = SL::Model::Record->new_from_workflow($invoice, $target_type);
|
||
|
||
$self->reclamation($reclamation);
|
||
... | ... | |
sub action_save_and_order {
|
||
my ($self) = @_;
|
||
|
||
my $to_type = $self->reclamation->is_sales ? 'sales_order'
|
||
: 'purchase_order';
|
||
my $to_type = $self->reclamation->is_sales ? SALES_ORDER_TYPE()
|
||
: PURCHASE_ORDER_TYPE();
|
||
|
||
$self->save_with_render_error();
|
||
flash_later('info', t8('The reclamation has been saved'));
|
||
... | ... | |
controller => 'Reclamation',
|
||
action => 'add_from_reclamation',
|
||
from_id => $self->reclamation->id,
|
||
type => sales_reclamation_type(),
|
||
type => SALES_RECLAMATION_TYPE(),
|
||
);
|
||
}
|
||
|
||
... | ... | |
controller => 'Reclamation',
|
||
action => 'add_from_reclamation',
|
||
from_id => $self->reclamation->id,
|
||
type => purchase_reclamation_type(),
|
||
type => PURCHASE_RECLAMATION_TYPE(),
|
||
);
|
||
}
|
||
|
||
... | ... | |
#
|
||
|
||
sub init_valid_types {
|
||
[ sales_reclamation_type(), purchase_reclamation_type() ];
|
||
$_[0]->type_data->valid_types;
|
||
}
|
||
|
||
sub init_type {
|
||
... | ... | |
sub init_cv {
|
||
my ($self) = @_;
|
||
|
||
my $cv = (any { $self->type eq $_ } (sales_reclamation_type())) ? 'customer'
|
||
: (any { $self->type eq $_ } (purchase_reclamation_type())) ? 'vendor'
|
||
my $cv = (any { $self->type eq $_ } (SALES_RECLAMATION_TYPE())) ? 'customer'
|
||
: (any { $self->type eq $_ } (PURCHASE_RECLAMATION_TYPE())) ? 'vendor'
|
||
: die "Not a valid type for reclamation";
|
||
|
||
return $cv;
|
||
... | ... | |
language => t8('Language'),
|
||
department => t8('Department'),
|
||
globalproject => t8('Project Number'),
|
||
cv_record_number => ($self->type eq 'sales_reclamation' ? t8('Customer Record Number') : t8('Vendor Record Number')),
|
||
cv_record_number => ($self->type eq SALES_RECLAMATION_TYPE() ? t8('Customer Record Number') : t8('Vendor Record Number')),
|
||
transaction_description => t8('Description'),
|
||
notes => t8('Notes'),
|
||
intnotes => t8('Internal Notes'),
|
||
... | ... | |
|
||
sub init_part_picker_classification_ids {
|
||
my ($self) = @_;
|
||
my $attribute = 'used_for_' . ($self->type eq sales_reclamation_type() ? 'sale' : 'purchase');
|
||
my $attribute = 'used_for_' . ($self->type eq SALES_RECLAMATION_TYPE() ? 'sale' : 'purchase');
|
||
|
||
return [ map { $_->id } @{ SL::DB::Manager::PartClassification->get_all(where => [ $attribute => 1 ]) } ];
|
||
}
|
||
... | ... | |
|
||
# check for direct delivery
|
||
# copy shipto in custom shipto (custom shipto will be copied by new_from() in case)
|
||
if ($::form->{type} eq purchase_reclamation_type()) {
|
||
if ($::form->{type} eq PURCHASE_RECLAMATION_TYPE()) {
|
||
if ($::form->{use_shipto}) {
|
||
my $custom_shipto = $source_reclamation->shipto->clone('SL::DB::Reclamation');
|
||
$self->reclamation->custom_shipto($custom_shipto) if $custom_shipto;
|
||
... | ... | |
sub => sub { $_[0]->closed ? t8('Yes') : t8('No') },
|
||
},
|
||
);
|
||
if ($self->type eq sales_reclamation_type()) {
|
||
if ($self->type eq SALES_RECLAMATION_TYPE()) {
|
||
$column_defs{customer} = ({
|
||
raw_data => sub { $_[0]->customervendor->presenter->customer(display => 'table-cell', callback => $callback) },
|
||
sub => sub { $_[0]->customervendor->name },
|
||
... | ... | |
},
|
||
sub => sub { $_[0]->contact ? $_[0]->contact->cp_name : '' },
|
||
});
|
||
} elsif ($self->type eq purchase_reclamation_type()) {
|
||
} elsif ($self->type eq PURCHASE_RECLAMATION_TYPE()) {
|
||
$column_defs{vendor} = ({
|
||
raw_data => sub { $_[0]->customervendor->presenter->vendor(display => 'table-cell', callback => $callback) },
|
||
sub => sub { $_[0]->customervendor->name },
|
||
... | ... | |
{ output => 0 },
|
||
models => $self->models
|
||
),
|
||
title => $self->type eq sales_reclamation_type() ? t8('Sales Reclamations') : t8('Purchase Reclamations'),
|
||
title => $self->type eq SALES_RECLAMATION_TYPE() ? t8('Sales Reclamations') : t8('Purchase Reclamations'),
|
||
allow_pdf_export => 1,
|
||
allow_csv_export => 1,
|
||
);
|
||
... | ... | |
sub _setup_edit_action_bar {
|
||
my ($self, %params) = @_;
|
||
|
||
my $deletion_allowed = ($self->type eq sales_reclamation_type()
|
||
my $deletion_allowed = ($self->type eq SALES_RECLAMATION_TYPE()
|
||
&& $::instance_conf->get_sales_reclamation_show_delete)
|
||
|| ($self->type eq purchase_reclamation_type()
|
||
|| ($self->type eq PURCHASE_RECLAMATION_TYPE()
|
||
&& $::instance_conf->get_purchase_reclamation_show_delete);
|
||
|
||
for my $bar ($::request->layout->get('actionbar')) {
|
||
... | ... | |
$::instance_conf->get_reclamation_warn_duplicate_parts,
|
||
$::instance_conf->get_reclamation_warn_no_reqdate,
|
||
],
|
||
only_if => (any { $self->type eq $_ } (purchase_reclamation_type())),
|
||
only_if => (any { $self->type eq $_ } (PURCHASE_RECLAMATION_TYPE())),
|
||
],
|
||
action => [
|
||
t8('Save and Purchase Reclamation'),
|
||
call => [ 'kivi.Reclamation.purchase_reclamation_check_for_direct_delivery' ],
|
||
only_if => (any { $self->type eq $_ } (sales_reclamation_type())),
|
||
only_if => (any { $self->type eq $_ } (SALES_RECLAMATION_TYPE())),
|
||
],
|
||
action => [
|
||
t8('Save and Order'),
|
||
... | ... | |
$::instance_conf->get_reclamation_warn_duplicate_parts,
|
||
$::instance_conf->get_reclamation_warn_no_reqdate,
|
||
],
|
||
only_if => (any { $self->type eq $_ } (sales_reclamation_type())),
|
||
only_if => (any { $self->type eq $_ } (SALES_RECLAMATION_TYPE())),
|
||
],
|
||
action => [
|
||
t8('Save and Supplier Delivery Order'),
|
||
... | ... | |
$::instance_conf->get_reclamation_warn_duplicate_parts,
|
||
$::instance_conf->get_reclamation_warn_no_reqdate,
|
||
],
|
||
only_if => (any { $self->type eq $_ } (purchase_reclamation_type())),
|
||
only_if => (any { $self->type eq $_ } (PURCHASE_RECLAMATION_TYPE())),
|
||
],
|
||
action => [
|
||
t8('Save and Credit Note'),
|
||
... | ... | |
$::instance_conf->get_reclamation_warn_duplicate_parts,
|
||
$::instance_conf->get_reclamation_warn_no_reqdate,
|
||
],
|
||
only_if => (any { $self->type eq $_ } (sales_reclamation_type())),
|
||
only_if => (any { $self->type eq $_ } (SALES_RECLAMATION_TYPE())),
|
||
],
|
||
], # end of combobox "Workflow"
|
||
|
||
... | ... | |
# t8("Edit Purchase Reclamation");
|
||
|
||
$action = ucfirst(lc($action));
|
||
return $self->type eq sales_reclamation_type() ? t8("$action Sales Reclamation")
|
||
: $self->type eq purchase_reclamation_type() ? t8("$action Purchase Reclamation")
|
||
return $self->type eq SALES_RECLAMATION_TYPE() ? t8("$action Sales Reclamation")
|
||
: $self->type eq PURCHASE_RECLAMATION_TYPE() ? t8("$action Purchase Reclamation")
|
||
: '';
|
||
}
|
||
|
||
... | ... | |
return $texts;
|
||
}
|
||
|
||
sub sales_reclamation_type {
|
||
'sales_reclamation';
|
||
}
|
||
|
||
sub purchase_reclamation_type {
|
||
'purchase_reclamation';
|
||
}
|
||
|
||
sub save_history {
|
||
my ($self, $addition) = @_;
|
||
|
||
... | ... | |
}
|
||
|
||
sub init_type_data {
|
||
SL::DB::Helper::TypeDataProxy->new('SL::DB::Reclamation', $_[0]->type);
|
||
SL::DB::Helper::TypeDataProxy->new('SL::DB::Reclamation', $::form->{type});
|
||
}
|
||
|
||
1;
|
SL/DB/DeliveryOrder.pm | ||
---|---|---|
use SL::DB::Unit;
|
||
|
||
use SL::DB::DeliveryOrder::TypeData qw(:types);
|
||
use SL::DB::Reclamation::TypeData qw(:types);
|
||
|
||
use SL::Helper::Number qw(_format_total _round_total);
|
||
|
||
... | ... | |
],
|
||
);
|
||
|
||
return first { $_->is_type('sales_order') } @{ $orders };
|
||
return first { $_->is_type(SALES_ORDER_TYPE()) } @{ $orders };
|
||
}
|
||
|
||
sub type {
|
||
... | ... | |
sub displayable_type {
|
||
my $type = shift->type;
|
||
|
||
return $::locale->text('Sales Delivery Order') if $type eq 'sales_delivery_order';
|
||
return $::locale->text('Purchase Delivery Order') if $type eq 'purchase_delivery_order';
|
||
return $::locale->text('Sales Delivery Order') if $type eq SALES_DELIVERY_ORDER_TYPE();
|
||
return $::locale->text('Purchase Delivery Order') if $type eq PURCHASE_DELIVERY_ORDER_TYPE();
|
||
|
||
die 'invalid type';
|
||
}
|
||
... | ... | |
sub convert_to_reclamation {
|
||
my ($self, %params) = @_;
|
||
|
||
$params{destination_type} = $self->is_sales ? 'sales_reclamation'
|
||
: 'purchase_reclamation';
|
||
$params{destination_type} = $self->is_sales ? SALES_RECLAMATION_TYPE()
|
||
: PURCHASE_RECLAMATION_TYPE();
|
||
|
||
my $reclamation = SL::DB::Reclamation->new_from($self, %params);
|
||
|
||
... | ... | |
}
|
||
|
||
# infer type from legacy fields if not given
|
||
$record_args{order_type} //= $source->customer_id ? 'sales_delivery_order'
|
||
: $source->vendor_id ? 'purchase_delivery_order'
|
||
: $source->is_sales ? 'sales_delivery_order'
|
||
$record_args{order_type} //= $source->customer_id ? SALES_DELIVERY_ORDER_TYPE()
|
||
: $source->vendor_id ? PURCHASE_DELIVERY_ORDER_TYPE()
|
||
: $source->is_sales ? SALES_DELIVERY_ORDER_TYPE()
|
||
: croak "need some way to set delivery order type from source";
|
||
|
||
my $delivery_order = $class->new(%record_args);
|
||
$delivery_order->assign_attributes(%{ $params{attributes} }) if $params{attributes};
|
||
|
||
my $items = delete($params{items}) || $source->items_sorted;
|
||
my @items = ( $delivery_order->is_type(SUPPLIER_DELIVERY_ORDER_TYPE) && ref($source) ne 'SL::DB::Reclamation' ) ?
|
||
my @items = ( $delivery_order->is_type(SUPPLIER_DELIVERY_ORDER_TYPE()) && ref($source) ne 'SL::DB::Reclamation' ) ?
|
||
()
|
||
: map { SL::DB::DeliveryOrderItem->new_from($_, %params) } @{ $items };
|
||
|
SL/DB/Order.pm | ||
---|---|---|
use SL::RecordLinks;
|
||
use Rose::DB::Object::Helpers qw(as_tree strip);
|
||
|
||
use SL::DB::Order::TypeData qw(:types);
|
||
use SL::DB::Reclamation::TypeData qw(:types);
|
||
|
||
__PACKAGE__->meta->add_relationship(
|
||
orderitems => {
|
||
type => 'one to many',
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
# force new project, if not set yet
|
||
if ($::instance_conf->get_order_always_project && !$self->globalproject_id && ($self->type eq 'sales_order')) {
|
||
if ($::instance_conf->get_order_always_project && !$self->globalproject_id && ($self->type eq SALES_ORDER_TYPE())) {
|
||
|
||
die t8("Error while creating project with project number of new order number, project number #1 already exists!", $self->ordnumber)
|
||
if SL::DB::Manager::Project->find_by(projectnumber => $self->ordnumber);
|
||
... | ... | |
sub type {
|
||
my $self = shift;
|
||
|
||
return 'sales_order_intake' if $self->customer_id && $self->intake;
|
||
return 'sales_order' if $self->customer_id && ! $self->quotation;
|
||
return 'purchase_order' if $self->vendor_id && ! $self->quotation;
|
||
return 'sales_quotation' if $self->customer_id && $self->quotation;
|
||
return 'request_quotation' if $self->vendor_id && $self->quotation && ! $self->intake;
|
||
return 'purchase_quotation_intake' if $self->vendor_id && $self->quotation && $self->intake;
|
||
return SALES_ORDER_INTAKE_TYPE() if $self->customer_id && $self->intake;
|
||
return SALES_ORDER_TYPE() if $self->customer_id && ! $self->quotation;
|
||
return PURCHASE_ORDER_TYPE() if $self->vendor_id && ! $self->quotation;
|
||
return SALES_QUOTATION_TYPE() if $self->customer_id && $self->quotation;
|
||
return REQUEST_QUOTATION_TYPE() if $self->vendor_id && $self->quotation && ! $self->intake;
|
||
return PURCHASE_QUOTATION_INTAKE_TYPE() if $self->vendor_id && $self->quotation && $self->intake;
|
||
|
||
return;
|
||
}
|
||
... | ... | |
# But this has a different meaning for sales quotations.
|
||
# deliverydate can be used to determine tax if tax_point isn't set.
|
||
|
||
return $_[0]->reqdate if $_[0]->type ne 'sales_quotation';
|
||
return $_[0]->reqdate if $_[0]->type ne SALES_QUOTATION_TYPE();
|
||
}
|
||
|
||
sub effective_tax_point {
|
||
... | ... | |
sub displayable_type {
|
||
my $type = shift->type;
|
||
|
||
return $::locale->text('Sales quotation') if $type eq 'sales_quotation';
|
||
return $::locale->text('Request quotation') if $type eq 'request_quotation';
|
||
return $::locale->text('Sales Order') if $type eq 'sales_order';
|
||
return $::locale->text('Purchase Order') if $type eq 'purchase_order';
|
||
return $::locale->text('Sales quotation') if $type eq SALES_QUOTATION_TYPE();
|
||
return $::locale->text('Request quotation') if $type eq REQUEST_QUOTATION_TYPE();
|
||
return $::locale->text('Sales Order') if $type eq SALES_ORDER_TYPE();
|
||
return $::locale->text('Purchase Order') if $type eq PURCHASE_ORDER_TYPE();
|
||
|
||
die 'invalid type';
|
||
}
|
||
... | ... | |
|
||
return 1 if $self->currency_id == $::instance_conf->get_currency_id;
|
||
|
||
my $rate = (any { $self->is_type($_) } qw(sales_quotation sales_order)) ? 'buy'
|
||
: (any { $self->is_type($_) } qw(request_quotation purchase_order)) ? 'sell'
|
||
my $rate = (any { $self->is_type($_) } (SALES_QUOTATION_TYPE(), SALES_ORDER_TYPE())) ? 'buy'
|
||
: (any { $self->is_type($_) } (REQUEST_QUOTATION_TYPE(), PURCHASE_ORDER_TYPE())) ? 'sell'
|
||
: undef;
|
||
return if !$rate;
|
||
|
||
... | ... | |
|
||
sub convert_to_reclamation {
|
||
my ($self, %params) = @_;
|
||
$params{destination_type} = $self->is_sales ? 'sales_reclamation'
|
||
: 'purchase_reclamation';
|
||
$params{destination_type} = $self->is_sales ? SALES_RECLAMATION_TYPE()
|
||
: PURCHASE_RECLAMATION_TYPE();
|
||
|
||
require SL::DB::Reclamation;
|
||
my $reclamation = SL::DB::Reclamation->new_from($self, %params);
|
||
... | ... | |
my $destination_type = delete $params{destination_type};
|
||
|
||
my @from_tos = (
|
||
{ from => 'sales_quotation', to => 'sales_order', abbr => 'sqso' },
|
||
{ from => 'request_quotation', to => 'purchase_order', abbr => 'rqpo' },
|
||
{ from => 'sales_quotation', to => 'sales_quotation', abbr => 'sqsq' },
|
||
{ from => 'sales_order', to => 'sales_order', abbr => 'soso' },
|
||
{ from => 'request_quotation', to => 'request_quotation', abbr => 'rqrq' },
|
||
{ from => 'purchase_order', to => 'purchase_order', abbr => 'popo' },
|
||
{ from => 'sales_order', to => 'purchase_order', abbr => 'sopo' },
|
||
{ from => 'purchase_order', to => 'sales_order', abbr => 'poso' },
|
||
{ from => 'sales_order', to => 'sales_quotation', abbr => 'sosq' },
|
||
{ from => 'purchase_order', to => 'request_quotation', abbr => 'porq' },
|
||
{ from => 'request_quotation', to => 'sales_quotation', abbr => 'rqsq' },
|
||
{ from => 'request_quotation', to => 'sales_order', abbr => 'rqso' },
|
||
{ from => 'sales_quotation', to => 'request_quotation', abbr => 'sqrq' },
|
||
{ from => 'sales_order', to => 'request_quotation', abbr => 'sorq' },
|
||
{ from => 'sales_reclamation', to => 'sales_order', abbr => 'srso' },
|
||
{ from => 'purchase_reclamation', to => 'purchase_order', abbr => 'prpo' },
|
||
{ from => 'sales_order_intake', to => 'sales_order_intake', abbr => 'soisoi' },
|
||
{ from => 'sales_order_intake', to => 'sales_quotation', abbr => 'soisq' },
|
||
{ from => 'sales_order_intake', to => 'request_quotation', abbr => 'soirq' },
|
||
{ from => 'sales_order_intake', to => 'sales_order', abbr => 'soiso' },
|
||
{ from => 'sales_order_intake', to => 'purchase_order', abbr => 'soipo' },
|
||
{ from => 'sales_quotation', to => 'sales_order_intake', abbr => 'sqsoi' },
|
||
{ from => 'purchase_quotation_intake', to => 'purchase_quotation_intake', abbr => 'pqipqi' },
|
||
{ from => 'purchase_quotation_intake', to => 'sales_quotation', abbr => 'pqisq' },
|
||
{ from => 'purchase_quotation_intake', to => 'sales_order', abbr => 'pqiso' },
|
||
{ from => 'purchase_quotation_intake', to => 'purchase_order', abbr => 'pqipo' },
|
||
{ from => 'request_quotation', to => 'purchase_quotation_intake', abbr => 'rqpqi' },
|
||
{ from => SALES_QUOTATION_TYPE(), to => SALES_ORDER_TYPE(), abbr => 'sqso' },
|
||
{ from => REQUEST_QUOTATION_TYPE(), to => PURCHASE_ORDER_TYPE(), abbr => 'rqpo' },
|
||
{ from => SALES_QUOTATION_TYPE(), to => SALES_QUOTATION_TYPE(), abbr => 'sqsq' },
|
||
{ from => SALES_ORDER_TYPE(), to => SALES_ORDER_TYPE(), abbr => 'soso' },
|
||
{ from => REQUEST_QUOTATION_TYPE(), to => REQUEST_QUOTATION_TYPE(), abbr => 'rqrq' },
|
||
{ from => PURCHASE_ORDER_TYPE(), to => PURCHASE_ORDER_TYPE(), abbr => 'popo' },
|
||
{ from => SALES_ORDER_TYPE(), to => PURCHASE_ORDER_TYPE(), abbr => 'sopo' },
|
||
{ from => PURCHASE_ORDER_TYPE(), to => SALES_ORDER_TYPE(), abbr => 'poso' },
|
||
{ from => SALES_ORDER_TYPE(), to => SALES_QUOTATION_TYPE(), abbr => 'sosq' },
|
||
{ from => PURCHASE_ORDER_TYPE(), to => REQUEST_QUOTATION_TYPE(), abbr => 'porq' },
|
||
{ from => REQUEST_QUOTATION_TYPE(), to => SALES_QUOTATION_TYPE(), abbr => 'rqsq' },
|
||
{ from => REQUEST_QUOTATION_TYPE(), to => SALES_ORDER_TYPE(), abbr => 'rqso' },
|
||
{ from => SALES_QUOTATION_TYPE(), to => REQUEST_QUOTATION_TYPE(), abbr => 'sqrq' },
|
||
{ from => SALES_ORDER_TYPE(), to => REQUEST_QUOTATION_TYPE(), abbr => 'sorq' },
|
||
{ from => SALES_RECLAMATION_TYPE(), to => SALES_ORDER_TYPE(), abbr => 'srso' },
|
||
{ from => PURCHASE_RECLAMATION_TYPE(), to => PURCHASE_ORDER_TYPE(), abbr => 'prpo' },
|
||
{ from => SALES_ORDER_INTAKE_TYPE(), to => SALES_ORDER_INTAKE_TYPE(), abbr => 'soisoi' },
|
||
{ from => SALES_ORDER_INTAKE_TYPE(), to => SALES_QUOTATION_TYPE(), abbr => 'soisq' },
|
||
{ from => SALES_ORDER_INTAKE_TYPE(), to => REQUEST_QUOTATION_TYPE(), abbr => 'soirq' },
|
||
{ from => SALES_ORDER_INTAKE_TYPE(), to => SALES_ORDER_TYPE(), abbr => 'soiso' },
|
||
{ from => SALES_ORDER_INTAKE_TYPE(), to => PURCHASE_ORDER_TYPE(), abbr => 'soipo' },
|
||
{ from => SALES_QUOTATION_TYPE(), to => SALES_ORDER_INTAKE_TYPE(), abbr => 'sqsoi' },
|
||
{ from => PURCHASE_QUOTATION_INTAKE_TYPE(), to => PURCHASE_QUOTATION_INTAKE_TYPE(), abbr => 'pqipqi' },
|
||
{ from => PURCHASE_QUOTATION_INTAKE_TYPE(), to => SALES_QUOTATION_TYPE(), abbr => 'pqisq' },
|
||
{ from => PURCHASE_QUOTATION_INTAKE_TYPE(), to => SALES_ORDER_TYPE(), abbr => 'pqiso' },
|
||
{ from => PURCHASE_QUOTATION_INTAKE_TYPE(), to => PURCHASE_ORDER_TYPE(), abbr => 'pqipo' },
|
||
{ from => REQUEST_QUOTATION_TYPE(), to => PURCHASE_QUOTATION_INTAKE_TYPE(), abbr => 'rqpqi' },
|
||
);
|
||
my $from_to = (grep { $_->{from} eq $source->type && $_->{to} eq $destination_type} @from_tos)[0];
|
||
croak("Cannot convert from '" . $source->type . "' to '" . $destination_type . "'") if !$from_to;
|
||
... | ... | |
push @items, @{$_->items_sorted} for @$sources;
|
||
# make order from first source and all items
|
||
my $order = $class->new_from($sources->[0],
|
||
destination_type => 'sales_order',
|
||
destination_type => SALES_ORDER_TYPE(),
|
||
attributes => \%attributes,
|
||
items => \@items,
|
||
%params);
|
||
... | ... | |
return if !$self->type;
|
||
|
||
my %number_method = (
|
||
sales_order_intake => 'ordnumber',
|
||
sales_order => 'ordnumber',
|
||
sales_quotation => 'quonumber',
|
||
purchase_order => 'ordnumber',
|
||
request_quotation => 'quonumber',
|
||
purchase_quotation_intake => 'quonumber',
|
||
SALES_ORDER_INTAKE_TYPE() => 'ordnumber',
|
||
SALES_ORDER_TYPE() => 'ordnumber',
|
||
SALES_QUOTATION_TYPE() => 'quonumber',
|
||
PURCHASE_ORDER_TYPE() => 'ordnumber',
|
||
REQUEST_QUOTATION_TYPE() => 'quonumber',
|
||
PURCHASE_QUOTATION_INTAKE_TYPE() => 'quonumber',
|
||
);
|
||
|
||
return $self->${ \ $number_method{$self->type} }(@_);
|
SL/DB/Reclamation.pm | ||
---|---|---|
use List::Util qw(max sum0);
|
||
use List::MoreUtils qw(any);
|
||
|
||
use SL::DB::DeliveryOrder::TypeData qw(:types);
|
||
use SL::DB::Reclamation::TypeData qw(:types);
|
||
use SL::DB::MetaSetup::Reclamation;
|
||
use SL::DB::Manager::Reclamation;
|
||
use SL::DB::Helper::Attr;
|
||
... | ... | |
sub type {
|
||
my ($self) = @_;
|
||
|
||
return 'sales_reclamation' if $self->customer_id;
|
||
return 'purchase_reclamation' if $self->vendor_id;
|
||
return SALES_RECLAMATION_TYPE() if $self->customer_id;
|
||
return PURCHASE_RECLAMATION_TYPE() if $self->vendor_id;
|
||
|
||
return;
|
||
}
|
||
... | ... | |
sub displayable_type {
|
||
my $type = shift->type;
|
||
|
||
return $::locale->text('Sales Reclamation') if $type eq 'sales_reclamation';
|
||
return $::locale->text('Purchase Reclamation') if $type eq 'purchase_reclamation';
|
||
return $::locale->text('Sales Reclamation') if $type eq SALES_RECLAMATION_TYPE();
|
||
return $::locale->text('Purchase Reclamation') if $type eq PURCHASE_RECLAMATION_TYPE();
|
||
|
||
die 'invalid type';
|
||
}
|
||
... | ... | |
|
||
return 1 if $self->currency_id == $::instance_conf->get_currency_id;
|
||
|
||
my $rate = (any { $self->is_type($_) } qw(sales_reclamation)) ? 'buy'
|
||
: (any { $self->is_type($_) } qw(purchase_reclamation)) ? 'sell'
|
||
my $rate = (any { $self->is_type($_) } (SALES_RECLAMATION_TYPE())) ? 'buy'
|
||
: (any { $self->is_type($_) } (PURCHASE_RECLAMATION_TYPE())) ? 'sell'
|
||
: undef;
|
||
return if !$rate;
|
||
|
||
... | ... | |
my ($self, %params) = @_;
|
||
|
||
my $order;
|
||
$params{destination_type} = $self->is_sales ? 'sales_order'
|
||
: 'purchase_order';
|
||
$params{destination_type} = $self->is_sales ? SALES_ORDER_TYPE()
|
||
: PURCHASE_ORDER_TYPE();
|
||
if (!$self->db->with_transaction(sub {
|
||
require SL::DB::Order;
|
||
$order = SL::DB::Order->new_from($self, %params);
|
||
... | ... | |
|
||
my @from_tos = (
|
||
#Reclamation
|
||
{ from => 'sales_reclamation', to => 'sales_reclamation', abbr => 'srsr', },
|
||
{ from => 'purchase_reclamation', to => 'purchase_reclamation', abbr => 'prpr', },
|
||
{ from => 'sales_reclamation', to => 'purchase_reclamation', abbr => 'srpr', },
|
||
{ from => 'purchase_reclamation', to => 'sales_reclamation', abbr => 'prsr', },
|
||
{ from => SALES_RECLAMATION_TYPE(), to => SALES_RECLAMATION_TYPE(), abbr => 'srsr', },
|
||
{ from => PURCHASE_RECLAMATION_TYPE(), to => PURCHASE_RECLAMATION_TYPE(), abbr => 'prpr', },
|
||
{ from => SALES_RECLAMATION_TYPE(), to => PURCHASE_RECLAMATION_TYPE(), abbr => 'srpr', },
|
||
{ from => PURCHASE_RECLAMATION_TYPE(), to => SALES_RECLAMATION_TYPE(), abbr => 'prsr', },
|
||
#Order
|
||
{ from => 'sales_order', to => 'sales_reclamation', abbr => 'sosr', },
|
||
{ from => 'purchase_order', to => 'purchase_reclamation', abbr => 'popr', },
|
||
{ from => SALES_ORDER_TYPE(), to => SALES_RECLAMATION_TYPE(), abbr => 'sosr', },
|
||
{ from => PURCHASE_ORDER_TYPE(), to => PURCHASE_RECLAMATION_TYPE(), abbr => 'popr', },
|
||
#Delivery Order
|
||
{ from => 'sales_delivery_order', to => 'sales_reclamation', abbr => 'sdsr', },
|
||
{ from => 'purchase_delivery_order', to => 'purchase_reclamation', abbr => 'pdpr', },
|
||
{ from => SALES_DELIVERY_ORDER_TYPE(), to => SALES_RECLAMATION_TYPE(), abbr => 'sdsr', },
|
||
{ from => PURCHASE_DELIVERY_ORDER_TYPE(), to => PURCHASE_RECLAMATION_TYPE(), abbr => 'pdpr', },
|
||
#Invoice
|
||
{ from => 'invoice', to => 'sales_reclamation', abbr => 'sisr', },
|
||
{ from => 'purchase_invoice', to => 'purchase_reclamation', abbr => 'pipr', },
|
||
{ from => 'invoice', to => SALES_RECLAMATION_TYPE(), abbr => 'sisr', },
|
||
{ from => 'purchase_invoice', to => PURCHASE_RECLAMATION_TYPE(), abbr => 'pipr', },
|
||
);
|
||
my $from_to = (grep { $_->{from} eq $source->type && $_->{to} eq $destination_type} @from_tos)[0];
|
||
if (!$from_to) {
|
SL/Model/Record.pm | ||
---|---|---|
use SL::DB::Status;
|
||
use SL::DB::ValidityToken;
|
||
use SL::DB::Helper::TypeDataProxy;
|
||
use SL::DB::Order::TypeData qw(:types);
|
||
use SL::DB::DeliveryOrder::TypeData qw(:types);
|
||
use SL::DB::Reclamation::TypeData qw(:types);
|
||
|
||
use SL::Util qw(trim);
|
||
use SL::Locale::String qw(t8);
|
||
... | ... | |
|
||
my %subtype_to_type = (
|
||
# Order
|
||
"request_quotation" => "SL::DB::Order",
|
||
"purchase_order" => "SL::DB::Order",
|
||
"sales_quotation" => "SL::DB::Order",
|
||
"sales_order" => "SL::DB::Order",
|
||
REQUEST_QUOTATION_TYPE() => "SL::DB::Order",
|
||
PURCHASE_ORDER_TYPE() => "SL::DB::Order",
|
||
SALES_QUOTATION_TYPE() => "SL::DB::Order",
|
||
SALES_ORDER_TYPE() => "SL::DB::Order",
|
||
# DeliveryOrder
|
||
"sales_delivery_order" => "SL::DB::DeliveryOrder",
|
||
"purchase_delivery_order" => "SL::DB::DeliveryOrder",
|
||
"rma_delivery_order" => "SL::DB::DeliveryOrder",
|
||
"supplier_delivery_order" => "SL::DB::DeliveryOrder",
|
||
SALES_DELIVERY_ORDER_TYPE() => "SL::DB::DeliveryOrder",
|
||
PURCHASE_DELIVERY_ORDER_TYPE() => "SL::DB::DeliveryOrder",
|
||
RMA_DELIVERY_ORDER_TYPE() => "SL::DB::DeliveryOrder",
|
||
SUPPLIER_DELIVERY_ORDER_TYPE() => "SL::DB::DeliveryOrder",
|
||
# Reclamation
|
||
"sales_reclamation" => "SL::DB::Reclamation",
|
||
"purchase_reclamation" => "SL::DB::Reclamation",
|
||
SALES_RECLAMATION_TYPE() => "SL::DB::Reclamation",
|
||
PURCHASE_RECLAMATION_TYPE() => "SL::DB::Reclamation",
|
||
);
|
||
my $target_type = $subtype_to_type{$target_subtype};
|
||
unless ($target_type) {
|
||
... | ... | |
|
||
my %subtype_to_type = (
|
||
# Order
|
||
"sales_order" => "SL::DB::Order",
|
||
SALES_ORDER_TYPE() => "SL::DB::Order",
|
||
);
|
||
my $target_type = $subtype_to_type{$target_subtype};
|
||
unless ($target_type) {
|
Auch abrufbar als: Unified diff
TypeData: nutzte Konstanten anstatt String für Typen