mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2026-03-13 13:57:07 +01:00
* This PR adds visual indicators on the Sales Order card (commande/card.php) to quickly identify if an order or its lines are shippable based on current stock levels. This feature mirrors the existing functionality found in the Orders List, bringing valuable logistics information directly into the Order Card context. Key Features: Global Shippable Status: Adds a "shippable" icon (Truck) next to the "Planned delivery date" field. Logic: Checks if all products in the order are in stock. Condition: Visible only if Stock and Shipment modules are enabled, a delivery date is set, and the order is validated. Visual: Green icon if fully shippable, Red/Warning if stock is insufficient. Includes a detailed tooltip. Per-Line Shippable Status: Adds a new "Shippable" column in the product lines table. Logic: Compares real stock vs. remaining quantity to ship for each line. Visual: Displays a green/red status bullet (standard Dolibarr status icons) directly in the line. Implementation: Done by updating objectline_title.tpl.php and objectline_view.tpl.php with specific checks for the commande element. New Configuration Option: Added a hidden option ORDER_DISABLE_SHIPPABLE_ICON_ON_CARD to disable this feature if needed (configurable in Home > Setup > Other Setup or via module settings). Backend Optimization: Added a new method getShippableInfos() in commande.class.php to centralize the stock check logic (optimized with stock caching to avoid N+1 query issues). Technical Details: Modified Files: commande/card.php: Integration of the global icon next to the date. commande/class/commande.class.php: Added getShippableInfos() method. core/tpl/objectline_title.tpl.php: Added "Shippable" column header (conditional for Orders). core/tpl/objectline_view.tpl.php: Added "Shippable" column cell content (conditional for Orders). Performance: Logic uses static caching for product stock to minimize database impact when rendering large orders. * missed element * img_picto * phan add * load_stock and global $i * phan * ci retour * change icon change phan directive * phan * Fight against optionflation Signed-off-by: Laurent Destailleur <eldy@destailleur.fr> * Change condition for displaying shippable icon Signed-off-by: Laurent Destailleur <eldy@destailleur.fr> * Change condition for displaying shippable status icon Signed-off-by: Laurent Destailleur <eldy@destailleur.fr> * Update card.php Signed-off-by: Laurent Destailleur <eldy@destailleur.fr> * Update shippable status condition in template Signed-off-by: Laurent Destailleur <eldy@destailleur.fr> * Update shippable status condition logic Signed-off-by: Laurent Destailleur <eldy@destailleur.fr> --------- Signed-off-by: Laurent Destailleur <eldy@destailleur.fr> Co-authored-by: jpb <jean-pascal.boudet@atm-consulting> Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
3764 lines
159 KiB
PHP
3764 lines
159 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>
|
|
*
|
|
* 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';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
|
|
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.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';
|
|
|
|
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';
|
|
}
|
|
|
|
|
|
/**
|
|
* @var Conf $conf
|
|
* @var DoliDB $db
|
|
* @var HookManager $hookmanager
|
|
* @var Societe $mysoc
|
|
* @var Translate $langs
|
|
* @var User $user
|
|
*/
|
|
|
|
// 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;
|
|
|
|
|
|
// 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);
|
|
$extrafields = new ExtraFields($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($object->error, $object->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 . ')';
|
|
}
|
|
|
|
$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,
|
|
'HT',
|
|
0,
|
|
$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 == 'setremisepercent' && $usercancreate) {
|
|
// $result = $object->setDiscount($user, price2num(GETPOST('remise_percent'), '', 2));
|
|
//} elseif ($action == 'setremiseabsolue' && $usercancreate) {
|
|
// $result = $object->set_remise_absolue($user, price2num(GETPOST('remise_absolue'), 'MU', 2));
|
|
} 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
|
|
$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, $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;
|
|
}
|
|
$result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, '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->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 . ')';
|
|
}
|
|
$result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, (float) $remise_percent, $tvatx, $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->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;
|
|
}
|
|
|
|
$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 {
|
|
$object->errors[] = $langs->trans("CorrespondingTitleNotFound");
|
|
}
|
|
|
|
if (isset($result) && $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
|
|
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');
|
|
} 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 = '';
|
|
} 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');
|
|
} 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 = '';
|
|
} 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']);
|
|
} 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;
|
|
|
|
$pu = $pu_ht;
|
|
$price_base_type = 'HT';
|
|
if (empty($pu) && !empty($pu_ttc)) {
|
|
$pu = $pu_ttc;
|
|
$price_base_type = 'TTC';
|
|
}
|
|
|
|
// 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);
|
|
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);
|
|
}
|
|
|
|
//$remise_absolue = 0;
|
|
|
|
$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;
|
|
}
|
|
/*if (!$dateorder) {
|
|
// Do not set 0 here (0 for a date is 1970)
|
|
$dateorder = (empty($dateinvoice) ? (empty($conf->global->MAIN_AUTOFILL_DATE_ORDER) ?-1 : '') : $dateorder);
|
|
}*/
|
|
} 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));
|
|
// $remise_percent = (!empty($objectsrc->remise_percent) ? $objectsrc->remise_percent : (!empty($soc->remise_percent) ? $soc->remise_percent : 0));
|
|
// $remise_absolue = (!empty($objectsrc->remise_absolue) ? $objectsrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 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 = $soc->shipping_method_id;
|
|
$warehouse_id = $soc->fk_warehouse;
|
|
$demand_reason_id = $soc->demand_reason_id;
|
|
// $remise_percent = $soc->remise_percent;
|
|
// $remise_absolue = 0;
|
|
$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>';
|
|
|
|
// Reference client
|
|
print '<tr><td>' . $langs->trans('RefCustomer') . '</td><td>';
|
|
if (getDolGlobalString('MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER') && !empty($origin) && !empty($originid)) {
|
|
print '<input type="text" name="ref_client" value="' . $ref_client . '"></td>';
|
|
} else {
|
|
print '<input type="text" name="ref_client" value="' . GETPOST('ref_client') . '"></td>';
|
|
}
|
|
print '</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";
|
|
|
|
// 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');
|
|
print '</td></tr>';
|
|
}
|
|
|
|
// Warehouse
|
|
if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
|
|
require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
|
|
$formproduct = new FormProduct($db);
|
|
print '<tr><td>' . $langs->trans('Warehouse') . '</td><td>';
|
|
print img_picto('', 'stock', 'class="pictofixedwidth"') . $formproduct->selectWarehouses((GETPOSTISSET('warehouse_id') ? 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
|
|
print '<tr><td>' . $langs->trans('DefaultModel') . '</td>';
|
|
print '<td>';
|
|
include_once DOL_DOCUMENT_ROOT . '/core/modules/commande/modules_commande.php';
|
|
$liste = ModelePDFCommandes::liste_modeles($db);
|
|
$preselected = getDolGlobalString('COMMANDE_ADDON_PDF');
|
|
print img_picto('', 'pdf', 'class="pictofixedwidth"');
|
|
print $form->selectarray('model', $liste, $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)) {
|
|
// TODO for compatibility
|
|
if ($origin == 'contrat') {
|
|
// Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
|
|
//$objectsrc->remise_absolue = $remise_absolue;
|
|
//$objectsrc->remise_percent = $remise_percent;
|
|
$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");
|
|
require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
|
|
$formproduct = new FormProduct($db);
|
|
$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");
|
|
require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
|
|
$formproduct = new FormProduct($db);
|
|
$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");
|
|
require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
|
|
$formproduct = new FormProduct($db);
|
|
$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=' . $object->thirdparty->id . '&search_societe=' . urlencode($object->thirdparty->name) . '">' . $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');
|
|
require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
|
|
$formproduct = new FormProduct($db);
|
|
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, 0, -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, 0, -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, 0, -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, 0, -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, 0, -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, 0, -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
|
|
$arrayforbutaction[] = array(
|
|
'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'), 'default', $_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();
|