if (-f "bin/mozilla/custom_io.pl") {
eval { require "bin/mozilla/custom_io.pl"; };
}
-if (-f "bin/mozilla/$::form->{login}_io.pl") {
- eval { require "bin/mozilla/$::form->{login}_io.pl"; };
+if (-f "bin/mozilla/$::myconfig{login}_io.pl") {
+ eval { require "bin/mozilla/$::myconfig{login}_io.pl"; };
}
1;
my $is_purchase = (first { $_ eq $form->{type} } qw(request_quotation purchase_order purchase_delivery_order)) || ($form->{script} eq 'ir.pl');
my $show_min_order_qty = first { $_ eq $form->{type} } qw(request_quotation purchase_order);
my $is_delivery_order = $form->{type} =~ /_delivery_order$/;
+ my $is_quotation = $form->{type} =~ /_quotation$/;
+ my $is_invoice = $form->{type} =~ /invoice/;
my $is_s_p_order = (first { $_ eq $form->{type} } qw(sales_order purchase_order));
+ my $show_ship_missing = $is_s_p_order && $::instance_conf->get_sales_purchase_order_ship_missing_column;
if ($is_delivery_order) {
if ($form->{type} eq 'sales_delivery_order') {
{ id => 'partnumber', width => 8, value => $locale->text('Number'), display => 1, },
{ id => 'description', width => 30, value => $locale->text('Part Description'), display => 1, },
{ id => 'ship', width => 5, value => $locale->text('Delivered'), display => $is_s_p_order, },
+ { id => 'ship_missing', width => 5, value => $locale->text('Not delivered'), display => $show_ship_missing, },
{ id => 'qty', width => 5, value => $locale->text('Qty'), display => 1, },
{ id => 'price_factor', width => 5, value => $locale->text('Price Factor'), display => !$is_delivery_order, },
{ id => 'unit', width => 5, value => $locale->text('Unit'), display => 1, },
my $deliverydate = $locale->text('Required by');
# special alignings
- my %align = map { $_ => 'right' } qw(qty ship right discount linetotal stock_in_out weight);
+ my %align = map { $_ => 'right' } qw(qty ship right discount linetotal stock_in_out weight ship_missing);
my %nowrap = map { $_ => 1 } qw(description unit);
$form->{marge_total} = 0;
$ship_qty /= ( $all_units->{$form->{"unit_$i"}}->{factor} || 1 );
$column_data{ship} = $form->format_amount(\%myconfig, $form->round_amount($ship_qty, 2) * 1) . ' ' . $form->{"unit_$i"};
+
+ my $ship_missing_qty = $form->{"qty_$i"} - $ship_qty;
+ my $ship_missing_amount = $form->round_amount($ship_missing_qty * $form->{"sellprice_$i"} * (100 - $form->{"discount_$i"}) / 100 / $price_factor, 2);
+
+ $column_data{ship_missing} = $form->format_amount(\%myconfig, $ship_missing_qty) . ' ' . $form->{"unit_$i"} . '; ' . $form->format_amount(\%myconfig, $ship_missing_amount, $decimalplaces);
}
my $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
# / calculate onhand
my @hidden_vars;
-
- if ($is_delivery_order) {
+ # add hidden ids for persistent (item|invoice)_ids and previous (converted_from*) ids
+ if ($is_quotation) {
+ push @hidden_vars, qw(orderitems_id converted_from_orderitems_id);
+ }
+ if ($is_s_p_order) {
+ push @hidden_vars, qw(orderitems_id converted_from_orderitems_id converted_from_invoice_id);
+ }
+ if ($is_invoice) {
+ push @hidden_vars, qw(invoice_id converted_from_orderitems_id converted_from_delivery_order_items_id converted_from_invoice_id);
+ }
+ if ($::form->{type} =~ /credit_note/) {
+ push @hidden_vars, qw(invoice_id converted_from_invoice_id);
+ }
+ if ($is_delivery_order) {
map { $form->{"${_}_${i}"} = $form->format_amount(\%myconfig, $form->{"${_}_${i}"}) } qw(sellprice discount lastcost);
push @hidden_vars, grep { defined $form->{"${_}_${i}"} } qw(sellprice discount not_discountable price_factor_id lastcost);
push @hidden_vars, "stock_${stock_in_out}_sum_qty", "stock_${stock_in_out}";
- push @hidden_vars, qw(delivery_order_items_id);
+ push @hidden_vars, qw(delivery_order_items_id converted_from_orderitems_id converted_from_delivery_order_items_id);
}
my @HIDDENS = map { value => $_}, (
$cgi->hidden("-name" => "unit_old_$i", "-value" => $form->{"selected_unit_$i"}),
$cgi->hidden("-name" => "price_new_$i", "-value" => $form->format_amount(\%myconfig, $form->{"price_new_$i"})),
map { ($cgi->hidden("-name" => $_, "-id" => $_, "-value" => $form->{$_})); } map { $_."_$i" }
- (qw(orderitems_id bo price_old id inventory_accno bin partsgroup partnotes active_price_source active_discount_source
+ (qw(bo price_old id inventory_accno bin partsgroup partnotes active_price_source active_discount_source
income_accno expense_accno listprice assembly taxaccounts ordnumber donumber transdate cusordnumber
longdescription basefactor marge_absolut marge_percent marge_price_factor weight), @hidden_vars)
);
print $::form->parse_html_template('io/select_item', { PREVIOUS_FORM => $previous_form,
MODE => $mode,
ITEM_LIST => \@item_list,
+ IS_ASSEMBLY => $mode eq 'IC',
IS_PURCHASE => $mode eq 'IS' });
$main::lxdebug->leave_sub();
}
sub item_selected {
+
+ # this function is used for adding parts to records (mode = IR/IS)
+ # and to assemblies (mode = IC)
+
$main::lxdebug->enter_sub();
my $form = $main::form;
my $id = delete($form->{select_item_id}) || croak 'Missing item selection ID';
my $i = $form->{ $mode eq 'IC' ? 'assembly_rows' : 'rowcount' };
+ if ( $mode eq 'IC' ) {
+ # assembly mode:
+ # the qty variables of the existing assembly items are all still formatted, so we parse them here (1 .. $i-1)
+ # including the qty of the just added part ($i)
+ $form->{"qty_$_"} = $form->parse_amount(\%myconfig, $form->{"qty_$_"}) for (1 .. $i);
+ };
+
$form->{"id_${i}"} = $id;
if ($mode eq 'IS') {
my $new_item = $form->{item_list}->[0] || croak "No item found for mode '${mode}' and ID '${id}'";
# if there was a price entered, override it
- my $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
+ my $sellprice;
+ unless ( $mode eq 'IC' ) {
+ $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
+ };
my @new_fields =
qw(id partnumber description sellprice listprice inventory_accno
map { $form->{"${_}_$i"} = $new_item->{$_} } @new_fields;
- my $record = _make_record();
- my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record);
- my $best_price = $price_source->best_price;
+ if (my $record = _make_record()) {
+ my $price_source = SL::PriceSource->new(record_item => $record->items->[$i-1], record => $record);
+ my $best_price = $price_source->best_price;
- if ($best_price) {
- $::form->{"sellprice_$i"} = $best_price->price;
- $::form->{"active_price_source_$i"} = $best_price->source;
- }
+ if ($best_price) {
+ $::form->{"sellprice_$i"} = $best_price->price;
+ $::form->{"active_price_source_$i"} = $best_price->source;
+ }
- my $best_discount = $price_source->best_discount;
+ my $best_discount = $price_source->best_discount;
- if ($best_discount) {
- $::form->{"discount_$i"} = $best_discount->discount;
- $::form->{"active_discount_source_$i"} = $best_discount->source;
+ if ($best_discount) {
+ $::form->{"discount_$i"} = $best_discount->discount;
+ $::form->{"active_discount_source_$i"} = $best_discount->source;
+ }
}
-
$form->{"marge_price_factor_$i"} = $new_item->{price_factor};
if ($form->{"part_payment_id_$i"} ne "") {
map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
qw(sellprice listprice weight);
+ # at this stage qty of newly added part needs to be have been parsed
$form->{weight} += ($form->{"weight_$i"} * $form->{"qty_$i"});
if ($form->{"not_discountable_$i"}) {
transdate longdescription basefactor marge_total marge_percent
marge_price_factor lastcost price_factor_id partnotes
stock_out stock_in has_sernumber reqdate orderitems_id
- active_price_source active_discount_source delivery_order_items_id);
+ active_price_source active_discount_source delivery_order_items_id
+ invoice_id converted_from_orderitems_id
+ converted_from_delivery_order_items_id converted_from_invoice_id);
my $ic_cvar_configs = CVar->get_configs(module => 'IC');
push @flds, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
$form->{old_employee_id} = $form->{employee_id};
$form->{old_salesman_id} = $form->{salesman_id};
- map { delete $form->{$_} } qw(id printed emailed queued);
+ # link doc invoice -> quotation (single id no multi mode)
+ $form->{convert_from_ar_ids} = delete $form->{id};
+
+ delete $form->{$_} foreach (qw(printed emailed queued));
my $buysell;
if ($form->{script} eq 'ir.pl' || $form->{type} eq 'request_quotation') {
$form->{title} = $locale->text('Add Purchase Order');
map({ $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"})
if ($form->{"${_}_${i}"}) }
qw(ship qty sellprice listprice basefactor discount));
+ $form->{"converted_from_invoice_id_$i"} = delete $form->{"invoice_id_$i"};
}
&prepare_order;
# we are coming from *_order and convert to quotation
# it seems that quotation is only called if we have a existing order
if ($form->{type} =~ /(sales|purchase)_order/) {
- delete $form->{"orderitems_id_$_"} for 1 .. $form->{"rowcount"};
+ $form->{"converted_from_orderitems_id_$_"} = delete $form->{"orderitems_id_$_"} for 1 .. $form->{"rowcount"};
}
+ # link doc order -> quotation (single id no multi mode)
+ $form->{convert_from_oe_ids} = delete $form->{id};
+
if ($form->{second_run}) {
$form->{print_and_post} = 0;
}
- map { delete $form->{$_} } qw(id printed emailed queued);
+ delete $form->{$_} foreach (qw(printed emailed queued));
my $buysell;
if ($form->{script} eq 'ir.pl' || $form->{type} eq 'purchase_order') {
$form->{TEMPLATE_DRIVER_OPTIONS}->{variable_content_types} = {
longdescription => 'html',
partnotes => 'html',
+ notes => 'html',
};
}
my $class = {
sales_order => 'OrderItem',
- purchase_oder => 'OrderItem',
+ purchase_order => 'OrderItem',
sales_quotation => 'OrderItem',
request_quotation => 'OrderItem',
invoice => 'InvoiceItem',
+ credit_note => 'InvoiceItem',
purchase_invoice => 'InvoiceItem',
purchase_delivery_order => 'DeliveryOrderItem',
sales_delivery_order => 'DeliveryOrderItem',
my @items;
for my $i (1 .. $::form->{rowcount}) {
next unless $::form->{"id_$i"};
- push @items, _make_record_item($i)
+ push @items, _make_record_item($i);
}
$obj->items(@items) if @items;
return $obj;
}
-