Revision ad04be0a
Von Sven Schöling vor mehr als 3 Jahren hinzugefügt
SL/Controller/DeliveryOrder.pm | ||
---|---|---|
use SL::Helper::UserPreferences::UpdatePositions;
|
||
|
||
use SL::Controller::Helper::GetModels;
|
||
use SL::Controller::DeliveryOrder::TypeData;
|
||
|
||
use List::Util qw(first sum0);
|
||
use List::UtilsBy qw(sort_by uniq_by);
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
$self->order->transdate(DateTime->now_local());
|
||
my $extra_days = $self->type eq sales_quotation_type() ? $::instance_conf->get_reqdate_interval :
|
||
$self->type eq sales_order_type() ? $::instance_conf->get_delivery_date_interval : 1;
|
||
|
||
if ( ($self->type eq sales_order_type() && $::instance_conf->get_deliverydate_on)
|
||
|| ($self->type eq sales_quotation_type() && $::instance_conf->get_reqdate_on)
|
||
&& (!$self->order->reqdate)) {
|
||
$self->order->reqdate(DateTime->today_local->next_workday(extra_days => $extra_days));
|
||
}
|
||
$self->set_reqdate_by_type;
|
||
|
||
|
||
$self->pre_render();
|
||
... | ... | |
return $self->js->render();
|
||
}
|
||
|
||
my $text = $self->type eq sales_order_type() ? $::locale->text('The order 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')
|
||
: '';
|
||
flash_later('info', $text);
|
||
flash_later('info', $self->type_data->text("delete"));
|
||
|
||
my @redirect_params = (
|
||
action => 'add',
|
||
... | ... | |
return $self->js->render();
|
||
}
|
||
|
||
my $text = $self->type eq sales_order_type() ? $::locale->text('The order 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')
|
||
: '';
|
||
flash_later('info', $text);
|
||
flash_later('info', $self->type_data->text("saved"));
|
||
|
||
my @redirect_params = (
|
||
action => 'edit',
|
||
... | ... | |
: $order->transdate;
|
||
|
||
# Set new reqdate unless changed if it is enabled in client config
|
||
if ($order->reqdate == $saved_order->reqdate) {
|
||
my $extra_days = $self->type eq sales_quotation_type() ? $::instance_conf->get_reqdate_interval :
|
||
$self->type eq sales_order_type() ? $::instance_conf->get_delivery_date_interval : 1;
|
||
|
||
if ( ($self->type eq sales_order_type() && !$::instance_conf->get_deliverydate_on)
|
||
|| ($self->type eq sales_quotation_type() && !$::instance_conf->get_reqdate_on)) {
|
||
$new_attrs{reqdate} = '';
|
||
} else {
|
||
$new_attrs{reqdate} = DateTime->today_local->next_workday(extra_days => $extra_days);
|
||
}
|
||
} else {
|
||
$new_attrs{reqdate} = $order->reqdate;
|
||
}
|
||
$new_attrs{reqdate} = $self->get_reqdate_by_type($order->reqdate, $saved_order->reqdate);
|
||
|
||
# Update employee
|
||
$new_attrs{employee} = SL::DB::Manager::Employee->current;
|
||
... | ... | |
# helpers
|
||
#
|
||
|
||
sub init_valid_types {
|
||
[ sales_order_type(), purchase_order_type(), sales_quotation_type(), request_quotation_type() ];
|
||
}
|
||
|
||
sub init_type {
|
||
my ($self) = @_;
|
||
|
||
... | ... | |
sub init_cv {
|
||
my ($self) = @_;
|
||
|
||
my $cv = (any { $self->type eq $_ } (sales_order_type(), sales_quotation_type())) ? 'customer'
|
||
: (any { $self->type eq $_ } (purchase_order_type(), request_quotation_type())) ? 'vendor'
|
||
: die "Not a valid type for order";
|
||
|
||
return $cv;
|
||
return $self->type_data->customervendor;
|
||
}
|
||
|
||
sub init_search_cvpartnumber {
|
||
... | ... | |
|
||
sub init_part_picker_classification_ids {
|
||
my ($self) = @_;
|
||
my $attribute = 'used_for_' . ($self->type =~ m{sales} ? 'sale' : 'purchase');
|
||
|
||
return [ map { $_->id } @{ SL::DB::Manager::PartClassification->get_all(where => [ $attribute => 1 ]) } ];
|
||
return [ map { $_->id } @{ SL::DB::Manager::PartClassification->get_all(where => $self->type_date->part_classification_query) } ];
|
||
}
|
||
|
||
sub check_auth {
|
||
my ($self) = @_;
|
||
|
||
my $right_for = { map { $_ => $_.'_edit' } @{$self->valid_types} };
|
||
|
||
my $right = $right_for->{ $self->type };
|
||
$right ||= 'DOES_NOT_EXIST';
|
||
|
||
$::auth->assert($right);
|
||
$::auth->assert($self->type_data->access || 'DOES_NOT_EXIST');
|
||
}
|
||
|
||
# build the selection box for contacts
|
||
... | ... | |
my $order;
|
||
$order = SL::DB::DeliveryOrder->new(id => $::form->{id})->load(with => [ 'orderitems', 'orderitems.part' ]) if $::form->{id};
|
||
$order ||= SL::DB::DeliveryOrder->new(orderitems => [],
|
||
quotation => (any { $self->type eq $_ } (sales_quotation_type(), request_quotation_type())),
|
||
quotation => $self->type_data->is_quotation,
|
||
currency_id => $::instance_conf->get_currency_id(),);
|
||
|
||
my $cv_id_method = $self->cv . '_id';
|
||
... | ... | |
return $self->js->render();
|
||
}
|
||
|
||
my $destination_type = $::form->{type} eq sales_order_type() ? sales_quotation_type() : request_quotation_type();
|
||
my $destination_type = $self->type_data->workflow("to_quotation_type");
|
||
|
||
$self->order(SL::DB::DeliveryOrder->new_from($self->order, destination_type => $destination_type));
|
||
$self->{converted_from_oe_id} = delete $::form->{id};
|
||
... | ... | |
return $self->js->render();
|
||
}
|
||
|
||
my $destination_type = $::form->{type} eq sales_quotation_type() ? sales_order_type()
|
||
: $::form->{type} eq request_quotation_type() ? purchase_order_type()
|
||
: $::form->{type} eq purchase_order_type() ? sales_order_type()
|
||
: $::form->{type} eq sales_order_type() ? purchase_order_type()
|
||
: '';
|
||
my $destination_type = $self->type_data->workflow("to_order_type");
|
||
|
||
# check for direct delivery
|
||
# copy shipto in custom shipto (custom shipto will be copied by new_from() in case)
|
||
my $custom_shipto;
|
||
if ( $::form->{type} eq sales_order_type() && $destination_type eq purchase_order_type()
|
||
&& $::form->{use_shipto} && $self->order->shipto) {
|
||
if ($self->type_data->workflow("to_order_copy_shipto") && $::form->{use_shipto} && $self->order->shipto) {
|
||
$custom_shipto = $self->order->shipto->clone('SL::DB::DeliveryOrder');
|
||
}
|
||
|
||
... | ... | |
$item->{new_fake_id} = join('_', 'new', Time::HiRes::gettimeofday(), int rand 1000000000000);
|
||
}
|
||
|
||
if ($::form->{type} eq sales_order_type() && $destination_type eq purchase_order_type()) {
|
||
if ($self->type_data->workflow("to_order_copy_shipto")) {
|
||
if ($::form->{use_shipto}) {
|
||
$self->order->custom_shipto($custom_shipto) if $custom_shipto;
|
||
} else {
|
||
... | ... | |
$item->active_discount_source($price_source->discount_from_source($item->active_discount_source));
|
||
}
|
||
|
||
if (any { $self->type eq $_ } (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.
|
||
SL::Helper::ShippedQty->new->calculate($self->order)->write_to(\@{$self->order->items});
|
||
}
|
||
|
||
if ($self->order->number && $::instance_conf->get_webdav) {
|
||
my $webdav = SL::Webdav->new(
|
||
type => $self->type,
|
||
... | ... | |
sub setup_edit_action_bar {
|
||
my ($self, %params) = @_;
|
||
|
||
my $deletion_allowed = (any { $self->type eq $_ } (sales_quotation_type(), request_quotation_type()))
|
||
|| (($self->type eq sales_order_type()) && $::instance_conf->get_sales_order_show_delete)
|
||
|| (($self->type eq purchase_order_type()) && $::instance_conf->get_purchase_order_show_delete);
|
||
my $deletion_allowed = $self->type_data->show_menu("delete");
|
||
|
||
for my $bar ($::request->layout->get('actionbar')) {
|
||
$bar->add(
|
||
... | ... | |
action => [
|
||
t8('Save and Quotation'),
|
||
submit => [ '#order_form', { action => "DeliveryOrder/sales_quotation" } ],
|
||
only_if => (any { $self->type eq $_ } (sales_order_type())),
|
||
only_if => $self->type_data->show_menu("save_and_quotation"),
|
||
],
|
||
action => [
|
||
t8('Save and RFQ'),
|
||
submit => [ '#order_form', { action => "DeliveryOrder/request_for_quotation" } ],
|
||
only_if => (any { $self->type eq $_ } (purchase_order_type())),
|
||
only_if => $self->type_data->show_menu("save_and_rfq"),
|
||
],
|
||
action => [
|
||
t8('Save and Sales Order'),
|
||
submit => [ '#order_form', { action => "DeliveryOrder/sales_order" } ],
|
||
only_if => (any { $self->type eq $_ } (sales_quotation_type(), purchase_order_type())),
|
||
only_if => $self->type_data->show_menu("save_and_sales_order"),
|
||
],
|
||
action => [
|
||
t8('Save and Purchase Order'),
|
||
call => [ 'kivi.Order.purchase_order_check_for_direct_delivery' ],
|
||
only_if => (any { $self->type eq $_ } (sales_order_type(), request_quotation_type())),
|
||
only_if => $self->type_data->show_menu("save_and_purchase_order"),
|
||
],
|
||
action => [
|
||
t8('Save and Delivery Order'),
|
||
call => [ 'kivi.Order.save', 'save_and_delivery_order', $::instance_conf->get_order_warn_duplicate_parts,
|
||
$::instance_conf->get_order_warn_no_deliverydate,
|
||
],
|
||
only_if => (any { $self->type eq $_ } (sales_order_type(), purchase_order_type()))
|
||
only_if => $self->type_data->show_menu("save_and_delivery_order"),
|
||
],
|
||
action => [
|
||
t8('Save and Invoice'),
|
||
... | ... | |
action => [
|
||
t8('Save and AP Transaction'),
|
||
call => [ 'kivi.Order.save', 'save_and_ap_transaction', $::instance_conf->get_order_warn_duplicate_parts ],
|
||
only_if => (any { $self->type eq $_ } (purchase_order_type()))
|
||
only_if => $self->type_data->show_menu("save_and_ap_transaction"),
|
||
],
|
||
|
||
], # end of combobox "Workflow"
|
||
... | ... | |
call => [ 'kivi.Order.delete_order' ],
|
||
confirm => $::locale->text('Do you really want to delete this object?'),
|
||
disabled => !$self->order->id ? t8('This object has not been saved yet.') : undef,
|
||
only_if => $deletion_allowed,
|
||
only_if => $self->type_data->show_menu("delete"),
|
||
],
|
||
|
||
combobox => [
|
||
... | ... | |
my ($self, $action) = @_;
|
||
|
||
return '' if none { lc($action)} qw(add edit);
|
||
|
||
# for locales:
|
||
# $::locale->text("Add Sales Order");
|
||
# $::locale->text("Add Purchase Order");
|
||
# $::locale->text("Add Quotation");
|
||
# $::locale->text("Add Request for Quotation");
|
||
# $::locale->text("Edit Sales Order");
|
||
# $::locale->text("Edit Purchase Order");
|
||
# $::locale->text("Edit Quotation");
|
||
# $::locale->text("Edit Request for Quotation");
|
||
|
||
$action = ucfirst(lc($action));
|
||
return $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")
|
||
: '';
|
||
return $self->type_data->text($action);
|
||
}
|
||
|
||
sub get_item_cvpartnumber {
|
||
... | ... | |
return $texts;
|
||
}
|
||
|
||
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 nr_key {
|
||
return $_[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'
|
||
: '';
|
||
return $_[0]->type_data->nr_key;
|
||
}
|
||
|
||
sub save_and_redirect_to {
|
||
... | ... | |
return $self->js->render();
|
||
}
|
||
|
||
my $text = $self->type eq sales_order_type() ? $::locale->text('The order 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')
|
||
: '';
|
||
flash_later('info', $text);
|
||
flash_later('info', $self->type_data->text("saved"));
|
||
|
||
$self->redirect_to(%params, id => $self->order->id);
|
||
}
|
||
... | ... | |
sub save_history {
|
||
my ($self, $addition) = @_;
|
||
|
||
my $number_type = $self->order->type =~ m{order} ? 'ordnumber' : 'quonumber';
|
||
my $number_type = $self->nr_key;
|
||
my $snumbers = $number_type . '_' . $self->order->$number_type;
|
||
|
||
SL::DB::History->new(
|
||
... | ... | |
return @errors;
|
||
}
|
||
|
||
sub init_type_data {
|
||
SL::Controller::DeliveryOrder::TypeData->new($_[0]);
|
||
}
|
||
|
||
sub init_valid_types {
|
||
$_[0]->type_data->valid_types;
|
||
}
|
||
|
||
1;
|
||
|
||
__END__
|
SL/Controller/DeliveryOrder/TypeData.pm | ||
---|---|---|
package SL::Controller::DeliveryOrder::TypeData;
|
||
|
||
use strict;
|
||
use Exporter qw(import);
|
||
use Scalar::Util qw(weaken);
|
||
use SL::Locale::String qw(t8);
|
||
|
||
use constant {
|
||
SALES_ORDER_TYPE => 'sales_order',
|
||
PURCHASE_ORDER_TYPE => 'purchase_order',
|
||
SALES_QUOTATION_TYPE => 'sales_quotation',
|
||
REQUEST_QUOTATION_TYPE => 'request_quotation'
|
||
};
|
||
|
||
our @EXPORT_OK = qw(SALES_ORDER_TYPE PURCHASE_ORDER_TYPE SALES_QUOTATION_TYPE REQUEST_QUOTATION_TYPE);
|
||
|
||
use Rose::Object::MakeMethods::Generic scalar => [ qw(c) ];
|
||
|
||
my %type_data = (
|
||
SALES_ORDER_TYPE() => {
|
||
text => {
|
||
delete => t8('The order has been deleted'),
|
||
saved => t8('The order has been saved'),
|
||
add => t8("Add Sales Order"),
|
||
edit => t8("Edit Sales Order"),
|
||
},
|
||
show_menu => {
|
||
save_and_quotation => 1,
|
||
save_and_rfq => 0,
|
||
save_and_sales_order => 0,
|
||
save_and_purchase_order => 1,
|
||
save_and_delivery_order => 1,
|
||
save_and_ap_transaction => 0,
|
||
delete => sub { $::instance_conf->get_sales_order_show_delete },
|
||
},
|
||
workflow => {
|
||
to_order_type => "purchase_order",
|
||
to_quotation_type => "sales_quotation",
|
||
to_order_copy_shipto => 1,
|
||
},
|
||
properties => {
|
||
customervendor => "customer",
|
||
is_quotation => 0,
|
||
nr_key => "ordnumber",
|
||
},
|
||
part_classification_query => [ "used_for_sale" => 1 ],
|
||
right => "sales_order_edit",
|
||
},
|
||
PURCHASE_ORDER_TYPE() => {
|
||
text =>{
|
||
delete => t8('The order has been deleted'),
|
||
saved => t8('The order has been saved'),
|
||
add => t8("Add Purchase Order"),
|
||
edit => t8("Edit Purchase Order"),
|
||
},
|
||
show_menu => {
|
||
save_and_quotation => 0,
|
||
save_and_rfq => 1,
|
||
save_and_sales_order => 1,
|
||
save_and_purchase_order => 0,
|
||
save_and_delivery_order => 1,
|
||
save_and_ap_transaction => 1,
|
||
delete => sub { $::instance_conf->get_purchase_order_show_delete },
|
||
},
|
||
workflow => {
|
||
to_order_type => "sales_order",
|
||
to_quotation_type => "request_quotation",
|
||
to_order_copy_shipto => 0,
|
||
},
|
||
properties => {
|
||
customervendor => "vendor",
|
||
is_quotation => 0,
|
||
nr_key => "ordnumber",
|
||
},
|
||
part_classification_query => [ "used_for_purchase" => 1 ],
|
||
right => "purchase_order_edit",
|
||
},
|
||
SALES_QUOTATION_TYPE() => {
|
||
text => {
|
||
delete => t8('The quotation has been deleted'),
|
||
saved => t8('The quotation has been saved'),
|
||
add => t8("Add Quotation"),
|
||
edit => t8("Edit Quotation"),
|
||
},
|
||
show_menu => {
|
||
save_and_quotation => 0,
|
||
save_and_rfq => 0,
|
||
save_and_sales_order => 1,
|
||
save_and_purchase_order => 0,
|
||
save_and_delivery_order => 0,
|
||
save_and_ap_transaction => 0,
|
||
delete => 1,
|
||
},
|
||
workflow => {
|
||
to_order_type => "sales_order",
|
||
to_quotation_type => "request_quotation",
|
||
to_order_copy_shipto => 0,
|
||
},
|
||
properties => {
|
||
customervendor => "customer",
|
||
is_quotation => 1,
|
||
nr_key => "quonumber",
|
||
},
|
||
part_classification_query => [ "used_for_sale" => 1 ],
|
||
right => "sales_quotation_edit",
|
||
},
|
||
REQUEST_QUOTATION_TYPE() => {
|
||
text => {
|
||
delete => t8('The rfq has been deleted'),
|
||
saved => t8('The rfq has been saved'),
|
||
add => t8("Add Request for Quotation"),
|
||
edit => t8("Edit Request for Quotation"),
|
||
},
|
||
show_menu => {
|
||
save_and_quotation => 0,
|
||
save_and_rfq => 0,
|
||
save_and_sales_order => 0,
|
||
save_and_purchase_order => 1,
|
||
save_and_delivery_order => 0,
|
||
save_and_ap_transaction => 0,
|
||
delete => 1,
|
||
},
|
||
workflow => {
|
||
to_order_type => "purchase_order",
|
||
to_quotation_type => "request_quotation",
|
||
to_order_copy_shipto => 0,
|
||
},
|
||
properties => {
|
||
customervendor => "vendor",
|
||
is_quotation => 1,
|
||
nr_key => "quonumber",
|
||
},
|
||
part_classification_query => [ "used_for_purchase" => 1 ],
|
||
right => "request_quotation_edit",
|
||
},
|
||
);
|
||
|
||
sub new {
|
||
my ($class, $controller) = @_;
|
||
my $o = bless {}, $class;
|
||
$o->c($controller);
|
||
weaken($o->{c});
|
||
|
||
return $o;
|
||
}
|
||
|
||
sub valid_types {
|
||
[
|
||
SALES_ORDER_TYPE,
|
||
PURCHASE_ORDER_TYPE,
|
||
SALES_QUOTATION_TYPE,
|
||
REQUEST_QUOTATION_TYPE,
|
||
];
|
||
}
|
||
|
||
sub type {
|
||
$_[0]->c->type;
|
||
}
|
||
|
||
sub get {
|
||
my ($self, $key) = @_;
|
||
|
||
my $ret = $type_data{$self->type}->{$key} // die "unknown property '$key'";
|
||
|
||
ref $ret eq 'CODE'
|
||
? $ret->()
|
||
: $ret;
|
||
}
|
||
|
||
sub _get3 {
|
||
my ($self, $topic, $key) = @_;
|
||
|
||
my $ret = $type_data{$self->type}->{$topic}->{$key} // die "unknown property '$key' in topic '$topic'";
|
||
|
||
ref $ret eq 'CODE'
|
||
? $ret->()
|
||
: $ret;
|
||
}
|
||
|
||
sub text {
|
||
my ($self, $string) = @_;
|
||
_get3($self, "text", $string);
|
||
}
|
||
|
||
sub show_menu {
|
||
my ($self, $string) = @_;
|
||
_get3($self, "show_menu", $string);
|
||
}
|
||
|
||
sub workflow {
|
||
my ($self, $string) = @_;
|
||
_get3($self, "workflow", $string);
|
||
}
|
||
|
||
sub properties {
|
||
my ($self, $string) = @_;
|
||
_get3($self, "properties", $string);
|
||
}
|
||
|
||
sub is_valid_type {
|
||
!!exists $type_data{$_[1]};
|
||
}
|
||
|
||
sub type_data {
|
||
$type_data{ $_[0]->type } // die "unknown type";
|
||
}
|
||
|
||
sub access {
|
||
$type_data{right};
|
||
}
|
||
|
||
sub is_quotation {
|
||
_get3($_[0], "properties", "is_quotation");
|
||
}
|
||
|
||
sub customervendor {
|
||
_get3($_[0], "properties", "customervendor");
|
||
}
|
||
|
||
sub nr_key {
|
||
_get3($_[0], "properties", "nr_key");
|
||
}
|
||
|
||
sub part_classification_query {
|
||
my ($self, $string) = @_;
|
||
_get($self, "part_classification_query");
|
||
}
|
||
|
||
sub set_reqdate_by_type {
|
||
my ($self) = @_;
|
||
|
||
my $extra_days = $self->type eq SALES_QUOTATION_TYPE ? $::instance_conf->get_reqdate_interval :
|
||
$self->type eq SALES_ORDER_TYPE ? $::instance_conf->get_delivery_date_interval : 1;
|
||
|
||
if ( ($self->type eq SALES_ORDER_TYPE && $::instance_conf->get_deliverydate_on)
|
||
|| ($self->type eq SALES_QUOTATION_TYPE && $::instance_conf->get_reqdate_on)
|
||
&& (!$self->order->reqdate)) {
|
||
$self->c->order->reqdate(DateTime->today_local->next_workday(extra_days => $extra_days));
|
||
}
|
||
}
|
||
|
||
sub get_reqdate_by_type {
|
||
my ($self, $reqdate, $saved_reqdate) = @_;
|
||
|
||
if ($reqdate == $saved_reqdate) {
|
||
my $extra_days = $self->type eq SALES_QUOTATION_TYPE ? $::instance_conf->get_reqdate_interval :
|
||
$self->type eq SALES_ORDER_TYPE ? $::instance_conf->get_delivery_date_interval : 1;
|
||
|
||
if ( ($self->type eq SALES_ORDER_TYPE && !$::instance_conf->get_deliverydate_on)
|
||
|| ($self->type eq SALES_QUOTATION_TYPE && !$::instance_conf->get_reqdate_on)) {
|
||
return '';
|
||
} else {
|
||
return DateTime->today_local->next_workday(extra_days => $extra_days);
|
||
}
|
||
} else {
|
||
return $reqdate;
|
||
}
|
||
}
|
Auch abrufbar als: Unified diff
DeliveryOrder: type data zentralisiert um das verhalten besser generalisieren zu können