17 |
17 |
use SL::DB::Part;
|
18 |
18 |
use SL::DB::Printer;
|
19 |
19 |
use SL::DB::Language;
|
|
20 |
use SL::DB::RecordLink;
|
20 |
21 |
|
21 |
22 |
use SL::Helper::CreatePDF qw(:all);
|
22 |
23 |
use SL::Helper::PrintOptions;
|
... | ... | |
60 |
61 |
$self->_pre_render();
|
61 |
62 |
$self->render(
|
62 |
63 |
'order/form',
|
63 |
|
title => $self->type eq _sales_order_type() ? $::locale->text('Add Sales Order')
|
64 |
|
: $self->type eq _purchase_order_type() ? $::locale->text('Add Purchase Order')
|
65 |
|
: $self->type eq _sales_quotation_type() ? $::locale->text('Add Quotation')
|
66 |
|
: $self->type eq _request_quotation_type() ? $::locale->text('Add Request for Quotation')
|
67 |
|
: '',
|
|
64 |
title => $self->_get_title_for('add'),
|
68 |
65 |
%{$self->{template_args}}
|
69 |
66 |
);
|
70 |
67 |
}
|
... | ... | |
78 |
75 |
$self->_pre_render();
|
79 |
76 |
$self->render(
|
80 |
77 |
'order/form',
|
81 |
|
title => $self->type eq _sales_order_type() ? $::locale->text('Edit Sales Order')
|
82 |
|
: $self->type eq _purchase_order_type() ? $::locale->text('Edit Purchase Order')
|
83 |
|
: $self->type eq _sales_quotation_type() ? $::locale->text('Edit Quotation')
|
84 |
|
: $self->type eq _request_quotation_type() ? $::locale->text('Edit Request for Quotation')
|
85 |
|
: '',
|
|
78 |
title => $self->_get_title_for('edit'),
|
86 |
79 |
%{$self->{template_args}}
|
87 |
80 |
);
|
88 |
81 |
}
|
... | ... | |
519 |
512 |
$self->redirect_to(@redirect_params);
|
520 |
513 |
}
|
521 |
514 |
|
|
515 |
# workflow from sales quotation to sales order
|
|
516 |
sub action_sales_order {
|
|
517 |
$_[0]->_workflow_sales_or_purchase_order();
|
|
518 |
}
|
|
519 |
|
|
520 |
# workflow from rfq to purchase order
|
|
521 |
sub action_purchase_order {
|
|
522 |
$_[0]->_workflow_sales_or_purchase_order();
|
|
523 |
}
|
|
524 |
|
522 |
525 |
# set form elements in respect to a changed customer or vendor
|
523 |
526 |
#
|
524 |
527 |
# This action is called on an change of the customer/vendor picker.
|
... | ... | |
1087 |
1090 |
$item ||= SL::DB::OrderItem->new(custom_variables => []);
|
1088 |
1091 |
|
1089 |
1092 |
$item->assign_attributes(%$attr);
|
1090 |
|
$item->longdescription($item->part->notes) if $is_new && !defined $attr->{longdescription};
|
1091 |
|
$item->project_id($record->globalproject_id) if $is_new && !defined $attr->{project_id};
|
1092 |
|
$item->lastcost($item->part->lastcost) if $is_new && !defined $attr->{lastcost_as_number};
|
|
1093 |
$item->longdescription($item->part->notes) if $is_new && !defined $attr->{longdescription};
|
|
1094 |
$item->project_id($record->globalproject_id) if $is_new && !defined $attr->{project_id};
|
|
1095 |
$item->lastcost($record->is_sales ? $item->part->lastcost : 0) if $is_new && !defined $attr->{lastcost_as_number};
|
1093 |
1096 |
|
1094 |
1097 |
return $item;
|
1095 |
1098 |
}
|
... | ... | |
1145 |
1148 |
$new_attr{active_discount_source} = $discount_src;
|
1146 |
1149 |
$new_attr{longdescription} = $part->notes if ! defined $attr->{longdescription};
|
1147 |
1150 |
$new_attr{project_id} = $record->globalproject_id;
|
1148 |
|
$new_attr{lastcost} = $part->lastcost;
|
|
1151 |
$new_attr{lastcost} = $record->is_sales ? $part->lastcost : 0;
|
1149 |
1152 |
|
1150 |
1153 |
# add_custom_variables adds cvars to an orderitem with no cvars for saving, but
|
1151 |
1154 |
# they cannot be retrieved via custom_variables until the order/orderitem is
|
... | ... | |
1230 |
1233 |
$db->with_transaction(sub {
|
1231 |
1234 |
SL::DB::OrderItem->new(id => $_)->delete for @{$self->item_ids_to_delete};
|
1232 |
1235 |
$self->order->save(cascade => 1);
|
|
1236 |
|
|
1237 |
# link records
|
|
1238 |
if ($::form->{converted_from_oe_id}) {
|
|
1239 |
SL::DB::Order->new(id => $::form->{converted_from_oe_id})->load->link_to_record($self->order);
|
|
1240 |
|
|
1241 |
if (scalar @{ $::form->{converted_from_orderitems_ids} || [] }) {
|
|
1242 |
my $idx = 0;
|
|
1243 |
foreach (@{ $self->order->items_sorted }) {
|
|
1244 |
my $from_id = $::form->{converted_from_orderitems_ids}->[$idx];
|
|
1245 |
next if !$from_id;
|
|
1246 |
SL::DB::RecordLink->new(from_table => 'orderitems',
|
|
1247 |
from_id => $from_id,
|
|
1248 |
to_table => 'orderitems',
|
|
1249 |
to_id => $_->id
|
|
1250 |
)->save;
|
|
1251 |
$idx++;
|
|
1252 |
}
|
|
1253 |
}
|
|
1254 |
}
|
|
1255 |
1;
|
1233 |
1256 |
}) || push(@{$errors}, $db->error);
|
1234 |
1257 |
|
1235 |
1258 |
return $errors;
|
1236 |
1259 |
}
|
1237 |
1260 |
|
|
1261 |
sub _workflow_sales_or_purchase_order {
|
|
1262 |
my ($self) = @_;
|
|
1263 |
|
|
1264 |
my $destination_type = $::form->{type} eq _sales_quotation_type() ? _sales_order_type()
|
|
1265 |
: $::form->{type} eq _request_quotation_type() ? _purchase_order_type()
|
|
1266 |
: '';
|
|
1267 |
|
|
1268 |
$self->order(SL::DB::Order->new_from($self->order, destination_type => $destination_type));
|
|
1269 |
$self->{converted_from_oe_id} = delete $::form->{id};
|
|
1270 |
|
|
1271 |
# change form type
|
|
1272 |
$::form->{type} = $destination_type;
|
|
1273 |
$self->init_type;
|
|
1274 |
$self->_check_auth;
|
|
1275 |
|
|
1276 |
$self->_recalc();
|
|
1277 |
$self->_get_unalterable_data();
|
|
1278 |
$self->_pre_render();
|
|
1279 |
|
|
1280 |
# trigger rendering values for second row/longdescription as hidden,
|
|
1281 |
# because they are loaded only on demand. So we need to keep the values
|
|
1282 |
# from the source.
|
|
1283 |
$_->{render_second_row} = 1 for @{ $self->order->items_sorted };
|
|
1284 |
$_->{render_longdescription} = 1 for @{ $self->order->items_sorted };
|
|
1285 |
|
|
1286 |
$self->render(
|
|
1287 |
'order/form',
|
|
1288 |
title => $self->_get_title_for('edit'),
|
|
1289 |
%{$self->{template_args}}
|
|
1290 |
);
|
|
1291 |
}
|
|
1292 |
|
1238 |
1293 |
|
1239 |
1294 |
sub _pre_render {
|
1240 |
1295 |
my ($self) = @_;
|
... | ... | |
1319 |
1374 |
call => [ 'kivi.Order.save_and_invoice', $::instance_conf->get_order_warn_duplicate_parts ],
|
1320 |
1375 |
checks => [ 'kivi.Order.check_save_active_periodic_invoices' ],
|
1321 |
1376 |
],
|
1322 |
|
|
1323 |
1377 |
], # end of combobox "Save"
|
1324 |
1378 |
|
|
1379 |
combobox => [
|
|
1380 |
action => [
|
|
1381 |
t8('Workflow'),
|
|
1382 |
],
|
|
1383 |
action => [
|
|
1384 |
t8('Sales Order'),
|
|
1385 |
submit => [ '#order_form', { action => "Order/sales_order" } ],
|
|
1386 |
only_if => (any { $self->type eq $_ } (_sales_quotation_type())),
|
|
1387 |
],
|
|
1388 |
action => [
|
|
1389 |
t8('Purchase Order'),
|
|
1390 |
submit => [ '#order_form', { action => "Order/purchase_order" } ],
|
|
1391 |
only_if => (any { $self->type eq $_ } (_request_quotation_type())),
|
|
1392 |
],
|
|
1393 |
], # end of combobox "Workflow"
|
|
1394 |
|
1325 |
1395 |
combobox => [
|
1326 |
1396 |
action => [
|
1327 |
1397 |
t8('Export'),
|
... | ... | |
1458 |
1528 |
return $active ? t8('active') : t8('inactive');
|
1459 |
1529 |
}
|
1460 |
1530 |
|
|
1531 |
sub _get_title_for {
|
|
1532 |
my ($self, $action) = @_;
|
|
1533 |
|
|
1534 |
return '' if none { lc($action)} qw(add edit);
|
|
1535 |
|
|
1536 |
# for locales:
|
|
1537 |
# $::locale->text("Add Sales Order");
|
|
1538 |
# $::locale->text("Add Purchase Order");
|
|
1539 |
# $::locale->text("Add Quotation");
|
|
1540 |
# $::locale->text("Add Request for Quotation");
|
|
1541 |
# $::locale->text("Edit Sales Order");
|
|
1542 |
# $::locale->text("Edit Purchase Order");
|
|
1543 |
# $::locale->text("Edit Quotation");
|
|
1544 |
# $::locale->text("Edit Request for Quotation");
|
|
1545 |
|
|
1546 |
$action = ucfirst(lc($action));
|
|
1547 |
return $self->type eq _sales_order_type() ? $::locale->text("$action Sales Order")
|
|
1548 |
: $self->type eq _purchase_order_type() ? $::locale->text("$action Purchase Order")
|
|
1549 |
: $self->type eq _sales_quotation_type() ? $::locale->text("$action Quotation")
|
|
1550 |
: $self->type eq _request_quotation_type() ? $::locale->text("$action Request for Quotation")
|
|
1551 |
: '';
|
|
1552 |
}
|
|
1553 |
|
1461 |
1554 |
sub _sales_order_type {
|
1462 |
1555 |
'sales_order';
|
1463 |
1556 |
}
|
Auftrags-Controller: Workflow von Angebot nach Auftrag (Ein- und Verkauf).