Projekt

Allgemein

Profil

Herunterladen (79,7 KB) Statistiken
| Zweig: | Markierung: | Revision:
f404e525 Sven Schöling
#=====================================================================
d707f7ac Moritz Bunkus
# LX-Office ERP
# Copyright (C) 2004
# Based on SQL-Ledger Version 2.1.9
# Web http://www.lx-office.org
#
#=====================================================================
# SQL-Ledger, Accounting
# Copyright (c) 1998-2003
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
f7b15d43 Christian Wittmer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1335, USA.
d707f7ac Moritz Bunkus
#======================================================================
#
# Delivery orders
#======================================================================

c9e68ea2 Moritz Bunkus
use Carp;
41adf433 Moritz Bunkus
use List::MoreUtils qw(uniq);
d707f7ac Moritz Bunkus
use List::Util qw(max sum);
use POSIX qw(strftime);

092d3110 Sven Schöling
use SL::Controller::DeliveryOrder;
088bf5a0 Moritz Bunkus
use SL::DB::DeliveryOrder;
e0bac67f Bernd Bleßmann
use SL::DB::DeliveryOrderItem;
092d3110 Sven Schöling
use SL::DB::DeliveryOrder::TypeData qw(:types validate_type);
5937dc5a Moritz Bunkus
use SL::DB::ValidityToken;
94f5cb15 Bernd Bleßmann
use SL::Helper::UserPreferences::DisplayPreferences;
d707f7ac Moritz Bunkus
use SL::DO;
use SL::IR;
use SL::IS;
87949627 Sven Schöling
use SL::MoreCommon qw(ary_diff restore_form save_form);
e0bac67f Bernd Bleßmann
use SL::Presenter::ItemsList;
d707f7ac Moritz Bunkus
use SL::ReportGenerator;
use SL::WH;
65b2387a Moritz Bunkus
use SL::YAML;
fc762fdc Jan Büren
use Sort::Naturally ();
d707f7ac Moritz Bunkus
require "bin/mozilla/common.pl";
require "bin/mozilla/io.pl";
require "bin/mozilla/reportgenerator.pl";

f404e525 Sven Schöling
use strict;

d707f7ac Moritz Bunkus
1;

# end of main

2e19657a Bernd Bleßmann
sub check_do_access_for_edit {
validate_type($::form->{type});

my $right = SL::DB::DeliveryOrder::TypeData::get3($::form->{type}, "rights", "edit");
$main::auth->assert($right);
}

d707f7ac Moritz Bunkus
sub check_do_access {
092d3110 Sven Schöling
validate_type($::form->{type});

2e19657a Bernd Bleßmann
my $right = SL::DB::DeliveryOrder::TypeData::get3($::form->{type}, "rights", "view");
092d3110 Sven Schöling
$main::auth->assert($right);
d707f7ac Moritz Bunkus
}

