Adding a line to a proposal, order, invoice, supplier order or supplier
invoice did not redirect after the POST succeeded, so pressing F5 (or
accepting the browser's "confirm form resubmission" dialog) replayed the
addline POST and duplicated the last line.
Add the same header('Location: ...'); exit(); redirect already used by
the neighboring confirm_addsubtotalline action, on the success path only,
in:
- htdocs/comm/propal/card.php
- htdocs/commande/card.php
- htdocs/compta/facture/card.php
- htdocs/fourn/commande/card.php
- htdocs/fourn/facture/card.php
Validation-error paths are untouched: no DB write happens there, so a
refresh can't duplicate anything, and the form must keep re-displaying
the user's typed values.
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
3788 lines
160 KiB
PHP
3788 lines
160 KiB
PHP
<?php
|
|
/* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
|
* Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
|
|
* Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
|
|
* Copyright (C) 2005-2015 Regis Houssin <regis.houssin@inodbox.com>
|
|
* Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
|
|
* Copyright (C) 2010-2013 Juanjo Menent <jmenent@2byte.es>
|
|
* Copyright (C) 2011-2023 Philippe Grand <philippe.grand@atoo-net.com>
|
|
* Copyright (C) 2012-2023 Christophe Battarel <christophe.battarel@altairis.fr>
|
|
* Copyright (C) 2012-2016 Marcos García <marcosgdf@gmail.com>
|
|
* Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
|
|
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
|
* Copyright (C) 2014 Ferran Marcet <fmarcet@2byte.es>
|
|
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
|
|
* Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
|
|
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
|
|
* Copyright (C) 2023-2024 Benjamin Falière <benjamin.faliere@altairis.fr>
|
|
* Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
|
|
* Copyright (C) 2025 Lenin Rivas <lenin.rivas777@gmail.com>
|
|
* Copyright (C) 2026 Lionel Vessiller <lvessiller@open-dsi.fr>
|
|
*
|
|
* 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 3 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, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file htdocs/commande/card.php
|
|
* \ingroup commande
|
|
* \brief Page to show sales order
|
|
*/
|
|
|
|
// Load Dolibarr environment
|
|
require '../main.inc.php';
|
|
/**
|
|
* @var Conf $conf
|
|
* @var DoliDB $db
|
|
* @var ExtraFields $extrafields
|
|
* @var HookManager $hookmanager
|
|
* @var Societe $mysoc
|
|
* @var Translate $langs
|
|
* @var User $user
|
|
*/
|
|
|
|
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formorder.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formmargin.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/modules/commande/modules_commande.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/lib/order.lib.php';
|
|
|
|
require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
|
|
|
|
if (isModEnabled("propal")) {
|
|
require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php';
|
|
}
|
|
|
|
if (isModEnabled('project')) {
|
|
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
|
|
}
|
|
|
|
if (isModEnabled('variants')) {
|
|
require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination.class.php';
|
|
}
|
|
|
|
|
|
// Load translation files required by the page
|
|
$langs->loadLangs(array('orders', 'sendings', 'companies', 'bills', 'propal', 'products', 'other'));
|
|
|
|
if (isModEnabled('incoterm')) {
|
|
$langs->load('incoterm');
|
|
}
|
|
if (isModEnabled('margin')) {
|
|
$langs->load('margins');
|
|
}
|
|
if (isModEnabled('productbatch')) {
|
|
$langs->load('productbatch');
|
|
}
|
|
|
|
|
|
$id = (GETPOSTINT('id') ? GETPOSTINT('id') : GETPOSTINT('orderid'));
|
|
$ref = GETPOST('ref', 'alpha');
|
|
$socid = GETPOSTINT('socid');
|
|
$action = GETPOST('action', 'aZ09');
|
|
$cancel = GETPOST('cancel', 'alpha');
|
|
$confirm = GETPOST('confirm', 'alpha');
|
|
$backtopage = GETPOST('backtopage', 'alpha');
|
|
|
|
$lineid = GETPOSTINT('lineid');
|
|
$contactid = GETPOSTINT('contactid');
|
|
$projectid = GETPOSTINT('projectid');
|
|
$origin = GETPOST('origin', 'alpha');
|
|
$originid = (GETPOSTINT('originid') ? GETPOSTINT('originid') : GETPOSTINT('origin_id')); // For backward compatibility
|
|
$rank = (GETPOSTINT('rank') > 0) ? GETPOSTINT('rank') : -1;
|
|
|
|
// Type Contact default
|
|
$type_contact_code = (getDolGlobalString('ORDER_TYPE_CONTACT_DEFAULT') ? getDolGlobalString('ORDER_TYPE_CONTACT_DEFAULT') : 'CUSTOMER');
|
|
|
|
// PDF
|
|
$hidedetails = (GETPOSTINT('hidedetails') ? GETPOSTINT('hidedetails') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
|
|
$hidedesc = (GETPOSTINT('hidedesc') ? GETPOSTINT('hidedesc') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
|
|
$hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
|
|
|
|
// Security check
|
|
if (!empty($user->socid)) {
|
|
$socid = $user->socid;
|
|
}
|
|
|
|
$array_options = 0;
|
|
$object_id = 0;
|
|
$price_base_type = null;
|
|
$lineClassName = null;
|
|
$remise_percent = null;
|
|
$ref_client = null;
|
|
$availability_id = null;
|
|
$shipping_method_id = null;
|
|
$warehouse_id = null;
|
|
$demand_reason_id = null;
|
|
$formproject = null;
|
|
$objectsrc = null;
|
|
$note_public = null;
|
|
$note_private = null;
|
|
$classname = null;
|
|
|
|
|
|
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
|
|
$hookmanager->initHooks(array('ordercard', 'globalcard'));
|
|
|
|
$result = restrictedArea($user, 'commande', $id);
|
|
|
|
$object = new Commande($db);
|
|
|
|
// fetch optionals attributes and labels
|
|
$extrafields->fetch_name_optionals_label($object->table_element);
|
|
|
|
// Load object
|
|
include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'
|
|
|
|
// Permissions / Rights
|
|
$usercanread = $user->hasRight("commande", "lire");
|
|
$usercancreate = $user->hasRight("commande", "creer");
|
|
$usercandelete = $user->hasRight("commande", "supprimer");
|
|
|
|
// Advanced permissions
|
|
$usercanclose = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('commande', 'order_advance', 'close')));
|
|
$usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $usercancreate) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('commande', 'order_advance', 'validate')));
|
|
$usercancancel = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $usercancreate) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('commande', 'order_advance', 'annuler')));
|
|
$usercansend = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('commande', 'order_advance', 'send'));
|
|
$usercangeneratedoc = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('commande', 'order_advance', 'generetedoc'));
|
|
|
|
$usermustrespectpricemin = ((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance')) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS'));
|
|
$usercancreatepurchaseorder = ($user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer'));
|
|
|
|
$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
|
|
$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
|
|
$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
|
|
$permissiontoeditextra = $usercancreate;
|
|
if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
|
|
// For action 'update_extras', is there a specific permission set for the attribute to update
|
|
$permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
|
|
}
|
|
|
|
$error = 0;
|
|
|
|
$date_delivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
|
|
|
|
$selectedLines = array();
|
|
|
|
|
|
/*
|
|
* Actions
|
|
*/
|
|
|
|
$parameters = array('socid' => $socid);
|
|
// Note that $action and $object may be modified by some hooks
|
|
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
|
|
if ($reshook < 0) {
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
|
}
|
|
|
|
if (empty($reshook)) {
|
|
$backurlforlist = DOL_URL_ROOT . '/commande/list.php';
|
|
|
|
if (empty($backtopage) || ($cancel && empty($id))) {
|
|
if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
|
|
if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
|
|
$backtopage = $backurlforlist;
|
|
} else {
|
|
$backtopage = DOL_URL_ROOT . '/commande/card.php?id=' . ((!empty($id) && $id > 0) ? $id : '__ID__');
|
|
}
|
|
}
|
|
}
|
|
|
|
$selectedLines = GETPOST('toselect', 'array:int');
|
|
|
|
if ($cancel) {
|
|
if (!empty($backtopageforcancel)) {
|
|
header("Location: " . $backtopageforcancel);
|
|
exit;
|
|
} elseif (!empty($backtopage)) {
|
|
header("Location: " . $backtopage);
|
|
exit;
|
|
}
|
|
$action = '';
|
|
}
|
|
|
|
include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be 'include', not 'include_once'
|
|
|
|
include DOL_DOCUMENT_ROOT . '/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
|
|
|
|
include DOL_DOCUMENT_ROOT . '/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
|
|
|
|
// Action clone object
|
|
if ($action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
|
|
if (!($socid > 0)) {
|
|
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('IdThirdParty')), null, 'errors');
|
|
} else {
|
|
if ($object->id > 0) {
|
|
// We clone object to avoid to denaturate loaded object when setting some properties for clone or if createFromClone modifies the object.
|
|
$objectutil = dol_clone($object, 1);
|
|
|
|
$result = $objectutil->createFromClone($user, $socid);
|
|
if ($result > 0) {
|
|
$warningMsgLineList = array();
|
|
// check all product lines are to sell otherwise add a warning message for each product line is not to sell
|
|
foreach ($object->lines as $line) {
|
|
if (!is_object($line->product)) {
|
|
$line->fetch_product();
|
|
}
|
|
if (is_object($line->product) && $line->product->id > 0) {
|
|
if (empty($line->product->status)) {
|
|
$warningMsgLineList[$line->id] = $langs->trans('WarningLineProductNotToSell', $line->product->ref);
|
|
}
|
|
}
|
|
}
|
|
if (!empty($warningMsgLineList)) {
|
|
setEventMessages('', $warningMsgLineList, 'warnings');
|
|
}
|
|
|
|
header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result);
|
|
exit;
|
|
} else {
|
|
setEventMessages($objectutil->error, $objectutil->errors, 'errors');
|
|
$action = '';
|
|
}
|
|
}
|
|
}
|
|
} elseif ($action == 'reopen' && $usercancreate) {
|
|
// Reopen a closed order
|
|
if ($object->status == Commande::STATUS_CANCELED || $object->status == Commande::STATUS_CLOSED) {
|
|
if (getDolGlobalInt('ORDER_REOPEN_TO_DRAFT')) {
|
|
$idwarehouse = GETPOSTINT('idwarehouse');
|
|
$result = $object->setDraft($user, $idwarehouse);
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} else {
|
|
$result = $object->set_reopen($user);
|
|
if ($result > 0) {
|
|
setEventMessages($langs->trans('OrderReopened', $object->ref), null);
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
}
|
|
} elseif ($action == 'confirm_delete' && $confirm == 'yes' && $usercandelete) {
|
|
// Remove order
|
|
$result = $object->delete($user);
|
|
if ($result > 0) {
|
|
header('Location: list.php?restore_lastsearch_values=1');
|
|
exit;
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) {
|
|
// Remove a product line
|
|
$result = $object->deleteLine($user, $lineid);
|
|
if ($result > 0) {
|
|
// reorder lines
|
|
$object->line_order(true);
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = '';
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
|
|
$newlang = GETPOST('lang_id', 'aZ09');
|
|
}
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
|
|
header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
|
|
exit;
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'confirm_delete_subtotalline' && $confirm == 'yes' && $usercancreate) {
|
|
$result = $object->deleteSubtotalLine($langs, GETPOSTINT('lineid'), (bool) GETPOST('deletecorrespondingsubtotalline'), $user);
|
|
if ($result > 0) {
|
|
// reorder lines
|
|
$object->line_order(true);
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = '';
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
|
|
$newlang = GETPOST('lang_id', 'aZ09');
|
|
}
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
|
|
header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
|
|
exit;
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'classin' && $usercancreate) {
|
|
// Link to a project
|
|
$object->setProject(GETPOSTINT('projectid'));
|
|
} elseif ($action == 'add' && $usercancreate) {
|
|
// Add order
|
|
$datecommande = dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
|
|
$date_delivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
|
|
|
|
if ($datecommande == '') {
|
|
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')), null, 'errors');
|
|
$action = 'create';
|
|
$error++;
|
|
}
|
|
|
|
if ($socid < 1) {
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), null, 'errors');
|
|
$action = 'create';
|
|
$error++;
|
|
}
|
|
|
|
if (!$error) {
|
|
$object->socid = $socid;
|
|
$object->fetch_thirdparty();
|
|
|
|
$db->begin();
|
|
|
|
$object->date_commande = $datecommande;
|
|
$object->note_private = GETPOST('note_private', 'restricthtml');
|
|
$object->note_public = GETPOST('note_public', 'restricthtml');
|
|
$object->source = GETPOSTINT('source_id');
|
|
$object->fk_project = GETPOSTINT('projectid');
|
|
$object->ref_client = GETPOST('ref_client', 'alpha');
|
|
$object->model_pdf = GETPOST('model');
|
|
$object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
|
|
$object->deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
|
|
$object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
|
|
$object->fk_account = GETPOSTINT('fk_account');
|
|
$object->availability_id = GETPOSTINT('availability_id');
|
|
$object->demand_reason_id = GETPOSTINT('demand_reason_id');
|
|
$object->delivery_date = $date_delivery;
|
|
$object->shipping_method_id = GETPOSTINT('shipping_method_id');
|
|
$object->warehouse_id = GETPOSTINT('warehouse_id');
|
|
$object->fk_delivery_address = GETPOSTINT('fk_address');
|
|
$object->contact_id = GETPOSTINT('contactid');
|
|
$object->fk_incoterms = GETPOSTINT('incoterm_id');
|
|
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
|
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
|
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
|
|
// Fill array 'array_options' with data from add form
|
|
$ret = $extrafields->setOptionalsFromPost(null, $object);
|
|
if ($ret < 0) {
|
|
$error++;
|
|
}
|
|
|
|
// If creation from another object of another module (Example: origin=propal, originid=1)
|
|
if (!empty($origin) && !empty($originid)) {
|
|
// Parse element/subelement (ex: project_task)
|
|
$element = $subelement = $origin;
|
|
$regs = array();
|
|
if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
|
|
$element = $regs[1];
|
|
$subelement = $regs[2];
|
|
}
|
|
|
|
// For compatibility
|
|
if ($element == 'order') {
|
|
$element = $subelement = 'commande';
|
|
}
|
|
if ($element == 'propal') {
|
|
$element = 'comm/propal';
|
|
$subelement = 'propal';
|
|
}
|
|
if ($element == 'contract') {
|
|
$element = $subelement = 'contrat';
|
|
}
|
|
|
|
$object->origin = $origin; // deprecated
|
|
$object->origin_type = $origin;
|
|
$object->origin_id = $originid;
|
|
|
|
// Possibility to add external linked objects with hooks
|
|
$object->linked_objects[$object->origin_type] = $object->origin_id;
|
|
$other_linked_objects = GETPOST('other_linked_objects', 'array');
|
|
if (!empty($other_linked_objects)) {
|
|
$object->linked_objects = array_merge($object->linked_objects, $other_linked_objects);
|
|
}
|
|
|
|
if (!$error) {
|
|
$object_id = $object->create($user);
|
|
|
|
if ($object_id > 0) {
|
|
dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
|
|
|
|
$classname = ucfirst($subelement);
|
|
$srcobject = new $classname($db);
|
|
'@phan-var-force Commande|Propal|Contrat $srcobject';
|
|
/** @var Commande|Propal|Contrat $srcobject */
|
|
|
|
dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines");
|
|
$result = $srcobject->fetch($object->origin_id);
|
|
if ($result > 0) {
|
|
$lines = $srcobject->lines;
|
|
if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
|
|
$srcobject->fetch_lines();
|
|
$lines = $srcobject->lines;
|
|
}
|
|
|
|
$fk_parent_line = 0;
|
|
$num = count($lines);
|
|
|
|
for ($i = 0; $i < $num; $i++) {
|
|
if (!in_array($lines[$i]->id, $selectedLines)) {
|
|
continue; // Skip unselected lines
|
|
}
|
|
|
|
$label = (!empty($lines[$i]->label) ? $lines[$i]->label : '');
|
|
$desc = (!empty($lines[$i]->desc) ? $lines[$i]->desc : '');
|
|
$product_type = (!empty($lines[$i]->product_type) ? $lines[$i]->product_type : 0);
|
|
|
|
// Dates
|
|
// TODO mutualiser
|
|
$date_start = $lines[$i]->date_debut_prevue;
|
|
if ($lines[$i]->date_debut_reel) {
|
|
$date_start = $lines[$i]->date_debut_reel;
|
|
}
|
|
if ($lines[$i]->date_start) {
|
|
$date_start = $lines[$i]->date_start;
|
|
}
|
|
$date_end = $lines[$i]->date_fin_prevue;
|
|
if ($lines[$i]->date_fin_reel) {
|
|
$date_end = $lines[$i]->date_fin_reel;
|
|
}
|
|
if ($lines[$i]->date_end) {
|
|
$date_end = $lines[$i]->date_end;
|
|
}
|
|
|
|
// Reset fk_parent_line for no child products and special product
|
|
if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
|
|
$fk_parent_line = 0;
|
|
}
|
|
|
|
// Extrafields
|
|
if (method_exists($lines[$i], 'fetch_optionals')) { // For avoid conflicts if trigger used
|
|
$lines[$i]->fetch_optionals();
|
|
$array_options = $lines[$i]->array_options;
|
|
}
|
|
|
|
$tva_tx = $lines[$i]->tva_tx;
|
|
if (!empty($lines[$i]->vat_src_code) && !preg_match('/\(/', $tva_tx)) {
|
|
$tva_tx .= ' (' . $lines[$i]->vat_src_code . ')';
|
|
}
|
|
|
|
// Preserve the original entry mode of the line so the total is computed from the typed value (no rounding drift).
|
|
$line_price_base_type = $lines[$i]->getPriceBaseType();
|
|
$result = $object->addline(
|
|
$desc,
|
|
$lines[$i]->subprice,
|
|
$lines[$i]->qty,
|
|
$tva_tx,
|
|
$lines[$i]->localtax1_tx,
|
|
$lines[$i]->localtax2_tx,
|
|
$lines[$i]->fk_product,
|
|
$lines[$i]->remise_percent,
|
|
$lines[$i]->info_bits,
|
|
$lines[$i]->fk_remise_except,
|
|
$line_price_base_type,
|
|
(float) $lines[$i]->subprice_ttc,
|
|
$date_start,
|
|
$date_end,
|
|
$product_type,
|
|
$lines[$i]->rang,
|
|
$lines[$i]->special_code,
|
|
$fk_parent_line,
|
|
$lines[$i]->fk_fournprice,
|
|
$lines[$i]->pa_ht,
|
|
$label,
|
|
$array_options,
|
|
$lines[$i]->fk_unit,
|
|
$object->origin,
|
|
$lines[$i]->rowid,
|
|
0,
|
|
$lines[$i]->ref_ext,
|
|
0
|
|
);
|
|
|
|
if ($result < 0) {
|
|
$error++;
|
|
break;
|
|
}
|
|
|
|
foreach ($object->lines as $line) {
|
|
if ($line->id == $result) {
|
|
$line->extraparams = $lines[$i]->extraparams;
|
|
$line->setExtraParameters();
|
|
}
|
|
}
|
|
|
|
// Defined the new fk_parent_line
|
|
if ($result > 0 && $lines[$i]->product_type == 9) {
|
|
$fk_parent_line = $result;
|
|
}
|
|
}
|
|
} else {
|
|
setEventMessages($srcobject->error, $srcobject->errors, 'errors');
|
|
$error++;
|
|
}
|
|
|
|
// Now we create same links to contact than the ones found on origin object
|
|
/* Useless, already into the create
|
|
if (getDolGlobalString('MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN')) {
|
|
$originforcontact = $object->origin;
|
|
$originidforcontact = $object->origin_id;
|
|
if ($originforcontact == 'shipping') // shipment and order share the same contacts. If creating from shipment we take data of order
|
|
{
|
|
$originforcontact=$srcobject->origin;
|
|
$originidforcontact=$srcobject->origin_id;
|
|
}
|
|
$sqlcontact = "SELECT code, fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
|
|
$sqlcontact.= " WHERE element_id = ".((int) $originidforcontact)." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$db->escape($originforcontact)."'";
|
|
|
|
$resqlcontact = $db->query($sqlcontact);
|
|
if ($resqlcontact)
|
|
{
|
|
while($objcontact = $db->fetch_object($resqlcontact))
|
|
{
|
|
//print $objcontact->code.'-'.$objcontact->fk_socpeople."\n";
|
|
$object->add_contact($objcontact->fk_socpeople, $objcontact->code);
|
|
}
|
|
}
|
|
else dol_print_error($resqlcontact);
|
|
}*/
|
|
|
|
// Hooks
|
|
$parameters = array('objFrom' => $srcobject);
|
|
// Note that $action and $object may be modified by hook
|
|
$reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action);
|
|
if ($reshook < 0) {
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
|
$error++;
|
|
}
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
$error++;
|
|
}
|
|
} else {
|
|
// Required extrafield left blank, error message already defined by setOptionalsFromPost()
|
|
$action = 'create';
|
|
}
|
|
} else {
|
|
if (!$error) {
|
|
$object_id = $object->create($user);
|
|
}
|
|
}
|
|
|
|
// Insert default contacts if defined
|
|
if ($object_id > 0) {
|
|
if (GETPOSTINT('contactid')) {
|
|
// $result = $object->add_contact(GETPOSTINT('contactid'), 'CUSTOMER', 'external');
|
|
$result = $object->add_contact(GETPOSTINT('contactid'), $type_contact_code, 'external');
|
|
if ($result < 0) {
|
|
setEventMessages($langs->trans("ErrorFailedToAddContact"), null, 'errors');
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
$id = $object_id;
|
|
$action = '';
|
|
}
|
|
|
|
if (isModEnabled('category')) {
|
|
$categories = GETPOST('categories', 'array');
|
|
if (method_exists($object, 'setCategories')) {
|
|
$object->setCategories($categories);
|
|
}
|
|
}
|
|
|
|
// End of object creation, we show it
|
|
if ($object_id > 0 && !$error) {
|
|
$db->commit();
|
|
header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object_id);
|
|
exit();
|
|
} else {
|
|
$db->rollback();
|
|
$action = 'create';
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
} elseif ($action == 'classifybilled' && $usercancreate) {
|
|
$ret = $object->classifyBilled($user);
|
|
|
|
if ($ret < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'classifyunbilled' && $usercancreate) {
|
|
$ret = $object->classifyUnBilled($user);
|
|
if ($ret < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setref_client' && $usercancreate) {
|
|
// Positionne ref commande client
|
|
$result = $object->set_ref_client($user, GETPOST('ref_client'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setremise' && $usercancreate) {
|
|
$result = $object->setDiscount($user, price2num(GETPOST('remise'), 2));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setabsolutediscount' && $usercancreate) {
|
|
if (GETPOST('remise_id')) {
|
|
if ($object->id > 0) {
|
|
$object->insert_discount(GETPOSTINT('remise_id'));
|
|
} else {
|
|
dol_print_error($db, $object->error);
|
|
}
|
|
}
|
|
} elseif ($action == 'setdate' && $usercancreate) {
|
|
$date = dol_mktime(0, 0, 0, GETPOSTINT('order_month'), GETPOSTINT('order_day'), GETPOSTINT('order_year'));
|
|
|
|
$result = $object->set_date($user, $date);
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setdate_livraison' && $usercancreate) {
|
|
$date_delivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
|
|
|
|
$object->fetch($id);
|
|
$result = $object->setDeliveryDate($user, $date_delivery);
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setmode' && $usercancreate) {
|
|
$result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setposinfo' && $usercancreate) {
|
|
$object->fetch($id);
|
|
$object->module_source = GETPOST('posmodule');
|
|
$object->pos_source = GETPOST('posterminal');
|
|
$result = $object->update($user);
|
|
if ($result < 0) {
|
|
dol_print_error($db, $object->error);
|
|
}
|
|
} elseif ($action == 'setmulticurrencycode' && $usercancreate) {
|
|
// Multicurrency Code
|
|
$result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
|
|
} elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
|
|
// Multicurrency rate
|
|
$result = $object->setMulticurrencyRate(GETPOSTFLOAT('multicurrency_tx'), GETPOSTINT('calculation_mode'));
|
|
} elseif ($action == 'setavailability' && $usercancreate) {
|
|
$result = $object->availability(GETPOSTINT('availability_id'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setdemandreason' && $usercancreate) {
|
|
$result = $object->demand_reason(GETPOSTINT('demand_reason_id'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setconditions' && $usercancreate) {
|
|
$result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'), GETPOSTFLOAT('cond_reglement_id_deposit_percent'));
|
|
if ($result < 0) {
|
|
dol_print_error($db, $object->error);
|
|
} else {
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = GETPOST('lang_id', 'alpha');
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
}
|
|
} elseif ($action == 'set_incoterms' && isModEnabled('incoterm') && $usercancreate) {
|
|
// Set incoterm
|
|
$result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setbankaccount' && $usercancreate) {
|
|
// bank account
|
|
$result = $object->setBankAccount(GETPOSTINT('fk_account'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setshippingmethod' && $usercancreate) {
|
|
// shipping method
|
|
$result = $object->setShippingMethod(GETPOSTINT('shipping_method_id'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'setwarehouse' && $usercancreate) {
|
|
// warehouse
|
|
$result = $object->setWarehouse(GETPOSTINT('warehouse_id'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'settags' && isModEnabled('category') && $usercancreate) {
|
|
$result = $object->setCategories(GETPOST('categories', 'array'));
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'addline' && GETPOST('updateallvatlinesblock', 'alpha') && GETPOST('vatforblocklines', 'alpha') !== '' && $usercancreate) {
|
|
$tx_tva = GETPOST('vatforblocklines') ? GETPOST('vatforblocklines') : 0;
|
|
$object->updateSubtotalLineBlockLines($langs, $object->getRangOfLine($lineid), 'tva', $tx_tva);
|
|
} elseif ($action == 'addline' && GETPOST('updatealldiscountlinesblock', 'alpha') && GETPOST('discountforblocklines', 'alpha') !== '' && $usercancreate) {
|
|
$discount = GETPOST('discountforblocklines') ? GETPOST('discountforblocklines') : 0;
|
|
$object->updateSubtotalLineBlockLines($langs, $object->getRangOfLine($lineid), 'discount', $discount);
|
|
} elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && (GETPOST('alldate_start', 'alpha') || GETPOST('alldate_end', 'alpha')) && $usercancreate) {
|
|
// Define date start and date end for all line
|
|
$alldate_start = dol_mktime(GETPOSTINT('alldate_starthour'), GETPOSTINT('alldate_startmin'), 0, GETPOSTINT('alldate_startmonth'), GETPOSTINT('alldate_startday'), GETPOSTINT('alldate_startyear'));
|
|
$alldate_end = dol_mktime(GETPOSTINT('alldate_endhour'), GETPOSTINT('alldate_endmin'), 0, GETPOSTINT('alldate_endmonth'), GETPOSTINT('alldate_endday'), GETPOSTINT('alldate_endyear'));
|
|
foreach ($object->lines as $line) {
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
|
|
continue;
|
|
}
|
|
if ($line->product_type == 1) { // only service line
|
|
// Preserve the original entry mode of the line so the total is not drifted by rounding.
|
|
$line_price_base_type = $line->getPriceBaseType();
|
|
$line_pu = ($line_price_base_type === 'TTC') ? (float) $line->subprice_ttc : (float) $line->subprice;
|
|
$result = $object->updateline($line->id, $line->desc, $line_pu, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line_price_base_type, $line->info_bits, $alldate_start, $alldate_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice);
|
|
}
|
|
}
|
|
} elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('vatforalllines', 'alpha') !== '' && $usercancreate) {
|
|
// Define vat_rate
|
|
$vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
|
|
$vat_rate = str_replace('*', '', $vat_rate);
|
|
$localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
|
|
$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
|
|
foreach ($object->lines as $line) {
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
|
|
continue;
|
|
}
|
|
// Preserve the original entry mode of the line so the total is not drifted by rounding.
|
|
$line_price_base_type = $line->getPriceBaseType();
|
|
$line_pu = ($line_price_base_type === 'TTC') ? (float) $line->subprice_ttc : (float) $line->subprice;
|
|
$result = $object->updateline($line->id, $line->desc, $line_pu, $line->qty, $line->remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $line_price_base_type, $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice);
|
|
}
|
|
} elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('remiseforalllines', 'alpha') !== '' && $usercancreate) {
|
|
// Define remise_percent
|
|
$remise_percent = (GETPOST('remiseforalllines') ? GETPOST('remiseforalllines') : 0);
|
|
$remise_percent = str_replace('*', '', $remise_percent);
|
|
foreach ($object->lines as $line) {
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
|
|
continue;
|
|
}
|
|
$tvatx = $line->tva_tx;
|
|
if (!empty($line->vat_src_code)) {
|
|
$tvatx .= ' (' . $line->vat_src_code . ')';
|
|
}
|
|
// Preserve the original entry mode of the line so the total is not drifted by rounding.
|
|
$line_price_base_type = $line->getPriceBaseType();
|
|
$line_pu = ($line_price_base_type === 'TTC') ? (float) $line->subprice_ttc : (float) $line->subprice;
|
|
$result = $object->updateline($line->id, $line->desc, $line_pu, $line->qty, (float) $remise_percent, $tvatx, $line->localtax1_tx, $line->localtax2_tx, $line_price_base_type, $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice);
|
|
}
|
|
} elseif ($action == 'addline' && $usercancreate && (
|
|
(GETPOST('submitforallmargins', 'alpha') && GETPOST('marginforalllines', 'alpha') !== '') ||
|
|
(GETPOST('submitforallmark', 'alpha') && GETPOST('markforalllines', 'alpha') !== '')
|
|
)) {
|
|
$outlangs = $langs;
|
|
// Define margin
|
|
$margin_rate = GETPOSTISSET('marginforalllines') ? GETPOST('marginforalllines', 'int') : '';
|
|
$mark_rate = GETPOSTISSET('markforalllines') ? GETPOST('markforalllines', 'int') : '';
|
|
foreach ($object->lines as &$line) {
|
|
if ($line->subprice > 0) {
|
|
if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
|
|
continue;
|
|
}
|
|
$subprice_multicurrency = $line->subprice;
|
|
if (is_numeric($margin_rate) && $margin_rate > 0) {
|
|
$line->subprice = (float) price2num((float) $line->pa_ht * (1 + (float) $margin_rate / 100), 'MU');
|
|
} elseif (is_numeric($mark_rate) && $mark_rate > 0) {
|
|
$line->subprice = (float) ($line->pa_ht / (1 - ((float) $mark_rate / 100)));
|
|
} else {
|
|
$line->subprice = (float) $line->pa_ht;
|
|
}
|
|
|
|
if ($line->fk_product > 0) {
|
|
$prod = new Product($db);
|
|
$res = $prod->fetch($line->fk_product);
|
|
if ($res > 0) {
|
|
if ($prod->price_min > $line->subprice) {
|
|
$price_subprice = price($line->subprice, 0, $outlangs, 1, -1, -1, 'auto');
|
|
$price_price_min = price($prod->price_min, 0, $outlangs, 1, -1, -1, 'auto');
|
|
setEventMessages($prod->ref . ' - ' . $prod->label . ' (' . $price_subprice . ' < ' . $price_price_min . ' ' . strtolower($langs->trans("MinPrice")) . ')' . "\n", null, 'warnings');
|
|
} else {
|
|
setEventMessages($prod->error, $prod->errors, 'errors');
|
|
}
|
|
} else {
|
|
setEventMessages($prod->error, $prod->errors, 'errors');
|
|
}
|
|
}
|
|
|
|
// Manage $line->subprice and $line->multicurrency_subprice
|
|
$multicurrency_subprice = (float) $line->subprice * $line->multicurrency_subprice / $subprice_multicurrency;
|
|
// Update DB
|
|
$result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->product_ref, $line->special_code, $line->array_options, $line->fk_unit, $multicurrency_subprice);
|
|
// Update $object with new margin info
|
|
if ($result > 0) {
|
|
if (is_numeric($margin_rate) && empty($mark_rate)) {
|
|
$line->marge_tx = $margin_rate;
|
|
} elseif (is_numeric($mark_rate) && empty($margin_rate)) {
|
|
$line->marque_tx = $mark_rate;
|
|
}
|
|
$line->total_ht = $line->qty * (float) $line->subprice;
|
|
$line->total_tva = $line->tva_tx * $line->qty * (float) $line->subprice;
|
|
$line->total_ttc = (1 + $line->tva_tx) * $line->qty * (float) $line->subprice;
|
|
// Manage $line->subprice and $line->multicurrency_subprice
|
|
$line->multicurrency_total_ht = $line->qty * (float) $subprice_multicurrency * $line->multicurrency_subprice / $line->subprice;
|
|
$line->multicurrency_total_tva = $line->tva_tx * $line->qty * (float) $subprice_multicurrency * $line->multicurrency_subprice / $line->subprice;
|
|
$line->multicurrency_total_ttc = (1 + $line->tva_tx) * $line->qty * (float) $subprice_multicurrency * $line->multicurrency_subprice / $line->subprice;
|
|
// Used previous $line->subprice and $line->multicurrency_subprice above, now they can be set to their new values
|
|
$line->multicurrency_subprice = $multicurrency_subprice;
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
}
|
|
} elseif ($action == 'confirm_addtitleline' && $usercancreate) {
|
|
// Handling adding a new title line for subtotals module
|
|
|
|
$langs->load('subtotals');
|
|
|
|
$desc = GETPOST('subtotallinedesc', 'alphanohtml');
|
|
$depth = GETPOSTINT('subtotallinelevel') ?? 1;
|
|
|
|
$subtotal_options = array();
|
|
|
|
foreach (Commande::$TITLE_OPTIONS as $option) {
|
|
$value = GETPOST($option, 'alphanohtml');
|
|
if ($value) {
|
|
$subtotal_options[$option] = $value == 'on' ? 1 : $value;
|
|
}
|
|
}
|
|
|
|
// Insert line
|
|
$result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
|
|
|
|
if ($result >= 0) {
|
|
if ($result == 0) {
|
|
setEventMessages($object->error, $object->errors, 'warnings');
|
|
}
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
$object->fetch_thirdparty();
|
|
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = GETPOST('lang_id', 'alpha');
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
|
|
exit();
|
|
} elseif ($action == 'confirm_addsubtotalline' && $usercancreate) {
|
|
// Handling adding a new subtotal line for subtotals module
|
|
|
|
$langs->load('subtotals');
|
|
|
|
$choosen_line = GETPOST('subtotaltitleline', 'alphanohtml');
|
|
foreach ($object->lines as $line) {
|
|
if ($line->desc == $choosen_line && $line->special_code == SUBTOTALS_SPECIAL_CODE) {
|
|
$desc = $line->desc;
|
|
$depth = -$line->qty;
|
|
}
|
|
}
|
|
|
|
$subtotal_options = array();
|
|
|
|
foreach (Commande::$SUBTOTAL_OPTIONS as $option) {
|
|
$value = GETPOST($option, 'alphanohtml');
|
|
if ($value) {
|
|
$subtotal_options[$option] = $value == 'on' ? 1 : $value;
|
|
}
|
|
}
|
|
|
|
// Insert line
|
|
if (isset($desc) && isset($depth)) {
|
|
$result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
|
|
} else {
|
|
$result = -1;
|
|
$object->errors[] = $langs->trans("CorrespondingTitleNotFound");
|
|
}
|
|
|
|
if ($result >= 0) {
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
$object->fetch_thirdparty();
|
|
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = GETPOST('lang_id', 'alpha');
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
|
|
exit();
|
|
} elseif ($action == 'addline' && !GETPOST('submitforalllines', 'alpha') && $usercancreate) { // Add a new line
|
|
$langs->load('errors');
|
|
$error = 0;
|
|
|
|
// Set if we used free entry or predefined product
|
|
$predef = '';
|
|
$line_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
|
|
|
|
$price_ht = '';
|
|
$price_ht_devise = '';
|
|
$price_ttc = '';
|
|
$price_ttc_devise = '';
|
|
|
|
if (GETPOST('price_ht') !== '') {
|
|
$price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
|
|
}
|
|
if (GETPOST('multicurrency_price_ht') !== '') {
|
|
$price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
|
|
}
|
|
if (GETPOST('price_ttc') !== '') {
|
|
$price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
|
|
}
|
|
if (GETPOST('multicurrency_price_ttc') !== '') {
|
|
$price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
|
|
}
|
|
|
|
$prod_entry_mode = GETPOST('prod_entry_mode', 'aZ09');
|
|
if ($prod_entry_mode == 'free') {
|
|
$idprod = 0;
|
|
} else {
|
|
$idprod = GETPOSTINT('idprod');
|
|
|
|
if (getDolGlobalString('MAIN_DISABLE_FREE_LINES') && $idprod <= 0) {
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
$tva_tx = GETPOST('tva_tx', 'alpha');
|
|
|
|
$qty = price2num(GETPOST('qty' . $predef, 'alpha'), 'MS', 2);
|
|
|
|
$remise_percent = (GETPOSTISSET('remise_percent' . $predef) ? price2num(GETPOST('remise_percent' . $predef, 'alpha'), '', 2) : 0);
|
|
if (empty($remise_percent)) {
|
|
$remise_percent = 0;
|
|
}
|
|
|
|
// Extrafields
|
|
$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
|
|
$array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
|
|
// Unset extrafield
|
|
if (is_array($extralabelsline)) {
|
|
// Get extra fields
|
|
foreach ($extralabelsline as $key => $value) {
|
|
unset($_POST["options_" . $key]);
|
|
}
|
|
}
|
|
|
|
$price_to_test_sign = ($price_ht ? $price_ht : $price_ttc);
|
|
|
|
if ((empty($idprod) || $idprod < 0) && ($price_to_test_sign < 0) && ($qty < 0)) {
|
|
$langs->load("errors");
|
|
setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
|
|
$error++;
|
|
}
|
|
if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) {
|
|
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
|
|
$error++;
|
|
}
|
|
if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && $price_ht === '' && $price_ht_devise === '' && $price_ttc === '' && $price_ttc_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for order.
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
|
|
$error++;
|
|
}
|
|
if ($qty == '') {
|
|
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
|
|
$error++;
|
|
}
|
|
|
|
if ($qty < 0 && !getDolGlobalString('ORDER_ENABLE_NEGATIVE_QTY')) {
|
|
setEventMessages($langs->trans('FieldCannotBeNegative', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
|
|
$error++;
|
|
}
|
|
|
|
if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($line_desc)) {
|
|
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
|
|
$error++;
|
|
}
|
|
|
|
if (!$error && isModEnabled('variants') && $prod_entry_mode != 'free') {
|
|
if ($combinations = GETPOST('combinations', 'array:alphanohtml')) {
|
|
//Check if there is a product with the given combination
|
|
$prodcomb = new ProductCombination($db);
|
|
|
|
if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
|
|
$idprod = $res->fk_product_child;
|
|
} else {
|
|
setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
|
|
$error++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error && (!empty($line_desc) || (!empty($idprod) && $idprod > 0))) {
|
|
$pu_ht = 0;
|
|
$pu_ttc = 0;
|
|
$pu_ht_devise = 0;
|
|
$pu_ttc_devise = 0;
|
|
$price_min = 0;
|
|
$price_min_ttc = 0;
|
|
$tva_npr = 0;
|
|
$price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
|
|
|
|
// Clean parameters
|
|
$date_start = dol_mktime(GETPOSTINT('date_start' . $predef . 'hour'), GETPOSTINT('date_start' . $predef . 'min'), GETPOSTINT('date_start' . $predef . 'sec'), GETPOSTINT('date_start' . $predef . 'month'), GETPOSTINT('date_start' . $predef . 'day'), GETPOSTINT('date_start' . $predef . 'year'));
|
|
$date_end = dol_mktime(GETPOSTINT('date_end' . $predef . 'hour'), GETPOSTINT('date_end' . $predef . 'min'), GETPOSTINT('date_end' . $predef . 'sec'), GETPOSTINT('date_end' . $predef . 'month'), GETPOSTINT('date_end' . $predef . 'day'), GETPOSTINT('date_end' . $predef . 'year'));
|
|
|
|
$db->begin();
|
|
|
|
// Ecrase $pu par celui du produit
|
|
// Ecrase $desc par celui du produit
|
|
// Ecrase $base_price_type par celui du produit
|
|
if (!empty($idprod) && $idprod > 0) {
|
|
$prod = new Product($db);
|
|
$prod->fetch($idprod);
|
|
|
|
$label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
|
|
|
|
// Update if prices fields are defined
|
|
/*$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
|
|
$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
|
|
if (empty($tva_tx)) {
|
|
$tva_npr = 0;
|
|
}*/
|
|
|
|
// Price unique per product
|
|
$pu_ht = $prod->price;
|
|
$pu_ttc = $prod->price_ttc;
|
|
$price_min = $prod->price_min;
|
|
$price_min_ttc = $prod->price_min_ttc;
|
|
$price_base_type = $prod->price_base_type;
|
|
|
|
if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
|
|
// If price per customer
|
|
require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
|
|
|
|
$prodcustprice = new ProductCustomerPrice($db);
|
|
|
|
$filter = array('t.fk_product' => (string) $prod->id, 't.fk_soc' => (string) $object->thirdparty->id);
|
|
|
|
// If a price per customer exist
|
|
$pricebycustomerexist = false;
|
|
$result = $prodcustprice->fetchAll('', '', 0, 0, $filter);
|
|
if ($result >= 0) {
|
|
// If there is some prices specific to the customer
|
|
if (count($prodcustprice->lines) > 0) {
|
|
$date_now = (int) floor(dol_now() / 86400) * 86400; // date without hours
|
|
foreach ($prodcustprice->lines as $k => $custprice_line) {
|
|
if ($custprice_line->date_begin <= $date_now && (empty($custprice_line->date_end) || $date_now <= $custprice_line->date_end)) {
|
|
$pricebycustomerexist = true;
|
|
$pu_ht = price($custprice_line->price);
|
|
$pu_ttc = price($custprice_line->price_ttc);
|
|
$price_min = price($custprice_line->price_min);
|
|
$price_min_ttc = price($custprice_line->price_min_ttc);
|
|
$price_base_type = $custprice_line->price_base_type;
|
|
/*$tva_tx = $custprice_line->tva_tx;
|
|
if ($custprice_line->default_vat_code && !preg_match('/\(.*\)/', (string) $tva_tx)) {
|
|
$tva_tx .= ' (' . $custprice_line->default_vat_code . ')';
|
|
}
|
|
$tva_npr = $custprice_line->recuperableonly;
|
|
if (empty($tva_tx)) {
|
|
$tva_npr = 0;
|
|
}*/
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
|
|
}
|
|
|
|
if (!$pricebycustomerexist && !empty($object->thirdparty->price_level)) { // If price per segment
|
|
$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
|
|
$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
|
|
$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
|
|
$price_min_ttc = $prod->multiprices_min_ttc[$object->thirdparty->price_level];
|
|
$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
|
|
if (getDolGlobalString('PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL')) { // using this option is a bug. kept for backward compatibility
|
|
if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) {
|
|
$tva_tx = $prod->multiprices_tva_tx[$object->thirdparty->price_level];
|
|
}
|
|
if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) {
|
|
$tva_npr = $prod->multiprices_recuperableonly[$object->thirdparty->price_level];
|
|
}
|
|
}
|
|
}
|
|
} elseif (getDolGlobalString('PRODUIT_MULTIPRICES') && !empty($object->thirdparty->price_level)) { // If price per segment
|
|
$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
|
|
$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
|
|
$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
|
|
$price_min_ttc = $prod->multiprices_min_ttc[$object->thirdparty->price_level];
|
|
$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
|
|
if (getDolGlobalString('PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL')) { // using this option is a bug. kept for backward compatibility
|
|
if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) {
|
|
$tva_tx = $prod->multiprices_tva_tx[$object->thirdparty->price_level];
|
|
}
|
|
if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) {
|
|
$tva_npr = $prod->multiprices_recuperableonly[$object->thirdparty->price_level];
|
|
}
|
|
}
|
|
} elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
|
|
// If price per customer
|
|
require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
|
|
|
|
$prodcustprice = new ProductCustomerPrice($db);
|
|
|
|
$filter = array('t.fk_product' => (string) $prod->id, 't.fk_soc' => (string) $object->thirdparty->id);
|
|
|
|
$result = $prodcustprice->fetchAll('', '', 0, 0, $filter);
|
|
if ($result >= 0) {
|
|
// If there is some prices specific to the customer
|
|
if (count($prodcustprice->lines) > 0) {
|
|
$date_now = (int) floor(dol_now() / 86400) * 86400; // date without hours
|
|
foreach ($prodcustprice->lines as $k => $custprice_line) {
|
|
if ($custprice_line->date_begin <= $date_now && (empty($custprice_line->date_end) || $date_now <= $custprice_line->date_end)) {
|
|
$pu_ht = price($custprice_line->price);
|
|
$pu_ttc = price($custprice_line->price_ttc);
|
|
$price_min = price($custprice_line->price_min);
|
|
$price_min_ttc = price($custprice_line->price_min_ttc);
|
|
$price_base_type = $custprice_line->price_base_type;
|
|
/*$tva_tx = $custprice_line->tva_tx;
|
|
if ($custprice_line->default_vat_code && !preg_match('/\(.*\)/', $tva_tx)) {
|
|
$tva_tx .= ' (' . $custprice_line->default_vat_code . ')';
|
|
}
|
|
$tva_npr = $custprice_line->recuperableonly;
|
|
if (empty($tva_tx)) {
|
|
$tva_npr = 0;
|
|
}*/
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
|
|
}
|
|
} elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY')) {
|
|
// If price per quantity
|
|
if ($prod->prices_by_qty[0]) { // yes, this product has some prices per quantity
|
|
// Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
|
|
$pqp = GETPOSTINT('pbq');
|
|
|
|
// Search price into product_price_by_qty from $prod->id
|
|
foreach ($prod->prices_by_qty_list[0] as $priceforthequantityarray) {
|
|
if ($priceforthequantityarray['rowid'] != $pqp) {
|
|
continue;
|
|
}
|
|
// We found the price
|
|
if ($priceforthequantityarray['price_base_type'] == 'HT') {
|
|
$pu_ht = $priceforthequantityarray['unitprice'];
|
|
} else {
|
|
$pu_ttc = $priceforthequantityarray['unitprice'];
|
|
}
|
|
// Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
|
|
break;
|
|
}
|
|
}
|
|
} elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
|
|
// If price per quantity and customer
|
|
if ($prod->prices_by_qty[$object->thirdparty->price_level]) { // yes, this product has some prices per quantity
|
|
// Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
|
|
$pqp = GETPOSTINT('pbq');
|
|
// Search price into product_price_by_qty from $prod->id
|
|
foreach ($prod->prices_by_qty_list[$object->thirdparty->price_level] as $priceforthequantityarray) {
|
|
if ($priceforthequantityarray['rowid'] != $pqp) {
|
|
continue;
|
|
}
|
|
// We found the price
|
|
if ($priceforthequantityarray['price_base_type'] == 'HT') {
|
|
$pu_ht = $priceforthequantityarray['unitprice'];
|
|
} else {
|
|
$pu_ttc = $priceforthequantityarray['unitprice'];
|
|
}
|
|
// Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$tmpvat = (float) price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx));
|
|
$tmpprodvat = (float) price2num(preg_replace('/\s*\(.*\)/', '', (string) $prod->tva_tx));
|
|
|
|
// Set unit price to use.
|
|
// Force price_base_type to match what the user actually entered, so the total is computed
|
|
// from the typed value and not from the converted/rounded value (avoids 0.01 rounding drift).
|
|
if (!empty($price_ht) || (string) $price_ht === '0') {
|
|
$pu_ht = (float) price2num($price_ht, 'MU');
|
|
$pu_ttc = (float) price2num((float) $pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
|
|
$price_base_type = 'HT';
|
|
} elseif (!empty($price_ht_devise) || (string) $price_ht_devise === '0') {
|
|
$pu_ht_devise = price2num($price_ht_devise, 'MU');
|
|
$pu_ttc_devise = (float) price2num((float) $pu_ht_devise * (1 + ((float) $tmpvat / 100)), 'MU');
|
|
$pu_ht = '';
|
|
$pu_ttc = '';
|
|
$price_base_type = 'HT';
|
|
} elseif (!empty($price_ttc) || (string) $price_ttc === '0') {
|
|
$pu_ttc = (float) price2num($price_ttc, 'MU');
|
|
$pu_ht = (float) price2num((float) $pu_ttc / (1 + ((float) $tmpvat / 100)), 'MU');
|
|
$price_base_type = 'TTC';
|
|
} elseif (!empty($price_ttc_devise) || (string) $price_ttc_devise === '0') {
|
|
$pu_ttc_devise = (float) price2num($price_ttc_devise, 'MU');
|
|
$pu_ht_devise = (float) price2num((float) $pu_ttc_devise / (1 + ((float) $tmpvat / 100)), 'MU');
|
|
$pu_ht = '';
|
|
$pu_ttc = '';
|
|
$price_base_type = 'TTC';
|
|
} elseif ($tmpvat != $tmpprodvat) {
|
|
// Is this still used ?
|
|
if ($price_base_type != 'HT') {
|
|
$pu_ht = (float) price2num((float) $pu_ttc / (1 + ((float) $tmpvat / 100)), 'MU');
|
|
} else {
|
|
$pu_ttc = (float) price2num((float) $pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
|
|
}
|
|
}
|
|
|
|
$desc = '';
|
|
|
|
// Define output language
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
|
|
$outputlangs = $langs;
|
|
$newlang = '';
|
|
if (/* empty($newlang) && */GETPOST('lang_id', 'aZ09')) {
|
|
$newlang = GETPOST('lang_id', 'aZ09');
|
|
}
|
|
if (empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
|
|
$desc = (!empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
|
|
} else {
|
|
$desc = $prod->description;
|
|
}
|
|
|
|
if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 0) {
|
|
// 'DoNotAutofillButAutoConcat'
|
|
$desc = dol_concatdesc($desc, $line_desc, false, getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION') ? true : false);
|
|
} else {
|
|
//'AutoFillFormFieldBeforeSubmit' or 'DoNotUseDescriptionOfProdut' => User has already done the modification they want
|
|
$desc = $line_desc;
|
|
}
|
|
|
|
// Add custom code and origin country into description
|
|
if (!getDolGlobalString('MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE') && (!empty($prod->customcode) || !empty($prod->country_code))) {
|
|
$tmptxt = '(';
|
|
// Define output language
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
|
|
$outputlangs = $langs;
|
|
$newlang = '';
|
|
if (/* empty($newlang) && */GETPOST('lang_id', 'alpha')) {
|
|
$newlang = GETPOST('lang_id', 'alpha');
|
|
}
|
|
if (empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
$outputlangs->load('products');
|
|
}
|
|
if (!empty($prod->customcode)) {
|
|
$tmptxt .= $outputlangs->transnoentitiesnoconv("CustomsCode") . ': ' . $prod->customcode;
|
|
}
|
|
if (!empty($prod->customcode) && !empty($prod->country_code)) {
|
|
$tmptxt .= ' - ';
|
|
}
|
|
if (!empty($prod->country_code)) {
|
|
$tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, '', $db, $outputlangs, 0);
|
|
}
|
|
} else {
|
|
if (!empty($prod->customcode)) {
|
|
$tmptxt .= $langs->transnoentitiesnoconv("CustomsCode") . ': ' . $prod->customcode;
|
|
}
|
|
if (!empty($prod->customcode) && !empty($prod->country_code)) {
|
|
$tmptxt .= ' - ';
|
|
}
|
|
if (!empty($prod->country_code)) {
|
|
$tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, '', $db, $langs, 0);
|
|
}
|
|
}
|
|
$tmptxt .= ')';
|
|
$desc = dol_concatdesc($desc, $tmptxt);
|
|
}
|
|
|
|
$type = $prod->type;
|
|
$fk_unit = $prod->fk_unit;
|
|
} else {
|
|
$pu_ht = price2num($price_ht, 'MU');
|
|
$pu_ttc = price2num($price_ttc, 'MU');
|
|
$tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
|
|
$tva_tx = str_replace('*', '', $tva_tx);
|
|
if (empty($tva_tx)) {
|
|
$tva_npr = 0;
|
|
}
|
|
$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
|
|
$desc = $line_desc;
|
|
$type = GETPOST('type');
|
|
$fk_unit = GETPOST('units', 'alpha');
|
|
$pu_ht_devise = price2num($price_ht_devise, 'MU');
|
|
$pu_ttc_devise = price2num($price_ttc_devise, 'MU');
|
|
|
|
if ($pu_ttc && !$pu_ht) {
|
|
$price_base_type = 'TTC';
|
|
}
|
|
}
|
|
|
|
$info_bits = 0;
|
|
if ($tva_npr) {
|
|
$info_bits |= 0x01;
|
|
}
|
|
|
|
// Local Taxes
|
|
$localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr);
|
|
$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr);
|
|
|
|
// Margin
|
|
$fournprice = (int) (GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : 0); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
|
$buyingprice = price2num((GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''), '', 2); // If buying_price is '0', we must keep this value
|
|
|
|
// Prepare a price equivalent for minimum price check
|
|
$pu_equivalent = $pu_ht;
|
|
$pu_equivalent_ttc = $pu_ttc;
|
|
|
|
$currency_tx = $object->multicurrency_tx;
|
|
|
|
// Check if we have a foreign currency
|
|
// If so, we update the pu_equiv as the equivalent price in base currency
|
|
if ($pu_ht == '' && $pu_ht_devise != '' && $currency_tx != '' && !empty((float) $currency_tx)) {
|
|
$pu_equivalent = (float) $pu_ht_devise / (float) $currency_tx;
|
|
}
|
|
if ($pu_ttc == '' && $pu_ttc_devise != '' && $currency_tx != '' && !empty((float) $currency_tx)) {
|
|
$pu_equivalent_ttc = (float) $pu_ttc_devise / (float) $currency_tx;
|
|
}
|
|
|
|
// TODO $pu_equivalent or $pu_equivalent_ttc must be calculated from the one not null taking into account all taxes
|
|
/*
|
|
if ($pu_equivalent) {
|
|
$tmp = calcul_price_total(1, $pu_equivalent, 0, $tva_tx, -1, -1, 0, 'HT', $info_bits, $type);
|
|
$pu_equivalent_ttc = ...
|
|
} else {
|
|
$tmp = calcul_price_total(1, $pu_equivalent_ttc, 0, $tva_tx, -1, -1, 0, 'TTC', $info_bits, $type);
|
|
$pu_equivalent_ht = ...
|
|
}
|
|
*/
|
|
|
|
//var_dump(price2num($price_min)); var_dump(price2num($pu_ht)); var_dump($remise_percent);
|
|
//var_dump(price2num($price_min_ttc)); var_dump(price2num($pu_ttc)); var_dump($remise_percent);exit;
|
|
|
|
$desc = dol_htmlcleanlastbr($desc);
|
|
|
|
// Check price is not lower than minimum
|
|
if ($usermustrespectpricemin) {
|
|
if ($pu_equivalent && $price_min && (((float) price2num($pu_equivalent) * (1 - $remise_percent / 100)) < (float) price2num($price_min)) && $price_base_type == 'HT') {
|
|
$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
|
|
setEventMessages($mesg, null, 'errors');
|
|
$error++;
|
|
} elseif ($pu_equivalent_ttc && $price_min_ttc && (((float) price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < (float) price2num($price_min_ttc)) && $price_base_type == 'TTC') {
|
|
$mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
|
|
setEventMessages($mesg, null, 'errors');
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
// Insert line
|
|
$result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, min($rank, count($object->lines) + 1), 0, GETPOSTINT('fk_parent_line'), (int) $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, (float) $pu_ht_devise);
|
|
|
|
if ($result > 0) {
|
|
$db->commit();
|
|
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
if ($ret > 0) {
|
|
$object->fetch_thirdparty();
|
|
}
|
|
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = GETPOST('lang_id', 'alpha');
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
|
|
unset($_POST['prod_entry_mode']);
|
|
|
|
unset($_POST['qty']);
|
|
unset($_POST['type']);
|
|
unset($_POST['remise_percent']);
|
|
unset($_POST['price_ht']);
|
|
unset($_POST['multicurrency_price_ht']);
|
|
unset($_POST['price_ttc']);
|
|
unset($_POST['tva_tx']);
|
|
unset($_POST['product_ref']);
|
|
unset($_POST['product_label']);
|
|
unset($_POST['product_desc']);
|
|
unset($_POST['fournprice']);
|
|
unset($_POST['buying_price']);
|
|
unset($_POST['np_marginRate']);
|
|
unset($_POST['np_markRate']);
|
|
unset($_POST['dp_desc']);
|
|
unset($_POST['idprod']);
|
|
unset($_POST['units']);
|
|
|
|
unset($_POST['date_starthour']);
|
|
unset($_POST['date_startmin']);
|
|
unset($_POST['date_startsec']);
|
|
unset($_POST['date_startday']);
|
|
unset($_POST['date_startmonth']);
|
|
unset($_POST['date_startyear']);
|
|
unset($_POST['date_endhour']);
|
|
unset($_POST['date_endmin']);
|
|
unset($_POST['date_endsec']);
|
|
unset($_POST['date_endday']);
|
|
unset($_POST['date_endmonth']);
|
|
unset($_POST['date_endyear']);
|
|
|
|
header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
|
|
exit();
|
|
} else {
|
|
$db->rollback();
|
|
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
}
|
|
} elseif ($action == 'updatetitleline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
|
|
// Handling updating a title line for subtotals module
|
|
|
|
$langs->load('subtotals');
|
|
|
|
$desc = GETPOST('line_desc', 'alphanohtml') ?? $langs->trans("Title");
|
|
$depth = GETPOSTINT('line_depth') ?? 1;
|
|
|
|
$subtotal_options = array();
|
|
|
|
foreach (Commande::$TITLE_OPTIONS as $option) {
|
|
$value = GETPOST($option, 'alphanohtml');
|
|
if ($value) {
|
|
$subtotal_options[$option] = $value == 'on' ? 1 : $value;
|
|
}
|
|
}
|
|
|
|
// Update line
|
|
$result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
|
|
|
|
if ($result >= 0) {
|
|
if ($result == 0) {
|
|
setEventMessages($object->error, $object->errors, 'warnings');
|
|
}
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
$object->fetch_thirdparty();
|
|
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = GETPOST('lang_id', 'alpha');
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'updatesubtotalline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
|
|
// Handling updating a subtotal line for subtotals module
|
|
|
|
$langs->load('subtotals');
|
|
|
|
$desc = GETPOST('line_desc', 'alphanohtml');
|
|
$depth = GETPOSTINT('line_depth');
|
|
|
|
$subtotal_options = array();
|
|
|
|
foreach (Commande::$SUBTOTAL_OPTIONS as $option) {
|
|
$value = GETPOST($option, 'alphanohtml');
|
|
if ($value) {
|
|
$subtotal_options[$option] = $value == 'on' ? 1 : $value;
|
|
}
|
|
}
|
|
|
|
// Update line
|
|
$result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
|
|
|
|
if ($result > 0) {
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
$object->fetch_thirdparty();
|
|
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = GETPOST('lang_id', 'alpha');
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'updateline' && $usercancreate && GETPOST('save')) {
|
|
// Update a line
|
|
|
|
// Clean parameters
|
|
$date_start = '';
|
|
$date_end = '';
|
|
$date_start = dol_mktime(GETPOSTINT('date_starthour'), GETPOSTINT('date_startmin'), GETPOSTINT('date_startsec'), GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
|
|
$date_end = dol_mktime(GETPOSTINT('date_endhour'), GETPOSTINT('date_endmin'), GETPOSTINT('date_endsec'), GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
|
|
|
|
$description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml'));
|
|
|
|
// Define info_bits
|
|
$info_bits = 0;
|
|
if (preg_match('/\*/', GETPOST('tva_tx'))) {
|
|
$info_bits |= 0x01;
|
|
}
|
|
|
|
// Define vat_rate
|
|
$vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx', 'alpha') : 0);
|
|
$vat_rate = str_replace('*', '', $vat_rate);
|
|
$localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
|
|
$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
|
|
$pu_ht = price2num(GETPOST('price_ht'), '', 2);
|
|
$pu_ttc = price2num(GETPOST('price_ttc'), '', 2);
|
|
|
|
$pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2);
|
|
$pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2);
|
|
|
|
$qty = price2num(GETPOST('qty', 'alpha'), 'MS');
|
|
|
|
// Prepare a price equivalent for minimum price check
|
|
$pu_equivalent = $pu_ht;
|
|
$pu_equivalent_ttc = $pu_ttc;
|
|
|
|
$currency_tx = $object->multicurrency_tx;
|
|
|
|
// Check if we have a foreign currency
|
|
// If so, we update the pu_equiv as the equivalent price in base currency
|
|
if ($pu_ht == '' && $pu_ht_devise != '' && $currency_tx != '' && !empty((float) $currency_tx)) {
|
|
$pu_equivalent = (float) $pu_ht_devise / (float) $currency_tx;
|
|
}
|
|
if ($pu_ttc == '' && $pu_ttc_devise != '' && $currency_tx != '' && !empty((float) $currency_tx)) {
|
|
$pu_equivalent_ttc = (float) $pu_ttc_devise / (float) $currency_tx;
|
|
}
|
|
|
|
// TODO $pu_equivalent or $pu_equivalent_ttc must be calculated from the one not null taking into account all taxes
|
|
/*
|
|
if ($pu_equivalent) {
|
|
$tmp = calcul_price_total(1, $pu_equivalent, 0, $vat_rate, -1, -1, 0, 'HT', $info_bits, $type);
|
|
$pu_equivalent_ttc = ...
|
|
} else {
|
|
$tmp = calcul_price_total(1, $pu_equivalent_ttc, 0, $vat_rate, -1, -1, 0, 'TTC', $info_bits, $type);
|
|
$pu_equivalent_ht = ...
|
|
}
|
|
*/
|
|
|
|
// Add buying price
|
|
$fournprice = (int) (GETPOST('fournprice') ? GETPOST('fournprice') : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
|
$buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we must keep this value
|
|
|
|
// Extrafields Lines
|
|
$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
|
|
$array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
|
|
// Unset extrafield POST Data
|
|
if (is_array($extralabelsline)) {
|
|
foreach ($extralabelsline as $key => $value) {
|
|
unset($_POST["options_" . $key]);
|
|
}
|
|
}
|
|
|
|
// Define special_code for special lines
|
|
$special_code = GETPOSTINT('special_code');
|
|
if (!GETPOST('qty')) {
|
|
$special_code = 3;
|
|
}
|
|
|
|
$remise_percent = GETPOST('remise_percent') != '' ? price2num(GETPOST('remise_percent'), '', 2) : 0;
|
|
|
|
// The form JS clears the other field when the user edits one of them: only the modified field is filled.
|
|
// When both fields are submitted, the user did not change the price - we must preserve the original
|
|
// storage mode of the line, otherwise a no-op save would shift the total by rounding.
|
|
$pu = $pu_ht;
|
|
$price_base_type = 'HT';
|
|
if (empty($pu_ht) && !empty($pu_ttc)) {
|
|
$pu = $pu_ttc;
|
|
$price_base_type = 'TTC';
|
|
} elseif (!empty($pu_ht) && !empty($pu_ttc)) {
|
|
foreach ($object->lines as $line_obj) {
|
|
if ($line_obj->id == GETPOSTINT('lineid')) {
|
|
// Line was originally entered in TTC mode (subprice_ttc filled by addline)
|
|
if ($line_obj->wasEnteredIncludingTax()) {
|
|
$pu = $pu_ttc;
|
|
$price_base_type = 'TTC';
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check minimum price
|
|
$productid = GETPOSTINT('productid');
|
|
if (!empty($productid)) {
|
|
$product = new Product($db);
|
|
$product->fetch($productid);
|
|
|
|
$type = $product->type;
|
|
|
|
$price_min = $product->price_min;
|
|
if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) && !empty($object->thirdparty->price_level)) {
|
|
$price_min = $product->multiprices_min[$object->thirdparty->price_level];
|
|
}
|
|
$price_min_ttc = $product->price_min_ttc;
|
|
if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) && !empty($object->thirdparty->price_level)) {
|
|
$price_min_ttc = $product->multiprices_min_ttc[$object->thirdparty->price_level];
|
|
}
|
|
|
|
$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
|
|
|
|
// Check price is not lower than minimum
|
|
if ($usermustrespectpricemin) {
|
|
if ($pu_equivalent && $price_min && (((float) price2num($pu_equivalent) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min)) && $price_base_type == 'HT') {
|
|
$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
|
|
setEventMessages($mesg, null, 'errors');
|
|
$error++;
|
|
$action = 'editline';
|
|
} elseif ($pu_equivalent_ttc && $price_min_ttc && (((float) price2num($pu_equivalent_ttc) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min_ttc)) && $price_base_type == 'TTC') {
|
|
$mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
|
|
setEventMessages($mesg, null, 'errors');
|
|
$error++;
|
|
$action = 'editline';
|
|
}
|
|
}
|
|
} else {
|
|
$type = GETPOST('type');
|
|
$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
|
|
|
|
// Check parameters
|
|
if (GETPOST('type') < 0) {
|
|
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
|
|
$error++;
|
|
$action = 'editline';
|
|
}
|
|
}
|
|
|
|
if ($qty < 0 && !getDolGlobalString('ORDER_ENABLE_NEGATIVE_QTY')) {
|
|
setEventMessages($langs->trans('FieldCannotBeNegative', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
|
|
$error++;
|
|
$action = 'editline';
|
|
}
|
|
|
|
$object->loadExpeditions();
|
|
if (isset($object->expeditions[GETPOST('lineid', 'int')])) {
|
|
if ($qty < $object->expeditions[GETPOST('lineid', 'int')]) {
|
|
setEventMessages($langs->trans('ErrorQtyOrderedLessQtyShipped'), null, 'errors');
|
|
$error++;
|
|
$action = 'editline';
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$db->begin();
|
|
|
|
if (!$user->hasRight('margins', 'creer')) {
|
|
foreach ($object->lines as &$line) {
|
|
if ($line->id == GETPOSTINT('lineid')) {
|
|
$fournprice = $line->fk_fournprice;
|
|
$buyingprice = $line->pa_ht;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$result = $object->updateline(GETPOSTINT('lineid'), $description, (float) $pu, (float) $qty, (float) $remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $price_base_type, $info_bits, $date_start, $date_end, $type, GETPOSTINT('fk_parent_line'), 0, (int) $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOSTINT('units'), (float) $pu_ht_devise);
|
|
|
|
|
|
if ($result >= 0) {
|
|
$db->commit();
|
|
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = '';
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
|
|
$newlang = GETPOST('lang_id', 'aZ09');
|
|
}
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
|
|
$ret = $object->fetch($object->id); // Reload to get new records
|
|
$object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
|
|
unset($_POST['qty']);
|
|
unset($_POST['type']);
|
|
unset($_POST['productid']);
|
|
unset($_POST['remise_percent']);
|
|
unset($_POST['price_ht']);
|
|
unset($_POST['multicurrency_price_ht']);
|
|
unset($_POST['price_ttc']);
|
|
unset($_POST['tva_tx']);
|
|
unset($_POST['product_ref']);
|
|
unset($_POST['product_label']);
|
|
unset($_POST['product_desc']);
|
|
unset($_POST['fournprice']);
|
|
unset($_POST['buying_price']);
|
|
|
|
unset($_POST['date_starthour']);
|
|
unset($_POST['date_startmin']);
|
|
unset($_POST['date_startsec']);
|
|
unset($_POST['date_startday']);
|
|
unset($_POST['date_startmonth']);
|
|
unset($_POST['date_startyear']);
|
|
unset($_POST['date_endhour']);
|
|
unset($_POST['date_endmin']);
|
|
unset($_POST['date_endsec']);
|
|
unset($_POST['date_endday']);
|
|
unset($_POST['date_endmonth']);
|
|
unset($_POST['date_endyear']);
|
|
} else {
|
|
$db->rollback();
|
|
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
} elseif ($action == 'updateline' && $usercancreate && GETPOST('cancel', 'alpha')) {
|
|
header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // To re-display card in edit mode
|
|
exit();
|
|
} elseif ($action == 'confirm_validate' && $confirm == 'yes' && $usercanvalidate) {
|
|
$idwarehouse = GETPOSTINT('idwarehouse');
|
|
|
|
$qualified_for_stock_change = 0;
|
|
if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(2);
|
|
} else {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(1);
|
|
}
|
|
|
|
// Check parameters
|
|
if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
|
|
if (!$idwarehouse || $idwarehouse == -1) {
|
|
$error++;
|
|
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
|
|
$action = '';
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$locationTarget = '';
|
|
|
|
$db->begin();
|
|
|
|
$result = $object->valid($user, $idwarehouse);
|
|
if ($result >= 0) {
|
|
$error = 0;
|
|
$deposit = null;
|
|
|
|
$deposit_percent_from_payment_terms = (float) getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id);
|
|
|
|
if (
|
|
GETPOST('generate_deposit', 'alpha') == 'on' && !empty($deposit_percent_from_payment_terms)
|
|
&& isModEnabled('invoice') && $user->hasRight('facture', 'creer')
|
|
) {
|
|
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
|
|
|
|
$date = dol_mktime(0, 0, 0, GETPOSTINT('datefmonth'), GETPOSTINT('datefday'), GETPOSTINT('datefyear'));
|
|
$forceFields = array();
|
|
|
|
if (GETPOSTISSET('date_pointoftax')) {
|
|
$forceFields['date_pointoftax'] = dol_mktime(0, 0, 0, GETPOSTINT('date_pointoftaxmonth'), GETPOSTINT('date_pointoftaxday'), GETPOSTINT('date_pointoftaxyear'));
|
|
}
|
|
|
|
$deposit = Facture::createDepositFromOrigin($object, $date, GETPOSTINT('cond_reglement_id'), $user, 0, GETPOSTINT('validate_generated_deposit') == 'on', $forceFields);
|
|
|
|
if ($deposit) {
|
|
setEventMessage('DepositGenerated');
|
|
$locationTarget = DOL_URL_ROOT . '/compta/facture/card.php?id=' . $deposit->id;
|
|
} else {
|
|
$error++;
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
|
|
// Define output language
|
|
if (! $error) {
|
|
$db->commit();
|
|
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
$outputlangs = $langs;
|
|
$newlang = '';
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
|
|
$newlang = GETPOST('lang_id', 'aZ09');
|
|
}
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
$model = $object->model_pdf;
|
|
$ret = $object->fetch($id); // Reload to get new records
|
|
|
|
$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
|
|
if ($deposit) {
|
|
$deposit->fetch($deposit->id); // Reload to get new records
|
|
$deposit->generateDocument($deposit->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
}
|
|
|
|
if ($locationTarget) {
|
|
header('Location: ' . $locationTarget);
|
|
exit;
|
|
}
|
|
} else {
|
|
$db->rollback();
|
|
}
|
|
} else {
|
|
$db->rollback();
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
} elseif ($action == 'confirm_modif' && $usercancreate) {
|
|
// Go back to draft status
|
|
$idwarehouse = GETPOST('idwarehouse');
|
|
|
|
$qualified_for_stock_change = 0;
|
|
if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(2);
|
|
} else {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(1);
|
|
}
|
|
|
|
// Check parameters
|
|
if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
|
|
if (!$idwarehouse || $idwarehouse == -1) {
|
|
$error++;
|
|
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
|
|
$action = '';
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$result = $object->setDraft($user, $idwarehouse);
|
|
if ($result >= 0) {
|
|
// Define output language
|
|
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
|
$outputlangs = $langs;
|
|
$newlang = '';
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
|
|
$newlang = GETPOST('lang_id', 'aZ09');
|
|
}
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $object->thirdparty->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
$model = $object->model_pdf;
|
|
$ret = $object->fetch($id); // Reload to get new records
|
|
|
|
$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
}
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
} elseif ($action == 'confirm_shipped' && $confirm == 'yes' && $usercanclose) {
|
|
$result = $object->cloture($user);
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} elseif ($action == 'confirm_cancel' && $confirm == 'yes' && $usercanvalidate) {
|
|
$idwarehouse = GETPOSTINT('idwarehouse');
|
|
|
|
$qualified_for_stock_change = 0;
|
|
if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(2);
|
|
} else {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(1);
|
|
}
|
|
|
|
// Check parameters
|
|
if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
|
|
if (!$idwarehouse || $idwarehouse == -1) {
|
|
$error++;
|
|
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
|
|
$action = '';
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$result = $object->cancel($user, $idwarehouse);
|
|
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($action == 'update_extras' && $permissiontoeditextra) {
|
|
$object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
|
|
|
|
$attribute_name = GETPOST('attribute', 'aZ09');
|
|
|
|
// Fill array 'array_options' with data from update form
|
|
$ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
|
|
if ($ret < 0) {
|
|
$error++;
|
|
}
|
|
|
|
if (!$error) {
|
|
// Actions on extra fields
|
|
$result = $object->updateExtraField($attribute_name, 'ORDER_MODIFY');
|
|
if ($result < 0) {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if ($error) {
|
|
$action = 'edit_extras';
|
|
}
|
|
}
|
|
|
|
// Add lines from objectlinked
|
|
if ($action == 'import_lines_from_object' && $usercancreate && $object->status == Commande::STATUS_DRAFT) {
|
|
$fromElement = GETPOST('fromelement');
|
|
$fromElementid = GETPOST('fromelementid');
|
|
$importLines = GETPOST('line_checkbox');
|
|
|
|
if (!empty($importLines) && is_array($importLines) && !empty($fromElement) && ctype_alpha($fromElement) && !empty($fromElementid)) {
|
|
if ($fromElement == 'commande') {
|
|
dol_include_once('/' . $fromElement . '/class/' . $fromElement . '.class.php');
|
|
$lineClassName = 'OrderLine';
|
|
} elseif ($fromElement == 'propal') {
|
|
dol_include_once('/comm/' . $fromElement . '/class/' . $fromElement . '.class.php');
|
|
$lineClassName = 'PropaleLigne';
|
|
} elseif ($fromElement == 'facture') {
|
|
dol_include_once('/compta/' . $fromElement . '/class/' . $fromElement . '.class.php');
|
|
$lineClassName = 'FactureLigne';
|
|
}
|
|
$nextRang = count($object->lines) + 1;
|
|
$importCount = 0;
|
|
$error = 0;
|
|
foreach ($importLines as $lineId) {
|
|
$lineId = intval($lineId);
|
|
$originLine = new $lineClassName($db);
|
|
if (intval($fromElementid) > 0 && $originLine->fetch($lineId) > 0) {
|
|
$originLine->fetch_optionals();
|
|
$desc = $originLine->desc;
|
|
$pu_ht = $originLine->subprice;
|
|
$qty = $originLine->qty;
|
|
$txtva = $originLine->tva_tx;
|
|
$txlocaltax1 = $originLine->localtax1_tx;
|
|
$txlocaltax2 = $originLine->localtax2_tx;
|
|
$fk_product = $originLine->fk_product;
|
|
$remise_percent = $originLine->remise_percent;
|
|
$date_start = $originLine->date_start;
|
|
$date_end = $originLine->date_end;
|
|
$fk_code_ventilation = 0;
|
|
$info_bits = $originLine->info_bits;
|
|
$fk_remise_except = $originLine->fk_remise_except;
|
|
$price_base_type = 'HT';
|
|
$pu_ttc = 0;
|
|
$type = $originLine->product_type;
|
|
$rang = $nextRang++;
|
|
$special_code = $originLine->special_code;
|
|
$origin = $originLine->element;
|
|
$origin_id = $originLine->id;
|
|
$fk_parent_line = 0;
|
|
$fk_fournprice = $originLine->fk_fournprice;
|
|
$pa_ht = $originLine->pa_ht;
|
|
$label = $originLine->label;
|
|
$array_options = $originLine->array_options;
|
|
$situation_percent = 100;
|
|
$fk_prev_id = '';
|
|
$fk_unit = $originLine->fk_unit;
|
|
$pu_ht_devise = $originLine->multicurrency_subprice;
|
|
|
|
$res = $object->addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $info_bits, $fk_remise_except, $price_base_type, $pu_ttc, $date_start, $date_end, $type, $rang, $special_code, $fk_parent_line, $fk_fournprice, $pa_ht, $label, $array_options, $fk_unit, $origin, $origin_id, $pu_ht_devise);
|
|
|
|
if ($res > 0) {
|
|
$importCount++;
|
|
} else {
|
|
$error++;
|
|
}
|
|
} else {
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if ($error) {
|
|
setEventMessages($langs->trans('ErrorsOnXLines', $error), null, 'errors');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Actions when printing a doc from card
|
|
include DOL_DOCUMENT_ROOT . '/core/actions_printing.inc.php';
|
|
|
|
// Actions to build doc
|
|
$upload_dir = !empty($conf->commande->multidir_output[$object->entity ?? $conf->entity]) ? $conf->commande->multidir_output[$object->entity ?? $conf->entity] : $conf->commande->dir_output;
|
|
$permissiontoadd = $usercancreate;
|
|
include DOL_DOCUMENT_ROOT . '/core/actions_builddoc.inc.php';
|
|
|
|
// Actions to send emails
|
|
$triggersendname = 'ORDER_SENTBYMAIL';
|
|
$paramname = 'id';
|
|
$autocopy = 'MAIN_MAIL_AUTOCOPY_ORDER_TO'; // used to know the automatic BCC to add
|
|
$trackid = 'ord' . $object->id;
|
|
include DOL_DOCUMENT_ROOT . '/core/actions_sendmails.inc.php';
|
|
|
|
|
|
if (!$error && getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB') && $usercancreate) {
|
|
if ($action == 'addcontact') { // Test on permission already done
|
|
if ($object->id > 0) {
|
|
$contactid = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
|
|
$typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
|
|
$result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
|
|
}
|
|
|
|
if ($result >= 0) {
|
|
header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
|
|
exit();
|
|
} else {
|
|
if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
|
|
$langs->load("errors");
|
|
setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
|
|
} else {
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
}
|
|
} elseif ($action == 'swapstatut') { // Test on permission already done
|
|
// bascule du statut d'un contact
|
|
if ($object->id > 0) {
|
|
$result = $object->swapContactStatus(GETPOSTINT('ligne'));
|
|
} else {
|
|
dol_print_error($db);
|
|
}
|
|
} elseif ($action == 'deletecontact') { // Test on permission already done
|
|
// Efface un contact
|
|
$result = $object->delete_contact($lineid);
|
|
|
|
if ($result >= 0) {
|
|
header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
|
|
exit();
|
|
} else {
|
|
dol_print_error($db);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* View
|
|
*/
|
|
|
|
$title = $object->ref . " - " . $langs->trans('Card');
|
|
if ($action == 'create') {
|
|
$title = $langs->trans("NewOrder");
|
|
}
|
|
$help_url = 'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes|DE:Modul_Kundenaufträge';
|
|
|
|
llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-order page-card');
|
|
|
|
$form = new Form($db);
|
|
$formfile = new FormFile($db);
|
|
$formorder = new FormOrder($db);
|
|
$formmargin = new FormMargin($db);
|
|
$formproduct = new FormProduct($db);
|
|
if (isModEnabled('project')) {
|
|
$formproject = new FormProjets($db);
|
|
}
|
|
|
|
// Mode creation
|
|
if ($action == 'create' && $usercancreate) {
|
|
print load_fiche_titre($langs->trans('CreateOrder'), '', 'order');
|
|
|
|
$soc = new Societe($db);
|
|
if ($socid > 0) {
|
|
$res = $soc->fetch($socid);
|
|
}
|
|
|
|
$currency_code = $conf->currency;
|
|
|
|
$cond_reglement_id = GETPOSTINT('cond_reglement_id');
|
|
$deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
|
|
$mode_reglement_id = GETPOSTINT('mode_reglement_id');
|
|
$fk_account = GETPOSTINT('fk_account');
|
|
|
|
if (!empty($origin) && !empty($originid)) {
|
|
// Parse element/subelement (ex: project_task)
|
|
$element = $subelement = $origin;
|
|
$regs = array();
|
|
if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
|
|
$element = $regs[1];
|
|
$subelement = $regs[2];
|
|
}
|
|
|
|
if ($element == 'project') {
|
|
$projectid = $originid;
|
|
|
|
if (!$cond_reglement_id) {
|
|
$cond_reglement_id = $soc->cond_reglement_id;
|
|
}
|
|
if (!$deposit_percent) {
|
|
$deposit_percent = $soc->deposit_percent;
|
|
}
|
|
if (!$mode_reglement_id) {
|
|
$mode_reglement_id = $soc->mode_reglement_id;
|
|
}
|
|
if (!$remise_percent) {
|
|
$remise_percent = $soc->remise_percent;
|
|
}
|
|
} else {
|
|
// For compatibility
|
|
if ($element == 'order' || $element == 'commande') {
|
|
$element = $subelement = 'commande';
|
|
} elseif ($element == 'propal') {
|
|
$element = 'comm/propal';
|
|
$subelement = 'propal';
|
|
} elseif ($element == 'contract') {
|
|
$element = $subelement = 'contrat';
|
|
}
|
|
|
|
dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
|
|
|
|
$classname = ucfirst($subelement);
|
|
$objectsrc = new $classname($db);
|
|
'@phan-var-force Commande|Propal|Contrat $objectsrc'; // Can possibly be other class but CommonObject is too general
|
|
$objectsrc->fetch($originid);
|
|
if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
|
|
$objectsrc->fetch_lines();
|
|
}
|
|
$objectsrc->fetch_thirdparty();
|
|
|
|
// Replicate extrafields
|
|
$objectsrc->fetch_optionals();
|
|
$object->array_options = $objectsrc->array_options;
|
|
|
|
$projectid = (int) $objectsrc->fk_project;
|
|
$ref_client = (!empty($objectsrc->ref_client) ? $objectsrc->ref_client : '');
|
|
|
|
$soc = $objectsrc->thirdparty;
|
|
$cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0));
|
|
$deposit_percent = (!empty($objectsrc->deposit_percent) ? $objectsrc->deposit_percent : (!empty($soc->deposit_percent) ? $soc->deposit_percent : null));
|
|
$mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
|
|
$fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0));
|
|
$availability_id = (!empty($objectsrc->availability_id) ? $objectsrc->availability_id : 0);
|
|
$shipping_method_id = (!empty($objectsrc->shipping_method_id) ? $objectsrc->shipping_method_id : (!empty($soc->shipping_method_id) ? $soc->shipping_method_id : 0));
|
|
$warehouse_id = (!empty($objectsrc->warehouse_id) ? $objectsrc->warehouse_id : (!empty($soc->warehouse_id) ? $soc->warehouse_id : 0));
|
|
$demand_reason_id = (!empty($objectsrc->demand_reason_id) ? $objectsrc->demand_reason_id : (!empty($soc->demand_reason_id) ? $soc->demand_reason_id : 0));
|
|
$dateorder = getDolGlobalString('MAIN_AUTOFILL_DATE_ORDER') ? '' : -1;
|
|
|
|
$date_delivery = (!empty($objectsrc->delivery_date) ? $objectsrc->delivery_date : '');
|
|
|
|
if (isModEnabled("multicurrency")) {
|
|
if (!empty($objectsrc->multicurrency_code)) {
|
|
$currency_code = $objectsrc->multicurrency_code;
|
|
}
|
|
if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
|
|
$currency_tx = $objectsrc->multicurrency_tx;
|
|
}
|
|
}
|
|
|
|
$note_private = $object->getDefaultCreateValueFor('note_private', (!empty($objectsrc->note_private) ? $objectsrc->note_private : null));
|
|
$note_public = $object->getDefaultCreateValueFor('note_public', (!empty($objectsrc->note_public) ? $objectsrc->note_public : null));
|
|
|
|
// Object source contacts list
|
|
$srccontactslist = $objectsrc->liste_contact(-1, 'external', 1);
|
|
}
|
|
} else {
|
|
$cond_reglement_id = empty($soc->cond_reglement_id) ? $cond_reglement_id : $soc->cond_reglement_id;
|
|
$deposit_percent = empty($soc->deposit_percent) ? $deposit_percent : $soc->deposit_percent;
|
|
$mode_reglement_id = empty($soc->mode_reglement_id) ? $mode_reglement_id : $soc->mode_reglement_id;
|
|
$fk_account = empty($soc->mode_reglement_id) ? $fk_account : $soc->fk_account;
|
|
$availability_id = 0;
|
|
$shipping_method_id = empty($soc->shipping_method_id) ? $shipping_method_id : $soc->shipping_method_id;
|
|
$warehouse_id = $soc->fk_warehouse;
|
|
$demand_reason_id = $soc->demand_reason_id;
|
|
$dateorder = getDolGlobalString('MAIN_AUTOFILL_DATE_ORDER') ? '' : -1;
|
|
|
|
if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) {
|
|
$currency_code = $soc->multicurrency_code;
|
|
}
|
|
|
|
$note_private = $object->getDefaultCreateValueFor('note_private');
|
|
$note_public = $object->getDefaultCreateValueFor('note_public');
|
|
}
|
|
|
|
// If form was posted (but error returned), we must reuse the value posted in priority (standard Dolibarr behaviour)
|
|
if (!GETPOST('changecompany')) {
|
|
if (GETPOSTISSET('cond_reglement_id')) {
|
|
$cond_reglement_id = GETPOSTINT('cond_reglement_id');
|
|
}
|
|
if (GETPOSTISSET('deposit_percent')) {
|
|
$deposit_percent = GETPOSTFLOAT('deposit_percent');
|
|
}
|
|
if (GETPOSTISSET('mode_reglement_id')) {
|
|
$mode_reglement_id = GETPOSTINT('mode_reglement_id');
|
|
}
|
|
if (GETPOSTISSET('cond_reglement_id')) {
|
|
$fk_account = GETPOSTINT('fk_account');
|
|
}
|
|
}
|
|
|
|
// Warehouse default if null
|
|
if ($soc->fk_warehouse > 0) {
|
|
$warehouse_id = $soc->fk_warehouse;
|
|
}
|
|
if (isModEnabled('stock') && empty($warehouse_id) && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
|
|
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
|
|
$warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE');
|
|
}
|
|
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->fk_warehouse)) {
|
|
$warehouse_id = $user->fk_warehouse;
|
|
}
|
|
}
|
|
|
|
print '<form name="crea_commande" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
|
|
print '<input type="hidden" name="token" value="' . newToken() . '">';
|
|
print '<input type="hidden" name="action" value="add">';
|
|
print '<input type="hidden" name="changecompany" value="0">'; // will be set to 1 by javascript so we know post is done after a company change
|
|
print '<input type="hidden" name="remise_percent" value="' . $soc->remise_percent . '">';
|
|
print '<input type="hidden" name="origin" value="' . $origin . '">';
|
|
print '<input type="hidden" name="originid" value="' . $originid . '">';
|
|
print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
|
|
if (!empty($currency_tx)) {
|
|
print '<input type="hidden" name="originmulticurrency_tx" value="' . $currency_tx . '">';
|
|
}
|
|
|
|
print dol_get_fiche_head([]);
|
|
|
|
// Call Hook tabContentCreateOrder
|
|
$parameters = array();
|
|
// Note that $action and $object may be modified by hook
|
|
$reshook = $hookmanager->executeHooks('tabContentCreateOrder', $parameters, $object, $action);
|
|
if (empty($reshook)) {
|
|
print '<table class="border centpercent">';
|
|
|
|
// Reference
|
|
//print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans('Ref') . '</td><td>' . $langs->trans("Draft") . '</td></tr>';
|
|
|
|
// Thirdparty
|
|
print '<tr>';
|
|
print '<td class="fieldrequired">' . $langs->trans('Customer') . '</td>';
|
|
if ($socid > 0) {
|
|
print '<td>';
|
|
print $soc->getNomUrl(1, 'customer');
|
|
print '<input type="hidden" name="socid" value="' . $soc->id . '">';
|
|
print '</td>';
|
|
} else {
|
|
print '<td class="valuefieldcreate">';
|
|
$filter = '((s.client:IN:1,2,3) AND (s.status:=:1))';
|
|
print img_picto('', 'company', 'class="pictofixedwidth"') . $form->select_company('', 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
|
|
// reload page to retrieve customer information
|
|
if (!getDolGlobalString('RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED')) {
|
|
print '<script>
|
|
$(document).ready(function() {
|
|
$("#socid").change(function() {
|
|
console.log("We have changed the company - Reload page");
|
|
var socid = $(this).val();
|
|
// reload page
|
|
$("input[name=action]").val("create");
|
|
$("input[name=changecompany]").val("1");
|
|
$("form[name=crea_commande]").submit();
|
|
});
|
|
});
|
|
</script>';
|
|
}
|
|
print ' <a href="' . DOL_URL_ROOT . '/societe/card.php?action=create&customer=3&fournisseur=0&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?action=create') . '"><span class="fa fa-plus-circle valignmiddle paddingleft" title="' . $langs->trans("AddThirdParty") . '"></span></a>';
|
|
print '</td>';
|
|
}
|
|
print '</tr>' . "\n";
|
|
|
|
// Reference of order on customer side
|
|
if (getDolGlobalString('MAIN_ASK_CUSTOMER_REF_OF_SALE_ORDER_AT_CREATION') || getDolGlobalString('MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER')) {
|
|
print '<tr><td>';
|
|
if (getDolGlobalString('MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER') && !empty($origin) && !empty($originid)) {
|
|
print $langs->trans('RefProposal') . '</td><td>';
|
|
print '<input type="text" name="ref_client" value="' . $ref_client . '">';
|
|
} else {
|
|
print $form->textwithpicto($langs->trans('RefCustomer'), $langs->trans('RefOfOnCustomerSide', $langs->transnoentitiesnoconv("Order"))) . '</td><td>';
|
|
print '<input type="text" name="ref_client" value="' . GETPOST('ref_client') . '">';
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Contact of order
|
|
if ($socid > 0) {
|
|
// Contacts (ask contact only if thirdparty already defined).
|
|
// print "<tr><td>".$langs->trans("DefaultContact").'</td><td>';
|
|
print "<tr><td>";
|
|
print $form->textwithpicto($langs->trans("DefaultContact"), $langs->trans("TypeContact_commande_external_" . $type_contact_code));
|
|
print '</td><td>';
|
|
print img_picto('', 'contact', 'class="pictofixedwidth"');
|
|
//print $form->selectcontacts($soc->id, $contactid, 'contactid', 1, empty($srccontactslist) ? "" : $srccontactslist, '', 1, 'maxwidth300 widthcentpercentminusx');
|
|
print $form->select_contact($soc->id, $contactid, 'contactid', 1, empty($srccontactslist) ? "" : $srccontactslist, '', 1, 'maxwidth300 widthcentpercentminusx', true);
|
|
print '</td></tr>';
|
|
|
|
// Line with information on Third Party Discounts
|
|
print '<tr><td>' . $langs->trans('Discounts') . '</td><td>';
|
|
|
|
$absolute_discount = $soc->getAvailableDiscounts();
|
|
|
|
$thirdparty = $soc;
|
|
$discount_type = 0;
|
|
$backtopage = $_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . urlencode((string) (GETPOST('origin'))) . '&originid=' . urlencode((string) (GETPOSTINT('originid')));
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/object_discounts.tpl.php';
|
|
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Date
|
|
$dateorder = (getDolGlobalString('MAIN_DO_NOT_AUTOFILL_DATE_ORDER') ? -1 : ''); // By default '' so we will autofill date. -1 means keep empty.
|
|
|
|
print '<tr><td class="fieldrequired">' . $langs->trans('Date') . '</td><td>';
|
|
print img_picto('', 'action', 'class="pictofixedwidth"');
|
|
print $form->selectDate($dateorder, 're', 0, 0, 0, "crea_commande", 1, 1); // Always autofill date with current date
|
|
print '</td></tr>';
|
|
|
|
// Date delivery planned
|
|
print '<tr><td>' . $langs->trans("DateDeliveryPlanned") . '</td>';
|
|
print '<td colspan="3">';
|
|
$date_delivery = ($date_delivery ? $date_delivery : $object->delivery_date);
|
|
print img_picto('', 'action', 'class="pictofixedwidth"');
|
|
print $form->selectDate($date_delivery ? $date_delivery : -1, 'liv_', 1, 1, 1);
|
|
print "</td>\n";
|
|
print '</tr>';
|
|
|
|
// Delivery delay
|
|
print '<tr class="fielddeliverydelay"><td>' . $langs->trans('AvailabilityPeriod') . '</td><td>';
|
|
print img_picto('', 'clock', 'class="pictofixedwidth"');
|
|
$form->selectAvailabilityDelay((GETPOSTISSET('availability_id') ? GETPOST('availability_id') : $availability_id), 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx');
|
|
print '</td></tr>';
|
|
|
|
// Terms of payment
|
|
print '<tr><td class="nowrap">' . $langs->trans('PaymentConditionsShort') . '</td><td>';
|
|
print img_picto('', 'payment', 'class="pictofixedwidth"');
|
|
print $form->getSelectConditionsPaiements((int) $cond_reglement_id, 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', (float) $deposit_percent);
|
|
print '</td></tr>';
|
|
|
|
// Payment mode
|
|
print '<tr><td>' . $langs->trans('PaymentMode') . '</td><td>';
|
|
print img_picto('', 'bank', 'class="pictofixedwidth"');
|
|
print $form->select_types_paiements((string) $mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
|
|
print '</td></tr>';
|
|
|
|
// Bank Account
|
|
if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_ORDER') && isModEnabled("bank")) {
|
|
print '<tr><td>' . $langs->trans('BankAccount') . '</td><td>';
|
|
print img_picto('', 'bank_account', 'class="pictofixedwidth"') . $form->select_comptes((int) $fk_account, 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Shipping Method
|
|
if (isModEnabled('shipping')) {
|
|
print '<tr><td>' . $langs->trans('SendingMethod') . '</td><td>';
|
|
print img_picto('', 'object_dolly', 'class="pictofixedwidth"');
|
|
$form->selectShippingMethod(((GETPOSTISSET('shipping_method_id') && GETPOSTINT('shipping_method_id') > 0) ? GETPOST('shipping_method_id') : $shipping_method_id), 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx'); // -1 is the "no value" placeholder for this select, not 0, so it must not override the fresh thirdparty default after a company change
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Warehouse
|
|
if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
|
|
print '<tr><td>' . $langs->trans('Warehouse') . '</td><td>';
|
|
print img_picto('', 'stock', 'class="pictofixedwidth"') . $formproduct->selectWarehouses(((GETPOSTISSET('warehouse_id') && !GETPOSTINT('changecompany')) ? GETPOST('warehouse_id') : $warehouse_id), 'warehouse_id', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth500 widthcentpercentminusxx');
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Source / Channel - What trigger creation
|
|
print '<tr><td>' . $langs->trans('Source') . '</td><td>';
|
|
print img_picto('', 'question', 'class="pictofixedwidth"');
|
|
$form->selectInputReason((GETPOSTISSET('demand_reason_id') ? GETPOST('demand_reason_id') : $demand_reason_id), 'demand_reason_id', '', 1, 'maxwidth200 widthcentpercentminusx');
|
|
print '</td></tr>';
|
|
|
|
// TODO How record was recorded OrderMode (llx_c_input_method)
|
|
|
|
// Project
|
|
if (isModEnabled('project')) {
|
|
$langs->load("projects");
|
|
print '<tr>';
|
|
print '<td>'.$langs->trans("Project").'</td><td>';
|
|
print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects((($soc->id > 0 && !getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_CUSTOMERS')) ? $soc->id : -1), (GETPOSTISSET('projectid') ? GETPOST('projectid') : $projectid), 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
|
|
print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$soc->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Incoterms
|
|
if (isModEnabled('incoterm')) {
|
|
print '<tr>';
|
|
print '<td><label for="incoterm_id">' . $form->textwithpicto($langs->trans("IncotermLabel"), !empty($objectsrc->fk_incoterms) ? (string) $objectsrc->fk_incoterms : (string) $soc->fk_incoterms, 1) . '</label></td>';
|
|
print '<td class="maxwidthonsmartphone">';
|
|
$incoterm_id = GETPOST('incoterm_id');
|
|
$location_incoterms = GETPOST('location_incoterms');
|
|
if (empty($incoterm_id)) {
|
|
$incoterm_id = (!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : $soc->fk_incoterms);
|
|
$location_incoterms = (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : $soc->location_incoterms);
|
|
}
|
|
print img_picto('', 'incoterm', 'class="pictofixedwidth"');
|
|
print $form->select_incoterms($incoterm_id, $location_incoterms);
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Other attributes
|
|
$parameters = array();
|
|
if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
|
|
$parameters['objectsrc'] = $objectsrc;
|
|
}
|
|
$parameters['socid'] = $socid;
|
|
|
|
// Note that $action and $object may be modified by hook
|
|
$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);
|
|
print $hookmanager->resPrint;
|
|
if (empty($reshook)) {
|
|
if (getDolGlobalString('THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_ORDER') && !empty($soc->id)) {
|
|
// copy from thirdparty
|
|
$tpExtrafields = new ExtraFields($db);
|
|
$tpExtrafieldLabels = $tpExtrafields->fetch_name_optionals_label($soc->table_element);
|
|
if ($soc->fetch_optionals() > 0) {
|
|
$object->array_options = array_merge($object->array_options, $soc->array_options);
|
|
}
|
|
}
|
|
|
|
print $object->showOptionals($extrafields, 'create', $parameters);
|
|
}
|
|
|
|
// Template to use by default
|
|
include_once DOL_DOCUMENT_ROOT . '/core/modules/commande/modules_commande.php';
|
|
$list = ModelePDFCommandes::liste_modeles($db);
|
|
if (is_array($list) && count($list) > 0) {
|
|
print '<tr><td>' . $langs->trans('DefaultModel') . '</td>';
|
|
print '<td>';
|
|
$preselected = getDolGlobalString('COMMANDE_ADDON_PDF');
|
|
print img_picto('', 'pdf', 'class="pictofixedwidth"');
|
|
print $form->selectarray('model', $list, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1);
|
|
print "</td></tr>";
|
|
}
|
|
|
|
// Multicurrency
|
|
if (isModEnabled("multicurrency")) {
|
|
print '<tr>';
|
|
print '<td>' . $form->editfieldkey("Currency", 'multicurrency_code', '', $object, 0) . '</td>';
|
|
print '<td class="maxwidthonsmartphone">';
|
|
print img_picto('', 'currency', 'class="pictofixedwidth"') . $form->selectMultiCurrency(((GETPOSTISSET('multicurrency_code') && !GETPOST('changecompany')) ? GETPOST('multicurrency_code') : $currency_code), 'multicurrency_code', 0, '', false, 'maxwidth200 widthcentpercentminusx');
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Categories
|
|
if (isModEnabled('category')) {
|
|
print '<tr><td>' . $langs->trans("Categories") . '</td><td colspan="3">';
|
|
print $form->selectCategories(Categorie::TYPE_ORDER, 'categories', $object);
|
|
print "</td></tr>";
|
|
}
|
|
|
|
// Note public
|
|
print '<tr>';
|
|
print '<td class="tdtop">' . $langs->trans('NotePublic') . '</td>';
|
|
print '<td>';
|
|
|
|
$doleditor = new DolEditor('note_public', (string) $note_public, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
|
|
print $doleditor->Create(1);
|
|
// print '<textarea name="note_public" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_public.'</textarea>';
|
|
print '</td></tr>';
|
|
|
|
// Note private
|
|
if (empty($user->socid)) {
|
|
print '<tr>';
|
|
print '<td class="tdtop">' . $langs->trans('NotePrivate') . '</td>';
|
|
print '<td>';
|
|
|
|
$doleditor = new DolEditor('note_private', (string) $note_private, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
|
|
print $doleditor->Create(1);
|
|
// print '<textarea name="note" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'</textarea>';
|
|
print '</td></tr>';
|
|
}
|
|
|
|
if (!empty($origin) && !empty($originid) && is_object($objectsrc) && !empty($classname)) {
|
|
// TODO for compatibility
|
|
if ($origin == 'contrat') {
|
|
// Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
|
|
$objectsrc->update_price(1);
|
|
}
|
|
|
|
print "\n<!-- " . $classname . " info -->\n";
|
|
print '<input type="hidden" name="amount" value="' . $objectsrc->total_ht . '">' . "\n";
|
|
print '<input type="hidden" name="total" value="' . $objectsrc->total_ttc . '">' . "\n";
|
|
print '<input type="hidden" name="tva" value="' . $objectsrc->total_tva . '">' . "\n";
|
|
print '<input type="hidden" name="origin" value="' . $objectsrc->element . '">';
|
|
print '<input type="hidden" name="originid" value="' . $objectsrc->id . '">';
|
|
|
|
switch ($classname) {
|
|
case 'Propal':
|
|
$newclassname = 'CommercialProposal';
|
|
break;
|
|
case 'Commande':
|
|
$newclassname = 'Order';
|
|
break;
|
|
case 'Expedition':
|
|
$newclassname = 'Sending';
|
|
break;
|
|
case 'Contrat':
|
|
$newclassname = 'Contract';
|
|
break;
|
|
default:
|
|
$newclassname = $classname;
|
|
}
|
|
|
|
print '<tr><td>' . $langs->trans($newclassname) . '</td><td>' . $objectsrc->getNomUrl(1) . '</td></tr>';
|
|
|
|
// Amount
|
|
print '<tr><td>' . $langs->trans('AmountHT') . '</td><td>' . price($objectsrc->total_ht) . '</td></tr>';
|
|
print '<tr><td>' . $langs->trans('AmountVAT') . '</td><td>' . price($objectsrc->total_tva) . "</td></tr>";
|
|
if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) { // Localtax1 RE
|
|
print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td><td>' . price($objectsrc->total_localtax1) . "</td></tr>";
|
|
}
|
|
|
|
if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) { // Localtax2 IRPF
|
|
print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td><td>' . price($objectsrc->total_localtax2) . "</td></tr>";
|
|
}
|
|
|
|
print '<tr><td>' . $langs->trans('AmountTTC') . '</td><td>' . price($objectsrc->total_ttc) . "</td></tr>";
|
|
|
|
if (isModEnabled("multicurrency")) {
|
|
print '<tr><td>' . $langs->trans('MulticurrencyAmountHT') . '</td><td>' . price($objectsrc->multicurrency_total_ht) . '</td></tr>';
|
|
print '<tr><td>' . $langs->trans('MulticurrencyAmountVAT') . '</td><td>' . price($objectsrc->multicurrency_total_tva) . "</td></tr>";
|
|
print '<tr><td>' . $langs->trans('MulticurrencyAmountTTC') . '</td><td>' . price($objectsrc->multicurrency_total_ttc) . "</td></tr>";
|
|
}
|
|
}
|
|
|
|
print "\n";
|
|
|
|
print '</table>';
|
|
}
|
|
|
|
print dol_get_fiche_end();
|
|
|
|
print $form->buttonsSaveCancel("CreateDraft");
|
|
|
|
// Show origin lines
|
|
if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
|
|
$title = $langs->trans('ProductsAndServices');
|
|
print load_fiche_titre($title);
|
|
|
|
print '<div class="div-table-responsive-no-min">';
|
|
print '<table class="noborder centpercent">';
|
|
|
|
$objectsrc->printOriginLinesList('', $selectedLines);
|
|
|
|
print '</table>';
|
|
print '</div>';
|
|
}
|
|
|
|
print '</form>';
|
|
} else {
|
|
// Mode view
|
|
$now = dol_now();
|
|
|
|
if ($object->id > 0) {
|
|
$product_static = new Product($db);
|
|
|
|
$soc = new Societe($db);
|
|
$soc->fetch($object->socid);
|
|
|
|
$author = new User($db);
|
|
$author->fetch($object->user_author_id);
|
|
|
|
$object->fetch_thirdparty();
|
|
$res = $object->fetch_optionals();
|
|
|
|
$head = commande_prepare_head($object);
|
|
print dol_get_fiche_head($head, 'order', $langs->trans("CustomerOrder"), -1, $object->picto, 0, '', '', 0, '', 1);
|
|
|
|
$formconfirm = '';
|
|
|
|
// Confirmation to delete
|
|
if ($action == 'delete') {
|
|
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('DeleteOrder'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', '', 0, 1);
|
|
}
|
|
|
|
// Confirmation of validation
|
|
if ($action == 'validate') {
|
|
// We check that object has a temporary ref
|
|
$ref = substr($object->ref, 1, 4);
|
|
if ($ref == 'PROV' || $ref == '') {
|
|
$numref = $object->getNextNumRef($soc);
|
|
if (empty($numref)) {
|
|
$error++;
|
|
setEventMessages($object->error, $object->errors, 'errors');
|
|
}
|
|
} else {
|
|
$numref = (string) $object->ref;
|
|
}
|
|
|
|
$text = $langs->trans('ConfirmValidateOrder', $numref);
|
|
if (isModEnabled('notification')) {
|
|
require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
|
|
$notify = new Notify($db);
|
|
$text .= '<br>';
|
|
$text .= $notify->confirmMessage('ORDER_VALIDATE', $object->socid, $object);
|
|
}
|
|
|
|
$qualified_for_stock_change = 0;
|
|
if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(2);
|
|
} else {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(1);
|
|
}
|
|
|
|
$formquestion = array();
|
|
if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
|
|
$langs->load("stocks");
|
|
$forcecombo = 0;
|
|
if ($conf->browser->name == 'ie') {
|
|
$forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
|
|
}
|
|
$formquestion = array(
|
|
// 'text' => $langs->trans("ConfirmClone"),
|
|
// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
|
|
// array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
|
|
array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOSTINT('idwarehouse') ? GETPOSTINT('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
|
|
);
|
|
}
|
|
|
|
// mandatoryPeriod
|
|
$nbMandated = 0;
|
|
foreach ($object->lines as $line) {
|
|
$res = $line->fetch_product();
|
|
if ($res > 0) {
|
|
if ($line->product->isService() && $line->product->isMandatoryPeriod() && (empty($line->date_start) || empty($line->date_end))) {
|
|
$nbMandated++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ($nbMandated > 0) {
|
|
if (getDolGlobalString('SERVICE_STRICT_MANDATORY_PERIOD')) {
|
|
setEventMessages($langs->trans("mandatoryPeriodNeedTobeSetMsgValidate"), null, 'errors');
|
|
$error++;
|
|
} else {
|
|
$text .= '<div><span class="clearboth nowraponall warning">' . img_warning() . $langs->trans("mandatoryPeriodNeedTobeSetMsgValidate") . '</span></div>';
|
|
}
|
|
}
|
|
|
|
if (getDolGlobalInt('SALE_ORDER_SUGGEST_DOWN_PAYMENT_INVOICE_CREATION')) {
|
|
// This is a hidden option:
|
|
// Suggestion to create invoice during order validation is not enabled by default.
|
|
// Such choice should be managed by the workflow module and trigger. This option generates conflicts with some setup.
|
|
// It may also break step of creating an order when invoicing must be done from proposals and not from orders
|
|
$deposit_percent_from_payment_terms = (float) getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id);
|
|
|
|
if (!empty($deposit_percent_from_payment_terms) && isModEnabled('invoice') && $user->hasRight('facture', 'creer')) {
|
|
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
|
|
|
|
$object->fetchObjectLinked();
|
|
|
|
$eligibleForDepositGeneration = true;
|
|
|
|
if (array_key_exists('facture', $object->linkedObjects)) {
|
|
foreach ($object->linkedObjects['facture'] as $invoice) {
|
|
'@phan-var-force Facture $invoice';
|
|
if ($invoice->type == Facture::TYPE_DEPOSIT) {
|
|
$eligibleForDepositGeneration = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($eligibleForDepositGeneration && array_key_exists('propal', $object->linkedObjects)) {
|
|
foreach ($object->linkedObjects['propal'] as $proposal) {
|
|
$proposal->fetchObjectLinked();
|
|
|
|
if (array_key_exists('facture', $proposal->linkedObjects)) {
|
|
foreach ($proposal->linkedObjects['facture'] as $invoice) {
|
|
'@phan-var-force Facture $invoice';
|
|
if ($invoice->type == Facture::TYPE_DEPOSIT) {
|
|
$eligibleForDepositGeneration = false;
|
|
break 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($eligibleForDepositGeneration) {
|
|
$formquestion[] = array(
|
|
'type' => 'checkbox',
|
|
'tdclass' => '',
|
|
'name' => 'generate_deposit',
|
|
'label' => $form->textwithpicto($langs->trans('GenerateDeposit', $object->deposit_percent), $langs->trans('DepositGenerationPermittedByThePaymentTermsSelected'))
|
|
);
|
|
|
|
$formquestion[] = array(
|
|
'type' => 'date',
|
|
'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
|
|
'name' => 'datef',
|
|
'label' => $langs->trans('DateInvoice'),
|
|
'value' => dol_now(),
|
|
'datenow' => true
|
|
);
|
|
|
|
if (getDolGlobalString('INVOICE_POINTOFTAX_DATE')) {
|
|
$formquestion[] = array(
|
|
'type' => 'date',
|
|
'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
|
|
'name' => 'date_pointoftax',
|
|
'label' => $langs->trans('DatePointOfTax'),
|
|
'value' => dol_now(),
|
|
'datenow' => true
|
|
);
|
|
}
|
|
|
|
$paymentTermsSelect = $form->getSelectConditionsPaiements(0, 'cond_reglement_id', -1, 0, 0, 'minwidth200');
|
|
|
|
$formquestion[] = array(
|
|
'type' => 'other',
|
|
'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
|
|
'name' => 'cond_reglement_id',
|
|
'label' => $langs->trans('PaymentTerm'),
|
|
'value' => $paymentTermsSelect
|
|
);
|
|
|
|
$formquestion[] = array(
|
|
'type' => 'checkbox',
|
|
'tdclass' => 'showonlyifgeneratedeposit',
|
|
'name' => 'validate_generated_deposit',
|
|
'label' => $langs->trans('ValidateGeneratedDeposit')
|
|
);
|
|
|
|
$formquestion[] = array(
|
|
'type' => 'onecolumn',
|
|
'value' => '
|
|
<script>
|
|
$(document).ready(function() {
|
|
$("[name=generate_deposit]").change(function () {
|
|
let $self = $(this);
|
|
let $target = $(".showonlyifgeneratedeposit").parent(".tagtr");
|
|
|
|
if (! $self.parents(".tagtr").is(":hidden") && $self.is(":checked")) {
|
|
$target.show();
|
|
} else {
|
|
$target.hide();
|
|
}
|
|
|
|
return true;
|
|
});
|
|
});
|
|
</script>
|
|
'
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('ValidateOrder'), $text, 'confirm_validate', $formquestion, 0, 1, 240);
|
|
}
|
|
}
|
|
|
|
// Confirm back to draft status
|
|
if ($action == 'modif') {
|
|
$qualified_for_stock_change = 0;
|
|
if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(2);
|
|
} else {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(1);
|
|
}
|
|
|
|
$text = $langs->trans('ConfirmUnvalidateOrder', $object->ref);
|
|
$formquestion = array();
|
|
if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
|
|
$langs->load("stocks");
|
|
$forcecombo = 0;
|
|
if ($conf->browser->name == 'ie') {
|
|
$forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
|
|
}
|
|
$formquestion = [
|
|
// 'text' => $langs->trans("ConfirmClone"),
|
|
// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
|
|
// array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
|
|
[
|
|
'type' => 'other',
|
|
'name' => 'idwarehouse',
|
|
'label' => $langs->trans("SelectWarehouseForStockIncrease"),
|
|
'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo)
|
|
]
|
|
];
|
|
}
|
|
|
|
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('UnvalidateOrder'), $text, 'confirm_modif', $formquestion, "yes", 1, 220);
|
|
}
|
|
|
|
// Confirmation of closing
|
|
if ($action == 'shipped') {
|
|
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('CloseOrder'), $langs->trans('ConfirmCloseOrder'), 'confirm_shipped', '', 0, 1);
|
|
}
|
|
|
|
// Confirmation of cancellation
|
|
if ($action == 'cancel') {
|
|
$qualified_for_stock_change = 0;
|
|
if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(2);
|
|
} else {
|
|
$qualified_for_stock_change = $object->hasProductsOrServices(1);
|
|
}
|
|
|
|
$text = $langs->trans('ConfirmCancelOrder', $object->ref);
|
|
$formquestion = array();
|
|
if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
|
|
$langs->load("stocks");
|
|
$forcecombo = 0;
|
|
if ($conf->browser->name == 'ie') {
|
|
$forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
|
|
}
|
|
$formquestion = array(
|
|
// 'text' => $langs->trans("ConfirmClone"),
|
|
// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
|
|
// array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
|
|
array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
|
|
);
|
|
}
|
|
|
|
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans("Cancel"), $text, 'confirm_cancel', $formquestion, 0, 1);
|
|
}
|
|
|
|
// Confirmation to delete line
|
|
if ($action == 'ask_deleteline') {
|
|
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
|
|
}
|
|
|
|
// Generate form to delete a subtotal line
|
|
if ($action == 'ask_subtotal_deleteline') {
|
|
$langs->load("subtotals");
|
|
$title = "DeleteSubtotalLine";
|
|
$question = "ConfirmDeleteSubtotalLine";
|
|
if (GETPOST('type') == 'title') {
|
|
$formconfirm = array(array('type' => 'checkbox', 'name' => 'deletecorrespondingsubtotalline', 'label' => $langs->trans("DeleteCorrespondingSubtotalLine"), 'value' => 0));
|
|
$title = "DeleteTitleLine";
|
|
$question = "ConfirmDeleteTitleLine";
|
|
}
|
|
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans($title), $langs->trans($question), 'confirm_delete_subtotalline', $formconfirm, 'no', 1);
|
|
}
|
|
|
|
// Clone confirmation
|
|
if ($action == 'clone') {
|
|
$filter = '(s.client:IN:1,2,3)';
|
|
// Create an array for form
|
|
$formquestion = array(
|
|
array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter, '', 0, 0, array(), 0, 'maxwidth300'))
|
|
);
|
|
$formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
|
|
}
|
|
|
|
// Subtotal line form
|
|
if ($action == 'add_title_line') {
|
|
$langs->load('subtotals');
|
|
$type = 'title';
|
|
$depth_array = $object->getPossibleLevels($langs);
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
|
|
} elseif ($action == 'add_subtotal_line') {
|
|
$langs->load('subtotals');
|
|
$type = 'subtotal';
|
|
$titles = $object->getPossibleTitles();
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
|
|
}
|
|
|
|
// Call Hook formConfirm
|
|
$parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
|
|
// Note that $action and $object may be modified by hook
|
|
$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
|
|
if (empty($reshook)) {
|
|
$formconfirm .= $hookmanager->resPrint;
|
|
} elseif ($reshook > 0) {
|
|
$formconfirm = $hookmanager->resPrint;
|
|
}
|
|
|
|
// Print form confirm
|
|
print $formconfirm;
|
|
|
|
|
|
// Order card
|
|
|
|
$linkback = '<a href="' . DOL_URL_ROOT . '/commande/list.php?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
|
|
|
|
$morehtmlref = '<div class="refidno">';
|
|
// Ref customer
|
|
$morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, (int) $usercancreate, 'string', '', 0, 1);
|
|
$morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, (int) $usercancreate, 'string' . (isset($conf->global->THIRDPARTY_REF_INPUT_SIZE) ? ':' . getDolGlobalString('THIRDPARTY_REF_INPUT_SIZE') : ''), '', null, null, '', 1);
|
|
// Thirdparty
|
|
$morehtmlref .= '<br>' . $soc->getNomUrl(1, 'customer');
|
|
if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
|
|
$morehtmlref .= ' (<a href="' . DOL_URL_ROOT . '/commande/list.php?socid=' . ((int) $object->thirdparty->id) . '">' . $langs->trans("OtherOrders") . '</a>)';
|
|
}
|
|
// Project
|
|
if (isModEnabled('project')) {
|
|
$langs->load("projects");
|
|
$morehtmlref .= '<br>';
|
|
if ($usercancreate) {
|
|
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
|
|
if ($action != 'classify') {
|
|
$morehtmlref .= '<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> ';
|
|
}
|
|
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
|
|
} else {
|
|
if (!empty($object->fk_project)) {
|
|
$proj = new Project($db);
|
|
$proj->fetch($object->fk_project);
|
|
$morehtmlref .= $proj->getNomUrl(1);
|
|
if ($proj->title) {
|
|
$morehtmlref .= '<span class="opacitymedium"> - ' . dol_escape_htmltag($proj->title) . '</span>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$morehtmlref .= '</div>';
|
|
|
|
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
|
|
|
|
// Call Hook tabContentViewOrder
|
|
$parameters = array();
|
|
// Note that $action and $object may be modified by hook
|
|
$reshook = $hookmanager->executeHooks('tabContentViewOrder', $parameters, $object, $action);
|
|
if (empty($reshook)) {
|
|
print '<div class="fichecenter">';
|
|
print '<div class="fichehalfleft">';
|
|
print '<div class="underbanner clearboth"></div>';
|
|
|
|
print '<table class="border tableforfield centpercent">';
|
|
|
|
// POS
|
|
if (isModEnabled('takepos') || $object->module_source || getDolGlobalString('ORDER_ALLOW_POS_SOURCE_EDIT')) {
|
|
$langs->load("cashdesk");
|
|
print '<tr><td class="fieldname_type">';
|
|
print '<table class="nobordernopadding centpercent"><tr><td>';
|
|
print $form->textwithpicto($langs->trans('PointOfSale'), $langs->trans('POSInfo'));
|
|
print '</td>';
|
|
if ($action != 'editposinfo' && $usercancreate) {
|
|
print '<td class="right"><a class="editfielda" href="' . $_SERVER["PHP_SELF"] . '?action=editposinfo&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->trans('SetPOSInfo'), 1) . '</a></td>';
|
|
}
|
|
print '</tr></table>';
|
|
print '</td><td class="valuefield fieldname_type">';
|
|
print '<form method="POST" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" name="formposinfo">';
|
|
print '<input type="hidden" name="action" value="setposinfo">';
|
|
print '<input type="hidden" name="token" value="' . newToken() . '">';
|
|
if ($action == 'editposinfo') {
|
|
print '<input type="text" class="maxwidth150" name="posmodule" placeholder="' . $langs->trans("POSModule") . '" value="' . $object->module_source . '"> ';
|
|
print '<input type="text" class="maxwidth100" name="posterminal" placeholder="' . $langs->trans("Terminal") . '" value="' . $object->pos_source . '">';
|
|
print '<input type="submit" class="button" name="submitposinfo" value="' . $langs->trans("Submit") . '">';
|
|
} else {
|
|
if ($object->module_source) {
|
|
print '<span class="opacitymediumbycolor paddingleft">' . dolPrintHTML(ucfirst($object->module_source) . ' - ' . $langs->transnoentitiesnoconv("Terminal") . ' ' . $object->pos_source) . '</span>';
|
|
}
|
|
}
|
|
print '</form>';
|
|
print '</td></tr>';
|
|
}
|
|
|
|
if ($soc->outstanding_limit) {
|
|
// Outstanding Bill
|
|
print '<tr><td class="titlefield">';
|
|
print $langs->trans('OutstandingBill');
|
|
print '</td><td class="valuefield">';
|
|
$arrayoutstandingbills = $soc->getOutstandingBills();
|
|
print price($arrayoutstandingbills['opened']) . ' / ';
|
|
print price($soc->outstanding_limit, 0, '', 1, -1, -1, $conf->currency);
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Relative and absolute discounts
|
|
if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
|
|
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
|
|
$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
|
|
} else {
|
|
$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
|
|
$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
|
|
}
|
|
|
|
$addrelativediscount = '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditRelativeDiscounts") . '</a>';
|
|
$addabsolutediscount = '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditGlobalDiscounts") . '</a>';
|
|
$addcreditnote = '<a href="' . DOL_URL_ROOT . '/compta/facture/card.php?action=create&socid=' . $soc->id . '&type=2&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("AddCreditNote") . '</a>';
|
|
|
|
print '<tr><td class="titlefield">' . $langs->trans('Discounts') . '</td><td class="valuefield">';
|
|
|
|
$absolute_discount = $soc->getAvailableDiscounts(null, $filterabsolutediscount);
|
|
$absolute_creditnote = $soc->getAvailableDiscounts(null, $filtercreditnote);
|
|
$absolute_discount = price2num($absolute_discount, 'MT');
|
|
$absolute_creditnote = price2num($absolute_creditnote, 'MT');
|
|
|
|
$thirdparty = $soc;
|
|
$discount_type = 0;
|
|
$backtopage = $_SERVER["PHP_SELF"] . '?id=' . $object->id;
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/object_discounts.tpl.php';
|
|
|
|
print '</td></tr>';
|
|
|
|
// Date
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate && $object->status == Commande::STATUS_DRAFT;
|
|
print $form->editfieldkey("Date", 'date', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editdate') {
|
|
print '<form name="setdate" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
|
|
print '<input type="hidden" name="token" value="' . newToken() . '">';
|
|
print '<input type="hidden" name="action" value="setdate">';
|
|
print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
|
|
print $form->selectDate($object->date, 'order_', 0, 0, 0, "setdate");
|
|
print '<input type="submit" class="button button-edit" value="' . $langs->trans('Modify') . '">';
|
|
print '</form>';
|
|
} else {
|
|
print $object->date ? dol_print_date($object->date, 'day') : ' ';
|
|
if ($object->hasDelay() && empty($object->delivery_date)) { // If there is a delivery date planned, warning should be on this date
|
|
print ' ' . img_picto($langs->trans("Late") . ' : ' . $object->showDelay(), "warning");
|
|
}
|
|
}
|
|
print '</td>';
|
|
print '</tr>';
|
|
|
|
// Delivery date planned
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("DateDeliveryPlanned", 'date_livraison', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editdate_livraison') {
|
|
print '<form name="setdate_livraison" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
|
|
print '<input type="hidden" name="token" value="' . newToken() . '">';
|
|
print '<input type="hidden" name="action" value="setdate_livraison">';
|
|
print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
|
|
print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', 1, 1, 0, "setdate_livraison", 1, 0);
|
|
print '<input type="submit" class="button button-edit" value="' . $langs->trans('Modify') . '">';
|
|
print '</form>';
|
|
} else {
|
|
print $object->delivery_date ? dol_print_date($object->delivery_date, 'dayhour') : ' ';
|
|
if ($object->hasDelay() && !empty($object->delivery_date)) {
|
|
print ' ' . img_picto($langs->trans("Late") . ' : ' . $object->showDelay(), "warning");
|
|
}
|
|
}
|
|
// --- SHIPPABLE icon ---
|
|
if (isModEnabled('stock') && isModEnabled('shipping') && !getDolGlobalString('ORDER_DISABLE_SHIPPABLE_ICON_ON_CARD') && !empty($object->delivery_date)) {
|
|
$shippableInfos = $object->getShippableInfos();
|
|
|
|
if (!empty($shippableInfos['has_product'])) {
|
|
print ' ';
|
|
print $form->textwithtooltip('', $shippableInfos['textinfo'], 2, 1, $shippableInfos['texticon'], '', 2);
|
|
|
|
if (!empty($shippableInfos['warning'])) {
|
|
print ' ';
|
|
print $form->textwithtooltip('', $langs->trans("NotEnoughForAllOrders"), 2, 1, img_picto('', 'error', '', 0, 0, 0, '', '2'), '', 2);
|
|
}
|
|
}
|
|
}
|
|
print '</td>';
|
|
print '</tr>';
|
|
|
|
// Delivery delay
|
|
print '<tr class="fielddeliverydelay"><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("AvailabilityPeriod", 'availability', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editavailability') {
|
|
$form->form_availability($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->availability_id, 'availability_id', 1);
|
|
} else {
|
|
$form->form_availability($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->availability_id, 'none', 1);
|
|
}
|
|
print '</td></tr>';
|
|
|
|
// Shipping Method
|
|
if (isModEnabled('shipping')) {
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("SendingMethod", 'shippingmethod', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editshippingmethod') {
|
|
$form->formSelectShippingMethod($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->shipping_method_id, 'shipping_method_id', 1);
|
|
} else {
|
|
$form->formSelectShippingMethod($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->shipping_method_id, 'none');
|
|
}
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Warehouse
|
|
if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
|
|
$langs->load('stocks');
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("Warehouse", 'warehouse', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editwarehouse') {
|
|
$formproduct->formSelectWarehouses($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->warehouse_id, 'warehouse_id', 1);
|
|
} else {
|
|
$formproduct->formSelectWarehouses($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->warehouse_id, 'none');
|
|
}
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Source reason (why we have an order)
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("Source", 'demandreason', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editdemandreason') {
|
|
$form->formInputReason($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->demand_reason_id, 'demand_reason_id', 1);
|
|
} else {
|
|
$form->formInputReason($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->demand_reason_id, 'none');
|
|
}
|
|
print '</td></tr>';
|
|
|
|
// Terms of payment
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("PaymentConditionsShort", 'conditions', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editconditions') {
|
|
$form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent);
|
|
} else {
|
|
$form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent);
|
|
}
|
|
print '</td>';
|
|
|
|
print '</tr>';
|
|
|
|
// Mode of payment
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("PaymentMode", 'mode', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editmode') {
|
|
$form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
|
|
} else {
|
|
$form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->mode_reglement_id, 'none');
|
|
}
|
|
print '</td></tr>';
|
|
|
|
// TODO Order mode (how we receive order). Not yet implemented
|
|
/*
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("SourceMode", 'inputmode', '', $object, $editenable);
|
|
print '</td><td>';
|
|
if ($action == 'editinputmode') {
|
|
$form->formInputMode($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->source, 'input_mode_id', 1);
|
|
} else {
|
|
$form->formInputMode($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->source, 'none');
|
|
}
|
|
print '</td></tr>';
|
|
*/
|
|
|
|
$tmparray = $object->getTotalWeightVolume();
|
|
$totalWeight = $tmparray['weight'];
|
|
$totalVolume = $tmparray['volume'];
|
|
if ($totalWeight) {
|
|
print '<tr><td>' . $langs->trans("CalculatedWeight") . '</td>';
|
|
print '<td class="valuefield">';
|
|
print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, getDolGlobalInt('MAIN_WEIGHT_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_WEIGHT_DEFAULT_UNIT', 'no'));
|
|
print '</td></tr>';
|
|
}
|
|
if ($totalVolume) {
|
|
print '<tr><td>' . $langs->trans("CalculatedVolume") . '</td>';
|
|
print '<td class="valuefield">';
|
|
print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_VOLUME_DEFAULT_UNIT', 'no'));
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// TODO How record was recorded OrderMode (llx_c_input_method)
|
|
|
|
// Incoterms
|
|
if (isModEnabled('incoterm')) {
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("IncotermLabel", 'incoterm', '', $object, (int) $editenable);
|
|
print '</td>';
|
|
print '<td class="valuefield">';
|
|
if ($action != 'editincoterm') {
|
|
print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
|
|
} else {
|
|
print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'] . '?id=' . $object->id);
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Bank Account
|
|
if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_ORDER') && isModEnabled("bank")) {
|
|
print '<tr><td>';
|
|
$editenable = $usercancreate;
|
|
print $form->editfieldkey("BankAccount", 'bankaccount', '', $object, (int) $editenable);
|
|
print '</td><td class="valuefield">';
|
|
if ($action == 'editbankaccount') {
|
|
$form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->fk_account, 'fk_account', 1);
|
|
} else {
|
|
$form->formSelectAccount($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->fk_account, 'none');
|
|
}
|
|
print '</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
// Tags-Categories
|
|
if (isModEnabled('category')) {
|
|
print '<tr><td>';
|
|
print '<table class="nobordernopadding centpercent"><tr><td>';
|
|
print $langs->trans("Categories");
|
|
print '<td><td class="right">';
|
|
if ($usercancreate) {
|
|
print '<a class="editfielda" href="' . DOL_URL_ROOT . '/commande/card.php?id=' . $object->id . '&action=edittags&token=' . newToken() . '">' . img_edit() . '</a>';
|
|
} else {
|
|
print ' ';
|
|
}
|
|
print '</td></tr></table>';
|
|
print '</td>';
|
|
print '<td>';
|
|
if ($action == 'edittags') {
|
|
print '<form method="POST" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '">';
|
|
print '<input type="hidden" name="action" value="settags">';
|
|
print '<input type="hidden" name="token" value="' . newToken() . '">';
|
|
print $form->selectCategories(Categorie::TYPE_ORDER, 'categories', $object);
|
|
print '<input type="submit" class="button valignmiddle smallpaddingimp" value="' . $langs->trans("Modify") . '">';
|
|
print '</form>';
|
|
} else {
|
|
print $form->showCategories($object->id, Categorie::TYPE_ORDER, 1);
|
|
}
|
|
print "</td></tr>";
|
|
}
|
|
|
|
// Other attributes
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
|
|
|
|
print '</table>';
|
|
|
|
print '</div>';
|
|
print '<div class="fichehalfright">';
|
|
print '<div class="underbanner clearboth"></div>';
|
|
|
|
print '<table class="border tableforfield centpercent">';
|
|
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/object_currency_amount.tpl.php';
|
|
|
|
$alert = '';
|
|
if (getDolGlobalString('ORDER_MANAGE_MIN_AMOUNT') && $object->total_ht < $object->thirdparty->order_min_amount) {
|
|
$alert = ' ' . img_warning($langs->trans('OrderMinAmount') . ': ' . price($object->thirdparty->order_min_amount));
|
|
}
|
|
|
|
print '<tr>';
|
|
print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
|
|
print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
|
|
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
|
// Multicurrency Amount HT
|
|
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
|
}
|
|
print '</tr>';
|
|
|
|
print '<tr>';
|
|
print '<td class="titlefieldmiddle">' . $langs->trans('AmountVAT') . '</td>';
|
|
print '<td class="nowrap amountcard right">' . price($object->total_tva, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
|
|
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
|
// Multicurrency Amount VAT
|
|
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 1, -1, -1, $object->multicurrency_code) . '</td>';
|
|
}
|
|
print '</tr>';
|
|
|
|
// Amount Local Taxes
|
|
if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) {
|
|
print '<tr>';
|
|
print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
|
|
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
|
|
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
|
$object->multicurrency_total_localtax1 = price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
|
|
|
|
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax1, 0, $langs, 1, -1, -1, $object->multicurrency_code) . '</td>';
|
|
}
|
|
print '</tr>';
|
|
}
|
|
|
|
// Amount Local Taxes
|
|
if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
|
|
print '<tr>';
|
|
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
|
|
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
|
|
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
|
$object->multicurrency_total_localtax2 = price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
|
|
|
|
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax2, 0, $langs, 1, -1, -1, $object->multicurrency_code) . '</td>';
|
|
}
|
|
print '</tr>';
|
|
}
|
|
|
|
print '<tr>';
|
|
print '<td>' . $langs->trans('AmountTTC') . '</td>';
|
|
print '<td class="valuefield nowrap right amountcard">' . price($object->total_ttc, 1, '', 1, -1, -1, $conf->currency) . '</td>';
|
|
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
|
// Multicurrency Amount TTC
|
|
print '<td class="valuefield nowrap right amountcard">' . price($object->multicurrency_total_ttc, 1, '', 1, -1, -1, $object->multicurrency_code) . '</td>';
|
|
}
|
|
print '</tr>' . "\n";
|
|
|
|
print '</table>';
|
|
|
|
// Statut
|
|
//print '<tr><td>' . $langs->trans('Status') . '</td><td>' . $object->getLibStatut(4) . '</td></tr>';
|
|
|
|
// Margin Infos
|
|
if (isModEnabled('margin')) {
|
|
$formmargin->displayMarginInfos($object);
|
|
}
|
|
|
|
|
|
print '</div>';
|
|
print '</div>'; // Close fichecenter
|
|
|
|
print '<div class="clearboth"></div><br>';
|
|
|
|
if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
|
|
$blocname = 'contacts';
|
|
$title = $langs->trans('ContactsAddresses');
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php';
|
|
}
|
|
|
|
if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
|
|
$blocname = 'notes';
|
|
$title = $langs->trans('Notes');
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php';
|
|
}
|
|
|
|
/*
|
|
* Lines
|
|
*/
|
|
|
|
// Get object lines
|
|
$result = $object->getLinesArray();
|
|
|
|
// Add products/services form
|
|
//$forceall = 1;
|
|
global $inputalsopricewithtax;
|
|
$inputalsopricewithtax = 1;
|
|
|
|
print '<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="POST">
|
|
<input type="hidden" name="token" value="' . newToken() . '">
|
|
<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline') . '">
|
|
<input type="hidden" name="mode" value="">
|
|
<input type="hidden" name="page_y" value="">
|
|
<input type="hidden" name="id" value="' . $object->id . '">
|
|
<input type="hidden" name="backtopage" value="' . $backtopage . '">
|
|
';
|
|
|
|
if (!empty($conf->use_javascript_ajax) && $object->status == Commande::STATUS_DRAFT) {
|
|
if (isModEnabled('subtotals')) {
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_ajaxrow.tpl.php';
|
|
} else {
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
|
|
}
|
|
}
|
|
|
|
print '<div class="div-table-responsive-no-min">';
|
|
print '<table id="tablelines" class="noborder noshadow" width="100%">';
|
|
|
|
// Show object lines
|
|
if (!empty($object->lines)) {
|
|
$object->printObjectLines($action, $mysoc, $soc, $lineid, 1);
|
|
}
|
|
|
|
/*
|
|
* Form to add new line
|
|
*/
|
|
if ($object->status == Commande::STATUS_DRAFT && $usercancreate && $action != 'selectlines') {
|
|
if ($action != 'editline') {
|
|
// Add free products/services
|
|
|
|
$parameters = array();
|
|
// Note that $action and $object may be modified by hook
|
|
$reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action);
|
|
if ($reshook < 0) {
|
|
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
|
}
|
|
if (empty($reshook)) {
|
|
$object->formAddObjectLine(1, $mysoc, $soc);
|
|
}
|
|
} else {
|
|
$parameters = array();
|
|
$reshook = $hookmanager->executeHooks('formEditObjectLine', $parameters, $object, $action);
|
|
}
|
|
}
|
|
print '</table>';
|
|
print '</div>';
|
|
|
|
print "</form>\n";
|
|
}
|
|
|
|
print dol_get_fiche_end();
|
|
|
|
/*
|
|
* Buttons for actions
|
|
*/
|
|
if ($action != 'presend' && $action != 'editline') {
|
|
print '<div class="tabsAction">';
|
|
|
|
$parameters = array();
|
|
$arrayforbutaction = array();
|
|
// Note that $action and $object may be modified by hook
|
|
$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action);
|
|
if (empty($reshook)) {
|
|
$numlines = count($object->lines);
|
|
|
|
// Reopen a closed order
|
|
if (($object->status == Commande::STATUS_CLOSED || $object->status == Commande::STATUS_CANCELED) && $usercancreate && (!$object->billed || !getDolGlobalInt('ORDER_DONT_REOPEN_BILLED'))) {
|
|
print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"] . '?action=reopen&token=' . newToken() . '&id=' . $object->id, '');
|
|
}
|
|
|
|
// Send
|
|
if (empty($user->socid)) {
|
|
if ($object->status > Commande::STATUS_DRAFT || getDolGlobalString('COMMANDE_SENDBYEMAIL_FOR_ALL_STATUS')) {
|
|
if ($usercansend) {
|
|
print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER["PHP_SELF"] . '?action=presend&token=' . newToken() . '&id=' . $object->id . '&mode=init#formmailbeforetitle', '');
|
|
} else {
|
|
print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER['PHP_SELF'] . '#', '', false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Subtotal
|
|
if ($object->status == Commande::STATUS_DRAFT && isModEnabled('subtotals')
|
|
&& (getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element)))) {
|
|
$langs->load('subtotals');
|
|
|
|
$url_button = array();
|
|
|
|
$url_button[] = array(
|
|
'lang' => 'subtotals',
|
|
'enabled' => (isModEnabled('order') && $object->status == Commande::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element))),
|
|
'perm' => (bool) $usercancreate,
|
|
'label' => $langs->trans('AddTitleLine'),
|
|
'url' => '/commande/card.php?id=' . $object->id . '&action=add_title_line&token=' . newToken()
|
|
);
|
|
|
|
$url_button[] = array(
|
|
'lang' => 'subtotals',
|
|
'enabled' => (isModEnabled('order') && $object->status == Commande::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element))),
|
|
'perm' => (bool) $usercancreate,
|
|
'label' => $langs->trans('AddSubtotalLine'),
|
|
'url' => '/commande/card.php?id=' . $object->id . '&action=add_subtotal_line&token=' . newToken()
|
|
);
|
|
print dolGetButtonAction('', $langs->trans('Subtotal'), 'default', $url_button, '', true);
|
|
}
|
|
|
|
// Valid
|
|
if ($object->status == Commande::STATUS_DRAFT && ($object->total_ttc >= 0 || getDolGlobalString('ORDER_ENABLE_NEGATIVE')) && $usercanvalidate) {
|
|
if ($numlines > 0) {
|
|
print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"] . '?action=validate&token=' . newToken() . '&id=' . $object->id, (string) $object->id, 1);
|
|
} else {
|
|
$langs->load("errors");
|
|
print dolGetButtonAction($langs->trans("ErrorObjectMustHaveLinesToBeValidated", $object->ref), $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"] . '?action=validate&token=' . newToken() . '&id=' . $object->id, (string) $object->id, -1);
|
|
}
|
|
}
|
|
// Edit
|
|
if (($object->status == Commande::STATUS_VALIDATED || ($object->status == Commande::STATUS_SHIPMENTONPROCESS && getDolGlobalString('EDIT_ORDER_SHIPMENT_ON_PROCESS'))) && $usercancreate) {
|
|
print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"] . '?action=modif&token=' . newToken() . '&id=' . $object->id, '');
|
|
}
|
|
|
|
// Create a purchase order
|
|
|
|
if (!getDolGlobalInt('COMMANDE_DISABLE_ADD_PURCHASE_ORDER')) {
|
|
$arrayforbutaction[] = array(
|
|
'lang' => 'orders',
|
|
'enabled' => (isModEnabled("supplier_order") && $object->status > Commande::STATUS_DRAFT),
|
|
'perm' => $usercancreatepurchaseorder,
|
|
'label' => 'AddPurchaseOrder',
|
|
'url' => '/fourn/commande/card.php?action=create&origin=' . urlencode($object->element) . '&originid=' . ((int) $object->id)
|
|
);
|
|
}
|
|
|
|
/*if (isModEnabled("supplier_order") && $object->status > Commande::STATUS_DRAFT && $object->getNbOfServicesLines() > 0) {
|
|
if ($usercancreatepurchaseorder) { isModEnabled("supplier_order") && $object->status > Commande::STATUS_DRAFT && $object->getNbOfServicesLines() > 0
|
|
print dolGetButtonAction('', $langs->trans('AddPurchaseOrder'), 'default', DOL_URL_ROOT.'/fourn/commande/card.php?action=create&origin='.$object->element.'&originid='.$object->id, '');
|
|
}
|
|
}*/
|
|
|
|
// Create intervention
|
|
if (!getDolGlobalInt('COMMANDE_DISABLE_ADD_INTERVENTION')) {
|
|
$arrayforbutaction[] = array(
|
|
'lang' => 'interventions',
|
|
'enabled' => (isModEnabled("intervention") && $object->status > Commande::STATUS_DRAFT && $object->status < Commande::STATUS_CLOSED && $object->getNbOfServicesLines() > 0),
|
|
'perm' => ($user->hasRight('ficheinter', 'creer') == 1),
|
|
'label' => 'AddIntervention',
|
|
'url' => '/fichinter/card.php?action=create&origin=' . urlencode($object->element) . '&originid=' . ((int) $object->id) . '&socid=' . ((int) $object->socid),
|
|
);
|
|
}
|
|
|
|
// Create contract
|
|
if (!getDolGlobalInt('COMMANDE_DISABLE_ADD_CONTRACT')) {
|
|
$arrayforbutaction[] = [
|
|
'lang' => 'contracts',
|
|
'enabled' => (isModEnabled("contract") && ($object->status == Commande::STATUS_VALIDATED || $object->status == Commande::STATUS_SHIPMENTONPROCESS || $object->status == Commande::STATUS_CLOSED)),
|
|
'perm' => ($user->hasRight('contrat', 'creer') == 1),
|
|
'label' => 'AddContract',
|
|
'url' => '/contrat/card.php?action=create&origin=' . $object->element . '&originid=' . $object->id . '&socid=' . $object->socid,
|
|
];
|
|
}
|
|
/*if (isModEnabled('contract') && ($object->status == Commande::STATUS_VALIDATED || $object->status == Commande::STATUS_SHIPMENTONPROCESS || $object->status == Commande::STATUS_CLOSED)) {
|
|
$langs->load("contracts");
|
|
|
|
if ($user->hasRight('contrat', 'creer')) {
|
|
print dolGetButtonAction('', $langs->trans('AddContract'), 'default', DOL_URL_ROOT.'/contrat/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, '');
|
|
}
|
|
}*/
|
|
|
|
$numshipping = 0;
|
|
|
|
// Create shipment
|
|
if (isModEnabled('shipping')) {
|
|
$numshipping = $object->countNbOfShipments();
|
|
|
|
if ($object->status > Commande::STATUS_DRAFT && $object->status < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES'))) {
|
|
if ((getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && $user->hasRight('expedition', 'creer')) || (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && $user->hasRight('expedition', 'delivery', 'creer'))) {
|
|
// Add button to create shipment into the combo
|
|
$arrayforbutaction[] = array(
|
|
'lang' => 'sendings',
|
|
'enabled' => (isModEnabled("shipping") && ($object->status > Commande::STATUS_DRAFT && $object->status < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES')))),
|
|
'perm' => $user->hasRight('expedition', 'creer'),
|
|
'label' => 'CreateShipment',
|
|
'url' => '/expedition/shipment.php?id=' . $object->id
|
|
);
|
|
} else {
|
|
//c$langs->load("errors");
|
|
//print dolGetButtonAction($langs->trans('ErrorModuleSetupNotComplete'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
|
|
$arrayforbutaction[] = array(
|
|
'lang' => 'sendings',
|
|
'enabled' => (isModEnabled("shipping") && ($object->status > Commande::STATUS_DRAFT && $object->status < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES')))),
|
|
'perm' => 0,
|
|
'label' => 'CreateShipment',
|
|
'url' => '/expedition/shipment.php?id=' . $object->id
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create bill
|
|
$arrayforbutaction[] = array(
|
|
'lang' => 'bills',
|
|
'enabled' => (isModEnabled('invoice') && $object->status > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0),
|
|
'perm' => ($user->hasRight('facture', 'creer') && !getDolGlobalInt('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')),
|
|
'label' => 'CreateBill',
|
|
'url' => '/compta/facture/card.php?action=create&token=' . newToken() . '&origin=' . urlencode($object->element) . '&originid=' . $object->id . '&socid=' . $object->socid
|
|
);
|
|
/*
|
|
if (isModEnabled('facture') && $object->status > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) {
|
|
if (isModEnabled('facture') && $user->hasRight('facture', 'creer') && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) {
|
|
print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&token='.newToken().'&origin='.urlencode($object->element).'&originid='.$object->id.'&socid='.$object->socid, '');
|
|
}
|
|
}*/
|
|
|
|
$actionButtonsParameters = [
|
|
"areDropdownButtons" => !getDolGlobalInt("MAIN_REMOVE_DROPDOWN_CREATE_BUTTONS_ON_ORDER")
|
|
];
|
|
|
|
if ($numlines > 0) {
|
|
print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayforbutaction, (string) $object->id, 1, $actionButtonsParameters);
|
|
} else {
|
|
print dolGetButtonAction($langs->trans("ErrorObjectMustHaveLinesToBeValidated", $object->ref), $langs->trans("Create"), 'default', $arrayforbutaction, (string) $object->id, 0, $actionButtonsParameters);
|
|
}
|
|
|
|
// Set to shipped
|
|
if (($object->status == Commande::STATUS_VALIDATED || $object->status == Commande::STATUS_SHIPMENTONPROCESS) && $usercanclose) {
|
|
print dolGetButtonAction('', $langs->trans('ClassifyShipped'), 'default', $_SERVER["PHP_SELF"] . '?action=shipped&token=' . newToken() . '&id=' . $object->id, '');
|
|
}
|
|
|
|
// Set billed or unbilled
|
|
// Note: Even if module invoice is not enabled, we should be able to use button "Classified billed"
|
|
if ($object->status > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) {
|
|
if ($usercancreate && $object->status >= Commande::STATUS_VALIDATED && !getDolGlobalString('ORDER_DISABLE_CLASSIFY_BILLED_FROM_ORDER') && !getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')) {
|
|
print dolGetButtonAction('', $langs->trans('ClassifyBilled'), 'default', $_SERVER["PHP_SELF"] . '?action=classifybilled&token=' . newToken() . '&id=' . $object->id, '');
|
|
}
|
|
}
|
|
if ($object->status > Commande::STATUS_DRAFT && $object->billed) {
|
|
if ($usercancreate && $object->status >= Commande::STATUS_VALIDATED && !getDolGlobalString('ORDER_DISABLE_CLASSIFY_BILLED_FROM_ORDER') && !getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')) {
|
|
print dolGetButtonAction('', $langs->trans('ClassifyUnBilled'), 'delete', $_SERVER["PHP_SELF"] . '?action=classifyunbilled&token=' . newToken() . '&id=' . $object->id, '');
|
|
}
|
|
}
|
|
|
|
// Clone
|
|
if ($usercancreate) {
|
|
print dolGetButtonAction('', $langs->trans('ToClone'), 'clone', $_SERVER["PHP_SELF"] . '?action=clone&token=' . newToken() . '&id=' . $object->id . '&socid=' . $object->socid, '');
|
|
}
|
|
|
|
// Cancel order
|
|
if ($object->status == Commande::STATUS_VALIDATED && !empty($usercancancel)) {
|
|
print '<a class="butActionDelete" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=cancel&token=' . newToken() . '">' . $langs->trans("CancelOrder") . '</a>';
|
|
}
|
|
|
|
// Delete order
|
|
if ($usercandelete) {
|
|
if ($numshipping == 0) {
|
|
print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"] . '?action=delete&token=' . newToken() . '&id=' . $object->id, '');
|
|
} else {
|
|
print dolGetButtonAction($langs->trans('ShippingExist'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF'] . '#', '', false);
|
|
}
|
|
}
|
|
}
|
|
print '</div>';
|
|
}
|
|
|
|
// Select mail models is same action as presend
|
|
if (GETPOST('modelselected')) {
|
|
$action = 'presend';
|
|
}
|
|
|
|
if ($action != 'presend') {
|
|
print '<div class="fichecenter"><div class="fichehalfleft">';
|
|
print '<a name="builddoc"></a>'; // ancre
|
|
// Documents
|
|
$objref = dol_sanitizeFileName($object->ref);
|
|
$relativepath = $objref . '/' . $objref . '.pdf';
|
|
$filedir = $conf->commande->multidir_output[$object->entity ?? $conf->entity] . '/' . $objref;
|
|
$urlsource = dolBuildUrl($_SERVER["PHP_SELF"], ["id" => $object->id]);
|
|
$genallowed = $usercanread;
|
|
$delallowed = $usercancreate;
|
|
$tooltipAfterComboOfModels = '';
|
|
if (getDolGlobalString('MAIN_PDF_ADD_TERMSOFSALE_ORDER')) {
|
|
$tooltipAfterComboOfModels = $langs->trans("AccordingToYourSetupTheFileWillBeConcatenated", getDolGlobalString('MAIN_INFO_ORDER_TERMSOFSALE'));
|
|
}
|
|
|
|
print $formfile->showdocuments('commande', $objref, $filedir, $urlsource, $genallowed, (int) $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang, '', $object, 0, 'remove_file', $tooltipAfterComboOfModels);
|
|
|
|
|
|
// Show links to link elements
|
|
$tmparray = $form->showLinkToObjectBlock($object, array(), array('order'), 1);
|
|
$linktoelem = $tmparray['linktoelem'];
|
|
$htmltoenteralink = $tmparray['htmltoenteralink'];
|
|
print $htmltoenteralink;
|
|
|
|
$compatibleImportElementsList = false;
|
|
if (
|
|
$usercancreate
|
|
&& $object->status == Commande::STATUS_DRAFT
|
|
) {
|
|
$compatibleImportElementsList = array('commande', 'propal', 'facture', 'subscription'); // import from linked elements
|
|
}
|
|
$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, $compatibleImportElementsList);
|
|
|
|
// Show online payment link
|
|
// The list can be complete by the hook 'doValidatePayment' executed inside getValidOnlinePaymentMethods()
|
|
include_once DOL_DOCUMENT_ROOT . '/core/lib/payments.lib.php';
|
|
$validpaymentmethod = getValidOnlinePaymentMethods('');
|
|
$useonlinepayment = count($validpaymentmethod);
|
|
|
|
if (getDolGlobalString('ORDER_HIDE_ONLINE_PAYMENT_ON_ORDER')) {
|
|
$useonlinepayment = 0;
|
|
}
|
|
if ($object->status != Commande::STATUS_DRAFT && $useonlinepayment) {
|
|
print '<br><!-- Link to pay -->';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/lib/payments.lib.php';
|
|
print showOnlinePaymentUrl('order', $object->ref) . '<br>';
|
|
}
|
|
|
|
print '</div><div class="fichehalfright">';
|
|
|
|
$MAXEVENT = 10;
|
|
|
|
//button to go to messaging from the events box
|
|
$morehtmlcenter = dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', dolBuildUrl(DOL_URL_ROOT . '/commande/messaging.php', ['id' => $object->id]));
|
|
$morehtmlcenter .= dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dolBuildUrl(DOL_URL_ROOT . '/commande/agenda.php', ['id' => $object->id]));
|
|
|
|
// List of actions on element
|
|
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
|
|
$formactions = new FormActions($db);
|
|
$somethingshown = $formactions->showactions($object, 'order', $socid, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for thirdparty
|
|
|
|
print '</div></div>';
|
|
}
|
|
|
|
// Presend form
|
|
$modelmail = 'order_send';
|
|
$defaulttopic = 'SendOrderRef';
|
|
$diroutput = getMultidirOutput($object);
|
|
$trackid = 'ord' . $object->id;
|
|
|
|
include DOL_DOCUMENT_ROOT . '/core/tpl/card_presend.tpl.php';
|
|
}
|
|
}
|
|
|
|
// End of page
|
|
llxFooter();
|
|
$db->close();
|