|
#=====================================================================
|
|
# 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
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
# MA 02110-1335, USA.
|
|
#======================================================================
|
|
#
|
|
# Order entry module
|
|
# Quotation module
|
|
#======================================================================
|
|
|
|
|
|
use Carp;
|
|
use POSIX qw(strftime);
|
|
use Try::Tiny;
|
|
|
|
use SL::DB::Order;
|
|
use SL::DB::OrderItem;
|
|
use SL::DO;
|
|
use SL::FU;
|
|
use SL::OE;
|
|
use SL::IR;
|
|
use SL::IS;
|
|
use SL::Helper::Flash qw(flash_later);
|
|
use SL::Helper::UserPreferences::DisplayPreferences;
|
|
use SL::Helper::ShippedQty;
|
|
use SL::MoreCommon qw(ary_diff restore_form save_form);
|
|
use SL::Presenter::ItemsList;
|
|
use SL::ReportGenerator;
|
|
use SL::YAML;
|
|
use List::MoreUtils qw(uniq any none);
|
|
use List::Util qw(min max reduce sum);
|
|
use Data::Dumper;
|
|
|
|
use SL::Controller::Order;
|
|
use SL::DB::Customer;
|
|
use SL::DB::TaxZone;
|
|
use SL::DB::PaymentTerm;
|
|
use SL::DB::ValidityToken;
|
|
use SL::DB::Vendor;
|
|
|
|
require "bin/mozilla/common.pl";
|
|
require "bin/mozilla/io.pl";
|
|
require "bin/mozilla/reportgenerator.pl";
|
|
|
|
use strict;
|
|
|
|
1;
|
|
|
|
# end of main
|
|
|
|
# For locales.pl:
|
|
# $locale->text('Edit the purchase_order');
|
|
# $locale->text('Edit the sales_order');
|
|
# $locale->text('Edit the request_quotation');
|
|
# $locale->text('Edit the sales_quotation');
|
|
|
|
# $locale->text('Workflow purchase_order');
|
|
# $locale->text('Workflow sales_order');
|
|
# $locale->text('Workflow request_quotation');
|
|
# $locale->text('Workflow sales_quotation');
|
|
|
|
my $oe_access_map = {
|
|
'sales_order_intake' => 'sales_order_edit',
|
|
'sales_order' => 'sales_order_edit',
|
|
'purchase_order' => 'purchase_order_edit',
|
|
'purchase_order_confirmation' => 'purchase_order_edit',
|
|
'request_quotation' => 'request_quotation_edit',
|
|
'sales_quotation' => 'sales_quotation_edit',
|
|
'purchase_quotation_intake' => 'request_quotation_edit',
|
|
};
|
|
|
|
my $oe_view_access_map = {
|
|
'sales_order_intake' => 'sales_order_edit | sales_order_view',
|
|
'sales_order' => 'sales_order_edit | sales_order_view',
|
|
'purchase_order' => 'purchase_order_edit | purchase_order_view',
|
|
'purchase_order_confirmation' => 'purchase_order_edit | purchase_order_view',
|
|
'request_quotation' => 'request_quotation_edit | request_quotation_view',
|
|
'sales_quotation' => 'sales_quotation_edit | sales_quotation_view',
|
|
'purchase_quotation_intake' => 'request_quotation_edit | request_quotation_view',
|
|
};
|
|
|
|
sub check_oe_access {
|
|
my (%params) = @_;
|
|
my $form = $main::form;
|
|
|
|
my $right = ($params{with_view}) ? $oe_view_access_map->{$form->{type}} : $oe_access_map->{$form->{type}};
|
|
$right ||= 'DOES_NOT_EXIST';
|
|
|
|
$main::auth->assert($right);
|
|
}
|
|
|
|
sub check_oe_conversion_to_sales_invoice_allowed {
|
|
return 1 if $::form->{type} !~ m/^sales/;
|
|
return 1 if ($::form->{type} =~ m/quotation/) && $::instance_conf->get_allow_sales_invoice_from_sales_quotation;
|
|
return 1 if ($::form->{type} =~ m/order/) && $::instance_conf->get_allow_sales_invoice_from_sales_order;
|
|
|
|
$::form->show_generic_error($::locale->text("You do not have the permissions to access this function."));
|
|
|
|
return 0;
|
|
}
|
|
|
|
sub new_sales_order {
|
|
$main::lxdebug->enter_sub();
|
|
|
|
check_oe_access();
|
|
|
|
my $c = SL::Controller::Order->new;
|
|
$c->action_edit_collective();
|
|
|
|
$main::lxdebug->leave_sub();
|
|
$::dispatcher->end_request;
|
|
}
|
|
|
|
sub convert_to_delivery_orders {
|
|
# collect order ids
|
|
my @multi_ids = map {
|
|
$_ =~ m{^multi_id_(\d+)$} && $::form->{'multi_id_' . $1} && $::form->{'trans_id_' . $1}
|
|
} grep { $_ =~ m{^multi_id_\d+$} } keys %$::form;
|
|
|
|
# make new delivery orders from given orders
|
|
my @orders = map { SL::DB::Order->new(id => $_)->load } @multi_ids;
|
|
my @do_ids;
|
|
my @failed;
|
|
foreach my $order (@orders) {
|
|
# Only consider not delivered quantities.
|
|
SL::Helper::ShippedQty->new->calculate($order)->write_to(\@{$order->items});
|
|
|
|
my @items_with_not_delivered_qty =
|
|
grep {$_->qty > 0}
|
|
map {$_->qty($_->qty - $_->shipped_qty); $_}
|
|
@{$order->items_sorted};
|
|
|
|
my $delivery_order;
|
|
try {
|
|
die t8('no undelivered items') if !@items_with_not_delivered_qty;
|
|
$delivery_order = $order->convert_to_delivery_order(items => \@items_with_not_delivered_qty);
|
|
} catch {
|
|
push @failed, {ordnumber => $order->ordnumber, error => $_};
|
|
};
|
|
push @do_ids, $delivery_order->id if $delivery_order;
|
|
}
|
|
|
|
require "bin/mozilla/do.pl";
|
|
$::form->{script} = 'do.pl';
|
|
$::form->{type} = 'sales_delivery_order';
|
|
$::form->{ids} = \@do_ids;
|
|
$::form->{"l_$_"} = 'Y' for qw(donumber ordnumber cusordnumber transdate reqdate name employee);
|
|
$::form->{top_info_text} = $::locale->text('Converted delivery orders');
|
|
|
|
flash('info', t8('#1 salses orders were converted to #2 delivery orders', scalar @orders, scalar @do_ids));
|
|
if (@failed) {
|
|
flash('error', t8('The following orders could not be converted to delivery orders:'));
|
|
flash('error', $_->{ordnumber} . ': ' . $_->{error}) for @failed;
|
|
}
|
|
|
|
orders();
|
|
}
|
|
|
|
sub order_links {
|
|
$main::lxdebug->enter_sub();
|
|
|
|
my (%params) = @_;
|
|
|
|
my $form = $main::form;
|
|
my %myconfig = %main::myconfig;
|
|
my $locale = $main::locale;
|
|
|
|
check_oe_access();
|
|
|
|
# retrieve order/quotation
|
|
my $editing = $form->{id};
|
|
|
|
OE->retrieve(\%myconfig, \%$form);
|
|
|
|
# if multiple rowcounts (== collective order) then check if the
|
|
# there were more than one customer (in that case OE::retrieve removes
|
|
# the content from the field)
|
|
$form->error($locale->text('Collective Orders only work for orders from one customer!'))
|
|
if $form->{rowcount} && $form->{type} eq 'sales_order'
|
|
&& defined $form->{customer} && $form->{customer} eq '';
|
|
|
|
$form->backup_vars(qw(payment_id language_id taxzone_id salesman_id taxincluded cp_id intnotes shipto_id delivery_term_id currency));
|
|
|
|
# get customer / vendor
|
|
if ($form->{type} =~ /(purchase_order|request_quotation)/) {
|
|
IR->get_vendor(\%myconfig, \%$form);
|
|
} else {
|
|
IS->get_customer(\%myconfig, \%$form);
|
|
$form->{billing_address_id} = $form->{default_billing_address_id} if $params{is_new};
|
|
}
|
|
|
|
$form->restore_vars(qw(payment_id language_id taxzone_id intnotes cp_id shipto_id delivery_term_id));
|
|
$form->restore_vars(qw(currency)) if $form->{id};
|
|
$form->restore_vars(qw(taxincluded)) if $form->{id};
|
|
$form->restore_vars(qw(salesman_id)) if $editing;
|
|
$form->{forex} = $form->{exchangerate};
|
|
$form->{employee} = "$form->{employee}--$form |