sub set_headings {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

my ($action) = @_;

f404e525 Sven Schöling
my $form = $main::form;
my $locale = $main::locale;

d707f7ac Moritz Bunkus
if ($form->{type} eq 'purchase_delivery_order') {
$form->{vc} = 'vendor';
$form->{title} = $action eq "edit" ? $locale->text('Edit Purchase Delivery Order') : $locale->text('Add Purchase Delivery Order');
} else {
$form->{vc} = 'customer';
$form->{title} = $action eq "edit" ? $locale->text('Edit Sales Delivery Order') : $locale->text('Add Sales Delivery Order');
}

$form->{heading} = $locale->text('Delivery Order');

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub add {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
2e19657a Bernd Bleßmann
check_do_access_for_edit();
d707f7ac Moritz Bunkus
f775b88a Moritz Bunkus
if (($::form->{type} =~ /purchase/) && !$::instance_conf->get_allow_new_purchase_invoice) {
$::form->show_generic_error($::locale->text("You do not have the permissions to access this function."));
}

f404e525 Sven Schöling
my $form = $main::form;

d707f7ac Moritz Bunkus
set_headings("add");

519f43a2 Moritz Bunkus
$form->{show_details} = $::myconfig{show_form_details};
d707f7ac Moritz Bunkus
$form->{callback} = build_std_url('action=add', 'type', 'vc') unless ($form->{callback});

a03e4841 Bernd Bleßmann
if (!$form->{form_validity_token}) {
$form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_DELIVERY_ORDER_SAVE())->token;
}

844a541e Moritz Bunkus
order_links(is_new => 1);
d707f7ac Moritz Bunkus
prepare_order();
display_form();

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

9b5b900b Tamino Steinert
sub add_from_reclamation {

require SL::DB::Reclamation;
my $reclamation = SL::DB::Reclamation->new(id => $::form->{from_id})->load;
my ($delivery_order, $error) = $reclamation->convert_to_delivery_order();
if($error) {
croak("Error while converting: " . $error);
}

# edit new saved delivery order
$::form->{id} = $delivery_order->id;
edit();
}

d707f7ac Moritz Bunkus
sub edit {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

f404e525 Sven Schöling
my $form = $main::form;

519f43a2 Moritz Bunkus
$form->{show_details} = $::myconfig{show_form_details};

d707f7ac Moritz Bunkus
# show history button
$form->{javascript} = qq|<script type="text/javascript" src="js/show_history.js"></script>|;
#/show hhistory button

$form->{simple_save} = 0;

set_headings("edit");

# editing without stuff to edit? try adding it first
if ($form->{rowcount} && !$form->{print_and_save}) {
# map { $id++ if $form->{"multi_id_$_"} } (1 .. $form->{rowcount});
# if (!$id) {

# reset rowcount
undef $form->{rowcount};
add();
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
return;
# }
} elsif (!$form->{id}) {
add();
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
return;
}

f404e525 Sven Schöling
my ($language_id, $printer_id);
d707f7ac Moritz Bunkus
if ($form->{print_and_save}) {
05691f2a Sven Schöling
$form->{action} = "dispatcher";
$form->{action_print} = "1";
d707f7ac Moritz Bunkus
$form->{resubmit} = 1;
$language_id = $form->{language_id};
$printer_id = $form->{printer_id};
}

set_headings("edit");

order_links();
prepare_order();

if ($form->{print_and_save}) {
$form->{language_id} = $language_id;
$form->{printer_id} = $printer_id;
}

display_form();

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub order_links {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

844a541e Moritz Bunkus
my %params = @_;
f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;

d707f7ac Moritz Bunkus
# retrieve order/quotation
my $editing = $form->{id};

454df69e Moritz Bunkus
DO->retrieve('vc' => $form->{vc},
'ids' => $form->{id});
d707f7ac Moritz Bunkus
03d3d025 Bernd Bleßmann
$form->backup_vars(qw(payment_id language_id taxzone_id salesman_id taxincluded cp_id intnotes delivery_term_id currency));
d707f7ac Moritz Bunkus
7fb467cc Moritz Bunkus
# get customer / vendor
if ($form->{vc} eq 'vendor') {
IR->get_vendor(\%myconfig, \%$form);
f3ea7204 Bernd Bleßmann
$form->{discount} = $form->{vendor_discount};
7fb467cc Moritz Bunkus
} else {
IS->get_customer(\%myconfig, \%$form);
2b88ba77 Jan Büren
$form->{discount} = $form->{customer_discount};
844a541e Moritz Bunkus
$form->{billing_address_id} = $form->{default_billing_address_id} if $params{is_new};
7fb467cc Moritz Bunkus
}
d707f7ac Moritz Bunkus
03d3d025 Bernd Bleßmann
$form->restore_vars(qw(payment_id language_id taxzone_id intnotes cp_id delivery_term_id));
81c95198 Bernd Bleßmann
$form->restore_vars(qw(currency)) if ($form->{id} || $form->{convert_from_oe_ids});
7fb467cc Moritz Bunkus
$form->restore_vars(qw(taxincluded)) if $form->{id};
$form->restore_vars(qw(salesman_id)) if $editing;
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub prepare_order {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;

d707f7ac Moritz Bunkus
$form->{formname} = $form->{type} unless $form->{formname};

my $i = 0;
f404e525 Sven Schöling
foreach my $ref (@{ $form->{form_details} }) {
d707f7ac Moritz Bunkus
$form->{rowcount} = ++$i;

map { $form->{"${_}_$i"} = $ref->{$_} } keys %{$ref};
}
for my $i (1 .. $form->{rowcount}) {
if ($form->{id}) {
$form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100);
} else {
$form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"});
}
f404e525 Sven Schöling
my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
d707f7ac Moritz Bunkus
$dec = length $dec;
f404e525 Sven Schöling
my $decimalplaces = ($dec > 2) ? $dec : 2;
d707f7ac Moritz Bunkus
# copy reqdate from deliverydate for invoice -> order conversion
$form->{"reqdate_$i"} = $form->{"deliverydate_$i"} unless $form->{"reqdate_$i"};

$form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
da804bf2 Geoffrey Richardson
$form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces);
d707f7ac Moritz Bunkus
(my $dec_qty) = ($form->{"qty_$i"} =~ /\.(\d+)/);
$dec_qty = length $dec_qty;
$form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
}

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

64297226 Moritz Bunkus
sub setup_do_action_bar {
my @transfer_qty = qw(kivi.SalesPurchase.delivery_order_check_transfer_qty);
my @req_trans_desc = qw(kivi.SalesPurchase.check_transaction_description) x!!$::instance_conf->get_require_transaction_description_ps;
36c8af52 Moritz Bunkus
my $is_customer = $::form->{vc} eq 'customer';
64297226 Moritz Bunkus
927ec727 Jan Büren
my $undo_date = DateTime->today->subtract(days => $::instance_conf->get_undo_transfer_interval);
my $insertdate = DateTime->from_kivitendo($::form->{insertdate});
my $undo_transfer = 0;
if (ref $undo_date eq 'DateTime' && ref $insertdate eq 'DateTime') {
3e79972f Jan Büren
$undo_transfer = $insertdate > $undo_date;
927ec727 Jan Büren
}
2e19657a Bernd Bleßmann
my $may_edit_create = $::auth->assert(SL::DB::DeliveryOrder::TypeData::get3($::form->{type}, "rights", "edit"), 1);

64297226 Moritz Bunkus
for my $bar ($::request->layout->get('actionbar')) {
$bar->add(
action =>
[ t8('Update'),
c2aaf253 Moritz Bunkus
submit => [ '#form', { action => "update" } ],
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
e6291b3a Moritz Bunkus
id => 'update_button',
64297226 Moritz Bunkus
accesskey => 'enter',
],

combobox => [
action => [
t8('Save'),
c2aaf253 Moritz Bunkus
submit => [ '#form', { action => "save" } ],
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form' ],
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: $::form->{delivered} ? t8('This record has already been delivered.')
: undef,
64297226 Moritz Bunkus
],
action => [
t8('Save as new'),
c2aaf253 Moritz Bunkus
submit => [ '#form', { action => "save_as_new" } ],
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form' ],
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: !$::form->{id},
64297226 Moritz Bunkus
],
action => [
t8('Mark as closed'),
c2aaf253 Moritz Bunkus
submit => [ '#form', { action => "mark_closed" } ],
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form' ],
64297226 Moritz Bunkus
confirm => t8('This will remove the delivery order from showing as open even if contents are not delivered. Proceed?'),
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: !$::form->{id} ? t8('This record has not been saved yet.')
64297226 Moritz Bunkus
: $::form->{closed} ? t8('This record has already been closed.')
: undef,
],
], # end of combobox "Save"

action => [
t8('Delete'),
c2aaf253 Moritz Bunkus
submit => [ '#form', { action => "delete" } ],
64297226 Moritz Bunkus
confirm => t8('Do you really want to delete this object?'),
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: !$::form->{id} ? t8('This record has not been saved yet.')
64297226 Moritz Bunkus
: $::form->{delivered} ? t8('This record has already been delivered.')
: ($::form->{vc} eq 'customer' && !$::instance_conf->get_sales_delivery_order_show_delete) ? t8('Deleting this type of record has been disabled in the configuration.')
: ($::form->{vc} eq 'vendor' && !$::instance_conf->get_purchase_delivery_order_show_delete) ? t8('Deleting this type of record has been disabled in the configuration.')
: undef,
],

combobox => [
36c8af52 Moritz Bunkus
action => [
64297226 Moritz Bunkus
t8('Transfer out'),
c2aaf253 Moritz Bunkus
submit => [ '#form', { action => "transfer_out" } ],
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form', @transfer_qty ],
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: $::form->{delivered} ? t8('This record has already been delivered.')
: undef,
36c8af52 Moritz Bunkus
only_if => $is_customer,
],
action => [
64297226 Moritz Bunkus
t8('Transfer out via default'),
c2aaf253 Moritz Bunkus
submit => [ '#form', { action => "transfer_out_default" } ],
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form' ],
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: $::form->{delivered} ? t8('This record has already been delivered.')
: undef,
36c8af52 Moritz Bunkus
only_if => $is_customer && $::instance_conf->get_transfer_default,
],
action => [
64297226 Moritz Bunkus
t8('Transfer in'),
7ed3358a Jan Büren
submit => [ '#form', { action => "transfer_in" } ],
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form', @transfer_qty ],
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: $::form->{delivered} ? t8('This record has already been delivered.')
: undef,
36c8af52 Moritz Bunkus
only_if => !$is_customer,
],
action => [
64297226 Moritz Bunkus
t8('Transfer in via default'),
c2aaf253 Moritz Bunkus
submit => [ '#form', { action => "transfer_in_default" } ],
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form' ],
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: $::form->{delivered} ? t8('This record has already been delivered.')
: undef,
36c8af52 Moritz Bunkus
only_if => !$is_customer && $::instance_conf->get_transfer_default,
],
927ec727 Jan Büren
action => [
t8('Undo Transfer'),
submit => [ '#form', { action => "delete_transfers" } ],
checks => [ 'kivi.validate_form' ],
only_if => $::form->{delivered},
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: !$undo_transfer ? t8('Transfer date exceeds the maximum allowed interval.')
: undef,
927ec727 Jan Büren
],
64297226 Moritz Bunkus
], # end of combobox "Transfer out"


'separator',

9b5b900b Tamino Steinert
combobox => [
action => [ t8('Workflow') ],
action => [
t8('Invoice'),
submit => [ '#form', { action => "invoice" } ],
disabled => !$::form->{id} ? t8('This record has not been saved yet.') : undef,
confirm => $::form->{delivered} ? undef
: ($::form->{vc} eq 'customer' && $::instance_conf->get_sales_delivery_order_check_stocked) ? t8('This record has not been stocked out. Proceed?')
: ($::form->{vc} eq 'vendor' && $::instance_conf->get_purchase_delivery_order_check_stocked) ? t8('This record has not been stocked in. Proceed?')
: undef,
],
action => [
t8('Save and Reclamation'),
submit => [ '#form', { action => "save_and_reclamation" } ],
],
64297226 Moritz Bunkus
],

combobox => [
action => [ t8('Export') ],
action => [
t8('Print'),
2e19657a Bernd Bleßmann
call => [ 'kivi.SalesPurchase.show_print_dialog' ],
checks => [ 'kivi.validate_form' ],
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.') : undef,
64297226 Moritz Bunkus
],
action => [
t8('E Mail'),
307f0b13 Moritz Bunkus
call => [ 'kivi.SalesPurchase.show_email_dialog' ],
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form' ],
2e19657a Bernd Bleßmann
disabled => !$may_edit_create ? t8('You do not have the permissions to access this function.')
: !$::form->{id} ? t8('This record has not been saved yet.')
: undef,
64297226 Moritz Bunkus
],
], # end of combobox "Export"

combobox => [
action => [ t8('more') ],
action => [
t8('History'),
call => [ 'set_history_window', $::form->{id} * 1, 'id' ],
disabled => !$::form->{id} ? t8('This record has not been saved yet.') : undef,
],
action => [
t8('Follow-Up'),
call => [ 'follow_up_window' ],
disabled => !$::form->{id} ? t8('This record has not been saved yet.') : undef,
],
], # end if combobox "more"
);
}
0ede1996 Sven Schöling
$::request->layout->add_javascripts('kivi.Validator.js');
64297226 Moritz Bunkus
}

a6cf76a2 Moritz Bunkus
sub setup_do_search_action_bar {
my %params = @_;

for my $bar ($::request->layout->get('actionbar')) {
$bar->add(
action => [
t8('Search'),
submit => [ '#form' ],
accesskey => 'enter',
0ede1996 Sven Schöling
checks => [ 'kivi.validate_form' ],
a6cf76a2 Moritz Bunkus
],
);
}
0ede1996 Sven Schöling
$::request->layout->add_javascripts('kivi.Validator.js');
a6cf76a2 Moritz Bunkus
}

sub setup_do_orders_action_bar {
my %params = @_;

for my $bar ($::request->layout->get('actionbar')) {
$bar->add(
action => [
t8('New invoice'),
6a75dc1c Moritz Bunkus
submit => [ '#form', { action => 'invoice_multi' } ],
checks => [ [ 'kivi.check_if_entries_selected', '#form tbody input[type=checkbox]' ] ],
a6cf76a2 Moritz Bunkus
accesskey => 'enter',
],
6a75dc1c Moritz Bunkus
action => [
t8('Print'),
call => [ 'kivi.SalesPurchase.show_print_dialog', 'js:kivi.MassDeliveryOrderPrint.submitMultiOrders' ],
checks => [ [ 'kivi.check_if_entries_selected', '#form tbody input[type=checkbox]' ] ],
],
a6cf76a2 Moritz Bunkus
);
}
}

d707f7ac Moritz Bunkus
sub form_header {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;

fdbb6888 Moritz Bunkus
my $class = "SL::DB::" . ($form->{vc} eq 'customer' ? 'Customer' : 'Vendor');
$form->{VC_OBJ} = $class->load_cached($form->{ $form->{vc} . '_id' });

0a3d4b15 Moritz Bunkus
$form->{CONTACT_OBJ} = $form->{cp_id} ? SL::DB::Contact->load_cached($form->{cp_id}) : undef;
08e820fa Moritz Bunkus
my $current_employee = SL::DB::Manager::Employee->current;
$form->{employee_id} = $form->{old_employee_id} if $form->{old_employee_id};
$form->{salesman_id} = $form->{old_salesman_id} if $form->{old_salesman_id};
$form->{employee_id} ||= $current_employee->id;
$form->{salesman_id} ||= $current_employee->id;
d707f7ac Moritz Bunkus
my $vc = $form->{vc} eq "customer" ? "customers" : "vendors";
fdbb6888 Moritz Bunkus
$form->get_lists("price_factors" => "ALL_PRICE_FACTORS",
d707f7ac Moritz Bunkus
"business_types" => "ALL_BUSINESS_TYPES",
);
2b37ad3a Jan Büren
$form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all_sorted;
473431b1 Moritz Bunkus
$form->{ALL_LANGUAGES} = SL::DB::Manager::Language->get_all_sorted;
590047d7 Sven Schöling
41adf433 Moritz Bunkus
# Projects
my @old_project_ids = uniq grep { $_ } map { $_ * 1 } ($form->{"globalproject_id"}, map { $form->{"project_id_$_"} } 1..$form->{"rowcount"});
my @old_ids_cond = @old_project_ids ? (id => \@old_project_ids) : ();
my @customer_cond;
if (($vc eq 'customers') && $::instance_conf->get_customer_projects_only_in_sales) {
@customer_cond = (
or => [
customer_id => $::form->{customer_id},
billable_customer_id => $::form->{customer_id},
]);
}
my @conditions = (
or => [
and => [ active => 1, @customer_cond ],
@old_ids_cond,
]);

fc6a8e32 Moritz Bunkus
$::form->{ALL_PROJECTS} = SL::DB::Manager::Project->get_all_sorted(query => \@conditions);
2f5363d2 Moritz Bunkus
$::form->{ALL_DELIVERY_TERMS} = SL::DB::Manager::DeliveryTerm->get_valid($::form->{delivery_term_id});
d139dd31 Moritz Bunkus
$::form->{ALL_EMPLOYEES} = SL::DB::Manager::Employee->get_all_sorted(query => [ or => [ id => $::form->{employee_id}, deleted => 0 ] ]);
$::form->{ALL_SALESMEN} = SL::DB::Manager::Employee->get_all_sorted(query => [ or => [ id => $::form->{salesman_id}, deleted => 0 ] ]);
5b8e9fcb Moritz Bunkus
$::form->{ALL_SHIPTO} = SL::DB::Manager::Shipto->get_all_sorted(query => [
a75836ca Bernd Bleßmann
or => [ and => [ trans_id => $::form->{"$::form->{vc}_id"} * 1, module => 'CT' ], and => [ shipto_id => $::form->{shipto_id} * 1, trans_id => undef ] ]
9b67d27c Sven Schöling
]);
3816bb51 Moritz Bunkus
$::form->{ALL_CONTACTS} = SL::DB::Manager::Contact->get_all_sorted(query => [
cb2abccd Sven Schöling
or => [
cp_cv_id => $::form->{"$::form->{vc}_id"} * 1,
and => [
cp_cv_id => undef,
cp_id => $::form->{cp_id} * 1
]
]
]);
d707f7ac Moritz Bunkus
ee561795 Bernd Bleßmann
my $dispatch_to_popup = '';
if ($form->{resubmit} && ($form->{format} eq "html")) {
$dispatch_to_popup = "window.open('about:blank','Beleg'); document.do.target = 'Beleg';";
3c255f28 Sven Schöling
$dispatch_to_popup .= "document.do.submit();";
c4ad2c7c Bernd Bleßmann
} elsif ($form->{resubmit} && $form->{action_print}) {
ee561795 Bernd Bleßmann
# emulate click for resubmitting actions
c4ad2c7c Bernd Bleßmann
$dispatch_to_popup = "kivi.SalesPurchase.show_print_dialog(); kivi.SalesPurchase.print_record();";
d707f7ac Moritz Bunkus
}
579920a7 Bernd Bleßmann
$::request->{layout}->add_javascripts_inline("\$(function(){$dispatch_to_popup});");
ee561795 Bernd Bleßmann
d707f7ac Moritz Bunkus
34925210 Bernd Bleßmann
$form->{follow_up_trans_info} = $form->{donumber} .'('. $form->{VC_OBJ}->name .')' if $form->{VC_OBJ};
94f5cb15 Bernd Bleßmann
$form->{longdescription_dialog_size_percentage} = SL::Helper::UserPreferences::DisplayPreferences->new()->get_longdescription_dialog_size_percentage();
af0023e0 Thomas Heck
5eb6ef41 Sven Schöling
$::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.File kivi.MassDeliveryOrderPrint kivi.SalesPurchase kivi.Part kivi.CustomerVendor kivi.Validator ckeditor/ckeditor ckeditor/adapters/jquery kivi.io));
ff058663 Moritz Bunkus
64297226 Moritz Bunkus
setup_do_action_bar();
89ac3ab1 Sven Schöling
d707f7ac Moritz Bunkus
$form->header();
e69e3657 Jan Büren
# Fix für Bug 1082 Erwartet wird: 'abteilungsNAME--abteilungsID'
1a0c73d3 Jan Büren
# und Erweiterung für Bug 1760:
# Das war leider nur ein Teil-Fix, da das Verhalten den 'Erneuern'-Knopf
b33690b0 Sven Schöling
# nicht überlebt. Konsequent jetzt auf L umgestellt
1a0c73d3 Jan Büren
# $ perldoc SL::Template::Plugin::L
# Daher entsprechend nur die Anpassung in form_header
# und in DO.pm gemacht. 4 Testfälle:
# department_id speichern | i.O.
# department_id lesen | i.O.
# department leer überlebt erneuern | i.O.
# department nicht leer überlebt erneuern | i.O.
# $main::lxdebug->message(0, 'ABTEILUNGS ID in form?' . $form->{department_id});
d707f7ac Moritz Bunkus
print $form->parse_html_template('do/form_header');

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub form_footer {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

f404e525 Sven Schöling
my $form = $main::form;

307f0b13 Moritz Bunkus
$form->{PRINT_OPTIONS} = setup_sales_purchase_print_options();
d707f7ac Moritz Bunkus
6f1ffd59 Bernd Bleßmann
my $shipto_cvars = SL::DB::Shipto->new->cvars_by_config;
foreach my $var (@{ $shipto_cvars }) {
my $name = "shiptocvar_" . $var->config->name;
$var->value($form->{$name}) if exists $form->{$name};
}

52d18c01 Jan Büren
print $form->parse_html_template('do/form_footer',
6f1ffd59 Bernd Bleßmann
{transfer_default => ($::instance_conf->get_transfer_default),
shipto_cvars => $shipto_cvars});
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub update_delivery_order {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;

d707f7ac Moritz Bunkus
set_headings($form->{"id"} ? "edit" : "add");

e8966d20 Bernd Bleßmann
$form->{insertdate} = SL::DB::DeliveryOrder->new(id => $form->{id})->load->itime_as_date if $form->{id};

d707f7ac Moritz Bunkus
$form->{update} = 1;

f404e525 Sven Schöling
my $payment_id;
d707f7ac Moritz Bunkus
$payment_id = $form->{payment_id} if $form->{payment_id};

fdbb6888 Moritz Bunkus
my $vc = $form->{vc};
if (($form->{"previous_${vc}_id"} || $form->{"${vc}_id"}) != $form->{"${vc}_id"}) {
$::form->{salesman_id} = SL::DB::Manager::Employee->current->id if exists $::form->{salesman_id};

844a541e Moritz Bunkus
if ($vc eq 'customer') {
IS->get_customer(\%myconfig, $form);
$::form->{billing_address_id} = $::form->{default_billing_address_id};
} else {
IR->get_vendor(\%myconfig, $form);
}
fdbb6888 Moritz Bunkus
}

c6d1bb55 Jan Büren
$form->{discount} = $form->{"$form->{vc}_discount"} if defined $form->{"$form->{vc}_discount"};
# Problem: Wenn man ohne Erneuern einen Kunden/Lieferanten
# wechselt, wird der entsprechende Kunden/ Lieferantenrabatt
# nicht übernommen. Grundproblem: In Commit 82574e78
# hab ich aus discount customer_discount und vendor_discount
# gemacht und entsprechend an den Oberflächen richtig hin-
# geschoben. Die damals bessere Lösung wäre gewesen:
# In den Templates nur die hidden für form-discount wieder ein-
# setzen dann wäre die Verrenkung jetzt nicht notwendig.
# TODO: Ggf. Bugfix 1284, 1575 und 817 wieder zusammenführen
# Testfälle: Kunden mit Rabatt 0 -> Rabatt 20 i.O.
# Kunde mit Rabatt 20 -> Rabatt 0 i.O.
# Kunde mit Rabatt 20 -> Rabatt 5,5 i.O.
d707f7ac Moritz Bunkus
$form->{payment_id} = $payment_id if $form->{payment_id} eq "";

f404e525 Sven Schöling
my $i = $form->{rowcount};
d707f7ac Moritz Bunkus
if ( ($form->{"partnumber_$i"} eq "")
&& ($form->{"description_$i"} eq "")
&& ($form->{"partsgroup_$i"} eq "")) {

check_form();

} else {

cb253140 Moritz Bunkus
my $mode;
d707f7ac Moritz Bunkus
if ($form->{type} eq 'purchase_delivery_order') {
IR->retrieve_item(\%myconfig, $form);
cb253140 Moritz Bunkus
$mode = 'IR';
d707f7ac Moritz Bunkus
} else {
IS->retrieve_item(\%myconfig, $form);
cb253140 Moritz Bunkus
$mode = 'IS';
d707f7ac Moritz Bunkus
}

my $rows = scalar @{ $form->{item_list} };

if ($rows) {
2a61343f Thomas Heck
$form->{"qty_$i"} = $form->parse_amount(\%myconfig, $form->{"qty_$i"});
if( !$form->{"qty_$i"} ) {
$form->{"qty_$i"} = 1;
}
d707f7ac Moritz Bunkus
if ($rows > 1) {

6ea1dd9b Bernd Bleßmann
select_item(mode => $mode, pre_entered_qty => $form->{"qty_$i"});
09479f02 Moritz Bunkus
$::dispatcher->end_request;
d707f7ac Moritz Bunkus
} else {

ca6d3683 Sven Schöling
my $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});

d707f7ac Moritz Bunkus
map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };

$form->{"marge_price_factor_$i"} = $form->{item_list}->[0]->{price_factor};
ca6d3683 Sven Schöling
if ($sellprice) {
$form->{"sellprice_$i"} = $sellprice;
} else {
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;
my $best_discount = $price_source->best_discount;

if ($best_price) {
$::form->{"sellprice_$i"} = $best_price->price;
$::form->{"active_price_source_$i"} = $best_price->source;
}
if ($best_discount) {
$::form->{"discount_$i"} = $best_discount->discount;
$::form->{"active_discount_source_$i"} = $best_discount->source;
}
}

89b26688 Sven Schöling
$form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"});
ca6d3683 Sven Schöling
$form->{"lastcost_$i"} = $form->format_amount(\%myconfig, $form->{"lastcost_$i"});
d707f7ac Moritz Bunkus
$form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
97908d77 Bernd Bleßmann
$form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"} * 100.0);
d707f7ac Moritz Bunkus
}

display_form();

} else {

# ok, so this is a new part
# ask if it is a part or service item

if ( $form->{"partsgroup_$i"}
&& ($form->{"partsnumber_$i"} eq "")
&& ($form->{"description_$i"} eq "")) {
$form->{rowcount}--;
$form->{"discount_$i"} = "";
a8428264 Bernd Bleßmann
$form->{"not_discountable_$i"} = "";
d707f7ac Moritz Bunkus
display_form();

} else {
$form->{"id_$i"} = 0;
new_item();
}
}
}

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub search {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;

330cfa6d Moritz Bunkus
$form->{vc} = $form->{type} eq 'purchase_delivery_order' ? 'vendor' : 'customer';
d707f7ac Moritz Bunkus
d93709bd Bernd Bleßmann
$form->get_lists("projects" => { "key" => "ALL_PROJECTS",
"all" => 1 },
"business_types" => "ALL_BUSINESS_TYPES");
d139dd31 Moritz Bunkus
$form->{ALL_EMPLOYEES} = SL::DB::Manager::Employee->get_all_sorted(query => [ deleted => 0 ]);
2b37ad3a Jan Büren
$form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all_sorted;
d707f7ac Moritz Bunkus
$form->{title} = $locale->text('Delivery Orders');

a6cf76a2 Moritz Bunkus
setup_do_search_action_bar();

d707f7ac Moritz Bunkus
$form->header();

print $form->parse_html_template('do/search');

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub orders {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
check_do_access();

f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
5494f687 Sven Schöling
my $cgi = $::request->{cgi};
f404e525 Sven Schöling
6a75dc1c Moritz Bunkus
$::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.MassDeliveryOrderPrint kivi.SalesPurchase));
f404e525 Sven Schöling
($form->{ $form->{vc} }, $form->{"$form->{vc}_id"}) = split(/--/, $form->{ $form->{vc} });
d707f7ac Moritz Bunkus
fc8ad1a3 Moritz Bunkus
report_generator_set_default_sort('transdate', 1);
d707f7ac Moritz Bunkus
DO->transactions();

$form->{rowcount} = scalar @{ $form->{DO} };

my @columns = qw(
253a9323 Bernd Bleßmann
ids transdate reqdate
d707f7ac Moritz Bunkus
id donumber
32020b3a Sven Schöling
ordnumber customernumber cusordnumber
edaf9f95 Sven Schöling
name employee salesman
d707f7ac Moritz Bunkus
shipvia globalprojectnumber
ed14204d Moritz Bunkus
transaction_description department
d707f7ac Moritz Bunkus
open delivered
e0bac67f Bernd Bleßmann
insertdate items
d707f7ac Moritz Bunkus
);

$form->{l_open} = $form->{l_closed} = "Y" if ($form->{open} && $form->{closed});
$form->{l_delivered} = "Y" if ($form->{delivered} && $form->{notdelivered});

$form->{title} = $locale->text('Delivery Orders');

my $attachment_basename = $form->{vc} eq 'vendor' ? $locale->text('purchase_delivery_order_list') : $locale->text('sales_delivery_order_list');

my $report = SL::ReportGenerator->new(\%myconfig, $form);

my @hidden_variables = map { "l_${_}" } @columns;
65e5f16a Peter Schulgin
push @hidden_variables, $form->{vc}, qw(l_closed l_notdelivered open closed delivered notdelivered donumber ordnumber serialnumber cusordnumber
30645d2c Bernd Bleßmann
transaction_description transdatefrom transdateto reqdatefrom reqdateto
4a06c433 Moritz Bunkus
type vc employee_id salesman_id project_id parts_partnumber parts_description
3ecc10d2 Tamino Steinert
insertdatefrom insertdateto business_id all department_id chargenumber full_text);
d707f7ac Moritz Bunkus
my $href = build_std_url('action=orders', grep { $form->{$_} } @hidden_variables);

my %column_defs = (
3cf720a8 Werner Hahn
'ids' => { raw_header_data => SL::Presenter::Tag::checkbox_tag("", id => "multi_all", checkall => "[data-checkall=1]"), align => 'center' },
30645d2c Bernd Bleßmann
'transdate' => { 'text' => $locale->text('Delivery Order Date'), },
253a9323 Bernd Bleßmann
'reqdate' => { 'text' => $locale->text('Reqdate'), },
d707f7ac Moritz Bunkus
'id' => { 'text' => $locale->text('ID'), },
'donumber' => { 'text' => $locale->text('Delivery Order'), },
'ordnumber' => { 'text' => $locale->text('Order'), },
7d026c7c Niclas Zimmermann
'customernumber' => { 'text' => $locale->text('Customer Number'), },
65e5f16a Peter Schulgin
'cusordnumber' => { 'text' => $locale->text('Customer Order Number'), },
d707f7ac Moritz Bunkus
'name' => { 'text' => $form->{vc} eq 'customer' ? $locale->text('Customer') : $locale->text('Vendor'), },
e31afd79 Geoffrey Richardson
'employee' => { 'text' => $locale->text('Employee'), },
edaf9f95 Sven Schöling
'salesman' => { 'text' => $locale->text('Salesman'), },
d707f7ac Moritz Bunkus
'shipvia' => { 'text' => $locale->text('Ship via'), },
'globalprojectnumber' => { 'text' => $locale->text('Project Number'), },
'transaction_description' => { 'text' => $locale->text('Transaction description'), },
'open' => { 'text' => $locale->text('Open'), },
'delivered' => { 'text' => $locale->text('Delivered'), },
ed14204d Moritz Bunkus
'department' => { 'text' => $locale->text('Department'), },
e8966d20 Bernd Bleßmann
'insertdate' => { 'text' => $locale->text('Insert Date'), },
e0bac67f Bernd Bleßmann
'items' => { 'text' => $locale->text('Positions'), },
d707f7ac Moritz Bunkus
);

e8966d20 Bernd Bleßmann
foreach my $name (qw(id transdate reqdate donumber ordnumber name employee salesman shipvia transaction_description department insertdate)) {
23c7245a Moritz Bunkus
my $sortdir = $form->{sort} eq $name ? 1 - $form->{sortdir} : $form->{sortdir};
$column_defs{$name}->{link} = $href . "&sort=$name&sortdir=$sortdir";
d707f7ac Moritz Bunkus
}

$form->{"l_type"} = "Y";
map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns;
454df69e Moritz Bunkus
$column_defs{ids}->{visible} = 'HTML';
d707f7ac Moritz Bunkus
$report->set_columns(%column_defs);
$report->set_column_order(@columns);

19688fca Moritz Bunkus
$report->set_export_options('orders', @hidden_variables, qw(sort sortdir));
d707f7ac Moritz Bunkus
23c7245a Moritz Bunkus
$report->set_sort_indicator($form->{sort}, $form->{sortdir});
d707f7ac Moritz Bunkus
my @options;
if ($form->{customer}) {
push @options, $locale->text('Customer') . " : $form->{customer}";
}
if ($form->{vendor}) {
push @options, $locale->text('Vendor') . " : $form->{vendor}";
}
b98b8e3f Sven Schöling
if ($form->{cp_name}) {
push @options, $locale->text('Contact Person') . " : $form->{cp_name}";
}
dec270d2 Geoffrey Richardson
if ($form->{department_id}) {
push @options, $locale->text('Department') . " : " . SL::DB::Department->new(id => $form->{department_id})->load->description;
d707f7ac Moritz Bunkus
}
if ($form->{donumber}) {
push @options, $locale->text('Delivery Order Number') . " : $form->{donumber}";
}
if ($form->{ordnumber}) {
push @options, $locale->text('Order Number') . " : $form->{ordnumber}";
}
2e4e2ba9 Moritz Bunkus
push @options, $locale->text('Serial Number') . " : $form->{serialnumber}" if $form->{serialnumber};
d93709bd Bernd Bleßmann
if ($form->{business_id}) {
my $vc_type_label = $form->{vc} eq 'customer' ? $locale->text('Customer type') : $locale->text('Vendor type');
push @options, $vc_type_label . " : " . SL::DB::Business->new(id => $form->{business_id})->load->description;
}
d707f7ac Moritz Bunkus
if ($form->{transaction_description}) {
push @options, $locale->text('Transaction description') . " : $form->{transaction_description}";
}
3ecc10d2 Tamino Steinert
if ($form->{fulltext}) {
push @options, $locale->text('Full Text') . " : $form->{fulltext}";
}
4a06c433 Moritz Bunkus
if ($form->{parts_description}) {
push @options, $locale->text('Part Description') . " : $form->{parts_description}";
}
if ($form->{parts_partnumber}) {
push @options, $locale->text('Part Number') . " : $form->{parts_partnumber}";
19522de1 Bernd Bleßmann
}
if ($form->{chargenumber}) {
3407c6a1 Bernd Bleßmann
push @options, $locale->text('Charge Number') . " : $form->{chargenumber}";
4a06c433 Moritz Bunkus
}
30645d2c Bernd Bleßmann
if ( $form->{transdatefrom} or $form->{transdateto} ) {
push @options, $locale->text('Delivery Order Date');
push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{transdatefrom}, 1) if $form->{transdatefrom};
push @options, $locale->text('Bis') . " " . $locale->date(\%myconfig, $form->{transdateto}, 1) if $form->{transdateto};
};
if ( $form->{reqdatefrom} or $form->{reqdateto} ) {
push @options, $locale->text('Reqdate');
push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{reqdatefrom}, 1) if $form->{reqdatefrom};
push @options, $locale->text('Bis') . " " . $locale->date(\%myconfig, $form->{reqdateto}, 1) if $form->{reqdateto};
};
e8966d20 Bernd Bleßmann
if ( $form->{insertdatefrom} or $form->{insertdateto} ) {
push @options, $locale->text('Insert Date');
push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{insertdatefrom}, 1) if $form->{insertdatefrom};
push @options, $locale->text('Bis') . " " . $locale->date(\%myconfig, $form->{insertdateto}, 1) if $form->{insertdateto};
};
d707f7ac Moritz Bunkus
if ($form->{open}) {
push @options, $locale->text('Open');
}
if ($form->{closed}) {
push @options, $locale->text('Closed');
}
if ($form->{delivered}) {
push @options, $locale->text('Delivered');
}
if ($form->{notdelivered}) {
push @options, $locale->text('Not delivered');
}
0c227fb2 Moritz Bunkus
push @options, $locale->text('Quick Search') . " : $form->{all}" if $form->{all};
d707f7ac Moritz Bunkus
54ce5144 Martin Helmling
my $pr = SL::DB::Manager::Printer->find_by(
printer_description => $::locale->text("sales_delivery_order_printer"));
if ($pr ) {
$form->{printer_id} = $pr->id;
}

6a75dc1c Moritz Bunkus
my $print_options = SL::Helper::PrintOptions->get_print_options(
options => {
hide_language_id => 1,
show_bothsided => 1,
show_headers => 1,
},
);

454df69e Moritz Bunkus
$report->set_options('top_info_text' => join("\n", @options),
'raw_top_info_text' => $form->parse_html_template('do/orders_top'),
6a75dc1c Moritz Bunkus
'raw_bottom_info_text' => $form->parse_html_template('do/orders_bottom', { print_options => $print_options }),
454df69e Moritz Bunkus
'output_format' => 'HTML',
'title' => $form->{title},
'attachment_basename' => $attachment_basename . strftime('_%Y%m%d', localtime time),
d707f7ac Moritz Bunkus
);
$report->set_options_from_form();
a873249c Moritz Bunkus
$locale->set_numberformat_wo_thousands_separator(\%myconfig) if lc($report->{options}->{output_format}) eq 'csv';
d707f7ac Moritz Bunkus
# add sort and escape callback, this one we use for the add sub
$form->{callback} = $href .= "&sort=$form->{sort}";

# escape callback for href
f404e525 Sven Schöling
my $callback = $form->escape($href);
d707f7ac Moritz Bunkus
my $edit_url = build_std_url('action=edit', 'type', 'vc');
984f6322 Bernd Bleßmann
my $edit_order_url = ($::instance_conf->get_feature_experimental_order)
f825d995 Bernd Bleßmann
? build_std_url('script=controller.pl', 'action=Order/edit', 'type=' . ($form->{type} eq 'sales_delivery_order' ? 'sales_order' : 'purchase_order'))
: build_std_url('script=oe.pl', 'action=edit', 'type=' . ($form->{type} eq 'sales_delivery_order' ? 'sales_order' : 'purchase_order'));
d707f7ac Moritz Bunkus
454df69e Moritz Bunkus
my $idx = 1;

f404e525 Sven Schöling
foreach my $dord (@{ $form->{DO} }) {
d707f7ac Moritz Bunkus
$dord->{open} = $dord->{closed} ? $locale->text('No') : $locale->text('Yes');
$dord->{delivered} = $dord->{delivered} ? $locale->text('Yes') : $locale->text('No');

e0bac67f Bernd Bleßmann
my $row = { map { $_ => { 'data' => $dord->{$_} } } grep {$_ ne 'items'} @columns };
d707f7ac Moritz Bunkus
54ce5144 Martin Helmling
my $ord_id = $dord->{id};
454df69e Moritz Bunkus
$row->{ids} = {
54ce5144 Martin Helmling
'raw_data' => $cgi->hidden('-name' => "trans_id_${idx}", '-value' => $ord_id)
3cf720a8 Werner Hahn
. $cgi->checkbox('-name' => "multi_id_${idx}",' id' => "multi_id_id_".$ord_id, '-value' => 1, 'data-checkall' => 1, '-label' => ''),
454df69e Moritz Bunkus
'valign' => 'center',
'align' => 'center',
};

092d3110 Sven Schöling
$row->{donumber}->{link} = SL::DB::DeliveryOrder::TypeData::get3($dord->{order_type}, "show_menu", "new_controller")
? SL::Controller::DeliveryOrder->url_for(action => "edit", id => $dord->{id}, type => $dord->{order_type})
: $edit_url . "&id=" . E($dord->{id}) . "&callback=${callback}";
b1c23196 Thomas Heck
$row->{ordnumber}->{link} = $edit_order_url . "&id=" . E($dord->{oe_id}) . "&callback=${callback}" if $dord->{oe_id};
e0bac67f Bernd Bleßmann
if ($form->{l_items}) {
my $items = SL::DB::Manager::DeliveryOrderItem->get_all_sorted(where => [id => $dord->{item_ids}]);
$row->{items}->{raw_data} = SL::Presenter::ItemsList::items_list($items) if lc($report->{options}->{output_format}) eq 'html';
$row->{items}->{data} = SL::Presenter::ItemsList::items_list($items, as_text => 1) if lc($report->{options}->{output_format}) ne 'html';
}

d707f7ac Moritz Bunkus
$report->add_data($row);
454df69e Moritz Bunkus
$idx++;
d707f7ac Moritz Bunkus
}

a6cf76a2 Moritz Bunkus
setup_do_orders_action_bar();

e7913c4c Moritz Bunkus
$report->generate_with_headers();
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub save {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
088bf5a0 Moritz Bunkus
my (%params) = @_;

2e19657a Bernd Bleßmann
check_do_access_for_edit();
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;

d735aab3 Martin Helmling
$form->mtime_ischanged('delivery_orders');

d707f7ac Moritz Bunkus
$form->{defaultcurrency} = $form->get_default_currency(\%myconfig);

$form->isblank("transdate", $locale->text('Delivery Order Date missing!'));

$form->{donumber} =~ s/^\s*//g;
$form->{donumber} =~ s/\s*$//g;

f404e525 Sven Schöling
my $msg = ucfirst $form->{vc};
fdbb6888 Moritz Bunkus
$form->isblank($form->{vc} . "_id", $locale->text($msg . " missing!"));
d707f7ac Moritz Bunkus
# $locale->text('Customer missing!');
# $locale->text('Vendor missing!');

0a5317e7 Moritz Bunkus
remove_emptied_rows();
d707f7ac Moritz Bunkus
validate_items();

ac24d564 Jan Büren
# check for serial number if part needs one
for my $i (1 .. $form->{rowcount} - 1) {
next unless $form->{"has_sernumber_$i"};
$form->isblank("serialnumber_$i",
$locale->text('Serial Number missing in Row') . " $i");
}
d707f7ac Moritz Bunkus
# if the name changed get new values
fdbb6888 Moritz Bunkus
my $vc = $form->{vc};
if (($form->{"previous_${vc}_id"} || $form->{"${vc}_id"}) != $form->{"${vc}_id"}) {
$::form->{salesman_id} = SL::DB::Manager::Employee->current->id if exists $::form->{salesman_id};

844a541e Moritz Bunkus
if ($vc eq 'customer') {
IS->get_customer(\%myconfig, $form);
$::form->{billing_address_id} = $::form->{default_billing_address_id};
} else {
IR->get_vendor(\%myconfig, $form);
}
fdbb6888 Moritz Bunkus
d707f7ac Moritz Bunkus
update();
09479f02 Moritz Bunkus
$::dispatcher->end_request;
d707f7ac Moritz Bunkus
}

7e4a1765 Bernd Bleßmann
if ($form->{saveasnew}) {
$form->{id} = 0;
$form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_DELIVERY_ORDER_SAVE())->token;
}

7a364ba1 Jan Büren
# we rely on converted_from_orderitems, if the workflow is used
# be sure that at least one position is linked to the original orderitem
if ($form->{convert_from_oe_ids}) {
my $has_linked_pos;
for my $i (1 .. $form->{rowcount}) {
if ($form->{"converted_from_orderitems_id_$i"}) {
$has_linked_pos = 1;
last;
}
}
if (!$has_linked_pos) {
$form->error($locale->text('Need at least one original position for the workflow Order to Delivery Order!'));
}
}
d707f7ac Moritz Bunkus
DO->save();
a03e4841 Bernd Bleßmann
d707f7ac Moritz Bunkus
# saving the history
if(!exists $form->{addition}) {
$form->{snumbers} = qq|donumber_| . $form->{donumber};
b65a230d Sven Schöling
$form->{addition} = "SAVED";
a590a651 Sven Schöling
$form->save_history;
d707f7ac Moritz Bunkus
}
# /saving the history

$form->{simple_save} = 1;
088bf5a0 Moritz Bunkus
if (!$params{no_redirect} && !$form->{print_and_save}) {
e4070a74 Sven Schöling
delete @{$form}{ary_diff([keys %{ $form }], [qw(login id script type cursor_fokus)])};
edit();
09479f02 Moritz Bunkus
$::dispatcher->end_request;
d707f7ac Moritz Bunkus
}
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub delete {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
2e19657a Bernd Bleßmann
check_do_access_for_edit();
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
94a32127 Jan Büren
my $ret;
if ($ret = DO->delete()) {
d707f7ac Moritz Bunkus
# saving the history
if(!exists $form->{addition}) {
$form->{snumbers} = qq|donumber_| . $form->{donumber};
b65a230d Sven Schöling
$form->{addition} = "DELETED";
a590a651 Sven Schöling
$form->save_history;
d707f7ac Moritz Bunkus
}
# /saving the history

$form->info($locale->text('Delivery Order deleted!'));
09479f02 Moritz Bunkus
$::dispatcher->end_request;
d707f7ac Moritz Bunkus
}

94a32127 Jan Büren
$form->error($locale->text('Cannot delete delivery order!') . $ret);
927ec727 Jan Büren
$main::lxdebug->leave_sub();
}
sub delete_transfers {
$main::lxdebug->enter_sub();

2e19657a Bernd Bleßmann
check_do_access_for_edit();
927ec727 Jan Büren
my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
my $ret;

die "Invalid form type" unless $form->{type} =~ m/^(sales|purchase)_delivery_order$/;

if ($ret = DO->delete_transfers()) {
# saving the history
if(!exists $form->{addition}) {
$form->{snumbers} = qq|donumber_| . $form->{donumber};
$form->{addition} = "UNDO TRANSFER";
$form->save_history;
}
# /saving the history

flash_later('info', $locale->text("Transfer undone."));

$form->{callback} = 'do.pl?action=edit&type=' . $form->{type} . '&id=' . $form->escape($form->{id});
$form->redirect;
}

$form->error($locale->text('Cannot undo delivery order transfer!') . $ret);
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub invoice {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
d707f7ac Moritz Bunkus
check_do_access();
d735aab3 Martin Helmling
$form->mtime_ischanged('delivery_orders');

f404e525 Sven Schöling
$main::auth->assert($form->{type} eq 'purchase_delivery_order' ? 'vendor_invoice_edit' : 'invoice_edit');
d707f7ac Moritz Bunkus
455a996a Bernd Bleßmann
$form->get_employee();

94e11003 Moritz Bunkus
$form->{convert_from_do_ids} = $form->{id};
0fd179c4 Jan Büren
# if we have a reqdate (Liefertermin), this is definetely the preferred
# deliverydate for invoices
$form->{deliverydate} = $form->{reqdate} || $form->{transdate};
94e11003 Moritz Bunkus
$form->{transdate} = $form->{invdate} = $form->current_date(\%myconfig);
$form->{duedate} = $form->current_date(\%myconfig, $form->{invdate}, $form->{terms} * 1);
$form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
3c1ceacd Moritz Bunkus
d707f7ac Moritz Bunkus
$form->{rowcount}--;

94e11003 Moritz Bunkus
delete @{$form}{qw(id closed delivered)};
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
my ($script, $buysell);
d707f7ac Moritz Bunkus
if ($form->{type} eq 'purchase_delivery_order') {
$form->{title} = $locale->text('Add Vendor Invoice');
$form->{script} = 'ir.pl';
$script = "ir";
1a16973b Sven Schöling
$buysell = 'sell';
1927b931 Bernd Bleßmann
$form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_PURCHASE_INVOICE_POST())->token;
d707f7ac Moritz Bunkus
} else {
$form->{title} = $locale->text('Add Sales Invoice');
$form->{script} = 'is.pl';
$script = "is";
$buysell = 'buy';
1927b931 Bernd Bleßmann
$form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_SALES_INVOICE_POST())->token;
d707f7ac Moritz Bunkus
}

f404e525 Sven Schöling
for my $i (1 .. $form->{rowcount}) {
25117316 Jan Büren
map { $form->{"${_}_${i}"} = $form->parse_amount(\%myconfig, $form->{"${_}_${i}"}) if $form->{"${_}_${i}"} } qw(ship qty sellprice lastcost basefactor discount);
2b88ba77 Jan Büren
# für bug 1284
25117316 Jan Büren
# adds a customer/vendor discount, unless we have a workflow case
# CAVEAT: has to be done, after the above parse_amount
a8428264 Bernd Bleßmann
unless ($form->{"ordnumber"}) {
if ($form->{discount}) { # Falls wir einen Lieferanten-/Kundenrabatt haben
# und rabattfähig sind, dann
unless ($form->{"not_discountable_$i"}) {
$form->{"discount_$i"} = $form->{discount}*100; # ... nehmen wir diesen Rabatt
}
}
2b88ba77 Jan Büren
}
bb7e2e85 Moritz Bunkus
$form->{"donumber_$i"} = $form->{donumber};
f0ad2143 Jan Büren
$form->{"converted_from_delivery_order_items_id_$i"} = delete $form->{"delivery_order_items_id_$i"};
d707f7ac Moritz Bunkus
}

$form->{type} = "invoice";

# locale messages
c607fb40 Sven Schöling
$main::locale = Locale->new("$myconfig{countrycode}", "$script");
97ca42c1 Sven Schöling
$locale = $main::locale;
d707f7ac Moritz Bunkus
require "bin/mozilla/$form->{script}";

my $currency = $form->{currency};
invoice_links();

c5b07505 Moritz Bunkus
if ($form->{ordnumber}) {
require SL::DB::Order;
ca7dfd3e Jan Büren
my $vc_id = $form->{type} =~ /^sales/ ? 'customer_id' : 'vendor_id';
if (my $order = SL::DB::Manager::Order->find_by(ordnumber => $form->{ordnumber}, $vc_id => $form->{"$vc_id"})) {
c5b07505 Moritz Bunkus
$order->load;
$form->{orddate} = $order->transdate_as_date;
dd5cd96c Werner Hahn
$form->{$_} = $order->$_ for qw(payment_id salesman_id taxzone_id quonumber taxincluded);
$form->{taxincluded_changed_by_user} = 1;
c5b07505 Moritz Bunkus
}
}

d707f7ac Moritz Bunkus
$form->{currency} = $currency;
$form->{exchangerate} = "";
a53233e5 Sven Schöling
$form->{forex} = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, $buysell);
$form->{exchangerate} = $form->{forex} if ($form->{forex});
d707f7ac Moritz Bunkus
prepare_invoice();

# format amounts
f404e525 Sven Schöling
for my $i (1 .. $form->{rowcount}) {
d707f7ac Moritz Bunkus
$form->{"discount_$i"} = $form->format_amount(\%myconfig, $form->{"discount_$i"});

f404e525 Sven Schöling
my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
d707f7ac Moritz Bunkus
$dec = length $dec;
f404e525 Sven Schöling
my $decimalplaces = ($dec > 2) ? $dec : 2;
d707f7ac Moritz Bunkus
# copy delivery date from reqdate for order -> invoice conversion
$form->{"deliverydate_$i"} = $form->{"reqdate_$i"}
unless $form->{"deliverydate_$i"};

da804bf2 Geoffrey Richardson
d707f7ac Moritz Bunkus
$form->{"sellprice_$i"} =
$form->format_amount(\%myconfig, $form->{"sellprice_$i"},
$decimalplaces);

da804bf2 Geoffrey Richardson
$form->{"lastcost_$i"} =
$form->format_amount(\%myconfig, $form->{"lastcost_$i"},
$decimalplaces);

d707f7ac Moritz Bunkus
(my $dec_qty) = ($form->{"qty_$i"} =~ /\.(\d+)/);
$dec_qty = length $dec_qty;
$form->{"qty_$i"} =
$form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);

}

display_form();

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

454df69e Moritz Bunkus
sub invoice_multi {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
454df69e Moritz Bunkus
check_do_access();
f404e525 Sven Schöling
$main::auth->assert($form->{type} eq 'sales_delivery_order' ? 'invoice_edit' : 'vendor_invoice_edit');
454df69e Moritz Bunkus
my @do_ids = map { $form->{"trans_id_$_"} } grep { $form->{"multi_id_$_"} } (1..$form->{rowcount});

if (!scalar @do_ids) {
a8459f49 Moritz Bunkus
$form->show_generic_error($locale->text('You have not selected any delivery order.'));
454df69e Moritz Bunkus
}

map { delete $form->{$_} } grep { m/^(?:trans|multi)_id_\d+/ } keys %{ $form };

if (!DO->retrieve('vc' => $form->{vc}, 'ids' => \@do_ids)) {
$form->show_generic_error($form->{vc} eq 'customer' ?
$locale->text('You cannot create an invoice for delivery orders for different customers.') :
$locale->text('You cannot create an invoice for delivery orders from different vendors.'),
'back_button' => 1);
}
b8eee773 Jan Büren
$form->{form_validity_token} = SL::DB::ValidityToken->create(scope => SL::DB::ValidityToken::SCOPE_SALES_INVOICE_POST())->token;
454df69e Moritz Bunkus
117dd89a Moritz Bunkus
my $source_type = $form->{type};
94e11003 Moritz Bunkus
$form->{convert_from_do_ids} = join ' ', @do_ids;
015f7118 Geoffrey Richardson
# bei der auswahl von mehreren Lieferscheinen fuer eine Rechnung, die einfach in donumber_array
# zwischenspeichern (DO.pm) und als ' '-separierte Liste wieder zurueckschreiben
# Hinweis: delete gibt den wert zurueck und loescht danach das element (nett und einfach)
# $shell: perldoc perlunc; /delete EXPR
b65a230d Sven Schöling
$form->{donumber} = delete $form->{donumber_array};
65e5f16a Peter Schulgin
$form->{ordnumber} = delete $form->{ordnumber_array};
$form->{cusordnumber} = delete $form->{cusordnumber_array};
94e11003 Moritz Bunkus
$form->{deliverydate} = $form->{transdate};
$form->{transdate} = $form->current_date(\%myconfig);
$form->{duedate} = $form->current_date(\%myconfig, $form->{invdate}, $form->{terms} * 1);
$form->{type} = "invoice";
$form->{closed} = 0;
$form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
454df69e Moritz Bunkus
f404e525 Sven Schöling
my ($script, $buysell);
117dd89a Moritz Bunkus
if ($source_type eq 'purchase_delivery_order') {
454df69e Moritz Bunkus
$form->{title} = $locale->text('Add Vendor Invoice');
$form->{script} = 'ir.pl';
$script = "ir";
$buysell = 'sell';

} else {
$form->{title} = $locale->text('Add Sales Invoice');
$form->{script} = 'is.pl';
$script = "is";
$buysell = 'buy';
}

map { delete $form->{$_} } qw(id subject message cc bcc printed emailed queued);

d85a3a7c Bernd Bleßmann
# get vendor or customer discount
my $vc_discount;
my $saved_form = save_form();
if ($form->{vc} eq 'vendor') {
IR->get_vendor(\%myconfig, \%$form);
$vc_discount = $form->{vendor_discount};
} else {
IS->get_customer(\%myconfig, \%$form);
de9a3d74 Jan Büren
$vc_discount = $form->{customer_discount};
d85a3a7c Bernd Bleßmann
}
fe950b4f Martin Helmling
# use payment terms from customer or vendor
restore_form($saved_form,0,qw(payment_id));
d85a3a7c Bernd Bleßmann
454df69e Moritz Bunkus
$form->{rowcount} = 0;
foreach my $ref (@{ $form->{form_details} }) {
$form->{rowcount}++;
d370f2a1 Sven Schöling
$ref->{reqdate} ||= $ref->{dord_transdate}; # copy transdates into each invoice row
454df69e Moritz Bunkus
map { $form->{"${_}_$form->{rowcount}"} = $ref->{$_} } keys %{ $ref };
d85a3a7c Bernd Bleßmann
map { $form->{"${_}_$form->{rowcount}"} = $form->format_amount(\%myconfig, $ref->{$_}) } qw(qty sellprice lastcost);
f0ad2143 Jan Büren
$form->{"converted_from_delivery_order_items_id_$form->{rowcount}"} = delete $form->{"delivery_order_items_id_$form->{rowcount}"};
d85a3a7c Bernd Bleßmann
be6f6cfd Moritz Bunkus
if ($vc_discount){ # falls wir einen Lieferanten/Kundenrabatt haben
d85a3a7c Bernd Bleßmann
# und keinen anderen discount wert an $i ...
$form->{"discount_$form->{rowcount}"} ||= $vc_discount; # ... nehmen wir diesen Rabatt
}

b65a230d Sven Schöling
$form->{"discount_$form->{rowcount}"} = $form->{"discount_$form->{rowcount}"} * 100; #s.a. Bug 1151
# Anm.: Eine Änderung des discounts in der SL/DO.pm->retrieve (select (doi.discount * 100) as discount) ergibt in psql einen
# Wert von 10.0000001490116. Ferner ist der Rabatt in der Rechnung dann bei 1.0 (?). Deswegen lasse ich das hier. jb 10.10.09
d85a3a7c Bernd Bleßmann
$form->{"discount_$form->{rowcount}"} = $form->format_amount(\%myconfig, $form->{"discount_$form->{rowcount}"});
454df69e Moritz Bunkus
}
delete $form->{form_details};

c607fb40 Sven Schöling
$locale = Locale->new("$myconfig{countrycode}", "$script");
454df69e Moritz Bunkus
require "bin/mozilla/$form->{script}";

invoice_links();
prepare_invoice();
34f5531f Bernd Bleßmann
454df69e Moritz Bunkus
display_form();

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
454df69e Moritz Bunkus
}

9b5b900b Tamino Steinert
sub save_and_reclamation {
my $form = $main::form;
my $type = $form->{type};

# save the delivery order
save(no_redirect => 1);

my $to_reclamation_type =
$type eq 'sales_delivery_order' ? 'sales_reclamation'
: 'purchase_reclamation';
$form->{callback} =
'controller.pl?action=Reclamation/add_from_delivery_order' .
'&type=' . $to_reclamation_type .
'&from_id=' . $form->escape($form->{id});
$form->redirect;
}

d707f7ac Moritz Bunkus
sub save_as_new {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
2e19657a Bernd Bleßmann
check_do_access_for_edit();
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
my $form = $main::form;

d707f7ac Moritz Bunkus
$form->{saveasnew} = 1;
$form->{closed} = 0;
74c7135d Moritz Bunkus
$form->{delivered} = 0;
d707f7ac Moritz Bunkus
map { delete $form->{$_} } qw(printed emailed queued);
0c05d1f7 Moritz Bunkus
delete @{ $form }{ grep { m/^stock_(?:in|out)_\d+/ } keys %{ $form } };
b8125c17 Bernd Bleßmann
$form->{"converted_from_delivery_order_items_id_$_"} = delete $form->{"delivery_order_items_id_$_"} for 1 .. $form->{"rowcount"};
008c2e15 Moritz Bunkus
# Let kivitendo assign a new order number if the user hasn't changed the
d707f7ac Moritz Bunkus
# previous one. If it has been changed manually then use it as-is.
$form->{donumber} =~ s/^\s*//g;
$form->{donumber} =~ s/\s*$//g;
if ($form->{saved_donumber} && ($form->{saved_donumber} eq $form->{donumber})) {
delete($form->{donumber});
}

save();

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub calculate_stock_in_out {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
d707f7ac Moritz Bunkus
my $i = shift;

if (!$form->{"id_${i}"}) {
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
return '';
}

f404e525 Sven Schöling
my $all_units = AM->retrieve_all_units();
137c9df3 Moritz Bunkus
d707f7ac Moritz Bunkus
my $in_out = $form->{type} =~ /^sales/ ? 'out' : 'in';
my $sinfo = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_${i}"});

06110580 Sven Schöling
my $do_qty = AM->sum_with_unit($::form->{"qty_$i"}, $::form->{"unit_$i"});
d707f7ac Moritz Bunkus
my $sum = AM->sum_with_unit(map { $_->{qty}, $_->{unit} } @{ $sinfo });
06110580 Sven Schöling
my $matches = $do_qty == $sum;
d707f7ac Moritz Bunkus
c7b5d49e Bernd Bleßmann
my $amount_unit = $all_units->{$form->{"partunit_$i"}}->{base_unit};
my $content = $form->format_amount(\%::myconfig, AM->convert_unit($amount_unit, $form->{"unit_$i"}) * $sum * 1) . ' ' . $form->{"unit_$i"};

06110580 Sven Schöling
$content = qq|<span id="stock_in_out_qty_display_${i}">${content}</span><input type=hidden id='stock_in_out_qty_matches_$i' value='$matches'> <input type="button" onclick="open_stock_in_out_window('${in_out}', $i);" value="?">|;
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
return $content;
}

sub get_basic_bin_wh_info {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
my $stock_info = shift;

f404e525 Sven Schöling
my $form = $main::form;

d707f7ac Moritz Bunkus
foreach my $sinfo (@{ $stock_info }) {
next unless ($sinfo->{bin_id});

my $bin_info = WH->get_basic_bin_info('id' => $sinfo->{bin_id});
map { $sinfo->{"${_}_description"} = $sinfo->{"${_}description"} = $bin_info->{"${_}_description"} } qw(bin warehouse);
}

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub stock_in_out_form {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
d707f7ac Moritz Bunkus
if ($form->{in_out} eq 'out') {
stock_out_form();
} else {
stock_in_form();
}

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub redo_stock_info {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
my %params = @_;

f404e525 Sven Schöling
my $form = $main::form;

d707f7ac Moritz Bunkus
my @non_empty = grep { $_->{qty} } @{ $params{stock_info} };

if ($params{add_empty_row}) {
push @non_empty, {
'warehouse_id' => scalar(@non_empty) ? $non_empty[-1]->{warehouse_id} : undef,
'bin_id' => scalar(@non_empty) ? $non_empty[-1]->{bin_id} : undef,
};
}

@{ $params{stock_info} } = @non_empty;

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub update_stock_in {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
d707f7ac Moritz Bunkus
my $stock_info = [];

foreach my $i (1..$form->{rowcount}) {
0f33c880 Moritz Bunkus
$form->{"qty_$i"} = $form->parse_amount(\%myconfig, $form->{"qty_$i"});
5f7cab51 Jan Büren
push @{ $stock_info }, { map { $_ => $form->{"${_}_${i}"} } qw(warehouse_id bin_id chargenumber
bestbefore qty unit delivery_order_items_stock_id) };
d707f7ac Moritz Bunkus
}

display_stock_in_form($stock_info);

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub stock_in_form {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
d707f7ac Moritz Bunkus
my $stock_info = DO->unpack_stock_information('packed' => $form->{stock});

display_stock_in_form($stock_info);

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub display_stock_in_form {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();
d707f7ac Moritz Bunkus
my $stock_info = shift;

f404e525 Sven Schöling
my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;

d707f7ac Moritz Bunkus
$form->{title} = $locale->text('Stock');

my $part_info = IC->get_basic_part_info('id' => $form->{parts_id});

71d04fc6 Jan Büren
# Standardlagerplatz für Standard-Auslagern verwenden, falls keiner für die Ware explizit definiert wurde
if ($::instance_conf->get_transfer_default_use_master_default_bin) {
ed023e22 Moritz Bunkus
$part_info->{warehouse_id} ||= $::instance_conf->get_warehouse_id;
$part_info->{bin_id} ||= $::instance_conf->get_bin_id;
71d04fc6 Jan Büren
}

07948c34 Moritz Bunkus
my $units = AM->retrieve_units(\%myconfig, $form);
8c6da403 Jan Büren
# der zweite Parameter von unit_select_data gibt den default-Namen (selected) vor
my $units_data = AM->unit_select_data($units, $form->{do_unit}, undef, $part_info->{unit});
d707f7ac Moritz Bunkus
$form->get_lists('warehouses' => { 'key' => 'WAREHOUSES',
696aad9c Moritz Bunkus
'bins' => 'BINS' });
d707f7ac Moritz Bunkus
74c7135d Moritz Bunkus
redo_stock_info('stock_info' => $stock_info, 'add_empty_row' => !$form->{delivered});
d707f7ac Moritz Bunkus
get_basic_bin_wh_info($stock_info);

ddb162b6 Sven Schöling
$form->header(no_layout => 1);
d707f7ac Moritz Bunkus
print $form->parse_html_template('do/stock_in_form', { 'UNITS' => $units_data,
'STOCK_INFO' => $stock_info,
'PART_INFO' => $part_info, });

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

50e62c57 Moritz Bunkus
sub _stock_in_out_set_qty_display {
my $stock_info = shift;
my $form = $::form;
my $all_units = AM->retrieve_all_units();
my $sum = AM->sum_with_unit(map { $_->{qty}, $_->{unit} } @{ $stock_info });
c7b5d49e Bernd Bleßmann
my $amount_unit = $all_units->{$form->{"partunit"}}->{base_unit};
$form->{qty_display} = $form->format_amount(\%::myconfig, AM->convert_unit($amount_unit, $form->{"do_unit"}) * $sum * 1) . ' ' . $form->{"do_unit"};
50e62c57 Moritz Bunkus
}

d707f7ac Moritz Bunkus
sub set_stock_in {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
d707f7ac Moritz Bunkus
my $stock_info = [];

foreach my $i (1..$form->{rowcount}) {
$form->{"qty_$i"} = $form->parse_amount(\%myconfig, $form->{"qty_$i"});

next if ($form->{"qty_$i"} <= 0);

286dc87c Jan Büren
push @{ $stock_info }, { map { $_ => $form->{"${_}_${i}"} } qw(delivery_order_items_stock_id warehouse_id bin_id chargenumber bestbefore qty unit) };
d707f7ac Moritz Bunkus
}

65b2387a Moritz Bunkus
$form->{stock} = SL::YAML::Dump($stock_info);
d707f7ac Moritz Bunkus
50e62c57 Moritz Bunkus
_stock_in_out_set_qty_display($stock_info);

06110580 Sven Schöling
my $do_qty = AM->sum_with_unit($::form->parse_amount(\%::myconfig, $::form->{do_qty}), $::form->{do_unit});
my $transfer_qty = AM->sum_with_unit(map { $_->{qty}, $_->{unit} } @{ $stock_info });

d707f7ac Moritz Bunkus
$form->header();
06110580 Sven Schöling
print $form->parse_html_template('do/set_stock_in_out', {
qty_matches => $do_qty == $transfer_qty,
});
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub stock_out_form {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
d707f7ac Moritz Bunkus
$form->{title} = $locale->text('Release From Stock');

my $part_info = IC->get_basic_part_info('id' => $form->{parts_id});

07948c34 Moritz Bunkus
my $units = AM->retrieve_units(\%myconfig, $form);
d707f7ac Moritz Bunkus
my $units_data = AM->unit_select_data($units, undef, undef, $part_info->{unit});

my @contents = DO->get_item_availability('parts_id' => $form->{parts_id});

my $stock_info = DO->unpack_stock_information('packed' => $form->{stock});

74c7135d Moritz Bunkus
if (!$form->{delivered}) {
d707f7ac Moritz Bunkus
foreach my $row (@contents) {
c7b5d49e Bernd Bleßmann
$row->{available_qty} = $form->format_amount(\%::myconfig, $row->{qty} * 1) . ' ' . $part_info->{unit};
d707f7ac Moritz Bunkus
foreach my $sinfo (@{ $stock_info }) {
next if (($row->{bin_id} != $sinfo->{bin_id}) ||
($row->{warehouse_id} != $sinfo->{warehouse_id}) ||
096f9e3e Bernd Bleßmann
($row->{chargenumber} ne $sinfo->{chargenumber}) ||
($row->{bestbefore} ne $sinfo->{bestbefore}));
d707f7ac Moritz Bunkus
286dc87c Jan Büren
map { $row->{"stock_$_"} = $sinfo->{$_} } qw(qty unit error delivery_order_items_stock_id);
d707f7ac Moritz Bunkus
}
}

} else {
get_basic_bin_wh_info($stock_info);

foreach my $sinfo (@{ $stock_info }) {
map { $sinfo->{"stock_$_"} = $sinfo->{$_} } qw(qty unit);
}
}

ddb162b6 Sven Schöling
$form->header(no_layout => 1);
d707f7ac Moritz Bunkus
print $form->parse_html_template('do/stock_out_form', { 'UNITS' => $units_data,
74c7135d Moritz Bunkus
'WHCONTENTS' => $form->{delivered} ? $stock_info : \@contents,
d707f7ac Moritz Bunkus
'PART_INFO' => $part_info, });

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

sub set_stock_out {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
d707f7ac Moritz Bunkus
my $stock_info = [];

foreach my $i (1 .. $form->{rowcount}) {
$form->{"qty_$i"} = $form->parse_amount(\%myconfig, $form->{"qty_$i"});

next if ($form->{"qty_$i"} <= 0);

push @{ $stock_info }, {
'warehouse_id' => $form->{"warehouse_id_$i"},
'bin_id' => $form->{"bin_id_$i"},
'chargenumber' => $form->{"chargenumber_$i"},
096f9e3e Bernd Bleßmann
'bestbefore' => $form->{"bestbefore_$i"},
d707f7ac Moritz Bunkus
'qty' => $form->{"qty_$i"},
'unit' => $form->{"unit_$i"},
'row' => $i,
286dc87c Jan Büren
'delivery_order_items_stock_id' => $form->{"delivery_order_items_stock_id_$i"},
d707f7ac Moritz Bunkus
};
}

my @errors = DO->check_stock_availability('requests' => $stock_info,
'parts_id' => $form->{parts_id});

65b2387a Moritz Bunkus
$form->{stock} = SL::YAML::Dump($stock_info);
d707f7ac Moritz Bunkus
if (@errors) {
$form->{ERRORS} = [];
map { push @{ $form->{ERRORS} }, $locale->text('Error in row #1: The quantity you entered is bigger than the stocked quantity.', $_->{row}); } @errors;
stock_in_out_form();

} else {
50e62c57 Moritz Bunkus
_stock_in_out_set_qty_display($stock_info);

06110580 Sven Schöling
my $do_qty = AM->sum_with_unit($::form->parse_amount(\%::myconfig, $::form->{do_qty}), $::form->{do_unit});
my $transfer_qty = AM->sum_with_unit(map { $_->{qty}, $_->{unit} } @{ $stock_info });

d707f7ac Moritz Bunkus
$form->header();
06110580 Sven Schöling
print $form->parse_html_template('do/set_stock_in_out', {
qty_matches => $do_qty == $transfer_qty,
});
d707f7ac Moritz Bunkus
}

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

74c7135d Moritz Bunkus
sub transfer_in {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
d707f7ac Moritz Bunkus
251dc385 Moritz Bunkus
if ($form->{id} && DO->is_marked_as_delivered(id => $form->{id})) {
a8459f49 Moritz Bunkus
$form->show_generic_error($locale->text('The parts for this delivery order have already been transferred in.'));
4a9b86a5 Moritz Bunkus
}

251dc385 Moritz Bunkus
save(no_redirect => 1);

d707f7ac Moritz Bunkus
my @part_ids = map { $form->{"id_${_}"} } grep { $form->{"id_${_}"} && $form->{"stock_in_${_}"} } (1 .. $form->{rowcount});
my @all_requests;

if (@part_ids) {
07948c34 Moritz Bunkus
my $units = AM->retrieve_units(\%myconfig, $form);
d707f7ac Moritz Bunkus
my %part_info_map = IC->get_basic_part_info('id' => \@part_ids);
my %request_map;

$form->{ERRORS} = [];

foreach my $i (1 .. $form->{rowcount}) {
next unless ($form->{"id_$i"} && $form->{"stock_in_$i"});

my $row_sum_base_qty = 0;
my $base_unit_factor = $units->{ $part_info_map{$form->{"id_$i"}}->{unit} }->{factor} || 1;

foreach my $request (@{ DO->unpack_stock_information('packed' => $form->{"stock_in_$i"}) }) {
$request->{parts_id} = $form->{"id_$i"};
$row_sum_base_qty += $request->{qty} * $units->{$request->{unit}}->{factor} / $base_unit_factor;

2317430a Moritz Bunkus
$request->{project_id} = $form->{"project_id_$i"} || $form->{globalproject_id};

d707f7ac Moritz Bunkus
push @all_requests, $request;
}

next if (0 == $row_sum_base_qty);

my $do_base_qty = $form->parse_amount(\%myconfig, $form->{"qty_$i"}) * $units->{$form->{"unit_$i"}}->{factor} / $base_unit_factor;

fe1c4800 Sven Schöling
# if ($do_base_qty != $row_sum_base_qty) {
# push @{ $form->{ERRORS} }, $locale->text('Error in position #1: You must either assign no stock at all or the full quantity of #2 #3.',
# $i, $form->{"qty_$i"}, $form->{"unit_$i"});
# }
d707f7ac Moritz Bunkus
}

if (@{ $form->{ERRORS} }) {
74c7135d Moritz Bunkus
push @{ $form->{ERRORS} }, $locale->text('The delivery order has not been marked as delivered. The warehouse contents have not changed.');
d707f7ac Moritz Bunkus
088bf5a0 Moritz Bunkus
set_headings('edit');
d707f7ac Moritz Bunkus
update();
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
09479f02 Moritz Bunkus
$::dispatcher->end_request;
d707f7ac Moritz Bunkus
}
}

DO->transfer_in_out('direction' => 'in',
'requests' => \@all_requests);

088bf5a0 Moritz Bunkus
SL::DB::DeliveryOrder->new(id => $form->{id})->load->update_attributes(delivered => 1);
d707f7ac Moritz Bunkus
ebde433e Jan Büren
flash_later('info', $locale->text("Transfer successful"));
088bf5a0 Moritz Bunkus
$form->{callback} = 'do.pl?action=edit&type=purchase_delivery_order&id=' . $form->escape($form->{id});
$form->redirect;
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

74c7135d Moritz Bunkus
sub transfer_out {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
d707f7ac Moritz Bunkus
251dc385 Moritz Bunkus
if ($form->{id} && DO->is_marked_as_delivered(id => $form->{id})) {
a8459f49 Moritz Bunkus
$form->show_generic_error($locale->text('The parts for this delivery order have already been transferred out.'));
4a9b86a5 Moritz Bunkus
}

251dc385 Moritz Bunkus
save(no_redirect => 1);

d707f7ac Moritz Bunkus
my @part_ids = map { $form->{"id_${_}"} } grep { $form->{"id_${_}"} && $form->{"stock_out_${_}"} } (1 .. $form->{rowcount});
my @all_requests;

if (@part_ids) {
07948c34 Moritz Bunkus
my $units = AM->retrieve_units(\%myconfig, $form);
d707f7ac Moritz Bunkus
my %part_info_map = IC->get_basic_part_info('id' => \@part_ids);
my %request_map;

$form->{ERRORS} = [];

foreach my $i (1 .. $form->{rowcount}) {
next unless ($form->{"id_$i"} && $form->{"stock_out_$i"});

my $row_sum_base_qty = 0;
my $base_unit_factor = $units->{ $part_info_map{$form->{"id_$i"}}->{unit} }->{factor} || 1;

foreach my $request (@{ DO->unpack_stock_information('packed' => $form->{"stock_out_$i"}) }) {
$request->{parts_id} = $form->{"id_$i"};
$request->{base_qty} = $request->{qty} * $units->{$request->{unit}}->{factor} / $base_unit_factor;
be6f6cfd Moritz Bunkus
$request->{project_id} = $form->{"project_id_$i"} ? $form->{"project_id_$i"} : $form->{globalproject_id};
d707f7ac Moritz Bunkus
096f9e3e Bernd Bleßmann
my $map_key = join '--', ($form->{"id_$i"}, @{$request}{qw(warehouse_id bin_id chargenumber bestbefore)});
d707f7ac Moritz Bunkus
$request_map{$map_key} ||= $request;
$request_map{$map_key}->{sum_base_qty} ||= 0;
$request_map{$map_key}->{sum_base_qty} += $request->{base_qty};
$row_sum_base_qty += $request->{base_qty};

push @all_requests, $request;
}

next if (0 == $row_sum_base_qty);

088bf5a0 Moritz Bunkus
my $do_base_qty = $form->{"qty_$i"} * $units->{$form->{"unit_$i"}}->{factor} / $base_unit_factor;
d707f7ac Moritz Bunkus
fe1c4800 Sven Schöling
# if ($do_base_qty != $row_sum_base_qty) {
# push @{ $form->{ERRORS} }, $locale->text('Error in position #1: You must either assign no transfer at all or the full quantity of #2 #3.',
# $i, $form->{"qty_$i"}, $form->{"unit_$i"});
# }
d707f7ac Moritz Bunkus
}

if (%request_map) {
my @bin_ids = map { $_->{bin_id} } values %request_map;
my %bin_info_map = WH->get_basic_bin_info('id' => \@bin_ids);
my @contents = DO->get_item_availability('parts_id' => \@part_ids);

foreach my $inv (@contents) {
096f9e3e Bernd Bleßmann
my $map_key = join '--', @{$inv}{qw(parts_id warehouse_id bin_id chargenumber bestbefore)};
d707f7ac Moritz Bunkus
next unless ($request_map{$map_key});

my $request = $request_map{$map_key};
$request->{ok} = $request->{sum_base_qty} <= $inv->{qty};
}

f404e525 Sven Schöling
foreach my $request (values %request_map) {
d707f7ac Moritz Bunkus
next if ($request->{ok});

my $pinfo = $part_info_map{$request->{parts_id}};
my $binfo = $bin_info_map{$request->{bin_id}};

4b31e6ba Bernd Bleßmann
if ($::instance_conf->get_show_bestbefore) {
73a404b5 Bernd Bleßmann
push @{ $form->{ERRORS} }, $locale->text("There is not enough available of '#1' at warehouse '#2', bin '#3', #4, #5, for the transfer of #6.",
$pinfo->{description},
$binfo->{warehouse_description},
$binfo->{bin_description},
$request->{chargenumber} ? $locale->text('chargenumber #1', $request->{chargenumber}) : $locale->text('no chargenumber'),
$request->{bestbefore} ? $locale->text('bestbefore #1', $request->{bestbefore}) : $locale->text('no bestbefore'),
c7b5d49e Bernd Bleßmann
$form->format_amount(\%::myconfig, $request->{sum_base_qty}) . ' ' . $pinfo->{unit});
73a404b5 Bernd Bleßmann
} else {
push @{ $form->{ERRORS} }, $locale->text("There is not enough available of '#1' at warehouse '#2', bin '#3', #4, for the transfer of #5.",
$pinfo->{description},
$binfo->{warehouse_description},
$binfo->{bin_description},
$request->{chargenumber} ? $locale->text('chargenumber #1', $request->{chargenumber}) : $locale->text('no chargenumber'),
c7b5d49e Bernd Bleßmann
$form->format_amount(\%::myconfig, $request->{sum_base_qty}) . ' ' . $pinfo->{unit});
73a404b5 Bernd Bleßmann
}
d707f7ac Moritz Bunkus
}
}

if (@{ $form->{ERRORS} }) {
74c7135d Moritz Bunkus
push @{ $form->{ERRORS} }, $locale->text('The delivery order has not been marked as delivered. The warehouse contents have not changed.');
d707f7ac Moritz Bunkus
088bf5a0 Moritz Bunkus
set_headings('edit');
d707f7ac Moritz Bunkus
update();
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
09479f02 Moritz Bunkus
$::dispatcher->end_request;
d707f7ac Moritz Bunkus
}
}
DO->transfer_in_out('direction' => 'out',
'requests' => \@all_requests);

088bf5a0 Moritz Bunkus
SL::DB::DeliveryOrder->new(id => $form->{id})->load->update_attributes(delivered => 1);
d707f7ac Moritz Bunkus
ebde433e Jan Büren
flash_later('info', $locale->text("Transfer successful"));
088bf5a0 Moritz Bunkus
$form->{callback} = 'do.pl?action=edit&type=sales_delivery_order&id=' . $form->escape($form->{id});
$form->redirect;
d707f7ac Moritz Bunkus
f404e525 Sven Schöling
$main::lxdebug->leave_sub();
d707f7ac Moritz Bunkus
}

1bfdd83b Moritz Bunkus
sub mark_closed {
f404e525 Sven Schöling
$main::lxdebug->enter_sub();

my $form = $main::form;
1bfdd83b Moritz Bunkus
DO->close_orders('ids' => [ $form->{id} ]);

$form->{closed} = 1;

update();

f404e525 Sven Schöling
$main::lxdebug->leave_sub();
1bfdd83b Moritz Bunkus
}

a2546588 Sven Schöling
sub display_form {
$::lxdebug->enter_sub;

51a586e7 Bernd Bleßmann
check_do_access();
a2546588 Sven Schöling
relink_accounts();
retrieve_partunits();

my $new_rowcount = $::form->{"rowcount"} * 1 + 1;
$::form->{"project_id_${new_rowcount}"} = $::form->{"globalproject_id"};

$::form->language_payment(\%::myconfig);

Common::webdav_folder($::form);

form_header();
display_row(++$::form->{rowcount});
form_footer();

$::lxdebug->leave_sub;
}
1bfdd83b Moritz Bunkus
d707f7ac Moritz Bunkus
sub yes {
f404e525 Sven Schöling
call_sub($main::form->{yes_nextsub});
d707f7ac Moritz Bunkus
}

sub no {
f404e525 Sven Schöling
call_sub($main::form->{no_nextsub});
d707f7ac Moritz Bunkus
}

sub update {
f404e525 Sven Schöling
call_sub($main::form->{update_nextsub} || $main::form->{nextsub} || 'update_delivery_order');
d707f7ac Moritz Bunkus
}
434f88fb Philip Reetz
sub dispatcher {
f404e525 Sven Schöling
my $form = $main::form;
my $locale = $main::locale;

a6ce2c7f Moritz Bunkus
foreach my $action (qw(update print save transfer_out transfer_out_default sort
52d18c01 Jan Büren
transfer_in transfer_in_default mark_closed save_as_new invoice delete)) {
434f88fb Philip Reetz
if ($form->{"action_${action}"}) {
call_sub($action);
return;
}
}

$form->error($locale->text('No action defined.'));
}
52d18c01 Jan Büren
sub transfer_out_default {
$main::lxdebug->enter_sub();

my $form = $main::form;

transfer_in_out_default('direction' => 'out');

$main::lxdebug->leave_sub();
}

sub transfer_in_default {
$main::lxdebug->enter_sub();

my $form = $main::form;

transfer_in_out_default('direction' => 'in');

$main::lxdebug->leave_sub();
}

# Falls das Standardlagerverfahren aktiv ist, wird
# geprüft, ob alle Standardlagerplätze für die Auslager-
# artikel vorhanden sind UND ob die Warenmenge ausreicht zum
# Auslagern. Falls nicht wird entsprechend eine Fehlermeldung
# generiert. Offen Chargennummer / bestbefore wird nicht berücksichtigt
sub transfer_in_out_default {
$main::lxdebug->enter_sub();

my $form = $main::form;
my %myconfig = %main::myconfig;
my $locale = $main::locale;
my %params = @_;

my (%missing_default_bins, %qty_parts, @all_requests, %part_info_map, $default_warehouse_id, $default_bin_id);

Common::check_params(\%params, qw(direction));

# entsprechende defaults holen, falls standardlagerplatz verwendet werden soll
if ($::instance_conf->get_transfer_default_use_master_default_bin) {
ed023e22 Moritz Bunkus
$default_warehouse_id = $::instance_conf->get_warehouse_id;
$default_bin_id = $::instance_conf->get_bin_id;
52d18c01 Jan Büren
}


my @part_ids = map { $form->{"id_${_}"} } (1 .. $form->{rowcount});
if (@part_ids) {
my $units = AM->retrieve_units(\%myconfig, $form);
%part_info_map = IC->get_basic_part_info('id' => \@part_ids);
foreach my $i (1 .. $form->{rowcount}) {
next unless ($form->{"id_$i"});
my $base_unit_factor = $units->{ $part_info_map{$form->{"id_$i"}}->{unit} }->{factor} || 1;
my $qty = $form->parse_amount(\%myconfig, $form->{"qty_$i"}) * $units->{$form->{"unit_$i"}}->{factor} / $base_unit_factor;
d98812a8 Jan Büren
a8459f49 Moritz Bunkus
$form->show_generic_error($locale->text("Cannot transfer negative entries." )) if ($qty < 0);
d98812a8 Jan Büren
# if we do not want to transfer services and this part is a service, set qty to zero
5caaac6b Jan Büren
# ... and do not create a hash entry in %qty_parts below (will skip check for bins for the transfer == out case)
# ... and push only a empty (undef) element to @all_requests (will skip check for bin_id and warehouse_id and will not alter the row)

8797da6a Jan Büren
$qty = 0 if (!$::instance_conf->get_transfer_default_services && $part_info_map{$form->{"id_$i"}}->{part_type} eq 'service');
52d18c01 Jan Büren
$qty_parts{$form->{"id_$i"}} += $qty;
79fe86a4 Jan Büren
if ($qty == 0) {
1947cd9a Jan Büren
delete $qty_parts{$form->{"id_$i"}} unless $qty_parts{$form->{"id_$i"}};
79fe86a4 Jan Büren
undef $form->{"stock_in_$i"};
}
52d18c01 Jan Büren
$part_info_map{$form->{"id_$i"}}{bin_id} ||= $default_bin_id;
$part_info_map{$form->{"id_$i"}}{warehouse_id} ||= $default_warehouse_id;

79fe86a4 Jan Büren
push @all_requests, ($qty == 0) ? { } : {
52d18c01 Jan Büren
'chargenumber' => '', #?? die müsste entsprechend geholt werden
#'bestbefore' => undef, # TODO wird nicht berücksichtigt
'bin_id' => $part_info_map{$form->{"id_$i"}}{bin_id},
'qty' => $qty,
'parts_id' => $form->{"id_$i"},
b8f55e88 Jan Büren
'comment' => $locale->text("Default transfer delivery order"),
52d18c01 Jan Büren
'unit' => $part_info_map{$form->{"id_$i"}}{unit},
'warehouse_id' => $part_info_map{$form->{"id_$i"}}{warehouse_id},
'oe_id' => $form->{id},
'project_id' => $form->{"project_id_$i"} ? $form->{"project_id_$i"} : $form->{globalproject_id}
};
}

# jetzt wird erst überprüft, ob die Stückzahl entsprechend stimmt.
5caaac6b Jan Büren
# check if bin (transfer in and transfer out and qty (transfer out) is correct
foreach my $key (keys %qty_parts) {
79fe86a4 Jan Büren
5caaac6b Jan Büren
$missing_default_bins{$key}{missing_bin} = 1 unless ($part_info_map{$key}{bin_id});
next unless ($part_info_map{$key}{bin_id}); # abbruch
52d18c01 Jan Büren
5caaac6b Jan Büren
if ($params{direction} eq 'out') { # wird nur für ausgehende Mengen benötigt
52d18c01 Jan Büren
my ($max_qty, $error) = WH->get_max_qty_parts_bin(parts_id => $key, bin_id => $part_info_map{$key}{bin_id});
if ($error == 1) {
# wir können nicht entscheiden, welche charge oder mhd (bestbefore) ausgewählt sein soll
# deshalb rückmeldung nach oben geben, manuell auszulagern
# TODO Bei nur einem Treffer mit Charge oder bestbefore wäre das noch möglich
$missing_default_bins{$key}{chargenumber} = 1;
}
if ($max_qty < $qty_parts{$key}){
$missing_default_bins{$key}{missing_qty} = $max_qty - $qty_parts{$key};
}
}
}
} # if @parts_id

# Abfrage für Fehlerbehandlung (nur bei direction == out)
if (scalar (keys %missing_default_bins)) {
my $fehlertext;
foreach my $fehler (keys %missing_default_bins) {

my $ware = WH->get_part_description(parts_id => $fehler);
if ($missing_default_bins{$fehler}{missing_bin}){
$fehlertext .= "Kein Standardlagerplatz definiert bei $ware <br>";
}
if ($missing_default_bins{$fehler}{missing_qty}) { # missing_qty
$fehlertext .= "Es fehlen " . $missing_default_bins{$fehler}{missing_qty}*-1 .
" von $ware auf dem Standard-Lagerplatz " . $part_info_map{$fehler}{bin} . " zum Auslagern<br>";
}
if ($missing_default_bins{$fehler}{chargenumber}){
$fehlertext .= "Die Ware hat eine Chargennummer oder eine Mindesthaltbarkeit definiert.
Hier kann man nicht automatisch entscheiden.
Bitte diesen Lieferschein manuell auslagern.
Bei: $ware";
}
# auslagern soll immer gehen, auch wenn nicht genügend auf lager ist.
# der lagerplatz ist hier extra konfigurierbar, bspw. Lager-Korrektur mit
# Lagerplatz Lagerplatz-Korrektur
ed023e22 Moritz Bunkus
my $default_warehouse_id_ignore_onhand = $::instance_conf->get_warehouse_id_ignore_onhand;
my $default_bin_id_ignore_onhand = $::instance_conf->get_bin_id_ignore_onhand;
52d18c01 Jan Büren
if ($::instance_conf->get_transfer_default_ignore_onhand && $default_bin_id_ignore_onhand) {
# entsprechende defaults holen
# falls chargenumber, bestbefore oder anzahl nicht stimmt, auf automatischen
# lagerplatz wegbuchen!
foreach (@all_requests) {
if ($_->{parts_id} eq $fehler){
$_->{bin_id} = $default_bin_id_ignore_onhand;
$_->{warehouse_id} = $default_warehouse_id_ignore_onhand;
}
}
} else {
#$main::lxdebug->message(0, 'Fehlertext: ' . $fehlertext);
a8459f49 Moritz Bunkus
$form->show_generic_error($locale->text("Cannot transfer. <br> Reason:<br>#1", $fehlertext ));
52d18c01 Jan Büren
}
}
}


# hier der eigentliche fallunterschied für in oder out
my $prefix = $params{direction} eq 'in' ? 'in' : 'out';

# dieser array_ref ist für DO->save da:
# einmal die all_requests in YAML verwandeln, damit delivery_order_items_stock
# gefüllt werden kann.
ae71699d Jan Büren
# could be dumped to the form in the first loop,
# but maybe bin_id and warehouse_id has changed to the "korrekturlager" with
# allowed negative qty ($::instance_conf->get_warehouse_id_ignore_onhand) ...
79fe86a4 Jan Büren
my $i = 0;
52d18c01 Jan Büren
foreach (@all_requests){
$i++;
79fe86a4 Jan Büren
next unless scalar(%{ $_ });
65b2387a Moritz Bunkus
$form->{"stock_${prefix}_$i"} = SL::YAML::Dump([$_]);
52d18c01 Jan Büren
}

save(no_redirect => 1); # Wir können auslagern, deshalb beleg speichern
# und in delivery_order_items_stock speichern
ae71699d Jan Büren
# ... and fill back the persistent dois_id for inventory fk
undef (@all_requests);
foreach my $i (1 .. $form->{rowcount}) {
next unless ($form->{"id_$i"} && $form->{"stock_${prefix}_$i"});
e26049ca Jan Büren
push @all_requests, @{ DO->unpack_stock_information('packed' => $form->{"stock_${prefix}_$i"}) };
ae71699d Jan Büren
}
52d18c01 Jan Büren
DO->transfer_in_out('direction' => $prefix,
'requests' => \@all_requests);

SL::DB::DeliveryOrder->new(id => $form->{id})->load->update_attributes(delivered => 1);

$form->{callback} = 'do.pl?action=edit&type=sales_delivery_order&id=' . $form->escape($form->{id}) if $params{direction} eq 'out';
$form->{callback} = 'do.pl?action=edit&type=purchase_delivery_order&id=' . $form->escape($form->{id}) if $params{direction} eq 'in';
$form->redirect;

}
fc762fdc Jan Büren
54086731 Jan Büren
sub sort {
$main::lxdebug->enter_sub();

fc762fdc Jan Büren
check_do_access();

54086731 Jan Büren
my $form = $main::form;
my %temp_hash;

819758a1 Jan Büren
save(no_redirect => 1); # has to be done, at least for newly added positions
54086731 Jan Büren
# hashify partnumbers, positions. key is delivery_order_items_id
for my $i (1 .. ($form->{rowcount}) ) {
$temp_hash{$form->{"delivery_order_items_id_$i"}} = { runningnumber => $form->{"runningnumber_$i"}, partnumber => $form->{"partnumber_$i"} };
26dfef7d Jan Büren
if ($form->{id} && $form->{"discount_$i"}) {
# prepare_order assumes a db value if there is a form->id and multiplies *100
# We hope for new controller code (no more format_amount/parse_amount distinction)
$form->{"discount_$i"} /=100;
}
54086731 Jan Büren
}
# naturally sort partnumbers and get a sorted array of doi_ids
fc762fdc Jan Büren
my @sorted_doi_ids = sort { Sort::Naturally::ncmp($temp_hash{$a}->{"partnumber"}, $temp_hash{$b}->{"partnumber"}) } keys %temp_hash;
54086731 Jan Büren

my $new_number = 1;
fc762fdc Jan Büren
54086731 Jan Büren
for (@sorted_doi_ids) {
$form->{"runningnumber_$temp_hash{$_}->{runningnumber}"} = $new_number;
$new_number++;
}
26dfef7d Jan Büren
# all parse_amounts changes are in form (i.e. , to .) therefore we need
# another format_amount to change it back, for the next save ;-(
# works great except for row discounts (see above comment)
prepare_order();


54086731 Jan Büren
$main::lxdebug->leave_sub();
save();
}
fc762fdc Jan Büren
__END__

=pod

=encoding utf8

=head1 NAME

do.pl - Script for all calls to delivery order

=head1 FUNCTIONS

=over 2

=item C<sort>

Sorts all position with Natural Sort. Can be activated in form_footer.html like this
C<E<lt>input class="submit" type="submit" name="action_sort" id="sort_button" value="[% 'Sort and Save' | $T8 %]"E<gt>>

=back

=head1 TODO

Sort and Save can be implemented as an optional button if configuration ca be set by client config.
Example coding for database scripts and templates in (git show af2f24b8), check also
autogeneration for rose (scripts/rose_auto_create_model.pl --h)