From b17c44c6653a49256640742364934e27b7b96ed1 Mon Sep 17 00:00:00 2001 From: wdammak <26695620+wdammak@users.noreply.github.com> Date: Sun, 16 Sep 2018 16:53:35 +0100 Subject: [PATCH 001/307] Update html.form.class.php Add the ability to sort products by category --- htdocs/core/class/html.form.class.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index df485ea0ede..dce2192d10d 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2013,6 +2013,7 @@ class Form $selectFields = " p.rowid, p.label, p.ref, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression"; (count($warehouseStatusArray)) ? $selectFieldsGrouped = ", sum(ps.reel) as stock" : $selectFieldsGrouped = ", p.stock"; + $selectFields .= ", pcat.fk_categorie as categorie_product_id"; $sql = "SELECT "; $sql.= $selectFields . $selectFieldsGrouped; @@ -2063,6 +2064,8 @@ class Form if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid"; } + //Product category + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as pcat ON pcat.fk_product=p.rowid"; $sql.= ' WHERE p.entity IN ('.getEntity('product').')'; if (count($warehouseStatusArray)) @@ -2113,9 +2116,10 @@ class Form { $sql.= ' GROUP BY'.$selectFields; } - $sql.= $db->order("p.ref"); - $sql.= $db->plimit($limit, 0); - + + (! empty($conf->global->PRODUIT_SORT_BY_CATEGORY)) ? $sql.= $db->order("pcat.fk_categorie") : $sql.= $db->order("p.ref"); + $sql.= $db->plimit($limit, 0) + // Build output string dol_syslog(get_class($this)."::select_produits_list search product", LOG_DEBUG); $result=$this->db->query($sql); From baed678b6e22da0da76c919269b430f7d4086c6d Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Tue, 2 Oct 2018 15:49:31 +0200 Subject: [PATCH 002/307] NEW shipping set draft and update line --- htdocs/expedition/card.php | 758 +++++++++++++++---- htdocs/expedition/class/expedition.class.php | 545 ++++++++++++- htdocs/langs/en_US/agenda.lang | 1 + htdocs/langs/fr_FR/agenda.lang | 1 + 4 files changed, 1153 insertions(+), 152 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 81b6ed455a7..fbe7d81622c 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -7,7 +7,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Marcos García * Copyright (C) 2014 Cedric GROSS - * Copyright (C) 2014-2015 Francis Appels + * Copyright (C) 2014-2017 Francis Appels * Copyright (C) 2015 Claudio Aschieri * Copyright (C) 2016 Ferran Marcet * Copyright (C) 2016 Yasser Carreón @@ -29,7 +29,7 @@ /** * \file htdocs/expedition/card.php * \ingroup expedition - * \brief Fiche descriptive d'une expedition + * \brief Card of a shipment */ require '../main.inc.php'; @@ -52,14 +52,8 @@ if (! empty($conf->projet->enabled)) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; } -$langs->load("sendings"); -$langs->load("companies"); -$langs->load("bills"); -$langs->load('deliveries'); -$langs->load('orders'); -$langs->load('stocks'); -$langs->load('other'); -$langs->load('propal'); +$langs->loadLangs(array("sendings","companies","bills",'deliveries','orders','stocks','other','propal')); + if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); if (! empty($conf->productbatch->enabled)) $langs->load('productbatch'); @@ -69,6 +63,7 @@ $id = $origin_id; if (empty($origin_id)) $origin_id = GETPOST('origin_id','int'); // Id of order or propal if (empty($origin_id)) $origin_id = GETPOST('object_id','int'); // Id of order or propal $ref=GETPOST('ref','alpha'); +$line_id = GETPOST('lineid','int')?GETPOST('lineid','int'):''; // Security check $socid=''; @@ -107,6 +102,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be inclu $hookmanager->initHooks(array('expeditioncard','globalcard')); $permissiondellink=$user->rights->expedition->livraison->creer; // Used by the include of actions_dellink.inc.php +//var_dump($object->lines[0]->detail_batch); /* @@ -127,12 +123,36 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once - // Set incoterm + // Reopen if ($action == 'reopen' && $user->rights->expedition->creer) { $object->fetch($id); $result = $object->reOpen(); } + + // Confirm back to draft status + if ($action == 'modif' && $user->rights->expedition->creer) + { + $result = $object->set_draft($user); + if ($result >= 0) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } // Set incoterm if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) @@ -173,9 +193,11 @@ if (empty($reshook)) $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { $result = $object->insertExtraFields(); - if ($result < 0) { - $error++; - } + if ($result < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } } else if ($reshook < 0) $error++; } @@ -503,8 +525,8 @@ if (empty($reshook)) } } - // Action update description of emailing - else if ($action == 'settrackingnumber' || $action == 'settrackingurl' + // Action update + else if ($action == 'settracking_number' || $action == 'settracking_url' || $action == 'settrueWeight' || $action == 'settrueWidth' || $action == 'settrueHeight' @@ -513,8 +535,8 @@ if (empty($reshook)) { $error=0; - if ($action == 'settrackingnumber') $object->tracking_number = trim(GETPOST('trackingnumber','alpha')); - if ($action == 'settrackingurl') $object->tracking_url = trim(GETPOST('trackingurl','int')); + if ($action == 'settracking_number') $object->tracking_number = trim(GETPOST('tracking_number','alpha')); + if ($action == 'settracking_url') $object->tracking_url = trim(GETPOST('tracking_url','int')); if ($action == 'settrueWeight') { $object->trueWeight = trim(GETPOST('trueWeight','int')); $object->weight_units = GETPOST('weight_units','int'); @@ -596,6 +618,292 @@ if (empty($reshook)) } } + /* + * delete a line + */ + elseif ($action == 'deleteline' && ! empty($line_id)) + { + $object->fetch($id); + $lines = $object->lines; + $line = new ExpeditionLigne($db); + + $num_prod = count($lines); + for ($i = 0 ; $i < $num_prod ; $i++) + { + if ($lines[$i]->id == $line_id) + { + if (count($lines[$i]->details_entrepot) > 1) + { + // delete multi warehouse lines + foreach ($lines[$i]->details_entrepot as $details_entrepot) { + $line->id = $details_entrepot->line_id; + if (! $error && $line->delete($user) < 0) + { + $error++; + } + } + } + else + { + // delete single warehouse line + $line->id = $line_id; + if (! $error && $line->delete($user) < 0) + { + $error++; + } + } + } + unset($_POST["lineid"]); + } + + if(! $error) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit(); + } + else + { + setEventMessages($line->error, $line->errors, 'errors'); + } + } + + /* + * Update a line + */ + else if ($action == 'updateline' && $user->rights->expedition->creer && GETPOST('save')) + { + // Clean parameters + $qty=0; + $entrepot_id = 0; + $batch_id = 0; + + $lines = $object->lines; + $num_prod = count($lines); + for ($i = 0 ; $i < $num_prod ; $i++) + { + if ($lines[$i]->id == $line_id) // we have found line to update + { + $line = new ExpeditionLigne($db); + // Extrafields Lines + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $line->array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield POST Data + if (is_array($extralabelsline)) { + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + $line->fk_product = $lines[$i]->fk_product; + if (is_array($lines[$i]->detail_batch) && count($lines[$i]->detail_batch) > 0) + { + // line with lot + foreach ($lines[$i]->detail_batch as $detail_batch) + { + $lotStock = new Productbatch($db); + $batch="batchl".$detail_batch->fk_expeditiondet."_".$detail_batch->fk_origin_stock; + $qty = "qtyl".$detail_batch->fk_expeditiondet.'_'.$detail_batch->id; + $batch_id = GETPOST($batch,'int'); + $batch_qty = GETPOST($qty, 'int'); + if (! empty($batch_id) && ($batch_id != $detail_batch->fk_origin_stock || $batch_qty != $detail_batch->dluo_qty)) + { + if ($lotStock->fetch($batch_id) > 0 && $line->fetch($detail_batch->fk_expeditiondet) > 0) // $line is ExpeditionLine + { + if ($lines[$i]->entrepot_id != 0) + { + // allow update line entrepot_id if not multi warehouse shipping + $line->entrepot_id = $lotStock->warehouseid; + } + + // detail_batch can be an object with keys, or an array of ExpeditionLineBatch + if (empty($line->detail_batch)) $line->detail_batch=new stdClass(); + + $line->detail_batch->fk_origin_stock = $batch_id; + $line->detail_batch->batch = $lotStock->batch; + $line->detail_batch->id = $detail_batch->id; + $line->detail_batch->entrepot_id = $lotStock->warehouseid; + $line->detail_batch->dluo_qty = $batch_qty; + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + else + { + setEventMessages($lotStock->error, $lotStock->errors, 'errors'); + $error++; + } + } + unset($_POST[$batch]); + unset($_POST[$qty]); + } + // add new batch + $lotStock = new Productbatch($db); + $batch="batchl".$line_id."_0"; + $qty = "qtyl".$line_id."_0"; + $batch_id = GETPOST($batch,'int'); + $batch_qty = GETPOST($qty, 'int'); + $lineIdToAddLot = 0; + if ($batch_qty > 0 && ! empty($batch_id)) + { + if ($lotStock->fetch($batch_id) > 0) + { + // check if lotStock warehouse id is same as line warehouse id + if ($lines[$i]->entrepot_id > 0) + { + // single warehouse shipment line + if ($lines[i]->entrepot_id == $lotStock->warehouseid) + { + $lineIdToAddLot = $line_id; + } + } + else if (count($lines[$i]->details_entrepot) > 1) + { + // multi warehouse shipment lines + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + if ($detail_entrepot->entrepot_id == $lotStock->warehouseid) + { + $lineIdToAddLot = $detail_entrepot->line_id; + } + } + } + if ($lineIdToAddLot) + { + // add lot to existing line + if ($line->fetch($lineIdToAddLot) > 0) + { + $line->detail_batch->fk_origin_stock = $batch_id; + $line->detail_batch->batch = $lotStock->batch; + $line->detail_batch->entrepot_id = $lotStock->warehouseid; + $line->detail_batch->dluo_qty = $batch_qty; + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + else + { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + else + { + // create new line with new lot + $line->origin_line_id = $lines[$i]->origin_line_id; + $line->entrepot_id = $lotStock->warehouseid; + $line->detail_batch[0] = new ExpeditionLineBatch($db); + $line->detail_batch[0]->fk_origin_stock = $batch_id; + $line->detail_batch[0]->batch = $lotStock->batch; + $line->detail_batch[0]->entrepot_id = $lotStock->warehouseid; + $line->detail_batch[0]->dluo_qty = $batch_qty; + if ($object->create_line_batch($line, $line->array_options) < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } + } + else + { + setEventMessages($lotStock->error, $lotStock->errors, 'errors'); + $error++; + } + } + } + else + { + if ($lines[$i]->fk_product > 0) + { + // line without lot + if ($lines[$i]->entrepot_id > 0) + { + // single warehouse shipment line + $stockLocation="entl".$line_id; + $qty = "qtyl".$line_id; + $line->id = $line_id; + $line->entrepot_id = GETPOST($stockLocation,'int'); + $line->qty = GETPOST($qty, 'int'); + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + unset($_POST[$stockLocation]); + unset($_POST[$qty]); + } + else if (count($lines[$i]->details_entrepot) > 1) + { + // multi warehouse shipment lines + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + if (! $error) { + $stockLocation="entl".$detail_entrepot->line_id; + $qty = "qtyl".$detail_entrepot->line_id; + $warehouse = GETPOST($stockLocation,'int'); + if (!empty ($warehouse)) + { + $line->id = $detail_entrepot->line_id; + $line->entrepot_id = $warehouse; + $line->qty = GETPOST($qty, 'int'); + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + unset($_POST[$stockLocation]); + unset($_POST[$qty]); + } + } + } + } + else // Product no predefined + { + $qty = "qtyl".$line_id; + $line->id = $line_id; + $line->qty = GETPOST($qty, 'int'); + $line->entrepot_id = 0; + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + unset($_POST[$qty]); + } + } + } + } + + unset($_POST["lineid"]); + + if (! $error) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) + $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->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->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + else + { + header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition + exit(); + } + } + + else if ($action == 'updateline' && $user->rights->expedition->creer && GETPOST('cancel','alpha') == $langs->trans('Cancel')) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition + exit(); + } + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to send emails @@ -704,6 +1012,7 @@ if ($action == 'create') if (! empty($conf->projet->enabled)) { $projectid = GETPOST('projectid','int')?GETPOST('projectid','int'):0; + if(empty($projectid) && ! empty($object->fk_project)) $projectid = $object->fk_project; if ($origin == 'project') $projectid = ($originid ? $originid : 0); $langs->load("projects"); @@ -902,7 +1211,8 @@ if ($action == 'create') if ($line->fk_product > 0) // If predefined product { $product->fetch($line->fk_product); - $product->load_stock('warehouseopen'); + $product->load_stock('warehouseopen'); // Load all $product->stock_warehouse[idwarehouse]->detail_batch + //var_dump($product->stock_warehouse[1]); print ''; print ''; // ancre pour retourner sur la ligne @@ -983,7 +1293,7 @@ if ($action == 'create') { // Quantity to send print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { if (GETPOST('qtyl'.$indiceAsked, 'int')) $defaultqty=GETPOST('qtyl'.$indiceAsked, 'int'); print ''; @@ -996,7 +1306,7 @@ if ($action == 'create') if (! empty($conf->stock->enabled)) { print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) // Type of product need stock change ? + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) // Type of product need stock change ? { // Show warehouse combo list $ent = "entl".$indiceAsked; @@ -1079,13 +1389,21 @@ if ($action == 'create') print ''; print ''; + print ''; print ''; print $staticwarehouse->getNomUrl(0).' / '; - print ''; print ''; - print $langs->trans("DetailBatchFormat", $dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); + + $detail=''; + $detail.= $langs->trans("Batch").': '.$dbatch->batch; + $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day"); + $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day"); + $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty; + $detail.= '
'; + print $detail; + $quantityToBeDelivered -= $deliverableQty; if ($quantityToBeDelivered < 0) { @@ -1139,7 +1457,7 @@ if ($action == 'create') // Quantity to send print ''; print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { print ''; print ''; @@ -1151,7 +1469,7 @@ if ($action == 'create') if (! empty($conf->stock->enabled)) { print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { print $tmpwarehouseObject->getNomUrl(0).' '; @@ -1241,14 +1559,12 @@ if ($action == 'create') print ''; print ''; - //print $langs->trans("DetailBatchFormat", $dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); //print $line->fk_product.' - '.$dbatch->batch; print $langs->trans("Batch").': '; $result = $productlotObject->fetch(0, $line->fk_product, $dbatch->batch); if ($result > 0) print $productlotObject->getNomUrl(1); else print 'TableLotIncompleteRunRepair'; print ' ('.$dbatch->qty.')'; - //print $langs->trans("DetailBatchFormat", 'ee'.$dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); $quantityToBeDelivered -= $deliverableQty; if ($quantityToBeDelivered < 0) { @@ -1266,7 +1582,7 @@ if ($action == 'create') { print ''; print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $disabled=''; if (! empty($conf->productbatch->enabled) && $product->hasbatch()) @@ -1282,7 +1598,7 @@ if ($action == 'create') print ''; print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $warehouse_selected_id = GETPOST('entrepot_id','int'); if ($warehouse_selected_id > 0) @@ -1328,7 +1644,13 @@ if ($action == 'create') print ""; - print '
'; + print '
'; + + print '
'; + print ''; + print '  '; + print ''; // Cancel for create does not post form if we don't know the backtopage + print '
'; print ''; @@ -1440,7 +1762,7 @@ else if ($id || $ref) } // Shipment card - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref='
'; // Ref customer shipment $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_customer', $object->ref_customer, $object, $user->rights->expedition->creer, 'string', '', 0, 1); @@ -1692,8 +2014,8 @@ else if ($id || $ref) print ''; // Tracking Number - print ''.$form->editfieldkey("TrackingNumber",'trackingnumber',$object->tracking_number,$object,$user->rights->expedition->creer).''; - print $form->editfieldval("TrackingNumber",'trackingnumber',$object->tracking_url,$object,$user->rights->expedition->creer,'string',$object->tracking_number); + print ''.$form->editfieldkey("TrackingNumber",'tracking_number',$object->tracking_number,$object,$user->rights->expedition->creer).''; + print $form->editfieldval("TrackingNumber",'tracking_number',$object->tracking_url,$object,$user->rights->expedition->creer,'string',$object->tracking_number); print ''; // Incoterms @@ -1728,48 +2050,87 @@ else if ($id || $ref) print '
'; - /* - * Lines of products - */ + // Lines of products + + if ($action == 'editline') + { + print '
+ + + + + '; + } print '
'; print '
'; print ''; print ''; + // # if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { print ''; } + // Product/Service print ''; + // Qty print ''; - if ($object->statut <= 1) + if ($origin && $origin_id > 0) { - print ''; + print ''; + } + if ($action == 'editline') + { + $editColspan = 3; + if (empty($conf->stock->enabled)) $editColspan--; + if (empty($conf->productbatch->enabled)) $editColspan--; + print ''; } else { - print ''; - } + if ($object->statut <= 1) + { + print ''; + } + else + { + print ''; + } + if (! empty($conf->stock->enabled)) + { + print ''; + } - if ($origin && $origin_id > 0) - { - print ''; + if (! empty($conf->productbatch->enabled)) + { + print ''; + } } - print ''; print ''; //print ''; - - if (! empty($conf->stock->enabled)) + if ($object->statut == 0) { - print ''; + print ''; + print ''; } - - if (! empty($conf->productbatch->enabled)) - { - print ''; - } - print "\n"; $var=false; @@ -1788,7 +2149,7 @@ else if ($id || $ref) } } - // Get list of products already sent for same source object + // Get list of products already sent for same source object into $alreadysent $alreadysent = array(); if ($origin && $origin_id > 0) { @@ -1837,6 +2198,7 @@ else if ($id || $ref) print ''; // id of order line print ''; + // # if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { print ''; @@ -1876,7 +2238,7 @@ else if ($id || $ref) else { print "'; - // Qty to ship or shipped - print ''; - // Qty in other shipments (with shipment and warehouse used) if ($origin && $origin_id > 0) { @@ -1927,70 +2286,188 @@ else if ($id || $ref) } print ''; + if ($action == 'editline' && $lines[$i]->id == $line_id) + { + // edit mode + print ''; + } + else + { + // Qty to ship or shipped + print ''; + + // Warehouse source + if (! empty($conf->stock->enabled)) + { + print ''; + } + + // Batch number managment + if (! empty($conf->productbatch->enabled)) + { + if (isset($lines[$i]->detail_batch)) + { + print ''; + print ''; + } else { + print ''; + } + } + } + // Weight print ''; // Volume print ''; // Size //print ''; - // Warehouse source - if (! empty($conf->stock->enabled)) + if ($action == 'editline' && $lines[$i]->id == $line_id) { - print ''; + print ''; + print ''; + + // Display lines extrafields + if (! empty($rowExtrafieldsStart)) { - print ''; - } else { - print ''; + print $rowExtrafieldsStart; + print $rowExtrafieldsView; + print $rowEnd; } } print ""; @@ -2001,11 +2478,16 @@ else if ($id || $ref) $line = new ExpeditionLigne($db); $line->fetch_optionals($lines[$i]->id,$extralabelslines); print ''; - print $line->showOptionals($extrafieldsline, 'view', array('style'=>$bc[$var], 'colspan'=>$colspan),$indiceAsked); + if ($action == 'editline' && $lines[$i]->id == $line_id) + { + print $line->showOptionals($extrafieldsline, 'edit', array('style'=>$bc[$var], 'colspan'=>$colspan),$indiceAsked); + } + else + { + print $line->showOptionals($extrafieldsline, 'view', array('style'=>$bc[$var], 'colspan'=>$colspan),$indiceAsked); + } print ''; } - - } // TODO Show also lines ordered but not delivered @@ -2035,7 +2517,7 @@ else if ($id || $ref) if (empty($reshook)) { - if ($object->statut == 0 && $num_prod > 0) + if ($object->statut == Expedition::STATUS_DRAFT && $num_prod > 0) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->creer)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->shipping_advance->validate))) @@ -2047,12 +2529,23 @@ else if ($id || $ref) print ''.$langs->trans("Validate").''; } } + // Edit + if ($object->statut == Expedition::STATUS_VALIDATED && $user->rights->expedition->creer) { + print ''; + } // TODO add alternative status // 0=draft, 1=validated, 2=billed, we miss a status "delivered" (only available on order) - if ($object->statut == 2 && $object->billed && $user->rights->expedition->creer) + if ($object->statut == Expedition::STATUS_CLOSED && $user->rights->expedition->creer) { - print ''.$langs->trans("ReOpen").''; + if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? + { + print ''.$langs->trans("ClassifyUnbilled").''; + } + else + { + print ''.$langs->trans("ReOpen").''; + } } // Send @@ -2066,7 +2559,7 @@ else if ($id || $ref) } // Create bill - if (! empty($conf->facture->enabled) && $object->statut > 0) + if (! empty($conf->facture->enabled) && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED)) { if ($user->rights->facture->creer) { @@ -2078,18 +2571,18 @@ else if ($id || $ref) // This is just to generate a delivery receipt //var_dump($object->linkedObjectsIds['delivery']); - if ($conf->livraison_bon->enabled && ($object->statut == 1 || $object->statut == 2) && $user->rights->expedition->livraison->creer && count($object->linkedObjectsIds['delivery']) == 0) + if ($conf->livraison_bon->enabled && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED) && $user->rights->expedition->livraison->creer && count($object->linkedObjectsIds['delivery']) == 0) { print ''.$langs->trans("CreateDeliveryOrder").''; } // Close - if (! empty($conf->facture->enabled) && $object->statut > 0) + if ($object->statut == Expedition::STATUS_VALIDATED) { if ($user->rights->expedition->creer && $object->statut > 0 && ! $object->billed) { $label="Close"; $paramaction='classifyclosed'; // = Transferred/Received // Label here should be "Close" or "ClassifyBilled" if we decided to make bill on shipments instead of orders - if (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // TODO Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close. + if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? { $label="ClassifyBilled"; $paramaction='classifybilled'; @@ -2113,7 +2606,7 @@ else if ($id || $ref) * Documents generated */ - if ($action != 'presend') + if ($action != 'presend' && $action != 'editline') { print '
'; @@ -2135,19 +2628,7 @@ else if ($id || $ref) print '
'; - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions=new FormActions($db); - $somethingshown=$formactions->showactions($object,'shipping',$socid); - - print '
'; } - - - /* - * Action presend - */ - //Select mail models is same action as presend if (GETPOST('modelselected')) { $action = 'presend'; @@ -2158,7 +2639,6 @@ else if ($id || $ref) include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $fileparams = dol_most_recent_file($conf->expedition->dir_output . '/sending/' . $ref, preg_quote($ref, '/').'[^\-]+'); $file=$fileparams['fullname']; - // Define output language $outputlangs = $langs; $newlang = ''; @@ -2166,14 +2646,12 @@ else if ($id || $ref) $newlang = $_REQUEST['lang_id']; if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (!empty($newlang)) { $outputlangs = new Translate('', $conf); $outputlangs->setDefaultLang($newlang); $outputlangs->load('sendings'); } - // Build document if it not exists if (! $file || ! is_readable($file)) { @@ -2186,23 +2664,18 @@ else if ($id || $ref) $fileparams = dol_most_recent_file($conf->expedition->dir_output . '/sending/' . $ref, preg_quote($ref, '/').'[^\-]+'); $file=$fileparams['fullname']; } - print '
'; print '
'; print '
'; print load_fiche_titre($langs->trans('SendShippingByEMail')); - dol_fiche_head(''); - // Cree l'objet formulaire mail include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - if($formmail->fromtype === 'user'){ $formmail->fromid = $user->id; - } $formmail->trackid='shi'.$object->id; if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set @@ -2226,7 +2699,6 @@ else if ($id || $ref) $formmail->substit['__SHIPPINGREF__']=$object->ref; $formmail->substit['__SHIPPINGTRACKNUM__']=$object->tracking_number; $formmail->substit['__SHIPPINGTRACKNUMURL__']=$object->tracking_url; - //Find the good contact adress if ($typeobject == 'commande' && $object->$typeobject->id && ! empty($conf->commande->enabled)) { $objectsrc=new Commande($db); @@ -2242,44 +2714,38 @@ else if ($id || $ref) { $contactarr=$objectsrc->liste_contact(-1,'external'); } - if (is_array($contactarr) && count($contactarr)>0) { foreach($contactarr as $contact) { - if ($contact['libelle']==$langs->trans('TypeContact_commande_external_CUSTOMER')) { - require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; - $contactstatic=new Contact($db); $contactstatic->fetch($contact['id']); $custcontact=$contactstatic->getFullName($langs,1); } } - if (!empty($custcontact)) { $formmail->substit['__CONTACTCIVNAME__']=$custcontact; } } - // Tableau des parametres complementaires $formmail->param['action']='send'; $formmail->param['models']='shipping_send'; $formmail->param['models_id']=GETPOST('modelmailselected','int'); $formmail->param['shippingid']=$object->id; $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - // Init list of files if (GETPOST("mode")=='init') { $formmail->clear_attached_files(); $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); } - // Show form print $formmail->get_form(); - dol_fiche_end(); } + + + } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 879b5745db4..f5eb969149a 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -642,9 +642,8 @@ class Expedition extends CommonObject { $numref = $this->getNextNumRef($soc); } - else - { - $numref = "EXP".$this->id; + else { + $numref = $this->ref; } $this->newref = $numref; @@ -2170,6 +2169,138 @@ class Expedition extends CommonObject return -1; } } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @return int <0 if KO, >0 if OK + */ + function set_draft($user) + { + global $conf,$langs; + + $error=0; + + // Protection + if ($this->statut <= self::STATUS_DRAFT) + { + return 0; + } + + if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->shipping_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + } + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."expedition"; + $sql.= " SET fk_statut = ".self::STATUS_DRAFT; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::set_draft", LOG_DEBUG); + if ($this->db->query($sql)) + { + // If stock increment is done on closing + if (! $error && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + + $langs->load("agenda"); + + // Loop on each product line to add a stock movement + // TODO possibilite d'expedier a partir d'une propale ou autre origine + $sql = "SELECT cd.fk_product, cd.subprice,"; + $sql.= " ed.rowid, ed.qty, ed.fk_entrepot,"; + $sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock"; + $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,"; + $sql.= " ".MAIN_DB_PREFIX."expeditiondet as ed"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."expeditiondet_batch as edb on edb.fk_expeditiondet = ed.rowid"; + $sql.= " WHERE ed.fk_expedition = ".$this->id; + $sql.= " AND cd.rowid = ed.fk_origin_line"; + + dol_syslog(get_class($this)."::valid select details", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $cpt = $this->db->num_rows($resql); + for ($i = 0; $i < $cpt; $i++) + { + $obj = $this->db->fetch_object($resql); + if (empty($obj->edbrowid)) + { + $qty = $obj->qty; + } + else + { + $qty = $obj->edbqty; + } + if ($qty <= 0) continue; + dol_syslog(get_class($this)."::reopen expedition movement index ".$i." ed.rowid=".$obj->rowid." edb.rowid=".$obj->edbrowid); + + //var_dump($this->lines[$i]); + $mouvS = new MouvementStock($this->db); + $mouvS->origin = &$this; + + if (empty($obj->edbrowid)) + { + // line without batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ShipmentBackToDraftInDolibarr",$this->ref)); + if ($result < 0) { + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; + } + } + else + { + // line with batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ShipmentBackToDraftInDolibarr",$this->ref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); + if ($result < 0) { + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; + } + } + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + } + + if (!$error) { + // Call trigger + $result=$this->call_trigger('SHIPPING_UNVALIDATE',$user); + if ($result < 0) $error++; + } + + if (!$error) { + $this->statut=self::STATUS_DRAFT; + $this->db->commit(); + return 1; + }else { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } /** * Create a document onto disk according to template module. @@ -2229,6 +2360,17 @@ class Expedition extends CommonObject */ class ExpeditionLigne extends CommonObjectLine { + public $element='expeditiondet'; + public $table_element='expeditiondet'; + + public $fk_origin_line; + + /** + * Id of shipment + * @var int + */ + public $fk_expedition; + var $db; // From llx_expeditiondet @@ -2236,6 +2378,12 @@ class ExpeditionLigne extends CommonObjectLine var $qty_shipped; var $fk_product; var $detail_batch; + /** + * Id of warehouse + * @var int + */ + public $entrepot_id; + // From llx_commandedet or llx_propaldet var $qty_asked; @@ -2252,10 +2400,7 @@ class ExpeditionLigne extends CommonObjectLine var $total_localtax1; // Total Local tax 1 var $total_localtax2; // Total Local tax 2 - public $element='expeditiondet'; - public $table_element='expeditiondet'; - public $fk_origin_line; // Deprecated /** @@ -2284,5 +2429,393 @@ class ExpeditionLigne extends CommonObjectLine $this->db=$db; } + /** + * Load line expedition + * + * @param int $rowid Id line order + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid) + { + $sql = 'SELECT ed.rowid, ed.fk_expedition, ed.fk_entrepot, ed.fk_origin_line, ed.qty, ed.rang'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as ed'; + $sql.= ' WHERE ed.rowid = '.$rowid; + $result = $this->db->query($sql); + if ($result) + { + $objp = $this->db->fetch_object($result); + $this->id = $objp->rowid; + $this->fk_expedition = $objp->fk_expedition; + $this->entrepot_id = $objp->fk_entrepot; + $this->fk_origin_line = $objp->fk_origin_line; + $this->qty = $objp->qty; + $this->rang = $objp->rang; + + $this->db->free($result); + + return 1; + } + else + { + $this->errors[] = $this->db->lasterror(); + $this->error = $this->db->lasterror(); + return -1; + } + } + + /** + * Insert line into database + * + * @param User $user User that modify + * @param int $notrigger 1 = disable triggers + * @return int <0 if KO, line id >0 if OK + */ + function insert($user=null, $notrigger=0) + { + global $langs, $conf; + + $error=0; + + // Check parameters + if (empty($this->fk_expedition) || empty($this->fk_origin_line) || ! is_numeric($this->qty)) + { + $this->error = 'ErrorMandatoryParametersNotProvided'; + return -1; + } + // Clean parameters + if (empty($this->entrepot_id)) $this->entrepot_id='null'; + + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."expeditiondet ("; + $sql.= "fk_expedition"; + $sql.= ", fk_entrepot"; + $sql.= ", fk_origin_line"; + $sql.= ", qty"; + $sql.= ") VALUES ("; + $sql.= $this->fk_expedition; + $sql.= ", ".$this->entrepot_id; + $sql.= ", ".$this->fk_origin_line; + $sql.= ", ".$this->qty; + $sql.= ")"; + + dol_syslog(get_class($this)."::insert", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."expeditiondet"); + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINESHIPPING_INSERT',$user); + if ($result < 0) + { + $error++; + } + // End call triggers + } + + if (! $error) { + $this->db->commit(); + return $this->id; + } + + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + + $this->db->rollback(); + return -1*$error; + } + else + { + $error++; + } + } + + /** + * Delete shipment line. + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int >0 if OK, <0 if KO + */ + function delete($user = null, $notrigger = 0) + { + global $conf; + + $error=0; + + $this->db->begin(); + + // delete batch expedition line + if ($conf->productbatch->enabled) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."expeditiondet_batch"; + $sql.= " WHERE fk_expeditiondet = ".$this->id; + + if (!$this->db->query($sql)) + { + $this->errors[]=$this->db->lasterror()." - sql=$sql"; + $error++; + } + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."expeditiondet"; + $sql.= " WHERE rowid = ".$this->id; + + if (! $error && $this->db->query($sql)) + { + // Remove extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $this->errors[]=$this->error; + $error++; + } + } + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINESHIPPING_DELETE',$user); + if ($result < 0) + { + $this->errors[]=$this->error; + $error++; + } + // End call triggers + } + } + else + { + $this->errors[]=$this->db->lasterror()." - sql=$sql"; + $error++; + } + + if (! $error) { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + + /** + * Update a line in database + * + * @param User $user User that modify + * @param int $notrigger 1 = disable triggers + * @return int < 0 if KO, > 0 if OK + */ + function update($user = null, $notrigger = 0) + { + global $conf; + + $error=0; + + dol_syslog(get_class($this)."::update id=$this->id, entrepot_id=$this->entrepot_id, product_id=$this->fk_product, qty=$this->qty"); + + $this->db->begin(); + + // Clean parameters + if (empty($this->qty)) $this->qty=0; + $qty=price2num($this->qty); + $remainingQty = 0; + $batch = null; + $batch_id = null; + $expedition_batch_id = null; + if (is_array($this->detail_batch)) // array of ExpeditionLineBatch + { + if (count($this->detail_batch) > 1) + { + dol_syslog(get_class($this).'::update only possible for one batch', LOG_ERR); + $this->errors[]='ErrorBadParameters'; + $error++; + } + else + { + $batch = $this->detail_batch[0]->batch; + $batch_id = $this->detail_batch[0]->fk_origin_stock; + $expedition_batch_id = $this->detail_batch[0]->id; + if ($this->entrepot_id != $this->detail_batch[0]->entrepot_id) + { + dol_syslog(get_class($this).'::update only possible for batch of same warehouse', LOG_ERR); + $this->errors[]='ErrorBadParameters'; + $error++; + } + $qty = price2num($this->detail_batch[0]->dluo_qty); + } + } + else if (! empty($this->detail_batch)) + { + $batch = $this->detail_batch->batch; + $batch_id = $this->detail_batch->fk_origin_stock; + $expedition_batch_id = $this->detail_batch->id; + if ($this->entrepot_id != $this->detail_batch->entrepot_id) + { + dol_syslog(get_class($this).'::update only possible for batch of same warehouse', LOG_ERR); + $this->errors[]='ErrorBadParameters'; + $error++; + } + $qty = price2num($this->detail_batch->dluo_qty); + } + + // check parameters + if (! isset($this->id) || ! isset($this->entrepot_id)) + { + dol_syslog(get_class($this).'::update missing line id and/or warehouse id', LOG_ERR); + $this->errors[]='ErrorMandatoryParametersNotProvided'; + $error++; + return -1; + } + + // update lot + + if (! empty($batch) && $conf->productbatch->enabled) + { + dol_syslog(get_class($this)."::update expedition batch id=$expedition_batch_id, batch_id=$batch_id, batch=$batch"); + + if (empty($batch_id) || empty($this->fk_product)) { + dol_syslog(get_class($this).'::update missing fk_origin_stock (batch_id) and/or fk_product', LOG_ERR); + $this->errors[]='ErrorMandatoryParametersNotProvided'; + $error++; + } + + // fetch remaining lot qty + require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php'; + if (! $error && ($lotArray = ExpeditionLineBatch::fetchAll($this->db, $this->id)) < 0) + { + $this->errors[]=$this->db->lasterror()." - ExpeditionLineBatch::fetchAll"; + $error++; + } + else + { + // caculate new total line qty + foreach ($lotArray as $lot) + { + if ($expedition_batch_id != $lot->id) + { + $remainingQty += $lot->dluo_qty; + } + } + $qty += $remainingQty; + + //fetch lot details + + // fetch from product_lot + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; + $lot = new Productlot($this->db); + if ($lot->fetch(0,$this->fk_product,$batch) < 0) + { + $this->errors[] = $lot->errors; + $error++; + } + if (! $error && ! empty($expedition_batch_id)) + { + // delete lot expedition line + $sql = "DELETE FROM ".MAIN_DB_PREFIX."expeditiondet_batch"; + $sql.= " WHERE fk_expeditiondet = ".$this->id; + $sql.= " AND rowid = ".$expedition_batch_id; + + if (!$this->db->query($sql)) + { + $this->errors[]=$this->db->lasterror()." - sql=$sql"; + $error++; + } + } + if (! $error && $this->detail_batch->dluo_qty > 0) + { + // create lot expedition line + if (isset($lot->id)) + { + $shipmentLot = new ExpeditionLineBatch($this->db); + $shipmentLot->batch = $lot->batch; + $shipmentLot->eatby = $lot->eatby; + $shipmentLot->sellby = $lot->sellby; + $shipmentLot->entrepot_id = $this->detail_batch->entrepot_id; + $shipmentLot->dluo_qty = $this->detail_batch->dluo_qty; + $shipmentLot->fk_origin_stock = $batch_id; + if ($shipmentLot->create($this->id) < 0) + { + $this->errors[]=$shipmentLot->errors; + $error++; + } + } + } + } + } + if (! $error) + { + // update line + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql.= " fk_entrepot = ".($this->entrepot_id > 0 ? $this->entrepot_id : 'null'); + $sql.= " , qty = ".$qty; + $sql.= " WHERE rowid = ".$this->id; + + if (!$this->db->query($sql)) + { + $this->errors[]=$this->db->lasterror()." - sql=$sql"; + $error++; + } + else + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $this->errors[]=$this->error; + $error++; + } + } + } + } + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINESHIPPING_UPDATE',$user); + if ($result < 0) + { + $this->errors[]=$this->error; + $error++; + } + // End call triggers + } + if (!$error) { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } } diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index a5857503c30..6fb40c12dd6 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -55,6 +55,7 @@ MemberSubscriptionAddedInDolibarr=Subscription for member %s added ShipmentValidatedInDolibarr=Shipment %s validated ShipmentClassifyClosedInDolibarr=Shipment %s classified billed ShipmentUnClassifyCloseddInDolibarr=Shipment %s classified reopened +ShipmentBackToDraftInDolibarr=Shipment %s go back to draft status ShipmentDeletedInDolibarr=Shipment %s deleted OrderCreatedInDolibarr=Order %s created OrderValidatedInDolibarr=Order %s validated diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index dbbf3513041..99155484d1b 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -55,6 +55,7 @@ MemberSubscriptionAddedInDolibarr=Souscription adhérent %s ShipmentValidatedInDolibarr=Expédition %s validée ShipmentClassifyClosedInDolibarr=Expédition %s classée payée ShipmentUnClassifyCloseddInDolibarr=Expédition %s réouverte +ShipmentBackToDraftInDolibarr=Expédition %s repassée en brouillon ShipmentDeletedInDolibarr=Expédition %s supprimée OrderCreatedInDolibarr=Commande %s créée OrderValidatedInDolibarr=Commande %s validée From 69c46ecd86c3c199bf3f6cae3bde473151694dcb Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Tue, 2 Oct 2018 16:54:20 +0200 Subject: [PATCH 003/307] set order status to valid when shipping set to draft --- htdocs/expedition/class/expedition.class.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index f5eb969149a..0db89a0a1e0 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2284,6 +2284,13 @@ class Expedition extends CommonObject $result=$this->call_trigger('SHIPPING_UNVALIDATE',$user); if ($result < 0) $error++; } + if($this->origin == 'commande'){ + $commande = new Commande($this->db); + $commande->fetch($this->origin_id); + $commande->statut = Commande::STATUS_VALIDATED; + $commande->update(); + } + if (!$error) { $this->statut=self::STATUS_DRAFT; From 41d8cb87a3f2075088a404f7b366786303744e84 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Wed, 3 Oct 2018 12:22:41 +0200 Subject: [PATCH 004/307] debut reception setup page --- htdocs/admin/reception_setup.php | 520 +++ htdocs/core/lib/reception.lib.php | 101 + htdocs/core/menus/init_menu_auguria.sql | 5 + htdocs/core/menus/standard/eldy.lib.php | 12 + htdocs/core/modules/modReception.class.php | 266 ++ .../doc/doc_generic_reception_odt.modules.php | 522 +++ htdocs/core/modules/reception/doc/index.html | 0 .../reception/doc/pdf_squille.modules.php | 1031 ++++++ htdocs/core/modules/reception/index.html | 0 .../modules/reception/mod_reception_beryl.php | 145 + .../reception/mod_reception_moonstone.php | 137 + .../modules/reception/modules_reception.php | 136 + .../mysql/tables/llx_reception.key.sql | 31 + htdocs/install/mysql/tables/llx_reception.sql | 62 + .../tables/llx_reception_extrafields.key.sql | 20 + .../tables/llx_reception_extrafields.sql | 26 + .../mysql/tables/llx_receptiondet.key.sql | 22 + .../install/mysql/tables/llx_receptiondet.sql | 29 + .../tables/llx_receptiondet_batch.key.sql | 20 + .../mysql/tables/llx_receptiondet_batch.sql | 27 + .../llx_receptiondet_extrafields.key.sql | 20 + .../tables/llx_receptiondet_extrafields.sql | 25 + htdocs/langs/en_US/receptions.lang | 70 + htdocs/langs/fr_FR/admin.lang | 7 + htdocs/langs/fr_FR/receptions.lang | 70 + htdocs/reception/card.php | 2754 ++++++++++++++++ .../reception/class/expeditionbatch.class.php | 223 ++ .../reception/class/expeditionstats.class.php | 142 + htdocs/reception/class/index.html | 0 htdocs/reception/class/reception.class.php | 2824 +++++++++++++++++ htdocs/reception/contact.php | 274 ++ htdocs/reception/index.php | 296 ++ htdocs/reception/list.php | 669 ++++ htdocs/reception/note.php | 164 + htdocs/reception/shipment.php | 939 ++++++ htdocs/reception/stats/index.php | 364 +++ htdocs/reception/stats/month.php | 76 + htdocs/reception/tpl/index.html | 0 .../reception/tpl/linkedobjectblock.tpl.php | 80 + 39 files changed, 12109 insertions(+) create mode 100644 htdocs/admin/reception_setup.php create mode 100644 htdocs/core/lib/reception.lib.php create mode 100644 htdocs/core/modules/modReception.class.php create mode 100644 htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php create mode 100644 htdocs/core/modules/reception/doc/index.html create mode 100644 htdocs/core/modules/reception/doc/pdf_squille.modules.php create mode 100644 htdocs/core/modules/reception/index.html create mode 100644 htdocs/core/modules/reception/mod_reception_beryl.php create mode 100644 htdocs/core/modules/reception/mod_reception_moonstone.php create mode 100644 htdocs/core/modules/reception/modules_reception.php create mode 100644 htdocs/install/mysql/tables/llx_reception.key.sql create mode 100644 htdocs/install/mysql/tables/llx_reception.sql create mode 100644 htdocs/install/mysql/tables/llx_reception_extrafields.key.sql create mode 100644 htdocs/install/mysql/tables/llx_reception_extrafields.sql create mode 100644 htdocs/install/mysql/tables/llx_receptiondet.key.sql create mode 100644 htdocs/install/mysql/tables/llx_receptiondet.sql create mode 100644 htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql create mode 100644 htdocs/install/mysql/tables/llx_receptiondet_batch.sql create mode 100644 htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql create mode 100644 htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql create mode 100644 htdocs/langs/en_US/receptions.lang create mode 100644 htdocs/langs/fr_FR/receptions.lang create mode 100644 htdocs/reception/card.php create mode 100644 htdocs/reception/class/expeditionbatch.class.php create mode 100644 htdocs/reception/class/expeditionstats.class.php create mode 100644 htdocs/reception/class/index.html create mode 100644 htdocs/reception/class/reception.class.php create mode 100644 htdocs/reception/contact.php create mode 100644 htdocs/reception/index.php create mode 100644 htdocs/reception/list.php create mode 100644 htdocs/reception/note.php create mode 100644 htdocs/reception/shipment.php create mode 100644 htdocs/reception/stats/index.php create mode 100644 htdocs/reception/stats/month.php create mode 100644 htdocs/reception/tpl/index.html create mode 100644 htdocs/reception/tpl/linkedobjectblock.tpl.php diff --git a/htdocs/admin/reception_setup.php b/htdocs/admin/reception_setup.php new file mode 100644 index 00000000000..710c1fb6ba1 --- /dev/null +++ b/htdocs/admin/reception_setup.php @@ -0,0 +1,520 @@ + + * + * 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 . + */ + +/** + * \file htdocs/admin/confexped.php + * \ingroup produit + * \brief Page to setup reception module + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/reception.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/reception/class/reception.class.php'; + +$langs->load("admin"); +$langs->load("receptions"); +$langs->load('other'); + + +if (!$user->admin) + accessforbidden(); + +$action=GETPOST('action','alpha'); +$value=GETPOST('value','alpha'); +$label = GETPOST('label','alpha'); +$scandir = GETPOST('scan_dir','alpha'); +$type='reception'; + + +/* + * Actions + */ + +if (! empty($conf->reception->enabled) && empty($conf->global->MAIN_SUBMODULE_RECEPTION)) +{ + // This option should always be set to on when module is on. + dolibarr_set_const($db, "MAIN_SUBMODULE_RECEPTION", "1",'chaine',0,'',$conf->entity); +} + +if (empty($conf->global->RECEPTION_ADDON_NUMBER)) +{ + $conf->global->RECEPTION_ADDON_NUMBER='mod_reception_beryl'; +} + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + +if ($action == 'updateMask') +{ + $maskconst=GETPOST('maskconstreception','alpha'); + $maskvalue=GETPOST('maskreception','alpha'); + if (! empty($maskconst)) + $res = dolibarr_set_const($db,$maskconst,$maskvalue,'chaine',0,'',$conf->entity); + + if (isset($res)) + { + if ($res > 0) + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + else + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} + +else if ($action == 'set_param') +{ + $freetext=GETPOST('RECEPTION_FREE_TEXT','none'); // No alpha here, we want exact string + $res = dolibarr_set_const($db, "RECEPTION_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); + if ($res <= 0) + { + $error++; + setEventMessages($langs->trans("Error"), null, 'errors'); + } + + $draft=GETPOST('RECEPTION_DRAFT_WATERMARK','alpha'); + $res = dolibarr_set_const($db, "RECEPTION_DRAFT_WATERMARK",trim($draft),'chaine',0,'',$conf->entity); + if ($res <= 0) + { + $error++; + setEventMessages($langs->trans("Error"), null, 'errors'); + } + + if (! $error) + { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } +} + +else if ($action == 'specimen') +{ + $modele=GETPOST('module','alpha'); + + $exp = new Reception($db); + $exp->initAsSpecimen(); + + // Search template files + $file=''; $classname=''; $filefound=0; + $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/reception/doc/pdf_".$modele.".modules.php",0); + if (file_exists($file)) + { + $filefound=1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) + { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($exp,$langs) > 0) + { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=reception&file=SPECIMEN.pdf"); + return; + } + else + { + setEventMessages($module->error, $module->errors, 'errors'); + dol_syslog($module->error, LOG_ERR); + } + } + else + { + setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} + +// Activate a model +else if ($action == 'set') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); +} + +else if ($action == 'del') +{ + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + if ($conf->global->RECEPTION_ADDON_PDF == "$value") dolibarr_del_const($db, 'RECEPTION_ADDON_PDF',$conf->entity); + } +} + +// Set default model +else if ($action == 'setdoc') +{ + if (dolibarr_set_const($db, "RECEPTION_ADDON_PDF",$value,'chaine',0,'',$conf->entity)) + { + // La constante qui a ete lue en avant du nouveau set + // on passe donc par une variable pour avoir un affichage coherent + $conf->global->RECEPTION_ADDON_PDF = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } +} + +else if ($action == 'setmodel') +{ + dolibarr_set_const($db, "RECEPTION_ADDON_NUMBER",$value,'chaine',0,'',$conf->entity); +} + + + + +/* + * View + */ + +$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + +$form=new Form($db); + +llxHeader("",$langs->trans("ReceptionsSetup")); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("ReceptionsSetup"),$linkback,'title_setup'); +print '
'; +$head = reception_admin_prepare_head(); + +dol_fiche_head($head, 'reception', $langs->trans("Receptions"), -1, 'reception'); + +// Reception numbering model + +print load_fiche_titre($langs->trans("ReceptionsNumberingModules")); + +print '
 '.$langs->trans("Products").''.$langs->trans("QtyOrdered").''.$langs->trans("QtyToShip").''.$langs->trans("QtyInOtherShipments").''; + if ($object->statut <= 1) + { + print $langs->trans("QtyToShip").' - '; + } + else + { + print $langs->trans("QtyShipped").' - '; + } + if (! empty($conf->stock->enabled)) + { + print $langs->trans("WarehouseSource").' - '; + } + if (! empty($conf->productbatch->enabled)) + { + print $langs->trans("Batch"); + } + print ''.$langs->trans("QtyShipped").''.$langs->trans("QtyToShip").''.$langs->trans("QtyShipped").''.$langs->trans("WarehouseSource").''.$langs->trans("QtyInOtherShipments").''.$langs->trans("Batch").''.$langs->trans("CalculatedWeight").''.$langs->trans("CalculatedVolume").''.$langs->trans("Size").''.$langs->trans("WarehouseSource").''.$langs->trans("Batch").'
'.($i+1).'"; - if ($lines[$i]->fk_product_type==1) $text = img_object($langs->trans('Service'),'service'); + if ($lines[$i]->product_type == Product::TYPE_SERVICE) $text = img_object($langs->trans('Service'),'service'); else $text = img_object($langs->trans('Product'),'product'); if (! empty($lines[$i]->label)) { @@ -1893,9 +2255,6 @@ else if ($id || $ref) // Qty ordered print ''.$lines[$i]->qty_asked.''.$lines[$i]->qty_shipped.''; + if (is_array($lines[$i]->detail_batch) && count($lines[$i]->detail_batch) > 0) + { + print ''; + $line = new ExpeditionLigne($db); + foreach ($lines[$i]->detail_batch as $detail_batch) + { + print ''; + // Qty to ship or shipped + print ''; + // Batch number managment + if ($lines[$i]->entrepot_id == 0) + { + // only show lot numbers from src warehouse when shipping from multiple warehouses + $line->fetch($detail_batch->fk_expeditiondet); + } + print ''; + print ''; + } + // add a 0 qty lot row to be able to add a lot + print ''; + // Qty to ship or shipped + print ''; + // Batch number managment + print ''; + print ''; + } + else if (! empty($conf->stock->enabled)) + { + if ($lines[$i]->fk_product > 0) + { + if ($lines[$i]->entrepot_id > 0) + { + print ''; + print ''; + // Qty to ship or shipped + print ''; + // Warehouse source + print ''; + // Batch number managment + print ''; + print ''; + } + else if (count($lines[$i]->details_entrepot) > 1) + { + print ''; + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + print ''; + // Qty to ship or shipped + print ''; + // Warehouse source + print ''; + // Batch number managment + print ''; + print ''; + } + } + else + { + print ''; + print ''; + } + } + else + { + print ''; + print ''; + // Qty to ship or shipped + print ''; + // Warehouse source + print ''; + // Batch number managment + print ''; + print ''; + } + } + print '
' . '' . '' . $formproduct->selectLotStock($detail_batch->fk_origin_stock, 'batchl'.$detail_batch->fk_expeditiondet.'_'.$detail_batch->fk_origin_stock, '', 1, 0, $lines[$i]->fk_product, $line->entrepot_id). '
' . '' . '' . $formproduct->selectLotStock('', 'batchl'.$line_id.'_0', '', 1, 0, $lines[$i]->fk_product). '
' . '' . '' . $formproduct->selectWarehouses($lines[$i]->entrepot_id, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1). ' - ' . $langs->trans("NA") . '
' . '' . '' . $formproduct->selectWarehouses($detail_entrepot->entrepot_id, 'entl'.$detail_entrepot->line_id, '', 1, 0, $lines[$i]->fk_product, '', 1) . ' - ' . $langs->trans("NA") . '
'.$langs->trans("NotEnoughStock").'
' . '' . '' . '' . '
'.$lines[$i]->qty_shipped.''; + if ($lines[$i]->entrepot_id > 0) + { + $entrepot = new Entrepot($db); + $entrepot->fetch($lines[$i]->entrepot_id); + print $entrepot->getNomUrl(1); + } + else if (count($lines[$i]->details_entrepot) > 1) + { + $detail = ''; + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + if ($detail_entrepot->entrepot_id > 0) + { + $entrepot = new Entrepot($db); + $entrepot->fetch($detail_entrepot->entrepot_id); + $detail.= $langs->trans("DetailWarehouseFormat",$entrepot->libelle,$detail_entrepot->qty_shipped).'
'; + } + } + print $form->textwithtooltip(img_picto('', 'object_stock').' '.$langs->trans("DetailWarehouseNumber"),$detail); + } + print '
'; + if ($lines[$i]->product_tobatch) + { + $detail = ''; + foreach ($lines[$i]->detail_batch as $dbatch) + { + $detail.= $langs->trans("Batch").': '.$dbatch->batch; + $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day"); + $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day"); + $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty; + $detail.= '
'; + } + print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"),$detail); + } + else + { + print $langs->trans("NA"); + } + print '
'; - if ($lines[$i]->fk_product_type == 0) print $lines[$i]->weight*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->weight_units,"weight"); + if ($lines[$i]->fk_product_type == Product::TYPE_PRODUCT) print $lines[$i]->weight*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->weight_units,"weight"); else print ' '; print ''; - if ($lines[$i]->fk_product_type == 0) print $lines[$i]->volume*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->volume_units,"volume"); + if ($lines[$i]->fk_product_type == Product::TYPE_PRODUCT) print $lines[$i]->volume*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->volume_units,"volume"); else print ' '; print ''.$lines[$i]->volume*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->volume_units,"volume").''; - if ($lines[$i]->entrepot_id > 0) - { - $entrepot = new Entrepot($db); - $entrepot->fetch($lines[$i]->entrepot_id); - print $entrepot->getNomUrl(1); - } - else if (count($lines[$i]->details_entrepot) > 1) - { - $detail = ''; - foreach ($lines[$i]->details_entrepot as $detail_entrepot) - { - if ($detail_entrepot->entrepot_id > 0) - { - $entrepot = new Entrepot($db); - $entrepot->fetch($detail_entrepot->entrepot_id); - $detail.= $langs->trans("DetailWarehouseFormat",$entrepot->libelle,$detail_entrepot->qty_shipped).'
'; - } - } - print $form->textwithtooltip(img_picto('', 'object_stock').' '.$langs->trans("DetailWarehouseNumber"),$detail); - } - print '
'; + print '
'; + print '
'; } - - // Batch number managment - if (! empty($conf->productbatch->enabled)) + else if ($object->statut == 0) { - if (isset($lines[$i]->detail_batch)) + // edit-delete buttons + print '
'; + print 'id . '">' . img_edit() . ''; + print ''; + print 'id . '">' . img_delete() . ''; + print ''; - if ($lines[$i]->product_tobatch) - { - $detail = ''; - foreach ($lines[$i]->detail_batch as $dbatch) - { - $detail.= $langs->trans("DetailBatchFormat",$dbatch->batch,dol_print_date($dbatch->eatby,"day"),dol_print_date($dbatch->sellby,"day"),$dbatch->dluo_qty).'
'; - } - print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"),$detail); - } - else - { - print $langs->trans("NA"); - } - print '
'; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) +{ + $dir = dol_buildpath($reldir."core/modules/reception/"); + + if (is_dir($dir)) + { + $handle = opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + if (substr($file, 0, 14) == 'mod_reception_' && substr($file, dol_strlen($file)-3, 3) == 'php') + { + $file = substr($file, 0, dol_strlen($file)-4); + + require_once $dir.$file.'.php'; + + $module = new $file; + + if ($module->isEnabled()) + { + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + print '\n"; + print ''; + + // Show example of numbering module + print ''."\n"; + + print ''; + + $reception=new Reception($db); + $reception->initAsSpecimen(); + + // Info + $htmltooltip=''; + $htmltooltip.=''.$langs->trans("Version").': '.$module->getVersion().'
'; + $nextval=$module->getNextValue($mysoc,$reception); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip.=''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/',$nextval) || $nextval=='NotConfigured') + $nextval = $langs->trans($nextval); + $htmltooltip.=$nextval.'
'; + } else { + $htmltooltip.=$langs->trans($module->error).'
'; + } + } + + print ''; + + print ''; + } + } + } + closedir($handle); + } + } +} + +print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->nom."'; + print $module->info(); + print ''; + $tmp=$module->getExample(); + if (preg_match('/^Error/',$tmp)) { + $langs->load("errors"); print '
'.$langs->trans($tmp).'
'; + } + elseif ($tmp=='NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + if ($conf->global->RECEPTION_ADDON_NUMBER == "$file") + { + print img_picto($langs->trans("Activated"),'switch_on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'">'; + print img_picto($langs->trans("Disabled"),'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print '

'; + + +/* + * Documents models for Receptions Receipt + */ +print load_fiche_titre($langs->trans("ReceptionsReceiptModel")); + +// Defini tableau def de modele invoice +$type="reception"; +$def = array(); + +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; + +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) +{ + foreach (array('','/doc') as $valdir) + { + $dir = dol_buildpath($reldir."core/modules/reception".$valdir); + + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + arsort($filelist); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + print ''; + + // Active + if (in_array($name, $def)) + { + print ''; + } + else + { + print '"; + } + + // Defaut + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip.='
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + $htmltooltip.='
'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } +} + +print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status").''.$langs->trans("Default").''.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print "'; + if ($conf->global->RECEPTION_ADDON_PDF == $name) + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print ''; + if ($module->type == 'pdf') + { + print 'scandir.'&label='.urlencode($module->name).'">'.img_object($langs->trans("Preview"),'reception').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
'; +print '
'; + + +/* + * Other options + * + */ +/* +print load_fiche_titre($langs->trans("OtherOptions")); + +print ''; +print ''; +print ''; + +print ""; +print ""; +print "\n"; +print ""; + +$substitutionarray=pdf_getSubstitutionArray($langs); +$substitutionarray['__(AnyTranslationKey)__']=$langs->trans("Translation"); +$htmltext = ''.$langs->trans("AvailableVariables").':
'; +foreach($substitutionarray as $key => $val) $htmltext.=$key.'
'; +$htmltext.='
'; + +print '\n"; + +print '\n"; +*/ +print '
".$langs->trans("Parameter")."
'; +print $form->textwithpicto($langs->trans("FreeLegalTextOnReceptions"), $langs->trans("AddCRIfTooLong").'

'.$htmltext).'
'; +$variablename='RECEPTION_FREE_TEXT'; +if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) +{ + print ''; +} +else +{ + include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor($variablename, $conf->global->$variablename,'',80,'dolibarr_notes'); + print $doleditor->Create(); +} +print "
'; +print $form->textwithpicto($langs->trans("WatermarkOnDraftContractCards"), $htmltext).'
'; +print ''; +print "
'; + +print '
'; + +print ''; + +llxFooter(); +$db->close(); diff --git a/htdocs/core/lib/reception.lib.php b/htdocs/core/lib/reception.lib.php new file mode 100644 index 00000000000..34cd46026ed --- /dev/null +++ b/htdocs/core/lib/reception.lib.php @@ -0,0 +1,101 @@ + + * Copyright (C) 2007 Rodolphe Quiedeville + * Copyright (C) 2010-2012 Regis Houssin + * Copyright (C) 2010 Juanjo Menent + * Copyright (C) 2015 Claudio Aschieri + * + * 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 . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/lib/reception.lib.php + * \brief Function for reception module + * \ingroup reception + */ + +/** + * Prepare array with list of tabs + * + * @param Reception $object Object related to tabs + * @return array Array of tabs to show + */ +function reception_prepare_head(Reception $object) +{ + global $langs, $conf, $user; + if (! empty($conf->reception->enabled)) $langs->load("receptions"); + $langs->load("orders"); + + $h = 0; + $head = array(); + $h = 0; + + $head[$h][0] = DOL_URL_ROOT."/admin/reception_setup.php"; + $head[$h][1] = $langs->trans("Setup"); + $h++; + + + + + + + complete_head_from_modules($conf,$langs,$object,$head,$h,'order','remove'); + + return $head; +} + +/** + * Return array head with list of tabs to view object informations. + * + * @return array head array with tabs + */ +function reception_admin_prepare_head() +{ + global $langs, $conf, $user; + $langs->load("receptions"); + + $h = 0; + $head = array(); + + $head[$h][0] = DOL_URL_ROOT."/admin/reception_setup.php"; + $head[$h][1] = $langs->trans("Reception"); + $head[$h][2] = 'reception'; + $h++; + + + if (! empty($conf->global->MAIN_SUBMODULE_RECEPTION)) + { + $head[$h][0] = DOL_URL_ROOT.'/admin/reception_extrafields.php'; + $head[$h][1] = $langs->trans("ExtraFields"); + $head[$h][2] = 'attributes_reception'; + $h++; + } + + if (! empty($conf->global->MAIN_SUBMODULE_RECEPTION)) + { + $head[$h][0] = DOL_URL_ROOT.'/admin/receptiondet_extrafields.php'; + $head[$h][1] = $langs->trans("ExtraFieldsLines"); + $head[$h][2] = 'attributeslines_reception'; + $h++; + } + + + + complete_head_from_modules($conf,$langs,null,$head,$h,'reception_admin','remove'); + + return $head; +} + + diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 445ec83d58d..2d92ace947a 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -122,6 +122,11 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expedition->enabled && $leftmenu=="sendings"', __HANDLER__, 'left', 1301__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/expedition/card.php?action=create2&leftmenu=sendings', 'NewSending', 1, 'sendings', '$user->rights->expedition->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expedition->enabled && $leftmenu=="sendings"', __HANDLER__, 'left', 1302__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/expedition/list.php?leftmenu=sendings', 'List', 1, 'sendings', '$user->rights->expedition->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->expedition->enabled && $leftmenu=="sendings"', __HANDLER__, 'left', 1303__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/expedition/stats/index.php?leftmenu=sendings', 'Statistics', 1, 'sendings', '$user->rights->expedition->lire', '', 2, 2, __ENTITY__); +-- Product - Reception +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->reception->enabled', __HANDLER__, 'left', 1300__+MAX_llx_menu__, 'commercial', 'receptions', 3__+MAX_llx_menu__, '/reception/index.php?leftmenu=receptions', 'Receptions', 0, 'receptions', '$user->rights->reception->lire', '', 2, 6, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->reception->enabled && $leftmenu=="receptions"', __HANDLER__, 'left', 1301__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/reception/card.php?action=create2&leftmenu=receptions', 'NewSending', 1, 'receptions', '$user->rights->reception->creer', '', 2, 0, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->reception->enabled && $leftmenu=="receptions"', __HANDLER__, 'left', 1302__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/reception/list.php?leftmenu=receptions', 'List', 1, 'receptions', '$user->rights->reception->lire', '', 2, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->reception->enabled && $leftmenu=="receptions"', __HANDLER__, 'left', 1303__+MAX_llx_menu__, 'commercial', '', 1300__+MAX_llx_menu__, '/reception/stats/index.php?leftmenu=receptions', 'Statistics', 1, 'receptions', '$user->rights->reception->lire', '', 2, 2, __ENTITY__); -- Commercial - Proposals insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->propal->enabled', __HANDLER__, 'left', 1100__+MAX_llx_menu__, 'commercial', 'propals', 5__+MAX_llx_menu__, '/comm/propal/index.php?leftmenu=propals', 'Prop', 0, 'propal', '$user->rights->propale->lire', '', 2, 4, __ENTITY__); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index e9876b31ece..486b8bc7e9c 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1269,6 +1269,18 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($usemenuhider || empty($leftmenu) || $leftmenu=="sendings") $newmenu->add("/expedition/list.php?leftmenu=sendings&viewstatut=2", $langs->trans("StatusSendingProcessedShort"), 2, $user->rights->expedition->lire); $newmenu->add("/expedition/stats/index.php?leftmenu=sendings", $langs->trans("Statistics"), 1, $user->rights->expedition->lire); } + // Receptions + if (! empty($conf->reception->enabled)) + { + $langs->load("receptions"); + $newmenu->add("/reception/index.php?leftmenu=receptions", $langs->trans("Receptions"), 0, $user->rights->reception->lire, '', $mainmenu, 'receptions'); + $newmenu->add("/reception/card.php?action=create2&leftmenu=receptions", $langs->trans("NewReception"), 1, $user->rights->reception->creer); + $newmenu->add("/reception/list.php?leftmenu=receptions", $langs->trans("List"), 1, $user->rights->reception->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="receptions") $newmenu->add("/reception/list.php?leftmenu=receptions&viewstatut=0", $langs->trans("StatusReceptionDraftShort"), 2, $user->rights->reception->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="receptions") $newmenu->add("/reception/list.php?leftmenu=receptions&viewstatut=1", $langs->trans("StatusReceptionValidatedShort"), 2, $user->rights->reception->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="receptions") $newmenu->add("/reception/list.php?leftmenu=receptions&viewstatut=2", $langs->trans("StatusReceptionProcessedShort"), 2, $user->rights->reception->lire); + $newmenu->add("/reception/stats/index.php?leftmenu=receptions", $langs->trans("Statistics"), 1, $user->rights->reception->lire); + } } diff --git a/htdocs/core/modules/modReception.class.php b/htdocs/core/modules/modReception.class.php new file mode 100644 index 00000000000..402c1a0f8f2 --- /dev/null +++ b/htdocs/core/modules/modReception.class.php @@ -0,0 +1,266 @@ + + * + * 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 . + */ + +/** + * \defgroup reception Module reception + * \brief Module pour gerer les réceptions de produits + * \file htdocs/core/modules/modReception.class.php + * \ingroup reception + * \brief Fichier de description et activation du module Reception + */ + +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; + + +/** + * Class to describe and enable module Reception + */ +class modReception extends DolibarrModules +{ + + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf, $user; + + $this->db = $db; + $this->numero = 104160; + + $this->family = "crm"; + $this->module_position = 40; + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + $this->description = "Gestion des réceptions fournisseurs"; + + // Possible values for version are: 'development', 'experimental', 'dolibarr' or version + $this->version = 'dolibarr'; + + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + $this->special = 0; + $this->picto = "sending"; + + // Data directories to create when module is enabled + $this->dirs = array("/reception/receipt", + "/reception/receipt/temp", + "/doctemplates/reception" + ); + + // Config pages + $this->config_page_url = array("reception_setup.php"); + + // Dependencies + $this->depends = array("modFournisseur"); + $this->requiredby = array(); + $this->conflictwith = array(); + $this->langfiles = array('receptions'); + + // Constants + $this->const = array(); + $r=0; + + $this->const[$r][0] = "RECEPTION_ADDON_PDF"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "squille"; + $this->const[$r][3] = 'Nom du gestionnaire de generation des bons receptions en PDF'; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "RECEPTION_ADDON_NUMBER"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "mod_reception_beryl"; + $this->const[$r][3] = 'Name for numbering manager for receptions'; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "RECEPTION_ADDON_PDF_ODT_PATH"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/receptions"; + $this->const[$r][3] = ""; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "MAIN_SUBMODULE_RECEPTION"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "1"; + $this->const[$r][3] = "Enable receptions"; + $this->const[$r][4] = 0; + $r++; + + // Boxes + $this->boxes = array(); + + // Permissions + $this->rights = array(); + $this->rights_class = 'reception'; + $r=0; + + $r++; + $this->rights[$r][0] = $this->numero.$r; + $this->rights[$r][1] = 'Lire les receptions'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'lire'; + + $r++; + $this->rights[$r][0] = $this->numero.$r; + $this->rights[$r][1] = 'Creer modifier les receptions'; + $this->rights[$r][2] = 'w'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'creer'; + + $r++; + $this->rights[$r][0] = $this->numero.$r; + $this->rights[$r][1] = 'Valider les receptions'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'reception_advance'; + $this->rights[$r][5] = 'validate'; + + $r++; + $this->rights[$r][0] = $this->numero.$r; // id de la permission + $this->rights[$r][1] = 'Envoyer les receptions aux clients'; // libelle de la permission + $this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour) + $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut + $this->rights[$r][4] = 'reception_advance'; + $this->rights[$r][5] = 'send'; + + $r++; + $this->rights[$r][0] = $this->numero.$r; + $this->rights[$r][1] = 'Exporter les receptions'; + $this->rights[$r][2] = 'r'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'reception'; + $this->rights[$r][5] = 'export'; + + $r++; + $this->rights[$r][0] = $this->numero.$r; + $this->rights[$r][1] = 'Supprimer les receptions'; + $this->rights[$r][2] = 'd'; + $this->rights[$r][3] = 0; + $this->rights[$r][4] = 'supprimer'; + + + // Menus + //------- + $this->menu = 1; // This module add menu entries. They are coded into menu manager. + + + // Exports + //-------- + $r=0; +/* + include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; + $shipment=new Commande($this->db); + $contact_arrays=$shipment->liste_type_contact('external','',0,0,''); + if (is_array($contact_arrays) && count($contact_arrays)>0){ + $idcontacts=join(',',array_keys($shipment->liste_type_contact('external','',0,0,''))); + } else { + $idcontacts=0; + } + + + $r++; + $this->export_code[$r]=$this->rights_class.'_'.$r; + $this->export_label[$r]='Shipments'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_permission[$r]=array(array("reception","shipment","export")); + $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'ThirdParty','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','d.nom'=>'State','co.label'=>'Country','co.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6','c.rowid'=>"Id",'c.ref'=>"Ref",'c.ref_customer'=>"RefCustomer",'c.fk_soc'=>"IdCompany",'c.date_creation'=>"DateCreation",'c.date_delivery'=>"DateDeliveryPlanned",'c.tracking_number'=>"TrackingNumber",'c.height'=>"Height",'c.width'=>"Width",'c.size'=>"Depth",'c.size_units'=>'SizeUnits','c.weight'=>"Weight",'c.weight_units'=>"WeightUnits",'c.fk_statut'=>'Status','c.note_public'=>"NotePublic",'ed.rowid'=>'LineId','cd.description'=>'Description','ed.qty'=>"Qty",'p.rowid'=>'ProductId','p.ref'=>'ProductRef','p.label'=>'ProductLabel','p.weight'=>'ProductWeight','p.weight_units'=>'WeightUnits','p.volume'=>'ProductVolume','p.volume_units'=>'VolumeUnits'); + if ($idcontacts && ! empty($conf->global->SHIPMENT_ADD_CONTACTS_IN_EXPORT)) $this->export_fields_array[$r]+=array('sp.rowid'=>'IdContact','sp.lastname'=>'Lastname','sp.firstname'=>'Firstname','sp.note_public'=>'NotePublic'); + //$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','co.label'=>'List:c_country:label:label','co.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','c.ref'=>"Text",'c.ref_client'=>"Text",'c.date_creation'=>"Date",'c.date_commande'=>"Date",'c.amount_ht'=>"Numeric",'c.remise_percent'=>"Numeric",'c.total_ht'=>"Numeric",'c.total_ttc'=>"Numeric",'c.facture'=>"Boolean",'c.fk_statut'=>'Status','c.note_public'=>"Text",'c.date_livraison'=>'Date','ed.qty'=>"Text"); + $this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','co.label'=>'List:c_country:label:label','co.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','c.ref'=>"Text",'c.ref_customer'=>"Text",'c.date_creation'=>"Date",'c.date_delivery'=>"Date",'c.tracking_number'=>"Numeric",'c.height'=>"Numeric",'c.width'=>"Numeric",'c.weight'=>"Numeric",'c.fk_statut'=>'Status','c.note_public'=>"Text",'ed.qty'=>"Numeric",'d.nom'=>'Text'); + $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','d.nom'=>'company','co.label'=>'company','co.code'=>'company','s.fk_pays'=>'company','s.phone'=>'company','s.siren'=>'company','s.ape'=>'company','s.siret'=>'company','s.idprof4'=>'company','s.idprof5'=>'company','s.idprof6'=>'company','c.rowid'=>"shipment",'c.ref'=>"shipment",'c.ref_customer'=>"shipment",'c.fk_soc'=>"shipment",'c.date_creation'=>"shipment",'c.date_delivery'=>"shipment",'c.tracking_number'=>'shipment','c.height'=>"shipment",'c.width'=>"shipment",'c.size'=>'shipment','c.size_units'=>'shipment','c.weight'=>"shipment",'c.weight_units'=>'shipment','c.fk_statut'=>"shipment",'c.note_public'=>"shipment",'ed.rowid'=>'shipment_line','cd.description'=>'shipment_line','ed.qty'=>"shipment_line",'p.rowid'=>'product','p.ref'=>'product','p.label'=>'product','p.weight'=>'product','p.weight_units'=>'product','p.volume'=>'product','p.volume_units'=>'product'); + if ($idcontacts && ! empty($conf->global->SHIPMENT_ADD_CONTACTS_IN_EXPORT)) $this->export_entities_array[$r]+=array('sp.rowid'=>'contact','sp.lastname'=>'contact','sp.firstname'=>'contact','sp.note_public'=>'contact'); + $this->export_dependencies_array[$r]=array('shipment_line'=>'ed.rowid','product'=>'ed.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + if ($idcontacts && ! empty($conf->global->SHIPMENT_ADD_CONTACTS_IN_EXPORT)) + { + $keyforselect='socpeople'; $keyforelement='contact'; $keyforaliasextra='extra3'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + } + $keyforselect='reception'; $keyforelement='shipment'; $keyforaliasextra='extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + $keyforselect='receptiondet'; $keyforelement='shipment_line'; $keyforaliasextra='extra2'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + + $this->export_sql_start[$r]='SELECT DISTINCT '; + $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'reception as c'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'reception_extrafields as extra ON c.rowid = extra.fk_object,'; + $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'societe as s'; + if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON s.fk_pays = co.rowid,'; + $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'receptiondet as ed'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'receptiondet_extrafields as extra2 ON ed.rowid = extra2.fk_object'; + $this->export_sql_end[$r] .=' , '.MAIN_DB_PREFIX.'commandedet as cd'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on cd.fk_product = p.rowid'; + if ($idcontacts && ! empty($conf->global->SHIPMENT_ADD_CONTACTS_IN_EXPORT)) + { + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'element_contact as ee ON ee.element_id = cd.fk_commande AND ee.fk_c_type_contact IN ('.$idcontacts.')'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople as sp ON sp.rowid = ee.fk_socpeople'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra3 ON sp.rowid = extra3.fk_object'; + } + $this->export_sql_end[$r] .=' WHERE c.fk_soc = s.rowid AND c.rowid = ed.fk_reception AND ed.fk_origin_line = cd.rowid'; + $this->export_sql_end[$r] .=' AND c.entity IN ('.getEntity('reception').')'; + if(!$user->rights->societe->client->voir) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id;*/ + } + + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function init($options='') + { + global $conf,$langs; + + // Permissions + $this->remove($options); + + //ODT template + $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/reception/template_reception.odt'; + $dirodt=DOL_DATA_ROOT.'/doctemplates/reception'; + $dest=$dirodt.'/template_reception.odt'; + + if (file_exists($src) && ! file_exists($dest)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + dol_mkdir($dirodt); + $result=dol_copy($src,$dest,0,0); + if ($result < 0) + { + $langs->load("errors"); + $this->error=$langs->trans('ErrorFailToCopyFile',$src,$dest); + return 0; + } + } + + $sql = array(); + + $sql = array( + "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = '".$this->db->escape($this->const[0][2])."' AND type = 'reception' AND entity = ".$conf->entity, + "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('".$this->db->escape($this->const[0][2])."','reception',".$conf->entity.")", + ); + + return $this->_init($sql,$options); + } +} diff --git a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php new file mode 100644 index 00000000000..4a19d82e449 --- /dev/null +++ b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php @@ -0,0 +1,522 @@ + +* +* 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 . +* or see http://www.gnu.org/ +*/ + +/** + * \file htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php + * \ingroup reception + * \brief File of class to build ODT documents for reception + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_reception_odt extends ModelePdfReception +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'RECEPTION_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva RECEPTION_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + } + + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".
\n"; + $texte.= '
'; + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= ''; + + // List of directories area + $texte.= ''; + + $texte.= ''; + $texte.= ''; + + $texte.= '
'; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->RECEPTION_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.(ods|odt)'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='
'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
'; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= '
'; + $texte.= ''; + $texte.= '
'; + $texte.= ''; + $texte.= '
'; + + // Scan directories + $nbofiles=count($listoffiles); + if (! empty($conf->global->RECEPTION_ADDON_PDF_ODT_PATH)) + { + $texte.=$langs->trans("NumberOfModelFilesFound").': '; + //$texte.=$nbofiles?'':''; + $texte.=count($listoffiles); + //$texte.=$nbofiles?'':''; + $texte.=''; + } + if ($nbofiles) + { + $texte.='
'; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '
'; + $texte.= '
'; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param Reception $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $user,$langs,$conf,$mysoc,$hookmanager; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("bills"); + + if ($conf->reception->dir_output."/reception") + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new Reception($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + + $dir = $conf->reception->dir_output."/reception"; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.od(t|s)/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + $newfiletmp=$objectref.'_'.$newfiletmp; + //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + // Get extension (ods or odt) + $newfileformat=substr($newfile, strrpos($newfile, '.')+1); + if ( ! empty($conf->global->MAIN_DOC_USE_TIMING)) + { + $format=$conf->global->MAIN_DOC_USE_TIMING; + if ($format == '1') $format='%Y%m%d%H%M%S'; + $filename=$newfiletmp.'-'.dol_print_date(dol_now(),$format).'.'.$newfileformat; + } + else + { + $filename=$newfiletmp.'.'.$newfileformat; + } + $file=$dir.'/'.$filename; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + + dol_mkdir($conf->reception->dir_temp); + + + // If BILLING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','BILLING'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else $socobject = $object->thirdparty; + } + else + { + $socobject=$object->thirdparty; + } + + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->name, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Line of free text + $newfreetext=''; + $paramfreetext='RECEPTION_FREE_TEXT'; + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + try { + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->reception->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + } + catch(Exception $e) + { + $this->error=$e->getMessage(); + return -1; + } + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + // Make substitutions into odt of freetext + try { + $odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + + // Make substitutions into odt of user info + $tmparray=$this->get_substitutionarray_user($user,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of mysoc + $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of thirdparty + $tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Replace tags of object + external modules + $tmparray=$this->get_substitutionarray_reception($object,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object); + // Call the ODTSubstitution hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Replace tags of lines + try + { + $listlines = $odfHandler->setSegment('lines'); + foreach ($object->lines as $line) + { + $tmparray=$this->get_substitutionarray_reception_lines($line,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); + $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Replace labels translated + $tmparray=$outputlangs->get_translations_for_substitutions(); + foreach($tmparray as $key=>$value) + { + try { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + } + + // Call the beforeODTSave hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Write new file + if (!empty($conf->global->MAIN_ODT_AS_PDF)) { + try { + $odfHandler->exportAsAttachedPDF($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + else { + try { + $odfHandler->saveToDisk($file); + }catch (Exception $e){ + $this->error=$e->getMessage(); + return -1; + } + } + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('afterODTCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + +} + diff --git a/htdocs/core/modules/reception/doc/index.html b/htdocs/core/modules/reception/doc/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/core/modules/reception/doc/pdf_squille.modules.php b/htdocs/core/modules/reception/doc/pdf_squille.modules.php new file mode 100644 index 00000000000..0f1add63c44 --- /dev/null +++ b/htdocs/core/modules/reception/doc/pdf_squille.modules.php @@ -0,0 +1,1031 @@ + + * + * 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 . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/reception/doc/pdf_squille.modules.php + * \ingroup reception + * \brief Fichier de la classe permettant de generer les bordereaux envoi au modele Squille + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; + + +/** + * Classe permettant de generer les borderaux envoi au modele Squille + */ +class pdf_squille extends ModelePdfReception +{ + var $emetteur; // Objet societe qui emet + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db=0) + { + global $conf,$langs,$mysoc; + + $this->db = $db; + $this->name = "squille"; + $this->description = $langs->trans("DocumentModelStandardPDF"); + + $this->type = 'pdf'; + $formatarray=pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; + $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; + $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; + $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; + + $this->option_logo = 1; + + // Get source company + $this->emetteur=$mysoc; + if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default if not defined + + // Define position of columns + $this->posxdesc=$this->marge_gauche+1; + $this->posxweightvol=$this->page_largeur - $this->marge_droite - 78; + $this->posxqtyordered=$this->page_largeur - $this->marge_droite - 56; + $this->posxqtytoship=$this->page_largeur - $this->marge_droite - 28; + $this->posxpuht=$this->page_largeur - $this->marge_droite; + + if (!empty($conf->global->MAIN_PDF_RECEPTION_DISPLAY_AMOUNT_HT)) { + + $this->posxweightvol=$this->page_largeur - $this->marge_droite - 118; + $this->posxqtyordered=$this->page_largeur - $this->marge_droite - 96; + $this->posxqtytoship=$this->page_largeur - $this->marge_droite - 68; + $this->posxpuht=$this->page_largeur - $this->marge_droite - 40; + $this->posxtotalht=$this->page_largeur - $this->marge_droite - 20; + } + + $this->posxpicture=$this->posxweightvol - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH); // width of images + + if ($this->page_largeur < 210) // To work with US executive format + { + $this->posxweightvol-=20; + $this->posxpicture-=20; + $this->posxqtyordered-=20; + $this->posxqtytoship-=20; + } + + if (! empty($conf->global->RECEPTION_PDF_HIDE_ORDERED)) + { + $this->posxweightvol += ($this->posxqtytoship - $this->posxqtyordered); + $this->posxpicture += ($this->posxqtytoship - $this->posxqtyordered); + $this->posxqtyordered = $this->posxqtytoship; + } + } + + /** + * Function to build pdf onto disk + * + * @param Object $object Object reception to generate (or id if old method) + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO + */ + function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $user,$conf,$langs,$hookmanager; + + $object->fetch_thirdparty(); + + if (! is_object($outputlangs)) $outputlangs=$langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("bills"); + $outputlangs->load("products"); + $outputlangs->load("propal"); + $outputlangs->load("deliveries"); + $outputlangs->load("sendings"); + $outputlangs->load("productbatch"); + + $nblignes = count($object->lines); + + // Loop on each lines to detect if there is at least one image to show + $realpatharray=array(); + if (! empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE)) + { + $objphoto = new Product($this->db); + + for ($i = 0 ; $i < $nblignes ; $i++) + { + if (empty($object->lines[$i]->fk_product)) continue; + + $objphoto = new Product($this->db); + $objphoto->fetch($object->lines[$i]->fk_product); + + $pdir = get_exdir($object->lines[$i]->fk_product,2,0,0,$objphoto,'product') . $object->lines[$i]->fk_product ."/photos/"; + $dir = $conf->product->dir_output.'/'.$pdir; + + $realpath=''; + + foreach ($objphoto->liste_photos($dir,1) as $key => $obj) + { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + { + if ($obj['photo_vignette']) + { + $filename= $obj['photo_vignette']; + } + else + { + $filename=$obj['photo']; + } + } + else + { + $filename=$obj['photo']; + } + + $realpath = $dir.$filename; + break; + } + + if ($realpath) $realpatharray[$i]=$realpath; + } + } + + if (count($realpatharray) == 0) $this->posxpicture=$this->posxweightvol; + + if ($conf->reception->dir_output) + { + // Definition de $dir et $file + if ($object->specimen) + { + $dir = $conf->reception->dir_output."/sending"; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $expref = dol_sanitizeFileName($object->ref); + $dir = $conf->reception->dir_output."/sending/" . $expref; + $file = $dir . "/" . $expref . ".pdf"; + } + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Add pdfgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + + // Set nblignes with the new facture lines content after hook + $nblignes = count($object->lines); + + $pdf=pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); + $heightforinfotot = 8; // Height reserved to output the info and total part + $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + 8; // Height reserved to output the footer (value include bottom margin) + $pdf->SetAutoPageBreak(1,0); + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + // Set path to the background PDF File + if (empty($conf->global->MAIN_DISABLE_FPDI) && ! empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb=0; + $pdf->SetDrawColor(128,128,128); + + if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("Reception")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("Reception")); + if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + $tab_top = 90; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10); + $tab_height = 130; + $tab_height_newpage = 150; + + // Incoterm + $height_incoterms = 0; + if ($conf->incoterm->enabled) + { + $desc_incoterms = $object->getIncotermsForPDF(); + if ($desc_incoterms) + { + $tab_top = 88; + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1); + $nexY = $pdf->GetY(); + $height_incoterms=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1); + + $tab_top = $nexY+6; + $height_incoterms += 4; + } + } + + if (! empty($object->note_public) || ! empty($object->tracking_number)) + { + $tab_top = 88 + $height_incoterms; + $tab_top_alt = $tab_top; + + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->writeHTMLCell(60, 4, $this->posxdesc-1, $tab_top-1, $outputlangs->transnoentities("TrackingNumber")." : " . $object->tracking_number, 0, 1, false, true, 'L'); + + $tab_top_alt = $pdf->GetY(); + //$tab_top_alt += 1; + + // Tracking number + if (! empty($object->tracking_number)) + { + $object->GetUrlTrackingStatus($object->tracking_number); + if (! empty($object->tracking_url)) + { + if ($object->reception_method_id > 0) + { + // Get code using getLabelFromKey + $code=$outputlangs->getLabelFromKey($this->db,$object->reception_method_id,'c_shipment_mode','rowid','code'); + $label=''; + if ($object->tracking_url != $object->tracking_number) $label.=$outputlangs->trans("LinkToTrackYourPackage")."
"; + $label.=$outputlangs->trans("SendingMethod").": ".$outputlangs->trans("SendingMethod".strtoupper($code)); + //var_dump($object->tracking_url != $object->tracking_number);exit; + if ($object->tracking_url != $object->tracking_number) + { + $label.=" : "; + $label.=$object->tracking_url; + } + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->writeHTMLCell(60, 4, $this->posxdesc-1, $tab_top_alt, $label, 0, 1, false, true, 'L'); + + $tab_top_alt = $pdf->GetY(); + } + } + } + + // Notes + if (! empty($object->note_public)) + { + $pdf->SetFont('','', $default_font_size - 1); // Dans boucle pour gerer multi-page + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top_alt, dol_htmlentitiesbr($object->note_public), 0, 1); + } + + $nexY = $pdf->GetY(); + $height_note=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1); + + $tab_height = $tab_height - $height_note; + $tab_top = $nexY+6; + } + else + { + $height_note=0; + } + + $iniY = $tab_top + 7; + $curY = $tab_top + 7; + $nexY = $tab_top + 7; + + // Loop on each lines + for ($i = 0; $i < $nblignes; $i++) + { + $curY = $nexY; + $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0,0,0); + + // Define size of image if we need it + $imglinesize=array(); + if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]); + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore=$pdf->getPage(); + + $showpricebeforepagebreak=1; + $posYAfterImage=0; + $posYAfterDescription=0; + + // We start with Photo of product line + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur-($heightforfooter+$heightforfreetext+$heightforinfotot))) // If photo too high, we moved completely on new page + { + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($pageposbefore+1); + + $curY = $tab_top_newpage; + $showpricebeforepagebreak=0; + } + + if (isset($imglinesize['width']) && isset($imglinesize['height'])) + { + $curX = $this->posxpicture-1; + $pdf->Image($realpatharray[$i], $curX + (($this->posxweightvol-$this->posxpicture-$imglinesize['width'])/2), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + // $pdf->Image does not increase value return by getY, so we save it manually + $posYAfterImage=$curY+$imglinesize['height']; + } + + // Description of product line + $curX = $this->posxdesc-1; + + $pdf->startTransaction(); + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxpicture-$curX,3,$curX,$curY,$hideref,$hidedesc); + + $pageposafter=$pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pageposafter=$pageposbefore; + //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxpicture-$curX,3,$curX,$curY,$hideref,$hidedesc); + + $pageposafter=$pdf->getPage(); + $posyafter=$pdf->GetY(); + //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new page + { + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($pageposafter+1); + } + } + else + { + // We found a page break + $showpricebeforepagebreak=0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $posYAfterDescription=$pdf->GetY(); + + $nexY = $pdf->GetY(); + $pageposafter=$pdf->getPage(); + + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description or photo were moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + // We suppose that a too long description is moved completely on next page + if ($pageposafter > $pageposbefore) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut + + $pdf->SetXY($this->posxweightvol, $curY); + $weighttxt=''; + if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight) + { + $weighttxt=round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuring_units_string($object->lines[$i]->weight_units,"weight"); + } + $voltxt=''; + if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume) + { + $voltxt=round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuring_units_string($object->lines[$i]->volume_units?$object->lines[$i]->volume_units:0,"volume"); + } + + $pdf->writeHTMLCell($this->posxqtyordered - $this->posxweightvol + 2, 3, $this->posxweightvol - 1, $curY, $weighttxt.(($weighttxt && $voltxt)?'
':'').$voltxt, 0, 0, false, true, 'C'); + //$pdf->MultiCell(($this->posxqtyordered - $this->posxweightvol), 3, $weighttxt.(($weighttxt && $voltxt)?'
':'').$voltxt,'','C'); + + if (empty($conf->global->RECEPTION_PDF_HIDE_ORDERED)) + { + $pdf->SetXY($this->posxqtyordered, $curY); + $pdf->MultiCell(($this->posxqtytoship - $this->posxqtyordered), 3, $object->lines[$i]->qty_asked,'','C'); + } + + $pdf->SetXY($this->posxqtytoship, $curY); + $pdf->MultiCell(($this->posxpuht - $this->posxqtytoship), 3, $object->lines[$i]->qty_shipped,'','C'); + + if(!empty($conf->global->MAIN_PDF_RECEPTION_DISPLAY_AMOUNT_HT)) + { + $pdf->SetXY($this->posxpuht, $curY); + $pdf->MultiCell(($this->posxtotalht - $this->posxpuht-1), 3, price($object->lines[$i]->subprice, 0, $outputlangs),'','R'); + + $pdf->SetXY($this->posxtotalht, $curY); + $pdf->MultiCell(($this->page_largeur - $this->marge_droite - $this->posxtotalht), 3, price($object->lines[$i]->total_ht, 0, $outputlangs),'','R'); + } + + $nexY+=3; + if ($weighttxt && $voltxt) $nexY+=2; + + // Add line + if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1)) + { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY-1, $this->page_largeur - $this->marge_droite, $nexY-1); + $pdf->SetLineStyle(array('dash'=>0)); + } + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) + { + $pdf->setPage($pagenb); + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + } + if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak) + { + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + } + } + + // Show square + if ($pagenb == 1) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } + + // Affiche zone totaux + $posy=$this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs); + + // Pied de page + $this->_pagefoot($pdf,$object,$outputlangs); + if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file,'F'); + + // Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + return 1; // No error + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + else + { + $this->error=$langs->transnoentities("ErrorConstantNotDefined","EXP_OUTPUTDIR"); + return 0; + } + } + + /** + * Show total to pay + * + * @param PDF $pdf Object PDF + * @param Facture $object Object invoice + * @param int $deja_regle Montant deja regle + * @param int $posy Position depart + * @param Translate $outputlangs Objet langs + * @return int Position pour suite + */ + function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs) + { + global $conf,$mysoc; + + $sign=1; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $tab2_top = $posy; + $tab2_hl = 4; + $pdf->SetFont('','B', $default_font_size - 1); + + // Tableau total + $col1x = $this->posxweightvol-50; $col2x = $this->posxweightvol; + /*if ($this->page_largeur < 210) // To work with US executive format + { + $col2x-=20; + }*/ + if (empty($conf->global->RECEPTION_PDF_HIDE_ORDERED)) $largcol2 = ($this->posxqtyordered - $this->posxweightvol); + else $largcol2 = ($this->posxqtytoship - $this->posxweightvol); + + $useborder=0; + $index = 0; + + $totalWeighttoshow=''; + $totalVolumetoshow=''; + + // Load dim data + $tmparray=$object->getTotalWeightVolume(); + $totalWeight=$tmparray['weight']; + $totalVolume=$tmparray['volume']; + $totalOrdered=$tmparray['ordered']; + $totalToShip=$tmparray['toship']; + // Set trueVolume and volume_units not currently stored into database + if ($object->trueWidth && $object->trueHeight && $object->trueDepth) + { + $object->trueVolume=price(($object->trueWidth * $object->trueHeight * $object->trueDepth), 0, $outputlangs, 0, 0); + $object->volume_units=$object->size_units * 3; + } + + if ($totalWeight!='') $totalWeighttoshow=showDimensionInBestUnit($totalWeight, 0, "weight", $outputlangs); + if ($totalVolume!='') $totalVolumetoshow=showDimensionInBestUnit($totalVolume, 0, "volume", $outputlangs); + if ($object->trueWeight) $totalWeighttoshow=showDimensionInBestUnit($object->trueWeight, $object->weight_units, "weight", $outputlangs); + if ($object->trueVolume) $totalVolumetoshow=showDimensionInBestUnit($object->trueVolume, $object->volume_units, "volume", $outputlangs); + + $pdf->SetFillColor(255,255,255); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("Total"), 0, 'L', 1); + + if (empty($conf->global->RECEPTION_PDF_HIDE_ORDERED)) + { + $pdf->SetXY($this->posxqtyordered, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->posxqtytoship - $this->posxqtyordered, $tab2_hl, $totalOrdered, 0, 'C', 1); + } + + $pdf->SetXY($this->posxqtytoship, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->posxpuht - $this->posxqtytoship, $tab2_hl, $totalToShip, 0, 'C', 1); + + if(!empty($conf->global->MAIN_PDF_RECEPTION_DISPLAY_AMOUNT_HT)) { + + $pdf->SetXY($this->posxpuht, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->posxtotalht - $this->posxpuht, $tab2_hl, '', 0, 'C', 1); + + $pdf->SetXY($this->posxtotalht, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxtotalht, $tab2_hl, price($object->total_ht, 0, $outputlangs), 0, 'C', 1); + + } + + // Total Weight + if ($totalWeighttoshow) + { + $pdf->SetXY($this->posxweightvol, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell(($this->posxqtyordered - $this->posxweightvol), $tab2_hl, $totalWeighttoshow, 0, 'C', 1); + + $index++; + } + if ($totalVolumetoshow) + { + $pdf->SetXY($this->posxweightvol, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell(($this->posxqtyordered - $this->posxweightvol), $tab2_hl, $totalVolumetoshow, 0, 'C', 1); + + $index++; + } + if (! $totalWeighttoshow && ! $totalVolumetoshow) $index++; + + $pdf->SetTextColor(0,0,0); + + return ($tab2_top + ($tab2_hl * $index)); + } + + /** + * Show table for lines + * + * @param PDF $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y + * @param Translate $outputlangs Langs object + * @param int $hidetop Hide top bar of array + * @param int $hidebottom Hide bottom bar of array + * @return void + */ + function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0) + { + global $conf; + + // Force to disable hidetop and hidebottom + $hidebottom=0; + if ($hidetop) $hidetop=-1; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','',$default_font_size - 2); + + // Output Rect + $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param + + $pdf->SetDrawColor(128,128,128); + $pdf->SetFont('','', $default_font_size - 1); + + if (empty($hidetop)) + { + $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); + + $pdf->SetXY($this->posxdesc-1, $tab_top+1); + $pdf->MultiCell($this->posxqtyordered - $this->posxdesc, 2, $outputlangs->transnoentities("Description"), '', 'L'); + } + + $pdf->line($this->posxweightvol-1, $tab_top, $this->posxweightvol-1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxweightvol-1, $tab_top+1); + $pdf->MultiCell(($this->posxqtyordered - $this->posxweightvol), 2, $outputlangs->transnoentities("WeightVolShort"),'','C'); + } + + if (empty($conf->global->RECEPTION_PDF_HIDE_ORDERED)) + { + $pdf->line($this->posxqtyordered-1, $tab_top, $this->posxqtyordered-1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxqtyordered-1, $tab_top+1); + $pdf->MultiCell(($this->posxqtytoship - $this->posxqtyordered), 2, $outputlangs->transnoentities("QtyOrdered"),'','C'); + } + } + + $pdf->line($this->posxqtytoship-1, $tab_top, $this->posxqtytoship-1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxqtytoship, $tab_top+1); + $pdf->MultiCell(($this->posxpuht - $this->posxqtytoship), 2, $outputlangs->transnoentities("QtyToShip"),'','C'); + } + + if(!empty($conf->global->MAIN_PDF_RECEPTION_DISPLAY_AMOUNT_HT)) { + + $pdf->line($this->posxpuht-1, $tab_top, $this->posxpuht-1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxpuht-1, $tab_top+1); + $pdf->MultiCell(($this->posxtotalht - $this->posxpuht), 2, $outputlangs->transnoentities("PriceUHT"),'','C'); + } + + $pdf->line($this->posxtotalht-1, $tab_top, $this->posxtotalht-1, $tab_top + $tab_height); + if (empty($hidetop)) + { + $pdf->SetXY($this->posxtotalht-1, $tab_top+1); + $pdf->MultiCell(($this->page_largeur - $this->marge_droite - $this->posxtotalht), 2, $outputlangs->transnoentities("TotalHT"),'','C'); + } + + } + + } + + /** + * Show top header of page. + * + * @param PDF $pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @return void + */ + function _pagehead(&$pdf, $object, $showaddress, $outputlangs) + { + global $conf,$langs,$mysoc; + + $langs->load("orders"); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); + + // Show Draft Watermark + if($object->statut==0 && (! empty($conf->global->RECEPTION_DRAFT_WATERMARK)) ) + { + pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->RECEPTION_DRAFT_WATERMARK); + } + + //Prepare la suite + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('','B', $default_font_size + 3); + + $w = 110; + + $posy=$this->marge_haute; + $posx=$this->page_largeur-$this->marge_droite-$w; + + $pdf->SetXY($this->marge_gauche,$posy); + + // Logo + $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) + { + if (is_readable($logo)) + { + $height=pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } + else + { + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } + else + { + $text=$this->emetteur->name; + $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + + // Show barcode + if (! empty($conf->barcode->enabled)) + { + $posx=105; + } + else + { + $posx=$this->marge_gauche+3; + } + //$pdf->Rect($this->marge_gauche, $this->marge_haute, $this->page_largeur-$this->marge_gauche-$this->marge_droite, 30); + if (! empty($conf->barcode->enabled)) + { + // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref + //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); + //$pdf->Image($logo,10, 5, 0, 24); + } + + $pdf->SetDrawColor(128,128,128); + if (! empty($conf->barcode->enabled)) + { + // TODO Build code bar with function writeBarCode of barcode module for sending ref $object->ref + //$pdf->SetXY($this->marge_gauche+3, $this->marge_haute+3); + //$pdf->Image($logo,10, 5, 0, 24); + } + + + $posx=$this->page_largeur - $w - $this->marge_droite; + $posy=$this->marge_haute; + + $pdf->SetFont('','B', $default_font_size + 2); + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $title=$outputlangs->transnoentities("SendingSheet"); + $pdf->MultiCell($w, 4, $title, '', 'R'); + + $pdf->SetFont('','', $default_font_size + 1); + + $posy+=5; + + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("RefSending") ." : ".$object->ref, '', 'R'); + + // Date planned delivery + if (! empty($object->date_delivery)) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 4, $outputlangs->transnoentities("DateDeliveryPlanned")." : ".dol_print_date($object->date_delivery,"day",false,$outputlangs,true), '', 'R'); + } + + if (! empty($object->thirdparty->code_client)) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R'); + } + + + $pdf->SetFont('','', $default_font_size + 3); + $Yoff=25; + + // Add list of linked orders + $origin = $object->origin; + $origin_id = $object->origin_id; + + // TODO move to external function + if (! empty($conf->$origin->enabled)) // commonly $origin='commande' + { + $outputlangs->load('orders'); + + $classname = ucfirst($origin); + $linkedobject = new $classname($this->db); + $result=$linkedobject->fetch($origin_id); + if ($result >= 0) + { + //$linkedobject->fetchObjectLinked() Get all linked object to the $linkedobject (commonly order) into $linkedobject->linkedObjects + + $pdf->SetFont('','', $default_font_size - 2); + $text=$linkedobject->ref; + if ($linkedobject->ref_client) $text.=' ('.$linkedobject->ref_client.')'; + $Yoff = $Yoff+8; + $pdf->SetXY($this->page_largeur - $this->marge_droite - $w,$Yoff); + $pdf->MultiCell($w, 2, $outputlangs->transnoentities("RefOrder") ." : ".$outputlangs->transnoentities($text), 0, 'R'); + $Yoff = $Yoff+3; + $pdf->SetXY($this->page_largeur - $this->marge_droite - $w,$Yoff); + $pdf->MultiCell($w, 2, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($linkedobject->date,"day",false,$outputlangs,true), 0, 'R'); + } + } + + if ($showaddress) + { + // Sender properties + $carac_emetteur=''; + // Add internal contact of origin element if defined + $arrayidcontact=array(); + if (! empty($origin) && is_object($object->$origin)) $arrayidcontact=$object->$origin->getIdContact('internal','SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $object->fetch_user(reset($arrayidcontact)); + $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$outputlangs->transnoentities("Name").": ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n"; + } + + $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty); + + // Show sender + $posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posx=$this->marge_gauche; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80; + + $hautcadre=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40; + $widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82; + + // Show sender frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(66,5, $outputlangs->transnoentities("Sender").":", 0, 'L'); + $pdf->SetXY($posx,$posy); + $pdf->SetFillColor(230,230,230); + $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0,0,60); + $pdf->SetFillColor(255,255,255); + + // Show sender name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B',$default_font_size); + $pdf->MultiCell($widthrecbox-2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + $posy=$pdf->getY(); + + // Show sender information + $pdf->SetXY($posx+2,$posy); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell($widthrecbox-2, 4, $carac_emetteur, 0, 'L'); + + + // If RECEPTION contact defined, we use it + $usecontact=false; + $arrayidcontact=$object->$origin->getIdContact('external','RECEPTION'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + //Recipient name + // On peut utiliser le nom de la societe du contact + if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) { + $thirdparty = $object->contact; + } else { + $thirdparty = $object->thirdparty; + } + + $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs); + + $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,(!empty($object->contact)?$object->contact:null),$usecontact,'targetwithdetails',$object); + + // Show recipient + $widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100; + if ($this->page_largeur < 210) $widthrecbox=84; // To work with US executive format + $posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posx=$this->page_largeur - $this->marge_droite - $widthrecbox; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche; + + // Show recipient frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx+2,$posy-5); + $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("Recipient").":", 0, 'L'); + $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); + + // Show recipient name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); + + // Show recipient information + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + } + + $pdf->SetTextColor(0,0,0); + } + + /** + * Show footer of page. Need this->emetteur object + * + * @param PDF $pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) + { + global $conf; + $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf,$outputlangs,'RECEPTION_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext); + } + +} + diff --git a/htdocs/core/modules/reception/index.html b/htdocs/core/modules/reception/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/core/modules/reception/mod_reception_beryl.php b/htdocs/core/modules/reception/mod_reception_beryl.php new file mode 100644 index 00000000000..2b17d5ee0f0 --- /dev/null +++ b/htdocs/core/modules/reception/mod_reception_beryl.php @@ -0,0 +1,145 @@ + + * + * 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 . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/reception/mod_reception_beryl.php + * \ingroup reception + * \brief File of class to manage shipments numbering rules Beryl + */ +require_once DOL_DOCUMENT_ROOT .'/core/modules/reception/modules_reception.php'; + +/** + * Class to manage reception numbering rules Beryl + */ +class mod_reception_beryl extends ModelNumRefReception +{ + var $version='dolibarr'; + var $prefix='RCP'; + var $error=''; + var $nom='Beryl'; + + + /** + * Return default description of numbering model + * + * @return string text description + */ + function info() + { + global $langs; + return $langs->trans("SimpleNumRefModelDesc",$this->prefix); + } + + + /** + * Return numbering example + * + * @return string Example + */ + function getExample() + { + return $this->prefix."0501-0001"; + } + + + /** + * Test if existing numbers make problems with numbering + * + * @return boolean false if conflit, true if ok + */ + function canBeActivated() + { + global $conf,$langs,$db; + + $coyymm=''; $max=''; + + $posindice=8; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql.= " FROM ".MAIN_DB_PREFIX."reception"; + $sql.= " WHERE ref LIKE '".$this->prefix."____-%'"; + $sql.= " AND entity = ".$conf->entity; + + $resql=$db->query($sql); + if ($resql) + { + $row = $db->fetch_row($resql); + if ($row) { $coyymm = substr($row[0],0,6); $max=$row[0]; } + } + if ($coyymm && ! preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i',$coyymm)) + { + $langs->load("errors"); + $this->error=$langs->trans('ErrorNumRefModel', $max); + return false; + } + + return true; + } + + /** + * Return next value + * + * @param Societe $objsoc Third party object + * @param Object $shipment Shipment object + * @return string Value if OK, 0 if KO + */ + function getNextValue($objsoc,$shipment) + { + global $db,$conf; + + $posindice=8; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql.= " FROM ".MAIN_DB_PREFIX."reception"; + $sql.= " WHERE ref like '".$this->prefix."____-%'"; + $sql.= " AND entity = ".$conf->entity; + + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + if ($obj) $max = intval($obj->max); + else $max=0; + } + else + { + dol_syslog("mod_reception_beryl::getNextValue", LOG_DEBUG); + return -1; + } + + $date=time(); + $yymm = strftime("%y%m",$date); + + if ($max >= (pow(10, 4) - 1)) $num=$max+1; // If counter > 9999, we do not format on 4 chars, we take number as it is + else $num = sprintf("%04s",$max+1); + + dol_syslog("mod_reception_beryl::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + } + + /** + * Return next free value + * + * @param Societe $objsoc Third party object + * @param Object $objforref Shipment object + * @return string Next free value + */ + function reception_get_num($objsoc,$objforref) + { + return $this->getNextValue($objsoc,$objforref); + } + +} diff --git a/htdocs/core/modules/reception/mod_reception_moonstone.php b/htdocs/core/modules/reception/mod_reception_moonstone.php new file mode 100644 index 00000000000..0c661e12cbe --- /dev/null +++ b/htdocs/core/modules/reception/mod_reception_moonstone.php @@ -0,0 +1,137 @@ + + * + * 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 . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/reception/mod_reception_moonstone.php + * \ingroup reception + * \brief File of class to manage reception numbering rules Moonstone + */ + +require_once DOL_DOCUMENT_ROOT .'/core/modules/reception/modules_reception.php'; + +/** + * Class to manage reception numbering rules Moonstone + */ +class mod_reception_moonstone extends ModelNumRefReception +{ + var $version='dolibarr'; + var $error = ''; + var $nom = 'Moonstone'; + + /** + * Return default description of numbering model + * + * @return string text description + */ + function info() + { + global $conf,$langs; + + $langs->load("bills"); + + $form = new Form($this->db); + + $texte = $langs->trans('GenericNumRefModelDesc')."
\n"; + $texte.= '
'; + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= ''; + + $tooltip=$langs->trans("GenericMaskCodes",$langs->transnoentities("Reception"),$langs->transnoentities("Reception")); + $tooltip.=$langs->trans("GenericMaskCodes2"); + $tooltip.=$langs->trans("GenericMaskCodes3"); + $tooltip.=$langs->trans("GenericMaskCodes4a",$langs->transnoentities("Reception"),$langs->transnoentities("Reception")); + $tooltip.=$langs->trans("GenericMaskCodes5"); + + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= ''; + $texte.= '
'.$langs->trans("Mask").':'.$form->textwithpicto('',$tooltip,1,1).' 
'; + $texte.= '
'; + + return $texte; + } + + /** + * Return numbering example + * + * @return string Example + */ + function getExample() + { + global $conf,$langs,$mysoc; + + $old_code_client=$mysoc->code_client; + $old_code_type=$mysoc->typent_code; + $mysoc->code_client='CCCCCCCCCC'; + $mysoc->typent_code='TTTTTTTTTT'; + $numExample = $this->getNextValue($mysoc,''); + $mysoc->code_client=$old_code_client; + $mysoc->typent_code=$old_code_type; + + if (! $numExample) + { + $numExample = $langs->trans('NotConfigured'); + } + return $numExample; + } + + /** + * Return next value + * + * @param Societe $objsoc Third party object + * @param Object $reception Reception object + * @return string Value if OK, 0 if KO + */ + function getNextValue($objsoc,$reception) + { + global $db,$conf; + + require_once DOL_DOCUMENT_ROOT .'/core/lib/functions2.lib.php'; + + $mask=$conf->global->RECEPTION_MOONSTONE_MASK; + + if (! $mask) + { + $this->error='NotConfigured'; + return 0; + } + + $date = $reception->date_reception; + + $numFinal=get_next_value($db,$mask,'reception','ref','',$objsoc,$date); + + return $numFinal; + } + + /** + * Return next free value + * + * @param Societe $objsoc Third party object + * @param Object $objforref Reception object + * @return string Next free value + */ + function reception_get_num($objsoc,$objforref) + { + return $this->getNextValue($objsoc,$objforref); + } + +} + diff --git a/htdocs/core/modules/reception/modules_reception.php b/htdocs/core/modules/reception/modules_reception.php new file mode 100644 index 00000000000..609e5e315ad --- /dev/null +++ b/htdocs/core/modules/reception/modules_reception.php @@ -0,0 +1,136 @@ + + * + * 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 . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/reception/modules_reception.php + * \ingroup reception + * \brief File that contains parent class for sending receipts models + * and parent class for sending receipts numbering models + */ + require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; + +/** + * Parent class of sending receipts models + */ +abstract class ModelePdfReception extends CommonDocGenerator +{ + var $error=''; + + + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + static function liste_modeles($db,$maxfilenamelength=0) + { + global $conf; + + $type='reception'; + $liste=array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $liste=getListOfModels($db,$type,$maxfilenamelength); + + return $liste; + } +} + + +/** + * Parent Class of numbering models of sending receipts references + */ +abstract class ModelNumRefReception +{ + var $error=''; + + /** Return if a model can be used or not + * + * @return boolean true if model can be used + */ + function isEnabled() + { + return true; + } + + /** + * Return default description of numbering model + * + * @return string text description + */ + function info() + { + global $langs; + $langs->load("reception"); + return $langs->trans("NoDescription"); + } + + /** + * Returns numbering example + * + * @return string Example + */ + function getExample() + { + global $langs; + $langs->load("reception"); + return $langs->trans("NoExample"); + } + + /** + * Test if existing numbers make problems with numbering + * + * @return boolean false if conflit, true if ok + */ + function canBeActivated() + { + return true; + } + + /** + * Returns next value assigned + * + * @param Societe $objsoc Third party object + * @param Object $shipment Shipment object + * @return string Value + */ + function getNextValue($objsoc, $shipment) + { + global $langs; + return $langs->trans("NotAvailable"); + } + + /** + * Returns version of the numbering model + * + * @return string Value + */ + function getVersion() + { + global $langs; + $langs->load("admin"); + + if ($this->version == 'development') return $langs->trans("VersionDevelopment"); + if ($this->version == 'experimental') return $langs->trans("VersionExperimental"); + if ($this->version == 'dolibarr') return DOL_VERSION; + if ($this->version) return $this->version; + return $langs->trans("NotAvailable"); + } +} diff --git a/htdocs/install/mysql/tables/llx_reception.key.sql b/htdocs/install/mysql/tables/llx_reception.key.sql new file mode 100644 index 00000000000..736945193ff --- /dev/null +++ b/htdocs/install/mysql/tables/llx_reception.key.sql @@ -0,0 +1,31 @@ +-- =================================================================== +-- Copyright (C) 2005 Laurent Destailleur +-- Copyright (C) 2008-2010 Regis Houssin +-- +-- 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 . +-- +-- =================================================================== + + +ALTER TABLE llx_expedition ADD UNIQUE INDEX idx_expedition_uk_ref (ref, entity); + +ALTER TABLE llx_expedition ADD INDEX idx_expedition_fk_soc (fk_soc); +ALTER TABLE llx_expedition ADD INDEX idx_expedition_fk_user_author (fk_user_author); +ALTER TABLE llx_expedition ADD INDEX idx_expedition_fk_user_valid (fk_user_valid); +ALTER TABLE llx_expedition ADD INDEX idx_expedition_fk_shipping_method (fk_shipping_method); + +ALTER TABLE llx_expedition ADD CONSTRAINT fk_expedition_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); +ALTER TABLE llx_expedition ADD CONSTRAINT fk_expedition_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); +ALTER TABLE llx_expedition ADD CONSTRAINT fk_expedition_fk_user_valid FOREIGN KEY (fk_user_valid) REFERENCES llx_user (rowid); +ALTER TABLE llx_expedition ADD CONSTRAINT fk_expedition_fk_shipping_method FOREIGN KEY (fk_shipping_method) REFERENCES llx_c_shipment_mode (rowid); diff --git a/htdocs/install/mysql/tables/llx_reception.sql b/htdocs/install/mysql/tables/llx_reception.sql new file mode 100644 index 00000000000..088e4893c06 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_reception.sql @@ -0,0 +1,62 @@ +-- =================================================================== +-- Copyright (C) 2003-2010 Rodolphe Quiedeville +-- Copyright (C) 2008-2010 Regis Houssin +-- Copyright (C) 2011-2012 Laurent Destailleur +-- Copyright (C) 2012 Juanjo Menent +-- +-- 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 . +-- +-- =================================================================== + +create table llx_expedition +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + ref varchar(30) NOT NULL, + entity integer DEFAULT 1 NOT NULL, -- multi company id + fk_soc integer NOT NULL, + fk_projet integer DEFAULT NULL, + + ref_ext varchar(30), -- reference into an external system (not used by dolibarr) + ref_int varchar(30), -- reference into an internal system (used by dolibarr to store extern id like paypal info) + ref_customer varchar(30), -- customer number + + date_creation datetime, -- date de creation + fk_user_author integer, -- author of creation + fk_user_modif integer, -- author of last change + date_valid datetime, -- date de validation + fk_user_valid integer, -- valideur + date_delivery datetime DEFAULT NULL, -- date planned of delivery + date_expedition datetime, -- not used (deprecated) + fk_address integer DEFAULT NULL, -- delivery address (deprecated) + fk_shipping_method integer, + tracking_number varchar(50), + fk_statut smallint DEFAULT 0, -- 0 = draft, 1 = validated, 2 = billed or closed depending on WORKFLOW_BILL_ON_SHIPMENT option + billed smallint DEFAULT 0, + + height float, -- height + width float, -- with + size_units integer, -- unit of all sizes (height, width, depth) + size float, -- depth + weight_units integer, -- unit of weight + weight float, -- weight + note_private text, + note_public text, + model_pdf varchar(255), + fk_incoterms integer, -- for incoterms + location_incoterms varchar(255), -- for incoterms + + import_key varchar(14), + extraparams varchar(255) -- for other parameters with json format +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_reception_extrafields.key.sql b/htdocs/install/mysql/tables/llx_reception_extrafields.key.sql new file mode 100644 index 00000000000..b539f460a08 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_reception_extrafields.key.sql @@ -0,0 +1,20 @@ +-- =================================================================== +-- Copyright (C) 2015 Claudio Aschieri +-- +-- 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 . +-- +-- =================================================================== + + +ALTER TABLE llx_expedition_extrafields ADD INDEX idx_expedition_extrafields (fk_object); diff --git a/htdocs/install/mysql/tables/llx_reception_extrafields.sql b/htdocs/install/mysql/tables/llx_reception_extrafields.sql new file mode 100644 index 00000000000..eff8465fbf6 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_reception_extrafields.sql @@ -0,0 +1,26 @@ +-- ======================================================================== +-- Copyright (C) 2015 Claudio Aschieri +-- +-- 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 . +-- +-- ======================================================================== + +create table llx_expedition_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_receptiondet.key.sql b/htdocs/install/mysql/tables/llx_receptiondet.key.sql new file mode 100644 index 00000000000..5f5b6a08183 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_receptiondet.key.sql @@ -0,0 +1,22 @@ +-- =================================================================== +-- Copyright (C) 2005 Laurent Destailleur +-- Copyright (C) 2008 Regis Houssin +-- +-- 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 . +-- +-- =================================================================== + + +ALTER TABLE llx_expeditiondet ADD INDEX idx_expeditiondet_fk_expedition (fk_expedition); +ALTER TABLE llx_expeditiondet ADD CONSTRAINT fk_expeditiondet_fk_expedition FOREIGN KEY (fk_expedition) REFERENCES llx_expedition (rowid); diff --git a/htdocs/install/mysql/tables/llx_receptiondet.sql b/htdocs/install/mysql/tables/llx_receptiondet.sql new file mode 100644 index 00000000000..bd05bd08898 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_receptiondet.sql @@ -0,0 +1,29 @@ +-- =================================================================== +-- Copyright (C) 2003 Rodolphe Quiedeville +-- Copyright (C) 2008 Regis Houssin +-- Copyright (C) 2011 Laurent Destailleur +-- +-- 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 . +-- +-- =================================================================== + +create table llx_expeditiondet +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_expedition integer NOT NULL, + fk_origin_line integer, -- Correspondance de la ligne avec le document d'origine (propal, commande) + fk_entrepot integer, -- Entrepot de depart du produit + qty real, -- Quantity + rang integer DEFAULT 0 +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql b/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql new file mode 100644 index 00000000000..70bfe974f34 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql @@ -0,0 +1,20 @@ +-- ============================================================================ +-- Copyright (C) 2014 Cédric GROSS +-- +-- 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 . +-- +-- ============================================================================ + +ALTER TABLE llx_expeditiondet_batch ADD INDEX idx_fk_expeditiondet (fk_expeditiondet); +ALTER TABLE llx_expeditiondet_batch ADD CONSTRAINT fk_expeditiondet_batch_fk_expeditiondet FOREIGN KEY (fk_expeditiondet) REFERENCES llx_expeditiondet(rowid); diff --git a/htdocs/install/mysql/tables/llx_receptiondet_batch.sql b/htdocs/install/mysql/tables/llx_receptiondet_batch.sql new file mode 100644 index 00000000000..2a1234d9342 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_receptiondet_batch.sql @@ -0,0 +1,27 @@ +-- ============================================================================ +-- Copyright (C) 2014 Cédric GROSS +-- +-- 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 . +-- +-- ============================================================================ +CREATE TABLE llx_expeditiondet_batch ( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_expeditiondet int NOT NULL, + eatby date DEFAULT NULL, + sellby date DEFAULT NULL, + batch varchar(30) DEFAULT NULL, + qty double NOT NULL DEFAULT '0', + fk_origin_stock integer NOT NULL +) ENGINE=InnoDB; + diff --git a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql b/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql new file mode 100644 index 00000000000..11e133442d5 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql @@ -0,0 +1,20 @@ +-- =================================================================== +-- Copyright (C) 2015 Claudio Aschieri +-- +-- 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 . +-- +-- =================================================================== + + +ALTER TABLE llx_expeditiondet_extrafields ADD INDEX idx_expeditiondet_extrafields (fk_object); diff --git a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql b/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql new file mode 100644 index 00000000000..e27c7f3e505 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql @@ -0,0 +1,25 @@ +-- =================================================================== +-- Copyright (C) 2015 Claudio Aschieri +-- +-- 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 . +-- +-- =================================================================== + +create table llx_expeditiondet_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, -- object id + import_key varchar(14) -- import key +)ENGINE=innodb; diff --git a/htdocs/langs/en_US/receptions.lang b/htdocs/langs/en_US/receptions.lang new file mode 100644 index 00000000000..51e6ab06e89 --- /dev/null +++ b/htdocs/langs/en_US/receptions.lang @@ -0,0 +1,70 @@ +# Dolibarr language file - Source file is en_US - receptions +RefReception=Ref. reception +Reception=Reception +Receptions=Receptions +AllReceptions=All Receptions +Reception=Reception +Receptions=Receptions +ShowReception=Show Receptions +Receivings=Delivery Receipts +ReceptionsArea=Receptions area +ListOfReceptions=List of receptions +ReceptionMethod=Shipping method +LastReceptions=Latest %s receptions +StatisticsOfReceptions=Statistics for receptions +NbOfReceptions=Number of receptions +NumberOfReceptionsByMonth=Number of receptions by month +ReceptionCard=Reception card +NewReception=New reception +CreateReception=Create reception +QtyShipped=Qty shipped +QtyPreparedOrShipped=Qty prepared or shipped +QtyToShip=Qty to ship +QtyReceived=Qty received +QtyInOtherReceptions=Qty in other receptions +KeepToShip=Remain to ship +OtherReceptionsForSameOrder=Other receptions for this order +ReceptionsAndReceivingForSameOrder=Receptions and receipts for this order +ReceptionsToValidate=Receptions to validate +StatusReceptionCanceled=Canceled +StatusReceptionDraft=Draft +StatusReceptionValidated=Validated (products to ship or already shipped) +StatusReceptionProcessed=Processed +StatusReceptionDraftShort=Draft +StatusReceptionValidatedShort=Validated +StatusReceptionProcessedShort=Processed +ReceptionSheet=Reception sheet +ConfirmDeleteReception=Are you sure you want to delete this reception? +ConfirmValidateReception=Are you sure you want to validate this reception with reference %s? +ConfirmCancelReception=Are you sure you want to cancel this reception? +DocumentModelMerou=Merou A5 model +WarningNoQtyLeftToSend=Warning, no products waiting to be shipped. +StatsOnReceptionsOnlyValidated=Statistics conducted on receptions only validated. Date used is date of validation of reception (planed delivery date is not always known). +DateDeliveryPlanned=Planned date of delivery +RefDeliveryReceipt=Ref delivery receipt +StatusReceipt=Status delivery receipt +DateReceived=Date delivery received +SendShippingByEMail=Send reception by EMail +SendShippingRef=Submission of reception %s +ActionsOnShipping=Events on reception +LinkToTrackYourPackage=Link to track your package +ReceptionCreationIsDoneFromOrder=For the moment, creation of a new reception is done from the order card. +ReceptionLine=Reception line +ProductQtyInCustomersOrdersRunning=Product quantity into open customers orders +ProductQtyInSuppliersOrdersRunning=Product quantity into open suppliers orders +ProductQtyInReceptionAlreadySent=Product quantity from open customer order already sent +ProductQtyInSuppliersReceptionAlreadyRecevied=Product quantity from open supplier order already received +NoProductToShipFoundIntoStock=No product to ship found into warehouse %s. Correct stock or go back to choose another warehouse. +WeightVolShort=Weight/Vol. +ValidateOrderFirstBeforeReception=You must first validate the order before being able to make receptions. + +# Reception methods +# ModelDocument +DocumentModelTyphon=More complete document model for delivery receipts (logo...) +Error_EXPEDITION_ADDON_NUMBER_NotDefined=Constant EXPEDITION_ADDON_NUMBER not defined +SumOfProductVolumes=Sum of product volumes +SumOfProductWeights=Sum of product weights + +# warehouse details +DetailWarehouseNumber= Warehouse details +DetailWarehouseFormat= W:%s (Qty : %d) diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index a5338997eb2..bfe6e81858c 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1438,6 +1438,13 @@ SendingsNumberingModules=Modèles de numérotation des expéditions SendingsAbility=Prise en charge des bons d'expédition pour les livraisons clients NoNeedForDeliveryReceipts=Dans le plupart des cas, la fiche expédition est utilisée en tant que bon d'expédition (liste des produits expédiés) et bon de livraison (signée par le client). Le bon de réception est un doublon de fonctionnalité et est rarement utilisé. FreeLegalTextOnShippings=Mention complémentaire sur les expéditions +##### Reception ##### +ReceptionsSetup=Configuration du module Réception/Livraison +ReceptionsReceiptModel=Modèles de bordereau de réception +ReceptionsNumberingModules=Modèles de numérotation des réceptions +ReceptionsAbility=Prise en charge des bons d'réception pour les livraisons clients +NoNeedForDeliveryReceipts=Dans le plupart des cas, la fiche réception est utilisée en tant que bon d'réception (liste des produits expédiés) et bon de livraison (signée par le client). Le bon de réception est un doublon de fonctionnalité et est rarement utilisé. +FreeLegalTextOnShippings=Mention complémentaire sur les réceptions ##### Deliveries ##### DeliveryOrderNumberingModules=Modèle de numérotation des bons de réception client DeliveryOrderModel=Modèle de bon de réception client diff --git a/htdocs/langs/fr_FR/receptions.lang b/htdocs/langs/fr_FR/receptions.lang new file mode 100644 index 00000000000..7522dc6eb51 --- /dev/null +++ b/htdocs/langs/fr_FR/receptions.lang @@ -0,0 +1,70 @@ +# Dolibarr language file - Source file is en_US - sendings +RefReception=Réf. réception +Reception=Réception +Receptions=Réceptions +AllReceptions=Toutes les réceptions +Shipment=Réception +Shipments=Réceptions +ShowReception=Afficher Réceptions +Receivings=Bons de réceptions +ReceptionsArea=Espace réceptions +ListOfReceptions=Liste des réceptions +ReceptionMethod=Méthode d'réception +LastReceptions=Les %s dernières réceptions +StatisticsOfReceptions=Statistiques des réceptions +NbOfReceptions=Nombre d'réceptions +NumberOfShipmentsByMonth=Nombre d'réceptions par mois +ReceptionCard=Fiche réception +NewReception=Nouvelle réception +CreateShipment=Créer réception +QtyShipped=Qté. expédiée +QtyPreparedOrShipped=Quantité préparée ou envoyée +QtyToShip=Qté. à expédier +QtyReceived=Qté. reçue +QtyInOtherShipments=Qté dans les autres réceptions +KeepToShip=Reste à expédier +OtherReceptionsForSameOrder=Autres réceptions pour cette commande +ReceptionsAndReceivingForSameOrder=Réceptions et réceptions pour cette commande +ReceptionsToValidate=Réceptions à valider +StatusReceptionCanceled=Annulée +StatusReceptionDraft=Brouillon +StatusReceptionValidated=Validée (produits à envoyer ou envoyés) +StatusReceptionProcessed=Traitée +StatusReceptionDraftShort=Brouillon +StatusReceptionValidatedShort=Validée +StatusReceptionProcessedShort=Traitée +ReceptionSheet=Fiche réception +ConfirmDeleteReception=Êtes-vous sûr de vouloir supprimer cette réception ? +ConfirmValidateReception=Êtes-vous sûr de vouloir valider cette réception sous la référence %s? +ConfirmCancelReception=Êtes-vous sûr de vouloir annuler cette réception ? +DocumentModelMerou=Modèle Merou A5 +WarningNoQtyLeftToSend=Alerte, aucun produit en attente d'réception. +StatsOnShipmentsOnlyValidated=Statistiques effectuées sur les réceptions validées uniquement. La date prise en compte est la date de validation (la date de prévision de livraison n'étant pas toujours renseignée). +DateDeliveryPlanned=Date prévue de livraison +RefDeliveryReceipt=Ref bon de réception +StatusReceipt=Status du bon de réception +DateReceived=Date de réception réelle +SendShippingByEMail=Envoyer bon d'réception par email +SendShippingRef=Envoi du bordereau d'réception %s +ActionsOnShipping=Événements sur l'réception +LinkToTrackYourPackage=Lien pour le suivi de votre colis +ShipmentCreationIsDoneFromOrder=Pour le moment, la création d'une nouvelle réception se fait depuis la fiche commande. +ShipmentLine=Ligne d'réception +ProductQtyInCustomersOrdersRunning=Quantité de produit en commandes client ouvertes +ProductQtyInSuppliersOrdersRunning=Quantité de produit en commandes fournisseur ouvertes +ProductQtyInShipmentAlreadySent=Quantité de produit en commande client ouverte déjà expédiée +ProductQtyInSuppliersShipmentAlreadyRecevied=Quantité de produit déjà reçu en commandes fournisseur ouvertes +NoProductToShipFoundIntoStock=Aucun produit à expédier n'a été trouver dans l'entrepôt %s. Corrigez l'inventaire ou retourner choisir un autre entrepôt. +WeightVolShort=Poids/vol. +ValidateOrderFirstBeforeShipment=Vous devez d'abord valider la commande pour pouvoir créer une réception. + +# Reception methods +# ModelDocument +DocumentModelTyphon=Modèle de bon de réception/livraison complet (logo…) +Error_EXPEDITION_ADDON_NUMBER_NotDefined=Constante EXPEDITION_ADDON_NUMBER non définie +SumOfProductVolumes=Somme des volumes des produits +SumOfProductWeights=Somme des poids des produits + +# warehouse details +DetailWarehouseNumber= Détail de l'entrepôt +DetailWarehouseFormat= W:%s (Qté : %d) diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php new file mode 100644 index 00000000000..fbe7d81622c --- /dev/null +++ b/htdocs/reception/card.php @@ -0,0 +1,2754 @@ + + * Copyright (C) 2005-2016 Laurent Destailleur + * Copyright (C) 2005 Simon TOSSER + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2011-2017 Juanjo Menent + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2013 Marcos García + * Copyright (C) 2014 Cedric GROSS + * Copyright (C) 2014-2017 Francis Appels + * Copyright (C) 2015 Claudio Aschieri + * Copyright (C) 2016 Ferran Marcet + * Copyright (C) 2016 Yasser Carreón + * + * 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 . + */ + +/** + * \file htdocs/expedition/card.php + * \ingroup expedition + * \brief Card of a shipment + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.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.'/product/stock/class/entrepot.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; +if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +if (! empty($conf->productbatch->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; +if (! empty($conf->projet->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} + +$langs->loadLangs(array("sendings","companies","bills",'deliveries','orders','stocks','other','propal')); + +if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); +if (! empty($conf->productbatch->enabled)) $langs->load('productbatch'); + +$origin = GETPOST('origin','alpha')?GETPOST('origin','alpha'):'expedition'; // Example: commande, propal +$origin_id = GETPOST('id','int')?GETPOST('id','int'):''; +$id = $origin_id; +if (empty($origin_id)) $origin_id = GETPOST('origin_id','int'); // Id of order or propal +if (empty($origin_id)) $origin_id = GETPOST('object_id','int'); // Id of order or propal +$ref=GETPOST('ref','alpha'); +$line_id = GETPOST('lineid','int')?GETPOST('lineid','int'):''; + +// Security check +$socid=''; +if ($user->societe_id) $socid=$user->societe_id; + +if ($origin == 'expedition') $result=restrictedArea($user, $origin, $id); +else { + $result=restrictedArea($user, 'expedition'); + if (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) accessforbidden(); +} + +$action = GETPOST('action','alpha'); +$confirm = GETPOST('confirm','alpha'); +$cancel = GETPOST('cancel','alpha'); + +//PDF +$hidedetails = (GETPOST('hidedetails','int') ? GETPOST('hidedetails','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); +$hidedesc = (GETPOST('hidedesc','int') ? GETPOST('hidedesc','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); +$hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); + +$object = new Expedition($db); +$extrafields = new ExtraFields($db); +$extrafieldsline = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + +// fetch optionals attributes lines and labels +$extralabelslines=$extrafieldsline->fetch_name_optionals_label($object->table_element_line); + + +// Load object. Make an object->fetch +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('expeditioncard','globalcard')); + +$permissiondellink=$user->rights->expedition->livraison->creer; // Used by the include of actions_dellink.inc.php +//var_dump($object->lines[0]->detail_batch); + + +/* + * Actions + */ + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + if ($cancel) + { + $action = ''; + $object->fetch($id); // show shipment also after canceling modification + } + + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + + // Reopen + if ($action == 'reopen' && $user->rights->expedition->creer) + { + $object->fetch($id); + $result = $object->reOpen(); + } + + // Confirm back to draft status + if ($action == 'modif' && $user->rights->expedition->creer) + { + $result = $object->set_draft($user); + if ($result >= 0) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + } + + // Set incoterm + if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) + { + $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); + } + + if ($action == 'setref_customer') + { + $result = $object->fetch($id); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } + + $result = $object->setValueFrom('ref_customer', GETPOST('ref_customer','alpha'), '', null, 'text', '', $user, 'SHIPMENT_MODIFY'); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $action = 'editref_customer'; + } else { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + } + + if ($action == 'update_extras') + { + // Fill array 'array_options' with data from update form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) $error++; + + if (! $error) + { + // Actions on extra fields (by external module or standard code) + // TODO le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('expeditiondao')); + $parameters = array('id' => $object->id); + $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) { + $result = $object->insertExtraFields(); + if ($result < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } else if ($reshook < 0) + $error++; + } + + if ($error) + $action = 'edit_extras'; + } + + // Create shipment + if ($action == 'add' && $user->rights->expedition->creer) + { + $error=0; + $predef=''; + + $db->begin(); + + $object->note = GETPOST('note','alpha'); + $object->origin = $origin; + $object->origin_id = $origin_id; + $object->fk_project = GETPOST('projectid','int'); + $object->weight = GETPOST('weight','int')==''?"NULL":GETPOST('weight','int'); + $object->sizeH = GETPOST('sizeH','int')==''?"NULL":GETPOST('sizeH','int'); + $object->sizeW = GETPOST('sizeW','int')==''?"NULL":GETPOST('sizeW','int'); + $object->sizeS = GETPOST('sizeS','int')==''?"NULL":GETPOST('sizeS','int'); + $object->size_units = GETPOST('size_units','int'); + $object->weight_units = GETPOST('weight_units','int'); + + $date_delivery = dol_mktime(GETPOST('date_deliveryhour','int'), GETPOST('date_deliverymin','int'), 0, GETPOST('date_deliverymonth','int'), GETPOST('date_deliveryday','int'), GETPOST('date_deliveryyear','int')); + + // On va boucler sur chaque ligne du document d'origine pour completer objet expedition + // avec info diverses + qte a livrer + $classname = ucfirst($object->origin); + $objectsrc = new $classname($db); + $objectsrc->fetch($object->origin_id); + + $object->socid = $objectsrc->socid; + $object->ref_customer = GETPOST('ref_customer','alpha'); + $object->model_pdf = GETPOST('model'); + $object->date_delivery = $date_delivery; // Date delivery planed + $object->fk_delivery_address = $objectsrc->fk_delivery_address; + $object->shipping_method_id = GETPOST('shipping_method_id','int'); + $object->tracking_number = GETPOST('tracking_number','alpha'); + $object->ref_int = GETPOST('ref_int','alpha'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); + $object->fk_incoterms = GETPOST('incoterm_id', 'int'); + $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); + + $batch_line = array(); + $stockLine = array(); + $array_options=array(); + + $num=count($objectsrc->lines); + $totalqty=0; + + for ($i = 0; $i < $num; $i++) + { + $idl="idl".$i; + + $sub_qty=array(); + $subtotalqty=0; + + $j=0; + $batch="batchl".$i."_0"; + $stockLocation="ent1".$i."_0"; + $qty = "qtyl".$i; + + if ($objectsrc->lines[$i]->product_tobatch) // If product need a batch number + { + if (isset($_POST[$batch])) + { + //shipment line with batch-enable product + $qty .= '_'.$j; + while (isset($_POST[$batch])) + { + // save line of detail into sub_qty + $sub_qty[$j]['q']=GETPOST($qty,'int'); // the qty we want to move for this stock record + $sub_qty[$j]['id_batch']=GETPOST($batch,'int'); // the id into llx_product_batch of stock record to move + $subtotalqty+=$sub_qty[$j]['q']; + + //var_dump($qty);var_dump($batch);var_dump($sub_qty[$j]['q']);var_dump($sub_qty[$j]['id_batch']); + + $j++; + $batch="batchl".$i."_".$j; + $qty = "qtyl".$i.'_'.$j; + } + + $batch_line[$i]['detail']=$sub_qty; // array of details + $batch_line[$i]['qty']=$subtotalqty; + $batch_line[$i]['ix_l']=GETPOST($idl,'int'); + + $totalqty+=$subtotalqty; + } + else + { + // No detail were provided for lots + if (! empty($_POST[$qty])) + { + // We try to set an amount + // Case we dont use the list of available qty for each warehouse/lot + // GUI does not allow this yet + setEventMessage('StockIsRequiredToChooseWhichLotToUse', 'errors'); + } + } + } + else if (isset($_POST[$stockLocation])) + { + //shipment line from multiple stock locations + $qty .= '_'.$j; + while (isset($_POST[$stockLocation])) + { + // save sub line of warehouse + $stockLine[$i][$j]['qty']=GETPOST($qty,'int'); + $stockLine[$i][$j]['warehouse_id']=GETPOST($stockLocation,'int'); + $stockLine[$i][$j]['ix_l']=GETPOST($idl,'int'); + + $totalqty+=GETPOST($qty,'int'); + + $j++; + $stockLocation="ent1".$i."_".$j; + $qty = "qtyl".$i.'_'.$j; + } + } + else + { + //var_dump(GETPOST($qty,'int')); var_dump($_POST); var_dump($batch);exit; + //shipment line for product with no batch management and no multiple stock location + if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int'); + } + + // Extrafields + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_options[$i] = $extrafieldsline->getOptionalsFromPost($extralabelsline, $i); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + } + + //var_dump($batch_line[2]); + + if ($totalqty > 0) // There is at least one thing to ship + { + //var_dump($_POST);exit; + for ($i = 0; $i < $num; $i++) + { + $qty = "qtyl".$i; + if (! isset($batch_line[$i])) + { + // not batch mode + if (isset($stockLine[$i])) + { + //shipment from multiple stock locations + $nbstockline = count($stockLine[$i]); + for($j = 0; $j < $nbstockline; $j++) + { + if ($stockLine[$i][$j]['qty']>0) + { + $ret=$object->addline($stockLine[$i][$j]['warehouse_id'], $stockLine[$i][$j]['ix_l'], $stockLine[$i][$j]['qty'], $array_options[$i]); + if ($ret < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } + } + } + else + { + if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS)) + { + $ent = "entl".$i; + $idl = "idl".$i; + $entrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):GETPOST('entrepot_id','int'); + if ($entrepot_id < 0) $entrepot_id=''; + if (! ($objectsrc->lines[$i]->fk_product > 0)) $entrepot_id = 0; + + $ret=$object->addline($entrepot_id, GETPOST($idl,'int'), GETPOST($qty,'int'), $array_options[$i]); + if ($ret < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } + } + } + else + { + // batch mode + if ($batch_line[$i]['qty']>0) + { + $ret=$object->addline_batch($batch_line[$i],$array_options[$i]); + if ($ret < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } + } + } + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) $error++; + + if (! $error) + { + $ret=$object->create($user); // This create shipment (like Odoo picking) and line of shipments. Stock movement will when validating shipment. + if ($ret <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } + } + else + { + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("QtyToShip").'/'.$langs->transnoentitiesnoconv("Warehouse")), null, 'errors'); + $error++; + } + + if (! $error) + { + $db->commit(); + header("Location: card.php?id=".$object->id); + exit; + } + else + { + $db->rollback(); + $_GET["commande_id"]=GETPOST('commande_id','int'); + $action='create'; + } + } + + /* + * Build a receiving receipt + */ + else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer) + { + $result = $object->create_delivery($user); + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT.'/livraison/card.php?action=create_delivery&id='.$result); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + else if ($action == 'confirm_valid' && $confirm == 'yes' && + ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->shipping_advance->validate))) + ) + { + $object->fetch_thirdparty(); + + $result = $object->valid($user); + + if ($result < 0) + { + $langs->load("errors"); + setEventMessages($langs->trans($object->error), null, 'errors'); + } + else + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result < 0) dol_print_error($db,$result); + } + } + } + + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer) + { + $result = $object->delete(); + if ($result > 0) + { + header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + // TODO add alternative status + /*else if ($action == 'reopen' && (! empty($user->rights->expedition->creer) || ! empty($user->rights->expedition->shipping_advance->validate))) + { + $result = $object->setStatut(0); + if ($result < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } + }*/ + + else if ($action == 'setdate_livraison' && $user->rights->expedition->creer) + { + //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; + $datedelivery=dol_mktime(GETPOST('liv_hour','int'), GETPOST('liv_min','int'), 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'), GETPOST('liv_year','int')); + + $object->fetch($id); + $result=$object->set_date_livraison($user,$datedelivery); + if ($result < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + // Action update + else if ($action == 'settracking_number' || $action == 'settracking_url' + || $action == 'settrueWeight' + || $action == 'settrueWidth' + || $action == 'settrueHeight' + || $action == 'settrueDepth' + || $action == 'setshipping_method_id') + { + $error=0; + + if ($action == 'settracking_number') $object->tracking_number = trim(GETPOST('tracking_number','alpha')); + if ($action == 'settracking_url') $object->tracking_url = trim(GETPOST('tracking_url','int')); + if ($action == 'settrueWeight') { + $object->trueWeight = trim(GETPOST('trueWeight','int')); + $object->weight_units = GETPOST('weight_units','int'); + } + if ($action == 'settrueWidth') $object->trueWidth = trim(GETPOST('trueWidth','int')); + if ($action == 'settrueHeight'){ + $object->trueHeight = trim(GETPOST('trueHeight','int')); + $object->size_units = GETPOST('size_units','int'); + } + if ($action == 'settrueDepth') $object->trueDepth = trim(GETPOST('trueDepth','int')); + if ($action == 'setshipping_method_id') $object->shipping_method_id = trim(GETPOST('shipping_method_id','int')); + + if (! $error) + { + if ($object->update($user) >= 0) + { + header("Location: card.php?id=".$object->id); + exit; + } + setEventMessages($object->error, $object->errors, 'errors'); + } + + $action=""; + } + + // Build document + else if ($action == 'builddoc') // En get ou en post + { + // Save last template used to generate document + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang=GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$shipment->thirdparty->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $action=''; + } + } + + // Delete file in doc form + elseif ($action == 'remove_file') + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $upload_dir = $conf->expedition->dir_output . "/sending"; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); + else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); + } + + elseif ($action == 'classifybilled') + { + $object->fetch($id); + $result = $object->set_billed(); + if($result >= 0) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit(); + } + } + + elseif ($action == 'classifyclosed') + { + $object->fetch($id); + $result = $object->setClosed(); + if($result >= 0) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit(); + } + } + + /* + * delete a line + */ + elseif ($action == 'deleteline' && ! empty($line_id)) + { + $object->fetch($id); + $lines = $object->lines; + $line = new ExpeditionLigne($db); + + $num_prod = count($lines); + for ($i = 0 ; $i < $num_prod ; $i++) + { + if ($lines[$i]->id == $line_id) + { + if (count($lines[$i]->details_entrepot) > 1) + { + // delete multi warehouse lines + foreach ($lines[$i]->details_entrepot as $details_entrepot) { + $line->id = $details_entrepot->line_id; + if (! $error && $line->delete($user) < 0) + { + $error++; + } + } + } + else + { + // delete single warehouse line + $line->id = $line_id; + if (! $error && $line->delete($user) < 0) + { + $error++; + } + } + } + unset($_POST["lineid"]); + } + + if(! $error) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit(); + } + else + { + setEventMessages($line->error, $line->errors, 'errors'); + } + } + + /* + * Update a line + */ + else if ($action == 'updateline' && $user->rights->expedition->creer && GETPOST('save')) + { + // Clean parameters + $qty=0; + $entrepot_id = 0; + $batch_id = 0; + + $lines = $object->lines; + $num_prod = count($lines); + for ($i = 0 ; $i < $num_prod ; $i++) + { + if ($lines[$i]->id == $line_id) // we have found line to update + { + $line = new ExpeditionLigne($db); + // Extrafields Lines + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $line->array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline); + // Unset extrafield POST Data + if (is_array($extralabelsline)) { + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + $line->fk_product = $lines[$i]->fk_product; + if (is_array($lines[$i]->detail_batch) && count($lines[$i]->detail_batch) > 0) + { + // line with lot + foreach ($lines[$i]->detail_batch as $detail_batch) + { + $lotStock = new Productbatch($db); + $batch="batchl".$detail_batch->fk_expeditiondet."_".$detail_batch->fk_origin_stock; + $qty = "qtyl".$detail_batch->fk_expeditiondet.'_'.$detail_batch->id; + $batch_id = GETPOST($batch,'int'); + $batch_qty = GETPOST($qty, 'int'); + if (! empty($batch_id) && ($batch_id != $detail_batch->fk_origin_stock || $batch_qty != $detail_batch->dluo_qty)) + { + if ($lotStock->fetch($batch_id) > 0 && $line->fetch($detail_batch->fk_expeditiondet) > 0) // $line is ExpeditionLine + { + if ($lines[$i]->entrepot_id != 0) + { + // allow update line entrepot_id if not multi warehouse shipping + $line->entrepot_id = $lotStock->warehouseid; + } + + // detail_batch can be an object with keys, or an array of ExpeditionLineBatch + if (empty($line->detail_batch)) $line->detail_batch=new stdClass(); + + $line->detail_batch->fk_origin_stock = $batch_id; + $line->detail_batch->batch = $lotStock->batch; + $line->detail_batch->id = $detail_batch->id; + $line->detail_batch->entrepot_id = $lotStock->warehouseid; + $line->detail_batch->dluo_qty = $batch_qty; + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + else + { + setEventMessages($lotStock->error, $lotStock->errors, 'errors'); + $error++; + } + } + unset($_POST[$batch]); + unset($_POST[$qty]); + } + // add new batch + $lotStock = new Productbatch($db); + $batch="batchl".$line_id."_0"; + $qty = "qtyl".$line_id."_0"; + $batch_id = GETPOST($batch,'int'); + $batch_qty = GETPOST($qty, 'int'); + $lineIdToAddLot = 0; + if ($batch_qty > 0 && ! empty($batch_id)) + { + if ($lotStock->fetch($batch_id) > 0) + { + // check if lotStock warehouse id is same as line warehouse id + if ($lines[$i]->entrepot_id > 0) + { + // single warehouse shipment line + if ($lines[i]->entrepot_id == $lotStock->warehouseid) + { + $lineIdToAddLot = $line_id; + } + } + else if (count($lines[$i]->details_entrepot) > 1) + { + // multi warehouse shipment lines + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + if ($detail_entrepot->entrepot_id == $lotStock->warehouseid) + { + $lineIdToAddLot = $detail_entrepot->line_id; + } + } + } + if ($lineIdToAddLot) + { + // add lot to existing line + if ($line->fetch($lineIdToAddLot) > 0) + { + $line->detail_batch->fk_origin_stock = $batch_id; + $line->detail_batch->batch = $lotStock->batch; + $line->detail_batch->entrepot_id = $lotStock->warehouseid; + $line->detail_batch->dluo_qty = $batch_qty; + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + else + { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + else + { + // create new line with new lot + $line->origin_line_id = $lines[$i]->origin_line_id; + $line->entrepot_id = $lotStock->warehouseid; + $line->detail_batch[0] = new ExpeditionLineBatch($db); + $line->detail_batch[0]->fk_origin_stock = $batch_id; + $line->detail_batch[0]->batch = $lotStock->batch; + $line->detail_batch[0]->entrepot_id = $lotStock->warehouseid; + $line->detail_batch[0]->dluo_qty = $batch_qty; + if ($object->create_line_batch($line, $line->array_options) < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + } + } + } + else + { + setEventMessages($lotStock->error, $lotStock->errors, 'errors'); + $error++; + } + } + } + else + { + if ($lines[$i]->fk_product > 0) + { + // line without lot + if ($lines[$i]->entrepot_id > 0) + { + // single warehouse shipment line + $stockLocation="entl".$line_id; + $qty = "qtyl".$line_id; + $line->id = $line_id; + $line->entrepot_id = GETPOST($stockLocation,'int'); + $line->qty = GETPOST($qty, 'int'); + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + unset($_POST[$stockLocation]); + unset($_POST[$qty]); + } + else if (count($lines[$i]->details_entrepot) > 1) + { + // multi warehouse shipment lines + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + if (! $error) { + $stockLocation="entl".$detail_entrepot->line_id; + $qty = "qtyl".$detail_entrepot->line_id; + $warehouse = GETPOST($stockLocation,'int'); + if (!empty ($warehouse)) + { + $line->id = $detail_entrepot->line_id; + $line->entrepot_id = $warehouse; + $line->qty = GETPOST($qty, 'int'); + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + unset($_POST[$stockLocation]); + unset($_POST[$qty]); + } + } + } + } + else // Product no predefined + { + $qty = "qtyl".$line_id; + $line->id = $line_id; + $line->qty = GETPOST($qty, 'int'); + $line->entrepot_id = 0; + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + unset($_POST[$qty]); + } + } + } + } + + unset($_POST["lineid"]); + + if (! $error) { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) + $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->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->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + else + { + header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition + exit(); + } + } + + else if ($action == 'updateline' && $user->rights->expedition->creer && GETPOST('cancel','alpha') == $langs->trans('Cancel')) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition + exit(); + } + + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + + // Actions to send emails + if (empty($id)) $id=$facid; + $trigger_name='SHIPPING_SENTBYMAIL'; + $paramname='id'; + $mode='emailfromshipment'; + $trackid='shi'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + +} + + +/* + * View + */ + +llxHeader('',$langs->trans('Shipment'),'Expedition'); + +$form = new Form($db); +$formfile = new FormFile($db); +$formproduct = new FormProduct($db); +if (! empty($conf->projet->enabled)) { $formproject = new FormProjets($db); } + +$product_static = new Product($db); +$shipment_static = new Expedition($db); +$warehousestatic = new Entrepot($db); + +if ($action == 'create2') +{ + print load_fiche_titre($langs->trans("CreateShipment")).'
'; + print $langs->trans("ShipmentCreationIsDoneFromOrder"); + $action=''; $id=''; $ref=''; +} + +// Mode creation. +if ($action == 'create') +{ + $expe = new Expedition($db); + + print load_fiche_titre($langs->trans("CreateShipment")); + if (! $origin) + { + setEventMessages($langs->trans("ErrorBadParameters"), null, 'errors'); + } + + if ($origin) + { + $classname = ucfirst($origin); + + $object = new $classname($db); + if ($object->fetch($origin_id)) // This include the fetch_lines + { + $soc = new Societe($db); + $soc->fetch($object->socid); + + $author = new User($db); + $author->fetch($object->user_author_id); + + if (! empty($conf->stock->enabled)) $entrepot = new Entrepot($db); + + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + if (GETPOST('entrepot_id','int')) + { + print ''; + } + + dol_fiche_head(''); + + print ''; + + // Ref + print ''; + print "\n"; + + // Ref client + print ''; + print ''; + + // Tiers + print ''; + print ''; + print ''; + + // Project + if (! empty($conf->projet->enabled)) + { + $projectid = GETPOST('projectid','int')?GETPOST('projectid','int'):0; + if(empty($projectid) && ! empty($object->fk_project)) $projectid = $object->fk_project; + if ($origin == 'project') $projectid = ($originid ? $originid : 0); + + $langs->load("projects"); + print ''; + print ''; + print ''; + } + + // Date delivery planned + print ''; + print '\n"; + print ''; + + // Note Public + print ''; + print '"; + + // Note Private + if ($object->note_private && ! $user->societe_id) + { + print ''; + print '"; + } + + // Weight + print ''; + // Dim + print ''; + + // Delivery method + print ""; + print '\n"; + + // Tracking number + print ""; + print '\n"; + + // Other attributes + $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"', 'socid'=>$socid); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$expe,$action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + if (empty($reshook) && ! empty($extrafields->attribute_label)) { + // copy from order + $orderExtrafields = new Extrafields($db); + $orderExtrafieldLabels = $orderExtrafields->fetch_name_optionals_label($object->table_element); + if ($object->fetch_optionals($object->id, $orderExtrafieldLabels) > 0) { + $expe->array_options = array_merge($expe->array_options, $object->array_options); + } + print $object->showOptionals($extrafields, 'edit'); + } + + + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print ''; + print ''; + } + + // Document model + include_once DOL_DOCUMENT_ROOT . '/core/modules/expedition/modules_expedition.php'; + $liste = ModelePdfExpedition::liste_modeles($db); + if (count($liste) > 1) + { + print ""; + print '\n"; + } + + print "
'; + if ($origin == 'commande' && ! empty($conf->commande->enabled)) + { + print $langs->trans("RefOrder").''.img_object($langs->trans("ShowOrder"),'order').' '.$object->ref; + } + if ($origin == 'propal' && ! empty($conf->propal->enabled)) + { + print $langs->trans("RefProposal").''.img_object($langs->trans("ShowProposal"),'propal').' '.$object->ref; + } + print '
'; + if ($origin == 'commande') print $langs->trans('RefCustomerOrder'); + else if ($origin == 'propal') print $langs->trans('RefCustomerOrder'); + else print $langs->trans('RefCustomer'); + print ''; + print ''; + print '
'.$langs->trans('Company').''.$soc->getNomUrl(1).'
' . $langs->trans("Project") . ''; + $numprojet = $formproject->select_projects($soc->id, $projectid, 'projectid', 0); + print '   id).'">' . $langs->trans("AddProject") . ''; + print '
'.$langs->trans("DateDeliveryPlanned").''; + //print dol_print_date($object->date_livraison,"day"); // date_livraison come from order and will be stored into date_delivery planed. + $date_delivery = ($date_delivery?$date_delivery:$object->date_livraison); // $date_delivery comes from GETPOST + print $form->select_date($date_delivery?$date_delivery:-1,'date_delivery',1,1,1); + print "
'.$langs->trans("NotePublic").''; + $doleditor = new DolEditor('note_public', $object->note_public, '', 60, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + print $doleditor->Create(1); + print "
'.$langs->trans("NotePrivate").''; + $doleditor = new DolEditor('note_private', $object->note_private, '', 60, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + print $doleditor->Create(1); + print "
'; + print $langs->trans("Weight"); + print ' '; + $text=$formproduct->select_measuring_units("weight_units","weight",GETPOST('weight_units','int')); + $htmltext=$langs->trans("KeepEmptyForAutoCalculation"); + print $form->textwithpicto($text, $htmltext); + print '
'; + print $langs->trans("Width").' x '.$langs->trans("Height").' x '.$langs->trans("Depth"); + print ' '; + print ' x '; + print ' x '; + print ' '; + $text=$formproduct->select_measuring_units("size_units","size"); + $htmltext=$langs->trans("KeepEmptyForAutoCalculation"); + print $form->textwithpicto($text, $htmltext); + print '
".$langs->trans("DeliveryMethod")."'; + $expe->fetch_delivery_methods(); + print $form->selectarray("shipping_method_id", $expe->meths, GETPOST('shipping_method_id','int'),1,0,0,"",1); + if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + print "
".$langs->trans("TrackingNumber")."'; + print ''; + print "
'; + print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:'')); + print '
".$langs->trans("DefaultModel")."'; + print $form->selectarray('model', $liste, $conf->global->EXPEDITION_ADDON_PDF); + print "
"; + + dol_fiche_end(); + + + // Shipment lines + + $numAsked = count($object->lines); + + print ''; + + + print '
'; + + + print ''; + + + // Load shipments already done for same order + $object->loadExpeditions(); + + if ($numAsked) + { + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->stock->enabled)) + { + if (empty($conf->productbatch->enabled)) + { + print ''; + } + else + { + print ''; + } + } + print "\n"; + } + + $var=true; + $indiceAsked = 0; + while ($indiceAsked < $numAsked) + { + $product = new Product($db); + + $line = $object->lines[$indiceAsked]; + + + // Show product and description + $type=$line->product_type?$line->product_type:$line->fk_product_type; + // Try to enhance type detection using date_start and date_end for free lines where type + // was not saved. + if (! empty($line->date_start)) $type=1; + if (! empty($line->date_end)) $type=1; + + print ''."\n"; + print ''."\n"; + + // Product label + if ($line->fk_product > 0) // If predefined product + { + $product->fetch($line->fk_product); + $product->load_stock('warehouseopen'); // Load all $product->stock_warehouse[idwarehouse]->detail_batch + //var_dump($product->stock_warehouse[1]); + + print ''; + } + else + { + print "\n"; + } + + // Qty + print ''; + $qtyProdCom=$line->qty; + + // Qty already shipped + print ''; + + // Qty to ship + $quantityAsked = $line->qty; + if ($line->product_type == 1 && empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $quantityToBeDelivered = 0; + } + else + { + $quantityToBeDelivered = $quantityAsked - $quantityDelivered; + } + $warehouse_id = GETPOST('entrepot_id','int'); + + $warehouseObject = null; + if ($warehouse_id > 0 || ! ($line->fk_product > 0) || empty($conf->stock->enabled)) // If warehouse was already selected or if product is not a predefined, we go into this part with no multiwarehouse selection + { + print ''; + //ship from preselected location + $stock = + $product->stock_warehouse[$warehouse_id]->real; // Convert to number + $deliverableQty=min($quantityToBeDelivered, $stock); + if ($deliverableQty < 0) $deliverableQty = 0; + if (empty($conf->productbatch->enabled) || ! $product->hasbatch()) + { + // Quantity to send + print ''; + + // Stock + if (! empty($conf->stock->enabled)) + { + print ''; + } + + print "\n"; + + // Show subproducts of product + if (! empty($conf->global->PRODUIT_SOUSPRODUITS) && $line->fk_product > 0) + { + $product->get_sousproduits_arbo(); + $prods_arbo = $product->get_arbo_each_prod($qtyProdCom); + if(count($prods_arbo) > 0) + { + foreach($prods_arbo as $key => $value) + { + //print $value[0]; + $img=''; + if ($value['stock'] < $value['stock_alert']) + { + $img=img_warning($langs->trans("StockTooLow")); + } + print " + "; + } + } + } + } + else + { + // Product need lot + print ''; // end line and start a new one for lot/serial + + $staticwarehouse=new Entrepot($db); + if ($warehouse_id > 0) $staticwarehouse->fetch($warehouse_id); + + $subj=0; + // Define nb of lines suggested for this order line + $nbofsuggested=0; + if (is_object($product->stock_warehouse[$warehouse_id]) && count($product->stock_warehouse[$warehouse_id]->detail_batch)) + { + foreach ($product->stock_warehouse[$warehouse_id]->detail_batch as $dbatch) + { + $nbofsuggested++; + } + } + print ''; + if (is_object($product->stock_warehouse[$warehouse_id]) && count($product->stock_warehouse[$warehouse_id]->detail_batch)) + { + foreach ($product->stock_warehouse[$warehouse_id]->detail_batch as $dbatch) + { + //var_dump($dbatch); + $batchStock = + $dbatch->qty; // To get a numeric + $deliverableQty = min($quantityToBeDelivered,$batchStock); + print ''; + print ''; + + print ''; + print ''; + } + } + else + { + print ''; + print ''; + + print ''; + } + } + } + else + { + // ship from multiple locations + if (empty($conf->productbatch->enabled) || ! $product->hasbatch()) + { + print ''; + print ''."\n"; // end line and start a new one for each warehouse + + print ''; + $subj=0; + // Define nb of lines suggested for this order line + $nbofsuggested=0; + foreach ($product->stock_warehouse as $warehouse_id=>$stock_warehouse) + { + if ($stock_warehouse->real > 0) + { + $nbofsuggested++; + } + } + $tmpwarehouseObject=new Entrepot($db); + foreach ($product->stock_warehouse as $warehouse_id=>$stock_warehouse) // $stock_warehouse is product_stock + { + $tmpwarehouseObject->fetch($warehouse_id); + if ($stock_warehouse->real > 0) + { + $stock = + $stock_warehouse->real; // Convert it to number + $deliverableQty = min($quantityToBeDelivered,$stock); + $deliverableQty = max(0, $deliverableQty); + // Quantity to send + print ''; + print ''; + + // Stock + if (! empty($conf->stock->enabled)) + { + print ''; + } + $quantityToBeDelivered -= $deliverableQty; + if ($quantityToBeDelivered < 0) + { + $quantityToBeDelivered = 0; + } + $subj++; + print "\n"; + } + } + // Show subproducts of product (not recommanded) + if (! empty($conf->global->PRODUIT_SOUSPRODUITS) && $line->fk_product > 0) + { + $product->get_sousproduits_arbo(); + $prods_arbo = $product->get_arbo_each_prod($qtyProdCom); + if (count($prods_arbo) > 0) + { + foreach($prods_arbo as $key => $value) + { + //print $value[0]; + $img=''; + if ($value['stock'] < $value['stock_alert']) + { + $img=img_warning($langs->trans("StockTooLow")); + } + print ' + "; + print ""; + } + } + } + } + else + { + print ''; + print ''; // end line and start a new one for lot/serial + + $subj=0; + print ''; + + $tmpwarehouseObject=new Entrepot($db); + $productlotObject=new Productlot($db); + // Define nb of lines suggested for this order line + $nbofsuggested=0; + foreach ($product->stock_warehouse as $warehouse_id=>$stock_warehouse) + { + if (($stock_warehouse->real > 0) && (count($stock_warehouse->detail_batch))) { + foreach ($stock_warehouse->detail_batch as $dbatch) + { + $nbofsuggested++; + } + } + } + foreach ($product->stock_warehouse as $warehouse_id=>$stock_warehouse) + { + $tmpwarehouseObject->fetch($warehouse_id); + if (($stock_warehouse->real > 0) && (count($stock_warehouse->detail_batch))) { + foreach ($stock_warehouse->detail_batch as $dbatch) + { + //var_dump($dbatch); + $batchStock = + $dbatch->qty; // To get a numeric + $deliverableQty = min($quantityToBeDelivered,$batchStock); + if ($deliverableQty < 0) $deliverableQty = 0; + print ''; + + print ''; + } + } + } + + } + if ($subj == 0) // Line not shown yet, we show it + { + print ''; + print ''; + + print ''; + print ''; + } + } + + + //Display lines extrafields + if (is_array($extralabelslines) && count($extralabelslines)>0) + { + $colspan=5; + $orderLineExtrafields = new Extrafields($db); + $orderLineExtrafieldLabels = $orderLineExtrafields->fetch_name_optionals_label($object->table_element_line); + $srcLine = new OrderLine($db); + $srcLine->fetch_optionals($line->id,$orderLineExtrafieldLabels); // fetch extrafields also available in orderline + $line = new ExpeditionLigne($db); + $line->fetch_optionals($object->id,$extralabelslines); + $line->array_options = array_merge($line->array_options, $srcLine->array_options); + print ''; + print $line->showOptionals($extrafieldsline, 'edit', array('style'=>$bc[$var], 'colspan'=>$colspan),$indiceAsked); + print ''; + } + + $indiceAsked++; + } + + print "
'.$langs->trans("Description").''.$langs->trans("QtyOrdered").''.$langs->trans("QtyShipped").''.$langs->trans("QtyToShip"); + if (empty($conf->productbatch->enabled)) + { + print '
('.$langs->trans("Fill").''; + print ' / '.$langs->trans("Reset").')'; + } + print '
'.$langs->trans("Warehouse").' ('.$langs->trans("Stock").')'.$langs->trans("Warehouse").' / '.$langs->trans("Batch").' ('.$langs->trans("Stock").')
'; + print ''; // ancre pour retourner sur la ligne + + // Show product and description + $product_static->type=$line->fk_product_type; + $product_static->id=$line->fk_product; + $product_static->ref=$line->ref; + $product_static->status_batch=$line->product_tobatch; + $text=$product_static->getNomUrl(1); + $text.= ' - '.(! empty($line->label)?$line->label:$line->product_label); + $description=($conf->global->PRODUIT_DESC_IN_FORM?'':dol_htmlentitiesbr($line->desc)); + print $form->textwithtooltip($text,$description,3,'','',$i); + + // Show range + print_date_range($db->jdate($line->date_start),$db->jdate($line->date_end)); + + // Add description in form + if (! empty($conf->global->PRODUIT_DESC_IN_FORM)) + { + print ($line->desc && $line->desc!=$line->product_label)?'
'.dol_htmlentitiesbr($line->desc):''; + } + + print '
"; + if ($type==1) $text = img_object($langs->trans('Service'),'service'); + else $text = img_object($langs->trans('Product'),'product'); + + if (! empty($line->label)) { + $text.= ' '.$line->label.''; + print $form->textwithtooltip($text,$line->desc,3,'','',$i); + } else { + print $text.' '.nl2br($line->desc); + } + + // Show range + print_date_range($db->jdate($line->date_start),$db->jdate($line->date_end)); + print "'.$line->qty; + print ''; + print ''; + $quantityDelivered = $object->expeditions[$line->id]; + print $quantityDelivered; + print ''; + print ''; + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + if (GETPOST('qtyl'.$indiceAsked, 'int')) $defaultqty=GETPOST('qtyl'.$indiceAsked, 'int'); + print ''; + print ''; + } + else print $langs->trans("NA"); + print ''; + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) // Type of product need stock change ? + { + // Show warehouse combo list + $ent = "entl".$indiceAsked; + $idl = "idl".$indiceAsked; + $tmpentrepot_id = is_numeric(GETPOST($ent,'int'))?GETPOST($ent,'int'):$warehouse_id; + if ($line->fk_product > 0) + { + print ''; + print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 1, 0, $line->fk_product, '', 1); + if ($tmpentrepot_id > 0 && $tmpentrepot_id == $warehouse_id) + { + //print $stock.' '.$quantityToBeDelivered; + if ($stock < $quantityToBeDelivered) + { + print ' '.img_warning($langs->trans("StockTooLow")); // Stock too low for this $warehouse_id but you can change warehouse + } + } + } + } + else + { + print $langs->trans("Service"); + } + print '
      -> + ".$value['fullpath']." + (".$value['nb'].") ".$value['nb_total']."  ".$value['stock']." ".$img."
'; + print ''; + print ''; + + print $staticwarehouse->getNomUrl(0).' / '; + + print ''; + + $detail=''; + $detail.= $langs->trans("Batch").': '.$dbatch->batch; + $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day"); + $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day"); + $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty; + $detail.= '
'; + print $detail; + + $quantityToBeDelivered -= $deliverableQty; + if ($quantityToBeDelivered < 0) + { + $quantityToBeDelivered = 0; + } + $subj++; + print '
'; + print ' '; + print ''; + print img_warning().' '.$langs->trans("NoProductToShipFoundIntoStock", $staticwarehouse->libelle); + print '
'; + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + print ''; + print ''; + } + else print $langs->trans("NA"); + print ''; + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + print $tmpwarehouseObject->getNomUrl(0).' '; + + print ''; + print '('.$stock.')'; + + } + else + { + print $langs->trans("Service"); + } + print '
'; + print "      -> + ".$value['fullpath']." + (".$value['nb'].") ".$value['nb_total']."  ".$value['stock']." ".$img."
'; + print ''; + print ''; + + print $tmpwarehouseObject->getNomUrl(0).' / '; + + print ''; + print ''; + + //print $line->fk_product.' - '.$dbatch->batch; + print $langs->trans("Batch").': '; + $result = $productlotObject->fetch(0, $line->fk_product, $dbatch->batch); + if ($result > 0) print $productlotObject->getNomUrl(1); + else print 'TableLotIncompleteRunRepair'; + print ' ('.$dbatch->qty.')'; + $quantityToBeDelivered -= $deliverableQty; + if ($quantityToBeDelivered < 0) + { + $quantityToBeDelivered = 0; + } + //dol_syslog('deliverableQty = '.$deliverableQty.' batchStock = '.$batchStock); + $subj++; + print '
'; + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $disabled=''; + if (! empty($conf->productbatch->enabled) && $product->hasbatch()) + { + $disabled='disabled="disabled"'; + } + print ' '; + } + else + { + print $langs->trans("NA"); + } + print ''; + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $warehouse_selected_id = GETPOST('entrepot_id','int'); + if ($warehouse_selected_id > 0) + { + $warehouseObject=new Entrepot($db); + $warehouseObject->fetch($warehouse_selected_id); + print img_warning().' '.$langs->trans("NoProductToShipFoundIntoStock", $warehouseObject->libelle); + } + else + { + if ($line->fk_product) print img_warning().' '.$langs->trans("StockTooLow"); + else print ''; + } + } + else + { + print $langs->trans("Service"); + } + print '
"; + + print '
'; + + print '
'; + print ''; + print '  '; + print ''; // Cancel for create does not post form if we don't know the backtopage + print '
'; + + print '
'; + + print '
'; + } + else + { + dol_print_error($db); + } + } +} +else if ($id || $ref) +/* *************************************************************************** */ +/* */ +/* Edit and view mode */ +/* */ +/* *************************************************************************** */ +{ + $lines = $object->lines; + + $num_prod = count($lines); + + if ($object->id > 0) + { + if (!empty($object->origin) && $object->origin_id > 0) + { + $typeobject = $object->origin; + $origin = $object->origin; + $origin_id = $object->origin_id; + $object->fetch_origin(); // Load property $object->commande, $object->propal, ... + } + + $soc = new Societe($db); + $soc->fetch($object->socid); + + $res = $object->fetch_optionals($object->id, $extralabels); + + $head=shipping_prepare_head($object); + dol_fiche_head($head, 'shipping', $langs->trans("Shipment"), -1, 'sending'); + + $formconfirm=''; + + // Confirm deleteion + if ($action == 'delete') + { + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('DeleteSending'),$langs->trans("ConfirmDeleteSending",$object->ref),'confirm_delete','',0,1); + } + + // Confirmation validation + if ($action == 'valid') + { + $objectref = substr($object->ref, 1, 4); + if ($objectref == 'PROV') + { + $numref = $object->getNextNumRef($soc); + } + else + { + $numref = $object->ref; + } + + $text = $langs->trans("ConfirmValidateSending",$numref); + + if (! empty($conf->notification->enabled)) + { + require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; + $notify=new Notify($db); + $text.='
'; + $text.=$notify->confirmMessage('SHIPPING_VALIDATE',$object->socid, $object); + } + + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('ValidateSending'),$text,'confirm_valid','',0,1); + + } + // Confirm cancelation + if ($action == 'annuler') + { + $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('CancelSending'),$langs->trans("ConfirmCancelSending",$object->ref),'confirm_cancel','',0,1); + + } + + if (! $formconfirm) { + $parameters = array(); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) $formconfirm.=$hookmanager->resPrint; + elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; + + + // Calculate totalWeight and totalVolume for all products + // by adding weight and volume of each product line. + $tmparray=$object->getTotalWeightVolume(); + $totalWeight=$tmparray['weight']; + $totalVolume=$tmparray['volume']; + + + if ($typeobject == 'commande' && $object->$typeobject->id && ! empty($conf->commande->enabled)) + { + $objectsrc=new Commande($db); + $objectsrc->fetch($object->$typeobject->id); + } + if ($typeobject == 'propal' && $object->$typeobject->id && ! empty($conf->propal->enabled)) + { + $objectsrc=new Propal($db); + $objectsrc->fetch($object->$typeobject->id); + } + + // Shipment card + $linkback = ''.$langs->trans("BackToList").''; + $morehtmlref='
'; + // Ref customer shipment + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_customer', $object->ref_customer, $object, $user->rights->expedition->creer, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_customer', $object->ref_customer, $object, $user->rights->expedition->creer, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1); + // Project + if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
' . $langs->trans('Project') . ' '; + if (0) { // Do not change on shipment + if ($action != 'classify') { + $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + } + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
'; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + // We don't have project on shipment, so we will use the project or source object instead + // TODO Add project on shipment + $morehtmlref .= ' : '; + if (! empty($objectsrc->fk_project)) { + $proj = new Project($db); + $proj->fetch($objectsrc->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } + } + $morehtmlref.='
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + print '
'; + print '
'; + + print ''; + + // Linked documents + if ($typeobject == 'commande' && $object->$typeobject->id && ! empty($conf->commande->enabled)) + { + print ''; + print '\n"; + print ''; + } + if ($typeobject == 'propal' && $object->$typeobject->id && ! empty($conf->propal->enabled)) + { + print ''; + print '\n"; + print ''; + } + + // Date creation + print ''; + print '\n"; + print ''; + + // Delivery date planned + print ''; + print ''; + + // Weight + print ''; + + // Width + print ''; + + // Height + print ''; + + // Depth + print ''; + + // Volume + print ''; + print '\n"; + print ''; + + // Other attributes + $cols = 2; + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + + print '
'; + print $langs->trans("RefOrder").''; + print $objectsrc->getNomUrl(1,'commande'); + print "
'; + print $langs->trans("RefProposal").''; + print $objectsrc->getNomUrl(1,'expedition'); + print "
'.$langs->trans("DateCreation").''.dol_print_date($object->date_creation,"dayhour")."
'; + print ''; + + if ($action != 'editdate_livraison') print ''; + print '
'; + print $langs->trans('DateDeliveryPlanned'); + print 'id.'">'.img_edit($langs->trans('SetDeliveryDate'),1).'
'; + print '
'; + if ($action == 'editdate_livraison') + { + print '
'; + print ''; + print ''; + print $form->select_date($object->date_delivery?$object->date_delivery:-1,'liv_',1,1,'',"setdate_livraison",1,0,1); + print ''; + print '
'; + } + else + { + print $object->date_delivery ? dol_print_date($object->date_delivery,'dayhour') : ' '; + } + print '
'; + print $form->editfieldkey("Weight",'trueWeight',$object->trueWeight,$object,$user->rights->expedition->creer); + print ''; + + if ($action=='edittrueWeight') + { + print '
'; + print ''; + print ''; + print ''; + print ''; + print $formproduct->select_measuring_units("weight_units","weight",$object->weight_units); + print ' '; + print ' '; + print '
'; + + } + else + { + print $object->trueWeight; + print ($object->trueWeight && $object->weight_units!='')?' '.measuring_units_string($object->weight_units,"weight"):''; + } + + // Calculated + if ($totalWeight > 0) + { + if (!empty($object->trueWeight)) print ' ('.$langs->trans("SumOfProductWeights").': '; + //print $totalWeight.' '.measuring_units_string(0,"weight"); + print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, isset($conf->global->MAIN_WEIGHT_DEFAULT_ROUND)?$conf->global->MAIN_WEIGHT_DEFAULT_ROUND:-1, isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT)?$conf->global->MAIN_WEIGHT_DEFAULT_UNIT:'no'); + //if (empty($object->trueWeight)) print ' ('.$langs->trans("Calculated").')'; + if (!empty($object->trueWeight)) print ')'; + } + print '
'.$form->editfieldkey("Width",'trueWidth',$object->trueWidth,$object,$user->rights->expedition->creer).''; + print $form->editfieldval("Width",'trueWidth',$object->trueWidth,$object,$user->rights->expedition->creer); + print ($object->trueWidth && $object->width_units!='')?' '.measuring_units_string($object->width_units,"size"):''; + print '
'.$form->editfieldkey("Height",'trueHeight',$object->trueHeight,$object,$user->rights->expedition->creer).''; + if($action=='edittrueHeight') + { + print '
'; + print ''; + print ''; + print ''; + print ''; + print $formproduct->select_measuring_units("size_units","size",$object->size_units); + print ' '; + print ' '; + print '
'; + + } + else + { + print $object->trueHeight; + print ($object->trueHeight && $object->height_units!='')?' '.measuring_units_string($object->height_units,"size"):''; + } + + print '
'.$form->editfieldkey("Depth",'trueDepth',$object->trueDepth,$object,$user->rights->expedition->creer).''; + print $form->editfieldval("Depth",'trueDepth',$object->trueDepth,$object,$user->rights->expedition->creer); + print ($object->trueDepth && $object->depth_units!='')?' '.measuring_units_string($object->depth_units,"size"):''; + print '
'; + print $langs->trans("Volume"); + print ''; + $calculatedVolume=0; + $volumeUnit=0; + if ($object->trueWidth && $object->trueHeight && $object->trueDepth) + { + $calculatedVolume=($object->trueWidth * $object->trueHeight * $object->trueDepth); + $volumeUnit=$object->size_units * 3; + } + // If sending volume not defined we use sum of products + if ($calculatedVolume > 0) + { + if ($volumeUnit < 50) + { + //print $calculatedVolume.' '.measuring_units_string($volumeUnit,"volume"); + print showDimensionInBestUnit($calculatedVolume, $volumeUnit, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND)?$conf->global->MAIN_VOLUME_DEFAULT_ROUND:-1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT)?$conf->global->MAIN_VOLUME_DEFAULT_UNIT:'no'); + } + else print $calculatedVolume.' '.measuring_units_string($volumeUnit,"volume"); + } + if ($totalVolume > 0) + { + if ($calculatedVolume) print ' ('.$langs->trans("SumOfProductVolumes").': '; + //print $totalVolume.' '.measuring_units_string(0,"volume"); + print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND)?$conf->global->MAIN_VOLUME_DEFAULT_ROUND:-1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT)?$conf->global->MAIN_VOLUME_DEFAULT_UNIT:'no'); + //if (empty($calculatedVolume)) print ' ('.$langs->trans("Calculated").')'; + if ($calculatedVolume) print ')'; + } + print "
'; + + print '
'; + print '
'; + print '
'; + print '
'; + + print ''; + + // Sending method + print ''; + print ''; + + // Tracking Number + print ''; + + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print ''; + } + + print "
'; + print ''; + + if ($action != 'editshipping_method_id') print ''; + print '
'; + print $langs->trans('SendingMethod'); + print 'id.'">'.img_edit($langs->trans('SetSendingMethod'),1).'
'; + print '
'; + if ($action == 'editshipping_method_id') + { + print '
'; + print ''; + print ''; + $object->fetch_delivery_methods(); + print $form->selectarray("shipping_method_id",$object->meths,$object->shipping_method_id,1,0,0,"",1); + if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + print ''; + print '
'; + } + else + { + if ($object->shipping_method_id > 0) + { + // Get code using getLabelFromKey + $code=$langs->getLabelFromKey($db,$object->shipping_method_id,'c_shipment_mode','rowid','code'); + print $langs->trans("SendingMethod".strtoupper($code)); + } + } + print '
'.$form->editfieldkey("TrackingNumber",'tracking_number',$object->tracking_number,$object,$user->rights->expedition->creer).''; + print $form->editfieldval("TrackingNumber",'tracking_number',$object->tracking_url,$object,$user->rights->expedition->creer,'string',$object->tracking_number); + print '
'; + print '
'; + print $langs->trans('IncotermLabel'); + print ''; + if ($user->rights->expedition->creer) print ''.img_edit().''; + else print ' '; + print '
'; + print '
'; + if ($action != 'editincoterm') + { + print $form->textwithpicto($object->display_incoterms(), $object->libelle_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 '
"; + + print '
'; + print '
'; + print '
'; + + print '
'; + + + // Lines of products + + if ($action == 'editline') + { + print '
+ + + + + '; + } + print '
'; + + print '
'; + print ''; + print ''; + // # + if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) + { + print ''; + } + // Product/Service + print ''; + // Qty + print ''; + if ($origin && $origin_id > 0) + { + print ''; + } + if ($action == 'editline') + { + $editColspan = 3; + if (empty($conf->stock->enabled)) $editColspan--; + if (empty($conf->productbatch->enabled)) $editColspan--; + print ''; + } + else + { + if ($object->statut <= 1) + { + print ''; + } + else + { + print ''; + } + if (! empty($conf->stock->enabled)) + { + print ''; + } + + if (! empty($conf->productbatch->enabled)) + { + print ''; + } + } + print ''; + print ''; + //print ''; + if ($object->statut == 0) + { + print ''; + print ''; + } + print "\n"; + + $var=false; + + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) + { + $object->fetch_thirdparty(); + $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); + } + } + + // Get list of products already sent for same source object into $alreadysent + $alreadysent = array(); + if ($origin && $origin_id > 0) + { + $sql = "SELECT obj.rowid, obj.fk_product, obj.label, obj.description, obj.product_type as fk_product_type, obj.qty as qty_asked, obj.date_start, obj.date_end"; + $sql.= ", ed.rowid as shipmentline_id, ed.qty as qty_shipped, ed.fk_expedition as expedition_id, ed.fk_origin_line, ed.fk_entrepot"; + $sql.= ", e.rowid as shipment_id, e.ref as shipment_ref, e.date_creation, e.date_valid, e.date_delivery, e.date_expedition"; + //if ($conf->livraison_bon->enabled) $sql .= ", l.rowid as livraison_id, l.ref as livraison_ref, l.date_delivery, ld.qty as qty_received"; + $sql.= ', p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch'; + $sql.= ', p.description as product_desc'; + $sql.= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed"; + $sql.= ", ".MAIN_DB_PREFIX."expedition as e"; + $sql.= ", ".MAIN_DB_PREFIX.$origin."det as obj"; + //if ($conf->livraison_bon->enabled) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."livraison as l ON l.fk_expedition = e.rowid LEFT JOIN ".MAIN_DB_PREFIX."livraisondet as ld ON ld.fk_livraison = l.rowid AND obj.rowid = ld.fk_origin_line"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON obj.fk_product = p.rowid"; + $sql.= " WHERE e.entity IN (".getEntity('expedition').")"; + $sql.= " AND obj.fk_".$origin." = ".$origin_id; + $sql.= " AND obj.rowid = ed.fk_origin_line"; + $sql.= " AND ed.fk_expedition = e.rowid"; + //if ($filter) $sql.= $filter; + $sql.= " ORDER BY obj.fk_product"; + + dol_syslog("get list of shipment lines", LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + while($i < $num) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + // $obj->rowid is rowid in $origin."det" table + $alreadysent[$obj->rowid][$obj->shipmentline_id]=array('shipment_ref'=>$obj->shipment_ref, 'shipment_id'=>$obj->shipment_id, 'warehouse'=>$obj->fk_entrepot, 'qty_shipped'=>$obj->qty_shipped, 'date_valid'=>$obj->date_valid, 'date_delivery'=>$obj->date_delivery); + } + $i++; + } + } + //var_dump($alreadysent); + } + + // Loop on each product to send/sent + for ($i = 0 ; $i < $num_prod ; $i++) + { + print ''; // id of order line + print ''; + + // # + if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) + { + print ''; + } + + // Predefined product or service + if ($lines[$i]->fk_product > 0) + { + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) + { + $prod = new Product($db); + $prod->fetch($lines[$i]->fk_product); + $label = ( ! empty($prod->multilangs[$outputlangs->defaultlang]["label"])) ? $prod->multilangs[$outputlangs->defaultlang]["label"] : $lines[$i]->product_label; + } + else + $label = (! empty($lines[$i]->label)?$lines[$i]->label:$lines[$i]->product_label); + + print '\n"; + } + else + { + print "\n"; + } + + // Qty ordered + print ''; + + // Qty in other shipments (with shipment and warehouse used) + if ($origin && $origin_id > 0) + { + print ''; + + if ($action == 'editline' && $lines[$i]->id == $line_id) + { + // edit mode + print ''; + } + else + { + // Qty to ship or shipped + print ''; + + // Warehouse source + if (! empty($conf->stock->enabled)) + { + print ''; + } + + // Batch number managment + if (! empty($conf->productbatch->enabled)) + { + if (isset($lines[$i]->detail_batch)) + { + print ''; + print ''; + } else { + print ''; + } + } + } + + // Weight + print ''; + + // Volume + print ''; + + // Size + //print ''; + + if ($action == 'editline' && $lines[$i]->id == $line_id) + { + print ''; + print ''; + + // Display lines extrafields + if (! empty($rowExtrafieldsStart)) + { + print $rowExtrafieldsStart; + print $rowExtrafieldsView; + print $rowEnd; + } + } + print ""; + + // Display lines extrafields + if (is_array($extralabelslines) && count($extralabelslines)>0) { + $colspan= empty($conf->productbatch->enabled) ? 5 : 6; + $line = new ExpeditionLigne($db); + $line->fetch_optionals($lines[$i]->id,$extralabelslines); + print ''; + if ($action == 'editline' && $lines[$i]->id == $line_id) + { + print $line->showOptionals($extrafieldsline, 'edit', array('style'=>$bc[$var], 'colspan'=>$colspan),$indiceAsked); + } + else + { + print $line->showOptionals($extrafieldsline, 'view', array('style'=>$bc[$var], 'colspan'=>$colspan),$indiceAsked); + } + print ''; + } + } + + // TODO Show also lines ordered but not delivered + + print "
 '.$langs->trans("Products").''.$langs->trans("QtyOrdered").''.$langs->trans("QtyInOtherShipments").''; + if ($object->statut <= 1) + { + print $langs->trans("QtyToShip").' - '; + } + else + { + print $langs->trans("QtyShipped").' - '; + } + if (! empty($conf->stock->enabled)) + { + print $langs->trans("WarehouseSource").' - '; + } + if (! empty($conf->productbatch->enabled)) + { + print $langs->trans("Batch"); + } + print ''.$langs->trans("QtyToShip").''.$langs->trans("QtyShipped").''.$langs->trans("WarehouseSource").''.$langs->trans("Batch").''.$langs->trans("CalculatedWeight").''.$langs->trans("CalculatedVolume").''.$langs->trans("Size").'
'.($i+1).''; + + // Show product and description + $product_static->type=$lines[$i]->fk_product_type; + $product_static->id=$lines[$i]->fk_product; + $product_static->ref=$lines[$i]->ref; + $product_static->status_batch=$lines[$i]->product_tobatch; + $text=$product_static->getNomUrl(1); + $text.= ' - '.$label; + $description=(! empty($conf->global->PRODUIT_DESC_IN_FORM)?'':dol_htmlentitiesbr($lines[$i]->description)); + print $form->textwithtooltip($text,$description,3,'','',$i); + print_date_range($lines[$i]->date_start,$lines[$i]->date_end); + if (! empty($conf->global->PRODUIT_DESC_IN_FORM)) + { + print (! empty($lines[$i]->description) && $lines[$i]->description!=$lines[$i]->product)?'
'.dol_htmlentitiesbr($lines[$i]->description):''; + } + print "
"; + if ($lines[$i]->product_type == Product::TYPE_SERVICE) $text = img_object($langs->trans('Service'),'service'); + else $text = img_object($langs->trans('Product'),'product'); + + if (! empty($lines[$i]->label)) { + $text.= ' '.$lines[$i]->label.''; + print $form->textwithtooltip($text,$lines[$i]->description,3,'','',$i); + } else { + print $text.' '.nl2br($lines[$i]->description); + } + + print_date_range($lines[$i]->date_start,$lines[$i]->date_end); + print "'.$lines[$i]->qty_asked.''; + foreach ($alreadysent as $key => $val) + { + if ($lines[$i]->fk_origin_line == $key) + { + $j = 0; + foreach($val as $shipmentline_id=> $shipmentline_var) + { + if ($shipmentline_var['shipment_id'] == $lines[$i]->fk_expedition) continue; // We want to show only "other shipments" + + $j++; + if ($j > 1) print '
'; + $shipment_static->fetch($shipmentline_var['shipment_id']); + print $shipment_static->getNomUrl(1); + print ' - '.$shipmentline_var['qty_shipped']; + $htmltext=$langs->trans("DateValidation").' : '.(empty($shipmentline_var['date_valid'])?$langs->trans("Draft"):dol_print_date($shipmentline_var['date_valid'], 'dayhour')); + if (! empty($conf->stock->enabled) && $shipmentline_var['warehouse'] > 0) + { + $warehousestatic->fetch($shipmentline_var['warehouse']); + $htmltext .= '
'.$langs->trans("From").' : '.$warehousestatic->getNomUrl(1); + } + print ' '.$form->textwithpicto('', $htmltext, 1); + } + } + } + } + print '
'; + if (is_array($lines[$i]->detail_batch) && count($lines[$i]->detail_batch) > 0) + { + print ''; + $line = new ExpeditionLigne($db); + foreach ($lines[$i]->detail_batch as $detail_batch) + { + print ''; + // Qty to ship or shipped + print ''; + // Batch number managment + if ($lines[$i]->entrepot_id == 0) + { + // only show lot numbers from src warehouse when shipping from multiple warehouses + $line->fetch($detail_batch->fk_expeditiondet); + } + print ''; + print ''; + } + // add a 0 qty lot row to be able to add a lot + print ''; + // Qty to ship or shipped + print ''; + // Batch number managment + print ''; + print ''; + } + else if (! empty($conf->stock->enabled)) + { + if ($lines[$i]->fk_product > 0) + { + if ($lines[$i]->entrepot_id > 0) + { + print ''; + print ''; + // Qty to ship or shipped + print ''; + // Warehouse source + print ''; + // Batch number managment + print ''; + print ''; + } + else if (count($lines[$i]->details_entrepot) > 1) + { + print ''; + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + print ''; + // Qty to ship or shipped + print ''; + // Warehouse source + print ''; + // Batch number managment + print ''; + print ''; + } + } + else + { + print ''; + print ''; + } + } + else + { + print ''; + print ''; + // Qty to ship or shipped + print ''; + // Warehouse source + print ''; + // Batch number managment + print ''; + print ''; + } + } + print '
' . '' . '' . $formproduct->selectLotStock($detail_batch->fk_origin_stock, 'batchl'.$detail_batch->fk_expeditiondet.'_'.$detail_batch->fk_origin_stock, '', 1, 0, $lines[$i]->fk_product, $line->entrepot_id). '
' . '' . '' . $formproduct->selectLotStock('', 'batchl'.$line_id.'_0', '', 1, 0, $lines[$i]->fk_product). '
' . '' . '' . $formproduct->selectWarehouses($lines[$i]->entrepot_id, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1). ' - ' . $langs->trans("NA") . '
' . '' . '' . $formproduct->selectWarehouses($detail_entrepot->entrepot_id, 'entl'.$detail_entrepot->line_id, '', 1, 0, $lines[$i]->fk_product, '', 1) . ' - ' . $langs->trans("NA") . '
'.$langs->trans("NotEnoughStock").'
' . '' . '' . '' . '
'.$lines[$i]->qty_shipped.''; + if ($lines[$i]->entrepot_id > 0) + { + $entrepot = new Entrepot($db); + $entrepot->fetch($lines[$i]->entrepot_id); + print $entrepot->getNomUrl(1); + } + else if (count($lines[$i]->details_entrepot) > 1) + { + $detail = ''; + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + if ($detail_entrepot->entrepot_id > 0) + { + $entrepot = new Entrepot($db); + $entrepot->fetch($detail_entrepot->entrepot_id); + $detail.= $langs->trans("DetailWarehouseFormat",$entrepot->libelle,$detail_entrepot->qty_shipped).'
'; + } + } + print $form->textwithtooltip(img_picto('', 'object_stock').' '.$langs->trans("DetailWarehouseNumber"),$detail); + } + print '
'; + if ($lines[$i]->product_tobatch) + { + $detail = ''; + foreach ($lines[$i]->detail_batch as $dbatch) + { + $detail.= $langs->trans("Batch").': '.$dbatch->batch; + $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day"); + $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day"); + $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty; + $detail.= '
'; + } + print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"),$detail); + } + else + { + print $langs->trans("NA"); + } + print '
'; + if ($lines[$i]->fk_product_type == Product::TYPE_PRODUCT) print $lines[$i]->weight*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->weight_units,"weight"); + else print ' '; + print ''; + if ($lines[$i]->fk_product_type == Product::TYPE_PRODUCT) print $lines[$i]->volume*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->volume_units,"volume"); + else print ' '; + print ''.$lines[$i]->volume*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->volume_units,"volume").''; + print '
'; + print '
'; + } + else if ($object->statut == 0) + { + // edit-delete buttons + print '
'; + print 'id . '">' . img_edit() . ''; + print ''; + print 'id . '">' . img_delete() . ''; + print '
\n"; + print '
'; + } + + + dol_fiche_end(); + + + $object->fetchObjectLinked($object->id,$object->element); + + + /* + * Boutons actions + */ + + if (($user->societe_id == 0) && ($action!='presend')) + { + print '
'; + + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if (empty($reshook)) + { + + if ($object->statut == Expedition::STATUS_DRAFT && $num_prod > 0) + { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->shipping_advance->validate))) + { + print ''.$langs->trans("Validate").''; + } + else + { + print ''.$langs->trans("Validate").''; + } + } + // Edit + if ($object->statut == Expedition::STATUS_VALIDATED && $user->rights->expedition->creer) { + print ''; + } + + // TODO add alternative status + // 0=draft, 1=validated, 2=billed, we miss a status "delivered" (only available on order) + if ($object->statut == Expedition::STATUS_CLOSED && $user->rights->expedition->creer) + { + if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? + { + print ''.$langs->trans("ClassifyUnbilled").''; + } + else + { + print ''.$langs->trans("ReOpen").''; + } + } + + // Send + if ($object->statut > 0) + { + if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->expedition->shipping_advance->send) + { + print ''.$langs->trans('SendByMail').''; + } + else print ''.$langs->trans('SendByMail').''; + } + + // Create bill + if (! empty($conf->facture->enabled) && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED)) + { + if ($user->rights->facture->creer) + { + // TODO show button only if (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) + // If we do that, we must also make this option official. + print ''.$langs->trans("CreateBill").''; + } + } + + // This is just to generate a delivery receipt + //var_dump($object->linkedObjectsIds['delivery']); + if ($conf->livraison_bon->enabled && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED) && $user->rights->expedition->livraison->creer && count($object->linkedObjectsIds['delivery']) == 0) + { + print ''.$langs->trans("CreateDeliveryOrder").''; + } + // Close + if ($object->statut == Expedition::STATUS_VALIDATED) + { + if ($user->rights->expedition->creer && $object->statut > 0 && ! $object->billed) + { + $label="Close"; $paramaction='classifyclosed'; // = Transferred/Received + // Label here should be "Close" or "ClassifyBilled" if we decided to make bill on shipments instead of orders + if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? + { + $label="ClassifyBilled"; + $paramaction='classifybilled'; + } + print ''.$langs->trans($label).''; + } + } + + if ($user->rights->expedition->supprimer) + { + print ''.$langs->trans("Delete").''; + } + + } + + print '
'; + } + + + /* + * Documents generated + */ + + if ($action != 'presend' && $action != 'editline') + { + print '
'; + + $objectref = dol_sanitizeFileName($object->ref); + $filedir = $conf->expedition->dir_output . "/sending/" .$objectref; + + $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; + + $genallowed=$user->rights->expedition->lire; + $delallowed=$user->rights->expedition->creer; + + print $formfile->showdocuments('expedition',$objectref,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang); + + + // Show links to link elements + //$linktoelem = $form->showLinkToObjectBlock($object, null, array('order')); + $somethingshown = $form->showLinkedObjectBlock($object, ''); + + + print '
'; + + } + //Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + if ($action == 'presend') + { + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($conf->expedition->dir_output . '/sending/' . $ref, preg_quote($ref, '/').'[^\-]+'); + $file=$fileparams['fullname']; + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (!empty($newlang)) + { + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang($newlang); + $outputlangs->load('sendings'); + } + // Build document if it not exists + if (! $file || ! is_readable($file)) + { + $result = $object->generateDocument(GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + dol_print_error($db,$object->error,$object->errors); + exit; + } + $fileparams = dol_most_recent_file($conf->expedition->dir_output . '/sending/' . $ref, preg_quote($ref, '/').'[^\-]+'); + $file=$fileparams['fullname']; + } + print '
'; + print '
'; + print '
'; + print load_fiche_titre($langs->trans('SendShippingByEMail')); + dol_fiche_head(''); + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); + $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); + if($formmail->fromtype === 'user'){ + $formmail->fromid = $user->id; + } + $formmail->trackid='shi'.$object->id; + if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set + { + include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'shi'.$object->id); + } + $formmail->withfrom=1; + $liste=array(); + foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; + $formmail->withto=GETPOST("sendto")?GETPOST("sendto"):$liste; + $formmail->withtocc=$liste; + $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic=$outputlangs->trans('SendShippingRef','__SHIPPINGREF__'); + $formmail->withfile=2; + $formmail->withbody=1; + $formmail->withdeliveryreceipt=1; + $formmail->withcancel=1; + // Tableau des substitutions + $formmail->setSubstitFromObject($object); + $formmail->substit['__SHIPPINGREF__']=$object->ref; + $formmail->substit['__SHIPPINGTRACKNUM__']=$object->tracking_number; + $formmail->substit['__SHIPPINGTRACKNUMURL__']=$object->tracking_url; + //Find the good contact adress + if ($typeobject == 'commande' && $object->$typeobject->id && ! empty($conf->commande->enabled)) { + $objectsrc=new Commande($db); + $objectsrc->fetch($object->$typeobject->id); + } + if ($typeobject == 'propal' && $object->$typeobject->id && ! empty($conf->propal->enabled)) { + $objectsrc=new Propal($db); + $objectsrc->fetch($object->$typeobject->id); + } + $custcontact=''; + $contactarr=array(); + if (is_object($objectsrc)) // For the case the shipment was created without orders + { + $contactarr=$objectsrc->liste_contact(-1,'external'); + } + if (is_array($contactarr) && count($contactarr)>0) { + foreach($contactarr as $contact) { + if ($contact['libelle']==$langs->trans('TypeContact_commande_external_CUSTOMER')) { + require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; + $contactstatic=new Contact($db); + $contactstatic->fetch($contact['id']); + $custcontact=$contactstatic->getFullName($langs,1); + } + } + if (!empty($custcontact)) { + $formmail->substit['__CONTACTCIVNAME__']=$custcontact; + } + } + // Tableau des parametres complementaires + $formmail->param['action']='send'; + $formmail->param['models']='shipping_send'; + $formmail->param['models_id']=GETPOST('modelmailselected','int'); + $formmail->param['shippingid']=$object->id; + $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); + } + // Show form + print $formmail->get_form(); + dol_fiche_end(); + } + + + +} + + +llxFooter(); + +$db->close(); diff --git a/htdocs/reception/class/expeditionbatch.class.php b/htdocs/reception/class/expeditionbatch.class.php new file mode 100644 index 00000000000..5253156e32a --- /dev/null +++ b/htdocs/reception/class/expeditionbatch.class.php @@ -0,0 +1,223 @@ + + * Copyright (C) 2013-2014 Cedric GROSS + * + * 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 . + */ + +/** + * \file expedition/class/expeditionbatch.class.php + * \ingroup productbatch + * \brief This file implements CRUD method for managing shipment batch lines + * with batch record + */ + +/** + * CRUD class for batch number management within shipment + */ +class ExpeditionLineBatch extends CommonObject +{ + var $element='expeditionlignebatch'; //!< Id that identify managed objects + private static $_table_element='expeditiondet_batch'; //!< Name of table without prefix where object is stored + + var $sellby; + var $eatby; + var $batch; + var $dluo_qty; + var $entrepot_id; + var $fk_origin_stock; + var $fk_expeditiondet; + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + function __construct($db) + { + $this->db = $db; + return 1; + } + + /** + * Fill object based on a product-warehouse-batch's record + * + * @param int $id_stockdluo Rowid in product_batch table + * @return int -1 if KO, 1 if OK + */ + function fetchFromStock($id_stockdluo) + { + $sql = "SELECT"; + $sql.= " t.sellby,"; + $sql.= " t.eatby,"; + $sql.= " t.batch,"; + $sql.= " e.fk_entrepot"; + + $sql.= " FROM ".MAIN_DB_PREFIX."product_batch as t inner join "; + $sql.= MAIN_DB_PREFIX."product_stock as e on t.fk_product_stock=e.rowid "; + $sql.= " WHERE t.rowid = ".(int) $id_stockdluo; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->sellby = $this->db->jdate($obj->sellby); + $this->eatby = $this->db->jdate($obj->eatby); + $this->batch = $obj->batch; + $this->entrepot_id= $obj->fk_entrepot; + $this->fk_origin_stock=(int) $id_stockdluo; + } + $this->db->free($resql); + + return 1; + } + else + { + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + /** + * Create an expeditiondet_batch DB record link to an expedtiondet record + * + * @param int $id_line_expdet rowid of expedtiondet record + * @return int <0 if KO, Id of record (>0) if OK + */ + function create($id_line_expdet) + { + $error = 0; + + $id_line_expdet = (int) $id_line_expdet; + + $sql = "INSERT INTO ".MAIN_DB_PREFIX.self::$_table_element." ("; + $sql.= "fk_expeditiondet"; + $sql.= ", sellby"; + $sql.= ", eatby"; + $sql.= ", batch"; + $sql.= ", qty"; + $sql.= ", fk_origin_stock"; + $sql.= ") VALUES ("; + $sql.= $id_line_expdet.","; + $sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':("'".$this->db->idate($this->sellby))."'").","; + $sql.= " ".(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':("'".$this->db->idate($this->eatby))."'").","; + $sql.= " ".(! isset($this->batch)?'NULL':("'".$this->db->escape($this->batch)."'")).","; + $sql.= " ".(! isset($this->dluo_qty)?'NULL':$this->dluo_qty).","; + $sql.= " ".(! isset($this->fk_origin_stock)?'NULL':$this->fk_origin_stock); + $sql.= ")"; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.self::$_table_element); + $this->fk_expeditiondet=$id_line_expdet; + return $this->id; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + + /** + * Delete batch record attach to a shipment + * + * @param DoliDB $db Database object + * @param int $id_expedition rowid of shipment + * @return int -1 if KO, 1 if OK + */ + static function deletefromexp($db,$id_expedition) + { + $id_expedition = (int) $id_expedition; + + $sql="DELETE FROM ".MAIN_DB_PREFIX.self::$_table_element; + $sql.=" WHERE fk_expeditiondet in (SELECT rowid FROM ".MAIN_DB_PREFIX."expeditiondet WHERE fk_expedition=".$id_expedition.")"; + + dol_syslog(__METHOD__, LOG_DEBUG); + if ($db->query($sql)) + { + return 1; + } + else + { + return -1; + } + } + + /** + * Retrieve all batch number details link to a shipment line + * + * @param DoliDB $db Database object + * @param int $id_line_expdet id of shipment line + * @return variant -1 if KO, array of ExpeditionLineBatch if OK + */ + static function fetchAll($db,$id_line_expdet) + { + $sql="SELECT rowid,"; + $sql.= "fk_expeditiondet"; + $sql.= ", sellby"; + $sql.= ", eatby"; + $sql.= ", batch"; + $sql.= ", qty"; + $sql.= ", fk_origin_stock"; + $sql.= " FROM ".MAIN_DB_PREFIX.self::$_table_element; + $sql.= " WHERE fk_expeditiondet=".(int) $id_line_expdet; + + dol_syslog(__METHOD__ ."", LOG_DEBUG); + $resql=$db->query($sql); + if ($resql) + { + $num=$db->num_rows($resql); + $i=0; + $ret = array(); + while ($i<$num) + { + $tmp=new self($db); + + $obj = $db->fetch_object($resql); + + $tmp->sellby = $db->jdate($obj->sellby); + $tmp->eatby = $db->jdate($obj->eatby); + $tmp->batch = $obj->batch; + $tmp->id = $obj->rowid; + $tmp->fk_origin_stock = $obj->fk_origin_stock; + $tmp->fk_expeditiondet = $obj->fk_expeditiondet; + $tmp->dluo_qty = $obj->qty; + + $ret[]=$tmp; + $i++; + } + $db->free($resql); + return $ret; + } + else + { + return -1; + } + } + +} diff --git a/htdocs/reception/class/expeditionstats.class.php b/htdocs/reception/class/expeditionstats.class.php new file mode 100644 index 00000000000..7fa16f4210f --- /dev/null +++ b/htdocs/reception/class/expeditionstats.class.php @@ -0,0 +1,142 @@ + + * Copyright (c) 2005-2013 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2011 Juanjo Menent + * + * 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 . + */ + +/** + * \file htdocs/expedition/class/expeditionstats.class.php + * \ingroup expedition + * \brief File of class fo tmanage shipment statistics + */ + +include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php'; +include_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php'; +include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + + +/** + * Class to manage shipment statistics + */ +class ExpeditionStats extends Stats +{ + public $table_element; + + var $socid; + var $userid; + + var $from; + var $field; + var $where; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + * @param int $socid Id third party for filter + * @param string $mode Option (not used) + * @param int $userid Id user for filter (creation user) + */ + function __construct($db, $socid, $mode, $userid=0) + { + global $user, $conf; + + $this->db = $db; + + $this->socid = ($socid > 0 ? $socid : 0); + $this->userid = $userid; + $this->cachefilesuffix = $mode; + + $object=new Expedition($this->db); + $this->from = MAIN_DB_PREFIX.$object->table_element." as c"; + //$this->from.= ", ".MAIN_DB_PREFIX."societe as s"; + $this->field='weight'; // Warning, unit of weight is NOT USED AND MUST BE + $this->where.= " c.fk_statut > 0"; // Not draft and not cancelled + + //$this->where.= " AND c.fk_soc = s.rowid AND c.entity = ".$conf->entity; + $this->where.= " AND c.entity = ".$conf->entity; + if (!$user->rights->societe->client->voir && !$this->socid) $this->where .= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; + if ($this->socid) + { + $this->where.=" AND c.fk_soc = ".$this->socid; + } + if ($this->userid > 0) $this->where.=' AND c.fk_user_author = '.$this->userid; + } + + /** + * Return shipment number by month for a year + * + * @param int $year Year to scan + * @return array Array with number by month + */ + function getNbByMonth($year) + { + global $user; + + $sql = "SELECT date_format(c.date_valid,'%m') as dm, COUNT(*) as nb"; + $sql.= " FROM ".$this->from; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; + $sql.= " AND ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + $res=$this->_getNbByMonth($year, $sql); + return $res; + } + + /** + * Return shipments number per year + * + * @return array Array with number by year + * + */ + function getNbByYear() + { + global $user; + + $sql = "SELECT date_format(c.date_valid,'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; + $sql.= " FROM ".$this->from; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE ".$this->where; + $sql.= " GROUP BY dm"; + $sql.= $this->db->order('dm','DESC'); + + return $this->_getNbByYear($sql); + } + + /** + * Return nb, total and average + * + * @return array Array of values + */ + function getAllByYear() + { + global $user; + + $sql = "SELECT date_format(c.date_valid,'%Y') as year, COUNT(*) as nb, SUM(c.".$this->field.") as total, AVG(".$this->field.") as avg"; + $sql.= " FROM ".$this->from; + if (!$user->rights->societe->client->voir && !$this->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE ".$this->where; + $sql.= " GROUP BY year"; + $sql.= $this->db->order('year','DESC'); + + return $this->_getAllByYear($sql); + } +} + diff --git a/htdocs/reception/class/index.html b/htdocs/reception/class/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php new file mode 100644 index 00000000000..324714fee7c --- /dev/null +++ b/htdocs/reception/class/reception.class.php @@ -0,0 +1,2824 @@ + + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2007 Franky Van Liedekerke + * Copyright (C) 2006-2012 Laurent Destailleur + * Copyright (C) 2011-2017 Juanjo Menent + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2014 Cedric GROSS + * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2014-2015 Francis Appels + * Copyright (C) 2015 Claudio Aschieri + * Copyright (C) 2016 Ferran Marcet + * + * 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 . + */ + +/** + * \file htdocs/reception/class/reception.class.php + * \ingroup reception + * \brief Fichier de la classe de gestion des receptions + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT."/core/class/commonobjectline.class.php"; +if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +if (! empty($conf->productbatch->enabled)) require_once DOL_DOCUMENT_ROOT.'/reception/class/receptionbatch.class.php'; + + +/** + * Class to manage receptions + */ +class Reception extends CommonObject +{ + public $element="reception"; + public $fk_element="fk_reception"; + public $table_element="reception"; + public $table_element_line="receptiondet"; + protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + public $picto = 'reception'; + + var $socid; + var $ref_customer; + var $ref_int; + var $brouillon; + var $entrepot_id; + var $lines=array(); + var $tracking_number; + var $tracking_url; + var $billed; + var $model_pdf; + + var $trueWeight; + var $weight_units; + var $trueWidth; + var $width_units; + var $trueHeight; + var $height_units; + var $trueDepth; + var $depth_units; + // A denormalized value + var $trueSize; + + var $date_delivery; // Date delivery planed + /** + * @deprecated + * @see date_reception + */ + var $date; + + /** + * Effective delivery date + * @var int + */ + public $date_reception; + var $date_creation; + var $date_valid; + + var $meths; + var $listmeths; // List of carriers + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CLOSED = 2; + + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + $this->lines = array(); + $this->products = array(); + + // List of long language codes for status + $this->statuts = array(); + $this->statuts[-1] = 'StatusReceptionCanceled'; + $this->statuts[0] = 'StatusReceptionDraft'; + $this->statuts[1] = 'StatusReceptionValidated'; + $this->statuts[2] = 'StatusReceptionProcessed'; + } + + /** + * Return next contract ref + * + * @param Societe $soc Thirdparty object + * @return string Free reference for contract + */ + function getNextNumRef($soc) + { + global $langs, $conf; + $langs->load("receptions"); + + if (!empty($conf->global->RECEPTION_ADDON_NUMBER)) + { + $mybool = false; + + $file = $conf->global->RECEPTION_ADDON_NUMBER.".php"; + $classname = $conf->global->RECEPTION_ADDON_NUMBER; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + + foreach ($dirmodels as $reldir) { + + $dir = dol_buildpath($reldir."core/modules/reception/"); + + // Load file with numbering class (if found) + $mybool|=@include_once $dir.$file; + } + + if (! $mybool) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } + + $obj = new $classname(); + $numref = ""; + $numref = $obj->getNextValue($soc,$this); + + if ( $numref != "") + { + return $numref; + } + else + { + dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } + else + { + print $langs->trans("Error")." ".$langs->trans("Error_RECEPTION_ADDON_NUMBER_NotDefined"); + return ""; + } + } + + /** + * Create reception en base + * + * @param User $user Objet du user qui cree + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 si erreur, id reception creee si ok + */ + function create($user, $notrigger=0) + { + global $conf, $hookmanager; + + $now=dol_now(); + + require_once DOL_DOCUMENT_ROOT .'/product/stock/class/mouvementstock.class.php'; + $error = 0; + + // Clean parameters + $this->brouillon = 1; + $this->tracking_number = dol_sanitizeFileName($this->tracking_number); + if (empty($this->fk_project)) $this->fk_project = 0; + + $this->user = $user; + + + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."reception ("; + $sql.= "ref"; + $sql.= ", entity"; + $sql.= ", ref_customer"; + $sql.= ", ref_int"; + $sql.= ", date_creation"; + $sql.= ", fk_user_author"; + $sql.= ", date_reception"; + $sql.= ", date_delivery"; + $sql.= ", fk_soc"; + $sql.= ", fk_projet"; + $sql.= ", fk_address"; + $sql.= ", fk_reception_method"; + $sql.= ", tracking_number"; + $sql.= ", weight"; + $sql.= ", size"; + $sql.= ", width"; + $sql.= ", height"; + $sql.= ", weight_units"; + $sql.= ", size_units"; + $sql.= ", note_private"; + $sql.= ", note_public"; + $sql.= ", model_pdf"; + $sql.= ", fk_incoterms, location_incoterms"; + $sql.= ") VALUES ("; + $sql.= "'(PROV)'"; + $sql.= ", ".$conf->entity; + $sql.= ", ".($this->ref_customer?"'".$this->db->escape($this->ref_customer)."'":"null"); + $sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); + $sql.= ", '".$this->db->idate($now)."'"; + $sql.= ", ".$user->id; + $sql.= ", ".($this->date_reception>0?"'".$this->db->idate($this->date_reception)."'":"null"); + $sql.= ", ".($this->date_delivery>0?"'".$this->db->idate($this->date_delivery)."'":"null"); + $sql.= ", ".$this->socid; + $sql.= ", ".$this->fk_project; + $sql.= ", ".($this->fk_delivery_address>0?$this->fk_delivery_address:"null"); + $sql.= ", ".($this->reception_method_id>0?$this->reception_method_id:"null"); + $sql.= ", '".$this->db->escape($this->tracking_number)."'"; + $sql.= ", ".$this->weight; + $sql.= ", ".$this->sizeS; // TODO Should use this->trueDepth + $sql.= ", ".$this->sizeW; // TODO Should use this->trueWidth + $sql.= ", ".$this->sizeH; // TODO Should use this->trueHeight + $sql.= ", ".$this->weight_units; + $sql.= ", ".$this->size_units; + $sql.= ", ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ", ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null"); + $sql.= ", ".(!empty($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null"); + $sql.= ", ".(int) $this->fk_incoterms; + $sql.= ", '".$this->db->escape($this->location_incoterms)."'"; + $sql.= ")"; + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."reception"); + + $sql = "UPDATE ".MAIN_DB_PREFIX."reception"; + $sql.= " SET ref = '(PROV".$this->id.")'"; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + if ($this->db->query($sql)) + { + // Insertion des lignes + $num=count($this->lines); + for ($i = 0; $i < $num; $i++) + { + if (! isset($this->lines[$i]->detail_batch)) + { // no batch management + if (! $this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->array_options) > 0) + { + $error++; + } + } + else + { // with batch management + if (! $this->create_line_batch($this->lines[$i],$this->lines[$i]->array_options) > 0) + { + $error++; + } + } + } + + if (! $error && $this->id && $this->origin_id) + { + $ret = $this->add_object_linked(); + if (!$ret) + { + $error++; + } + } + + // Actions on extra fields (by external module or standard code) + // TODO le hook fait double emploi avec le trigger !! + $hookmanager->initHooks(array('receptiondao')); + $parameters=array('socid'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('RECEPTION_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + + } + else + { + $error++; + $this->error=$this->db->lasterror()." - sql=$sql"; + $this->db->rollback(); + return -3; + } + } + else + { + $error++; + $this->error=$this->db->lasterror()." - sql=$sql"; + $this->db->rollback(); + return -2; + } + } + else + { + $error++; + $this->error=$this->db->error()." - sql=$sql"; + $this->db->rollback(); + return -1; + } + } + + /** + * Create a reception line + * + * @param int $entrepot_id Id of warehouse + * @param int $origin_line_id Id of source line + * @param int $qty Quantity + * @param array $array_options extrafields array + * @return int <0 if KO, line_id if OK + */ + function create_line($entrepot_id, $origin_line_id, $qty,$array_options=0) + { + global $conf; + $error = 0; + $line_id = 0; + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."receptiondet ("; + $sql.= "fk_reception"; + $sql.= ", fk_entrepot"; + $sql.= ", fk_origin_line"; + $sql.= ", qty"; + $sql.= ") VALUES ("; + $sql.= $this->id; + $sql.= ", ".($entrepot_id?$entrepot_id:'null'); + $sql.= ", ".$origin_line_id; + $sql.= ", ".$qty; + $sql.= ")"; + + dol_syslog(get_class($this)."::create_line", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $line_id = $this->db->last_insert_id(MAIN_DB_PREFIX."receptiondet"); + } + else + { + $error++; + } + + if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options)>0) // For avoid conflicts if trigger used + { + $receptionline = new ReceptionLigne($this->db); + $receptionline->array_options=$array_options; + $receptionline->id= $this->db->last_insert_id(MAIN_DB_PREFIX.$receptionline->table_element); + $result=$receptionline->insertExtraFields(); + if ($result < 0) + { + $this->error[]=$receptionline->error; + $error++; + } + } + + if (! $error) return $line_id; + else return -1; + } + + + /** + * Create the detail (eat-by date) of the reception line + * + * @param object $line_ext full line informations + * @param array $array_options extrafields array + * @return int <0 if KO, >0 if OK + */ + function create_line_batch($line_ext,$array_options=0) + { + $error = 0; + $stockLocationQty = array(); // associated array with batch qty in stock location + + $tab=$line_ext->detail_batch; + // create stockLocation Qty array + foreach ($tab as $detbatch) + { + if ($detbatch->entrepot_id) + { + $stockLocationQty[$detbatch->entrepot_id] += $detbatch->dluo_qty; + } + } + // create reception lines + foreach ($stockLocationQty as $stockLocation => $qty) + { + if (($line_id = $this->create_line($stockLocation,$line_ext->origin_line_id,$qty,$array_options)) < 0) + { + $error++; + } + else + { + // create reception batch lines for stockLocation + foreach ($tab as $detbatch) + { + if ($detbatch->entrepot_id == $stockLocation){ + if (! ($detbatch->create($line_id) >0)) // Create an receptionlinebatch + { + $error++; + } + } + } + } + } + + if (! $error) return 1; + else return -1; + } + + /** + * Get object and lines from database + * + * @param int $id Id of object to load + * @param string $ref Ref of object + * @param string $ref_ext External reference of object + * @param string $ref_int Internal reference of other object + * @return int >0 if OK, 0 if not found, <0 if KO + */ + function fetch($id, $ref='', $ref_ext='', $ref_int='') + { + global $conf; + + // Check parameters + if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; + + $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut"; + $sql.= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height"; + $sql.= ", e.date_reception as date_reception, e.model_pdf, e.fk_address, e.date_delivery"; + $sql.= ", e.fk_reception_method, e.tracking_number"; + $sql.= ", el.fk_source as origin_id, el.sourcetype as origin"; + $sql.= ", e.note_private, e.note_public"; + $sql.= ', e.fk_incoterms, e.location_incoterms'; + $sql.= ', i.libelle as libelle_incoterms'; + $sql.= " FROM ".MAIN_DB_PREFIX."reception as e"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element)."'"; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON e.fk_incoterms = i.rowid'; + $sql.= " WHERE e.entity IN (".getEntity('reception').")"; + if ($id) $sql.= " AND e.rowid=".$id; + if ($ref) $sql.= " AND e.ref='".$this->db->escape($ref)."'"; + if ($ref_ext) $sql.= " AND e.ref_ext='".$this->db->escape($ref_ext)."'"; + if ($ref_int) $sql.= " AND e.ref_int='".$this->db->escape($ref_int)."'"; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + + $this->id = $obj->rowid; + $this->ref = $obj->ref; + $this->socid = $obj->socid; + $this->ref_customer = $obj->ref_customer; + $this->ref_ext = $obj->ref_ext; + $this->ref_int = $obj->ref_int; + $this->statut = $obj->fk_statut; + $this->user_author_id = $obj->fk_user_author; + $this->date_creation = $this->db->jdate($obj->date_creation); + $this->date = $this->db->jdate($obj->date_reception); // TODO deprecated + $this->date_reception = $this->db->jdate($obj->date_reception); // TODO deprecated + $this->date_reception = $this->db->jdate($obj->date_reception); // Date real + $this->date_delivery = $this->db->jdate($obj->date_delivery); // Date planed + $this->fk_delivery_address = $obj->fk_address; + $this->modelpdf = $obj->model_pdf; + $this->reception_method_id = $obj->fk_reception_method; + $this->tracking_number = $obj->tracking_number; + $this->origin = ($obj->origin?$obj->origin:'commande'); // For compatibility + $this->origin_id = $obj->origin_id; + $this->billed = ($obj->fk_statut==2?1:0); + + $this->trueWeight = $obj->weight; + $this->weight_units = $obj->weight_units; + + $this->trueWidth = $obj->width; + $this->width_units = $obj->size_units; + $this->trueHeight = $obj->height; + $this->height_units = $obj->size_units; + $this->trueDepth = $obj->size; + $this->depth_units = $obj->size_units; + + $this->note_public = $obj->note_public; + $this->note_private = $obj->note_private; + + // A denormalized value + $this->trueSize = $obj->size."x".$obj->width."x".$obj->height; + $this->size_units = $obj->size_units; + + //Incoterms + $this->fk_incoterms = $obj->fk_incoterms; + $this->location_incoterms = $obj->location_incoterms; + $this->libelle_incoterms = $obj->libelle_incoterms; + + $this->db->free($result); + + if ($this->statut == 0) $this->brouillon = 1; + + $file = $conf->reception->dir_output . "/" .get_exdir($this->id, 2, 0, 0, $this, 'reception') . "/" . $this->id.".pdf"; + $this->pdf_filename = $file; + + // Tracking url + $this->GetUrlTrackingStatus($obj->tracking_number); + + /* + * Thirparty + */ + $result=$this->fetch_thirdparty(); + + // Retrieve all extrafields for reception + // fetch optionals attributes and labels + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields=new ExtraFields($this->db); + $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); + $this->fetch_optionals($this->id,$extralabels); + + /* + * Lines + */ + $result=$this->fetch_lines(); + if ($result < 0) + { + return -3; + } + + return 1; + } + else + { + dol_syslog(get_class($this).'::Fetch no reception found', LOG_ERR); + $this->error='Delivery with id '.$id.' not found'; + return 0; + } + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + /** + * Validate object and update stock if option enabled + * + * @param User $user Object user that validate + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <0 if OK, >0 if KO + */ + function valid($user, $notrigger=0) + { + global $conf, $langs; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + dol_syslog(get_class($this)."::valid"); + + // Protection + if ($this->statut) + { + dol_syslog(get_class($this)."::valid no draft status", LOG_WARNING); + return 0; + } + + if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->reception->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->reception->reception_advance->validate)))) + { + $this->error='Permission denied'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + } + + $this->db->begin(); + + $error = 0; + + // Define new ref + $soc = new Societe($this->db); + $soc->fetch($this->socid); + + // Class of company linked to order + $result=$soc->set_as_client(); + + // Define new ref + if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life + { + $numref = $this->getNextNumRef($soc); + } + else { + $numref = $this->ref; + } + $this->newref = $numref; + + $now=dol_now(); + + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX."reception SET"; + $sql.= " ref='".$numref."'"; + $sql.= ", fk_statut = 1"; + $sql.= ", date_valid = '".$this->db->idate($now)."'"; + $sql.= ", fk_user_valid = ".$user->id; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::valid update reception", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $this->error=$this->db->lasterror(); + $error++; + } + + // If stock increment is done on reception (recommanded choice) + if (! $error && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + + $langs->load("agenda"); + + // Loop on each product line to add a stock movement + // TODO in future, reception lines may not be linked to order line + $sql = "SELECT cd.fk_product, cd.subprice,"; + $sql.= " ed.rowid, ed.qty, ed.fk_entrepot,"; + $sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock"; + $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,"; + $sql.= " ".MAIN_DB_PREFIX."receptiondet as ed"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."receptiondet_batch as edb on edb.fk_receptiondet = ed.rowid"; + $sql.= " WHERE ed.fk_reception = ".$this->id; + $sql.= " AND cd.rowid = ed.fk_origin_line"; + + dol_syslog(get_class($this)."::valid select details", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $cpt = $this->db->num_rows($resql); + for ($i = 0; $i < $cpt; $i++) + { + $obj = $this->db->fetch_object($resql); + if (empty($obj->edbrowid)) + { + $qty = $obj->qty; + } + else + { + $qty = $obj->edbqty; + } + if ($qty <= 0) continue; + dol_syslog(get_class($this)."::valid movement index ".$i." ed.rowid=".$obj->rowid." edb.rowid=".$obj->edbrowid); + + //var_dump($this->lines[$i]); + $mouvS = new MouvementStock($this->db); + $mouvS->origin = &$this; + + if (empty($obj->edbrowid)) + { + // line without batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record. + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionValidatedInDolibarr",$numref)); + if ($result < 0) { + $error++; + $this->errors[]=$mouvS->error; + $this->errors = array_merge($this->errors, $mouvS->errors); + break; + } + } + else + { + // line with batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record. + // Note: ->fk_origin_stock = id into table llx_product_batch (may be rename into llx_product_stock_batch in another version) + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionValidatedInDolibarr",$numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); + if ($result < 0) { + $error++; + $this->errors[]=$mouvS->error; + $this->errors = array_merge($this->errors, $mouvS->errors); + break; + } + } + } + } + else + { + $this->db->rollback(); + $this->error=$this->db->error(); + return -2; + } + + } + + // Change status of order to "reception in process" + $ret = $this->setStatut(Commande::STATUS_RECEPTIONONPROCESS, $this->origin_id, $this->origin); + + if (! $ret) + { + $error++; + } + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('RECEPTION_VALIDATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (! $error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // On renomme repertoire ($this->ref = ancienne ref, $numfa = nouvelle ref) + // in order not to lose the attached files + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($numref); + $dirsource = $conf->reception->dir_output.'/reception/'.$oldref; + $dirdest = $conf->reception->dir_output.'/reception/'.$newref; + if (file_exists($dirsource)) + { + dol_syslog(get_class($this)."::valid rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles=dol_dir_list($conf->reception->dir_output.'/reception/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); + foreach($listoffiles as $fileentry) + { + $dirsource=$fileentry['name']; + $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); + $dirsource=$fileentry['path'].'/'.$dirsource; + $dirdest=$fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (! $error) + { + $this->ref = $numref; + $this->statut = 1; + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::valid ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + + + /** + * Create a delivery receipt from a reception + * + * @param User $user User + * @return int <0 if KO, >=0 if OK + */ + function create_delivery($user) + { + global $conf; + + if ($conf->livraison_bon->enabled) + { + if ($this->statut == 1 || $this->statut == 2) + { + // Reception validee + include_once DOL_DOCUMENT_ROOT.'/livraison/class/livraison.class.php'; + $delivery = new Livraison($this->db); + $result=$delivery->create_from_reception($user, $this->id); + if ($result > 0) + { + return $result; + } + else + { + $this->error=$delivery->error; + return $result; + } + } + else return 0; + } + else return 0; + } + + /** + * Add an reception line. + * If STOCK_WAREHOUSE_NOT_REQUIRED_FOR_RECEPTIONS is set, you can add a reception line, with no stock source defined + * If STOCK_MUST_BE_ENOUGH_FOR_RECEPTION is not set, you can add a reception line, even if not enough into stock + * + * @param int $entrepot_id Id of warehouse + * @param int $id Id of source line (order line) + * @param int $qty Quantity + * @param array $array_options extrafields array + * @return int <0 if KO, >0 if OK + */ + function addline($entrepot_id, $id, $qty,$array_options=0) + { + global $conf, $langs; + + $num = count($this->lines); + $line = new ReceptionLigne($this->db); + + $line->entrepot_id = $entrepot_id; + $line->origin_line_id = $id; + $line->qty = $qty; + + $orderline = new OrderLine($this->db); + $orderline->fetch($id); + + if (! empty($conf->stock->enabled) && ! empty($orderline->fk_product)) + { + $fk_product = $orderline->fk_product; + + if (! ($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_RECEPTIONS)) + { + $langs->load("errors"); + $this->error=$langs->trans("ErrorWarehouseRequiredIntoReceptionLine"); + return -1; + } + + if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_RECEPTION) + { + // Check must be done for stock of product into warehouse if $entrepot_id defined + $product=new Product($this->db); + $result=$product->fetch($fk_product); + + if ($entrepot_id > 0) { + $product->load_stock('warehouseopen'); + $product_stock = $product->stock_warehouse[$entrepot_id]->real; + } + else + $product_stock = $product->stock_reel; + + $product_type=$product->type; + if ($product_type == 0 && $product_stock < $qty) + { + $langs->load("errors"); + $this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnReception', $product->ref); + $this->db->rollback(); + return -3; + } + } + } + + // If product need a batch number, we should not have called this function but addline_batch instead. + if (! empty($conf->productbatch->enabled) && ! empty($orderline->fk_product) && ! empty($orderline->product_tobatch)) + { + $this->error='ADDLINE_WAS_CALLED_INSTEAD_OF_ADDLINEBATCH'; + return -4; + } + + // extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options)>0) // For avoid conflicts if trigger used + $line->array_options = $array_options; + + $this->lines[$num] = $line; + } + + /** + * Add a reception line with batch record + * + * @param array $dbatch Array of value (key 'detail' -> Array, key 'qty' total quantity for line, key ix_l : original line index) + * @param array $array_options extrafields array + * @return int <0 if KO, >0 if OK + */ + function addline_batch($dbatch,$array_options=0) + { + global $conf,$langs; + + $num = count($this->lines); + if ($dbatch['qty']>0) + { + $line = new ReceptionLigne($this->db); + $tab=array(); + foreach ($dbatch['detail'] as $key=>$value) + { + if ($value['q']>0) + { + // $value['q']=qty to move + // $value['id_batch']=id into llx_product_batch of record to move + //var_dump($value); + + $linebatch = new ReceptionLineBatch($this->db); + $ret=$linebatch->fetchFromStock($value['id_batch']); // load serial, sellby, eatby + if ($ret<0) + { + $this->error=$linebatch->error; + return -1; + } + $linebatch->dluo_qty=$value['q']; + $tab[]=$linebatch; + + if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_RECEPTION) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; + $prod_batch = new Productbatch($this->db); + $prod_batch->fetch($value['id_batch']); + + if ($prod_batch->qty < $linebatch->dluo_qty) + { + $langs->load("errors"); + $this->errors[]=$langs->trans('ErrorStockIsNotEnoughToAddProductOnReception', $prod_batch->fk_product); + dol_syslog(get_class($this)."::addline_batch error=Product ".$prod_batch->batch.": ".$this->errorsToString(), LOG_ERR); + $this->db->rollback(); + return -1; + } + } + + //var_dump($linebatch); + } + } + $line->entrepot_id = $linebatch->entrepot_id; + $line->origin_line_id = $dbatch['ix_l']; + $line->qty = $dbatch['qty']; + $line->detail_batch=$tab; + + // extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options)>0) // For avoid conflicts if trigger used + $line->array_options = $array_options; + + //var_dump($line); + $this->lines[$num] = $line; + return 1; + } + } + + /** + * Update database + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user=null, $notrigger=0) + { + global $conf; + $error=0; + + // Clean parameters + + if (isset($this->ref)) $this->ref=trim($this->ref); + if (isset($this->entity)) $this->entity=trim($this->entity); + if (isset($this->ref_customer)) $this->ref_customer=trim($this->ref_customer); + if (isset($this->socid)) $this->socid=trim($this->socid); + if (isset($this->fk_user_author)) $this->fk_user_author=trim($this->fk_user_author); + if (isset($this->fk_user_valid)) $this->fk_user_valid=trim($this->fk_user_valid); + if (isset($this->fk_delivery_address)) $this->fk_delivery_address=trim($this->fk_delivery_address); + if (isset($this->reception_method_id)) $this->reception_method_id=trim($this->reception_method_id); + if (isset($this->tracking_number)) $this->tracking_number=trim($this->tracking_number); + if (isset($this->statut)) $this->statut=(int) $this->statut; + if (isset($this->trueDepth)) $this->trueDepth=trim($this->trueDepth); + if (isset($this->trueWidth)) $this->trueWidth=trim($this->trueWidth); + if (isset($this->trueHeight)) $this->trueHeight=trim($this->trueHeight); + if (isset($this->size_units)) $this->size_units=trim($this->size_units); + if (isset($this->weight_units)) $this->weight_units=trim($this->weight_units); + if (isset($this->trueWeight)) $this->weight=trim($this->trueWeight); + if (isset($this->note_private)) $this->note=trim($this->note_private); + if (isset($this->note_public)) $this->note=trim($this->note_public); + if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf); + + + + // Check parameters + // Put here code to add control on parameters values + + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX."reception SET"; + + $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; + $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; + $sql.= " ref_customer=".(isset($this->ref_customer)?"'".$this->db->escape($this->ref_customer)."'":"null").","; + $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").","; + $sql.= " date_creation=".(dol_strlen($this->date_creation)!=0 ? "'".$this->db->idate($this->date_creation)."'" : 'null').","; + $sql.= " fk_user_author=".(isset($this->fk_user_author)?$this->fk_user_author:"null").","; + $sql.= " date_valid=".(dol_strlen($this->date_valid)!=0 ? "'".$this->db->idate($this->date_valid)."'" : 'null').","; + $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").","; + $sql.= " date_reception=".(dol_strlen($this->date_reception)!=0 ? "'".$this->db->idate($this->date_reception)."'" : 'null').","; + $sql.= " date_delivery=".(dol_strlen($this->date_delivery)!=0 ? "'".$this->db->idate($this->date_delivery)."'" : 'null').","; + $sql.= " fk_address=".(isset($this->fk_delivery_address)?$this->fk_delivery_address:"null").","; + $sql.= " fk_reception_method=".((isset($this->reception_method_id) && $this->reception_method_id > 0)?$this->reception_method_id:"null").","; + $sql.= " tracking_number=".(isset($this->tracking_number)?"'".$this->db->escape($this->tracking_number)."'":"null").","; + $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").","; + $sql.= " height=".(($this->trueHeight != '')?$this->trueHeight:"null").","; + $sql.= " width=".(($this->trueWidth != '')?$this->trueWidth:"null").","; + $sql.= " size_units=".(isset($this->size_units)?$this->size_units:"null").","; + $sql.= " size=".(($this->trueDepth != '')?$this->trueDepth:"null").","; + $sql.= " weight_units=".(isset($this->weight_units)?$this->weight_units:"null").","; + $sql.= " weight=".(($this->trueWeight != '')?$this->trueWeight:"null").","; + $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; + $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; + $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").","; + $sql.= " entity=".$conf->entity; + + $sql.= " WHERE rowid=".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('RECEPTION_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + /** + * Delete reception. + * Warning, do not delete a reception if a delivery is linked to (with table llx_element_element) + * + * @return int >0 if OK, 0 if deletion done but failed to delete files, <0 if KO + */ + function delete() + { + global $conf, $langs, $user; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + if ($conf->productbatch->enabled) + { + require_once DOL_DOCUMENT_ROOT.'/reception/class/receptionbatch.class.php'; + } + $error=0; + $this->error=''; + + // Add a protection to refuse deleting if reception has at least one delivery + $this->fetchObjectLinked($this->id, 'reception', 0, 'delivery'); // Get deliveries linked to this reception + if (count($this->linkedObjectsIds) > 0) + { + $this->error='ErrorThereIsSomeDeliveries'; + return -1; + } + + $this->db->begin(); + // Stock control + if ($conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_RECEPTION && $this->statut > 0) + { + require_once(DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php"); + + $langs->load("agenda"); + + // Loop on each product line to add a stock movement + $sql = "SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.rowid as receptiondet_id"; + $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,"; + $sql.= " ".MAIN_DB_PREFIX."receptiondet as ed"; + $sql.= " WHERE ed.fk_reception = ".$this->id; + $sql.= " AND cd.rowid = ed.fk_origin_line"; + + dol_syslog(get_class($this)."::delete select details", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $cpt = $this->db->num_rows($resql); + for ($i = 0; $i < $cpt; $i++) + { + dol_syslog(get_class($this)."::delete movement index ".$i); + $obj = $this->db->fetch_object($resql); + + $mouvS = new MouvementStock($this->db); + // we do not log origin because it will be deleted + $mouvS->origin = null; + // get lot/serial + $lotArray = null; + if ($conf->productbatch->enabled) + { + $lotArray = ReceptionLineBatch::fetchAll($this->db,$obj->receptiondet_id); + if (! is_array($lotArray)) + { + $error++;$this->errors[]="Error ".$this->db->lasterror(); + } + } + if (empty($lotArray)) { + // no lot/serial + // We increment stock of product (and sub-products) + // We use warehouse selected for each line + $result=$mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans("ReceptionDeletedInDolibarr", $this->ref)); // Price is set to 0, because we don't want to see WAP changed + if ($result < 0) + { + $error++;$this->errors=$this->errors + $mouvS->errors; + break; + } + } + else + { + // We increment stock of batches + // We use warehouse selected for each line + foreach($lotArray as $lot) + { + $result=$mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $lot->dluo_qty, 0, $langs->trans("ReceptionDeletedInDolibarr", $this->ref), $lot->eatby, $lot->sellby, $lot->batch); // Price is set to 0, because we don't want to see WAP changed + if ($result < 0) + { + $error++;$this->errors=$this->errors + $mouvS->errors; + break; + } + } + if ($error) break; // break for loop incase of error + } + } + } + else + { + $error++;$this->errors[]="Error ".$this->db->lasterror(); + } + } + + // delete batch reception line + if (! $error && $conf->productbatch->enabled) + { + if (ReceptionLineBatch::deletefromexp($this->db,$this->id) < 0) + { + $error++;$this->errors[]="Error ".$this->db->lasterror(); + } + } + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."receptiondet"; + $sql.= " WHERE fk_reception = ".$this->id; + + if ( $this->db->query($sql) ) + { + // Delete linked object + $res = $this->deleteObjectLinked(); + if ($res < 0) $error++; + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."reception"; + $sql.= " WHERE rowid = ".$this->id; + + if ($this->db->query($sql)) + { + // Call trigger + $result=$this->call_trigger('RECEPTION_DELETE',$user); + if ($result < 0) { $error++; } + // End call triggers + + if (! empty($this->origin) && $this->origin_id > 0) + { + $this->fetch_origin(); + $origin=$this->origin; + if ($this->$origin->statut == Commande::STATUS_RECEPTIONONPROCESS) // If order source of reception is "reception in progress" + { + // Check if there is no more reception. If not, we can move back status of order to "validated" instead of "reception in progress" + $this->$origin->loadReceptions(); + //var_dump($this->$origin->receptions);exit; + if (count($this->$origin->receptions) <= 0) + { + $this->$origin->setStatut(Commande::STATUS_VALIDATED); + } + } + } + + if (! $error) + { + $this->db->commit(); + + // We delete PDFs + $ref = dol_sanitizeFileName($this->ref); + if (! empty($conf->reception->dir_output)) + { + $dir = $conf->reception->dir_output . '/reception/' . $ref ; + $file = $dir . '/' . $ref . '.pdf'; + if (file_exists($file)) + { + if (! dol_delete_file($file)) + { + return 0; + } + } + if (file_exists($dir)) + { + if (!dol_delete_dir_recursive($dir)) + { + $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir); + return 0; + } + } + } + + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->lasterror()." - sql=$sql"; + $this->db->rollback(); + return -3; + } + } + else + { + $this->error=$this->db->lasterror()." - sql=$sql"; + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->lasterror()." - sql=$sql"; + $this->db->rollback(); + return -1; + } + } + else + { + $this->db->rollback(); + return -1; + } + + } + + /** + * Load lines + * + * @return int >0 if OK, Otherwise if KO + */ + function fetch_lines() + { + global $conf, $mysoc; + // TODO: recuperer les champs du document associe a part + + $sql = "SELECT cd.rowid, cd.fk_product, cd.label as custom_label, cd.description, cd.qty as qty_asked, cd.product_type"; + $sql.= ", cd.total_ht, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.total_tva"; + $sql.= ", cd.vat_src_code, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.price, cd.subprice, cd.remise_percent,cd.buy_price_ht as pa_ht"; + $sql.= ", cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc"; + $sql.= ", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot"; + $sql.= ", p.ref as product_ref, p.label as product_label, p.fk_product_type"; + $sql.= ", p.weight, p.weight_units, p.length, p.length_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tobatch as product_tobatch"; + $sql.= " FROM (".MAIN_DB_PREFIX."receptiondet as ed,"; + $sql.= " ".MAIN_DB_PREFIX."commandedet as cd)"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product"; + $sql.= " WHERE ed.fk_reception = ".$this->id; + $sql.= " AND ed.fk_origin_line = cd.rowid"; + $sql.= " ORDER BY cd.rang, ed.fk_origin_line"; + + dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + + $num = $this->db->num_rows($resql); + $i = 0; + $lineindex = 0; + $originline = 0; + + $this->total_ht = 0; + $this->total_tva = 0; + $this->total_ttc = 0; + $this->total_localtax1 = 0; + $this->total_localtax2 = 0; + + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + if ($originline == $obj->fk_origin_line) { + $line->entrepot_id = 0; // entrepod_id in details_entrepot + $line->qty_shipped += $obj->qty_shipped; + } else { + $line = new ReceptionLigne($this->db); + $line->entrepot_id = $obj->fk_entrepot; + $line->qty_shipped = $obj->qty_shipped; + } + + $detail_entrepot = new stdClass; + $detail_entrepot->entrepot_id = $obj->fk_entrepot; + $detail_entrepot->qty_shipped = $obj->qty_shipped; + $line->details_entrepot[] = $detail_entrepot; + + $line->line_id = $obj->line_id; + $line->rowid = $obj->line_id; // TODO deprecated + $line->id = $obj->line_id; + + $line->fk_origin = 'orderline'; + $line->fk_origin_line = $obj->fk_origin_line; + $line->origin_line_id = $obj->fk_origin_line; // TODO deprecated + + $line->fk_reception = $this->id; // id of parent + + $line->product_type = $obj->product_type; + $line->fk_product = $obj->fk_product; + $line->fk_product_type = $obj->fk_product_type; + $line->ref = $obj->product_ref; // TODO deprecated + $line->product_ref = $obj->product_ref; + $line->product_label = $obj->product_label; + $line->libelle = $obj->product_label; // TODO deprecated + $line->product_tobatch = $obj->product_tobatch; + $line->label = $obj->custom_label; + $line->description = $obj->description; + $line->qty_asked = $obj->qty_asked; + $line->weight = $obj->weight; + $line->weight_units = $obj->weight_units; + $line->length = $obj->length; + $line->length_units = $obj->length_units; + $line->surface = $obj->surface; + $line->surface_units = $obj->surface_units; + $line->volume = $obj->volume; + $line->volume_units = $obj->volume_units; + + $line->pa_ht = $obj->pa_ht; + + // Local taxes + $localtax_array=array(0=>$obj->localtax1_type, 1=>$obj->localtax1_tx, 2=>$obj->localtax2_type, 3=>$obj->localtax2_tx); + $localtax1_tx = get_localtax($obj->tva_tx, 1, $this->thirdparty); + $localtax2_tx = get_localtax($obj->tva_tx, 2, $this->thirdparty); + + // For invoicing + $tabprice = calcul_price_total($obj->qty_shipped, $obj->subprice, $obj->remise_percent, $obj->tva_tx, $localtax1_tx, $localtax2_tx, 0, 'HT', $obj->info_bits, $obj->fk_product_type, $mysoc, $localtax_array); // We force type to 0 + $line->desc = $obj->description; // We need ->desc because some code into CommonObject use desc (property defined for other elements) + $line->qty = $line->qty_shipped; + $line->total_ht = $tabprice[0]; + $line->total_localtax1 = $tabprice[9]; + $line->total_localtax2 = $tabprice[10]; + $line->total_ttc = $tabprice[2]; + $line->total_tva = $tabprice[1]; + $line->vat_src_code = $obj->vat_src_code; + $line->tva_tx = $obj->tva_tx; + $line->localtax1_tx = $obj->localtax1_tx; + $line->localtax2_tx = $obj->localtax2_tx; + $line->price = $obj->price; + $line->subprice = $obj->subprice; + $line->remise_percent = $obj->remise_percent; + + $this->total_ht+= $tabprice[0]; + $this->total_tva+= $tabprice[1]; + $this->total_ttc+= $tabprice[2]; + $this->total_localtax1+= $tabprice[9]; + $this->total_localtax2+= $tabprice[10]; + + // Multicurrency + $this->fk_multicurrency = $obj->fk_multicurrency; + $this->multicurrency_code = $obj->multicurrency_code; + $this->multicurrency_subprice = $obj->multicurrency_subprice; + $this->multicurrency_total_ht = $obj->multicurrency_total_ht; + $this->multicurrency_total_tva = $obj->multicurrency_total_tva; + $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc; + + if ($originline != $obj->fk_origin_line) + { + $line->detail_batch = array(); + } + // Eat-by date + if (! empty($conf->productbatch->enabled) && $obj->line_id > 0) + { + require_once DOL_DOCUMENT_ROOT.'/reception/class/receptionbatch.class.php'; + + $newdetailbatch = ReceptionLineBatch::fetchAll($this->db,$obj->line_id); + if (is_array($newdetailbatch)) + { + if ($originline != $obj->fk_origin_line) + { + $line->detail_batch = $newdetailbatch; + } + else + { + $line->detail_batch = array_merge($line->detail_batch, $newdetailbatch); + } + } + } + + if ($originline != $obj->fk_origin_line) + { + $this->lines[$lineindex] = $line; + $lineindex++; + } + else + { + $line->total_ht += $tabprice[0]; + $line->total_localtax1 += $tabprice[9]; + $line->total_localtax2 += $tabprice[10]; + $line->total_ttc += $tabprice[2]; + $line->total_tva += $tabprice[1]; + } + + $i++; + $originline = $obj->fk_origin_line; + } + $this->db->free($resql); + return 1; + } + else + { + $this->error=$this->db->error(); + return -3; + } + } + + /** + * Return clicable link of object (with eventually picto) + * + * @param int $withpicto Add picto into link + * @param int $option Where point the link + * @param int $max Max length to show + * @param int $short Use short labels + * @param int $notooltip 1=No tooltip + * @return string String with URL + */ + function getNomUrl($withpicto=0,$option=0,$max=0,$short=0,$notooltip=0) + { + global $langs; + + $result=''; + $label = '' . $langs->trans("ShowReception") . ''; + $label .= '
' . $langs->trans('Ref') . ': '.$this->ref; + $label .= '
'.$langs->trans('RefCustomer').': '.($this->ref_customer ? $this->ref_customer : $this->ref_client); + + $url = DOL_URL_ROOT.'/reception/card.php?id='.$this->id; + + if ($short) return $url; + + $linkclose=''; + if (empty($notooltip)) + { + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label=$langs->trans("ShowReception"); + $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose.=' class="classfortooltip"'; + } + + $linkstart = ''; + $linkend=''; + + $picto='reception'; + + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); + if ($withpicto && $withpicto != 2) $result.=' '; + $result.=$linkstart.$this->ref.$linkend; + return $result; + } + + /** + * Return status label + * + * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto + * @return string Libelle + */ + function getLibStatut($mode=0) + { + return $this->LibStatut($this->statut,$mode); + } + + /** + * Return label of a status + * + * @param int $statut Id statut + * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto + * @return string Label of status + */ + function LibStatut($statut,$mode) + { + global $langs; + + if ($mode==0) + { + if ($statut==0) return $langs->trans($this->statuts[$statut]); + if ($statut==1) return $langs->trans($this->statuts[$statut]); + if ($statut==2) return $langs->trans($this->statuts[$statut]); + } + if ($mode==1) + { + if ($statut==0) return $langs->trans('StatusReceptionDraftShort'); + if ($statut==1) return $langs->trans('StatusReceptionValidatedShort'); + if ($statut==2) return $langs->trans('StatusReceptionProcessedShort'); + } + if ($mode == 3) + { + if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0'); + if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4'); + if ($statut==2) return img_picto($langs->trans('StatusReceptionProcessed'),'statut6'); + } + if ($mode == 4) + { + if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]); + if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]); + if ($statut==2) return img_picto($langs->trans('StatusReceptionProcessed'),'statut6').' '.$langs->trans('StatusReceptionProcessed'); + } + if ($mode == 5) + { + if ($statut==0) return $langs->trans('StatusReceptionDraftShort').' '.img_picto($langs->trans($this->statuts[$statut]),'statut0'); + if ($statut==1) return $langs->trans('StatusReceptionValidatedShort').' '.img_picto($langs->trans($this->statuts[$statut]),'statut4'); + if ($statut==2) return $langs->trans('StatusReceptionProcessedShort').' '.img_picto($langs->trans('StatusReceptionProcessedShort'),'statut6'); + } + } + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + global $langs; + + $now=dol_now(); + + dol_syslog(get_class($this)."::initAsSpecimen"); + + // Load array of products prodids + $num_prods = 0; + $prodids = array(); + $sql = "SELECT rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."product"; + $sql.= " WHERE entity IN (".getEntity('product').")"; + $resql = $this->db->query($sql); + if ($resql) + { + $num_prods = $this->db->num_rows($resql); + $i = 0; + while ($i < $num_prods) + { + $i++; + $row = $this->db->fetch_row($resql); + $prodids[$i] = $row[0]; + } + } + + $order=new Commande($this->db); + $order->initAsSpecimen(); + + // Initialise parametres + $this->id=0; + $this->ref = 'SPECIMEN'; + $this->specimen=1; + $this->statut = 1; + $this->livraison_id = 0; + $this->date = $now; + $this->date_creation = $now; + $this->date_valid = $now; + $this->date_delivery = $now; + $this->date_reception = $now + 24*3600; + + $this->entrepot_id = 0; + $this->fk_delivery_address = 0; + $this->socid = 1; + + $this->commande_id = 0; + $this->commande = $order; + + $this->origin_id = 1; + $this->origin = 'commande'; + + $this->note_private = 'Private note'; + $this->note_public = 'Public note'; + + $nbp = 5; + $xnbp = 0; + while ($xnbp < $nbp) + { + $line=new ReceptionLigne($this->db); + $line->desc=$langs->trans("Description")." ".$xnbp; + $line->libelle=$langs->trans("Description")." ".$xnbp; + $line->qty=10; + $line->qty_asked=5; + $line->qty_shipped=4; + $line->fk_product=$this->commande->lines[$xnbp]->fk_product; + + $this->lines[]=$line; + $xnbp++; + } + + } + + /** + * Set the planned delivery date + * + * @param User $user Objet utilisateur qui modifie + * @param timestamp $date_livraison Date de livraison + * @return int <0 if KO, >0 if OK + */ + function set_date_livraison($user, $date_livraison) + { + if ($user->rights->reception->creer) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."reception"; + $sql.= " SET date_delivery = ".($date_livraison ? "'".$this->db->idate($date_livraison)."'" : 'null'); + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::set_date_livraison", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->date_delivery = $date_livraison; + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + else + { + return -2; + } + } + + /** + * Fetch deliveries method and return an array. Load array this->meths(rowid=>label). + * + * @return void + */ + function fetch_delivery_methods() + { + global $langs; + $this->meths = array(); + + $sql = "SELECT em.rowid, em.code, em.libelle"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_reception_mode as em"; + $sql.= " WHERE em.active = 1"; + $sql.= " ORDER BY em.libelle ASC"; + + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + $label=$langs->trans('ReceptionMethod'.$obj->code); + $this->meths[$obj->rowid] = ($label != 'ReceptionMethod'.$obj->code?$label:$obj->libelle); + } + } + } + + /** + * Fetch all deliveries method and return an array. Load array this->listmeths. + * + * @param id $id only this carrier, all if none + * @return void + */ + function list_delivery_methods($id='') + { + global $langs; + + $this->listmeths = array(); + $i=0; + + $sql = "SELECT em.rowid, em.code, em.libelle, em.description, em.tracking, em.active"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_reception_mode as em"; + if ($id!='') $sql.= " WHERE em.rowid=".$id; + + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + $this->listmeths[$i]['rowid'] = $obj->rowid; + $this->listmeths[$i]['code'] = $obj->code; + $label=$langs->trans('ReceptionMethod'.$obj->code); + $this->listmeths[$i]['libelle'] = ($label != 'ReceptionMethod'.$obj->code?$label:$obj->libelle); + $this->listmeths[$i]['description'] = $obj->description; + $this->listmeths[$i]['tracking'] = $obj->tracking; + $this->listmeths[$i]['active'] = $obj->active; + $i++; + } + } + } + + /** + * Update/create delivery method. + * + * @param string $id id method to activate + * + * @return void + */ + function update_delivery_method($id='') + { + if ($id=='') + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."c_reception_mode (code, libelle, description, tracking)"; + $sql.=" VALUES ('".$this->update['code']."','".$this->update['libelle']."','".$this->update['description']."','".$this->update['tracking']."')"; + $resql = $this->db->query($sql); + } + else + { + $sql = "UPDATE ".MAIN_DB_PREFIX."c_reception_mode SET"; + $sql.= " code='".$this->db->escape($this->update['code'])."'"; + $sql.= ",libelle='".$this->db->escape($this->update['libelle'])."'"; + $sql.= ",description='".$this->db->escape($this->update['description'])."'"; + $sql.= ",tracking='".$this->db->escape($this->update['tracking'])."'"; + $sql.= " WHERE rowid=".$id; + $resql = $this->db->query($sql); + } + if ($resql < 0) dol_print_error($this->db,''); + } + + /** + * Activate delivery method. + * + * @param id $id id method to activate + * + * @return void + */ + function activ_delivery_method($id) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'c_reception_mode SET active=1'; + $sql.= ' WHERE rowid='.$id; + + $resql = $this->db->query($sql); + + } + + /** + * DesActivate delivery method. + * + * @param id $id id method to desactivate + * + * @return void + */ + function disable_delivery_method($id) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX.'c_reception_mode SET active=0'; + $sql.= ' WHERE rowid='.$id; + + $resql = $this->db->query($sql); + + } + + + /** + * Forge an set tracking url + * + * @param string $value Value + * @return void + */ + function GetUrlTrackingStatus($value='') + { + if (! empty($this->reception_method_id)) + { + $sql = "SELECT em.code, em.tracking"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_reception_mode as em"; + $sql.= " WHERE em.rowid = ".$this->reception_method_id; + + $resql = $this->db->query($sql); + if ($resql) + { + if ($obj = $this->db->fetch_object($resql)) + { + $tracking = $obj->tracking; + } + } + } + + if (!empty($tracking) && !empty($value)) + { + $url = str_replace('{TRACKID}', $value, $tracking); + $this->tracking_url = sprintf(''.($value?$value:'url').'',$url,$url); + } + else + { + $this->tracking_url = $value; + } + } + + /** + * Classify the reception as closed. + * + * @return int <0 if KO, >0 if OK + */ + function setClosed() + { + global $conf,$langs,$user; + + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'reception SET fk_statut='.self::STATUS_CLOSED; + $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0'; + + $resql=$this->db->query($sql); + if ($resql) + { + // Set order billed if 100% of order is shipped (qty in reception lines match qty in order lines) + if ($this->origin == 'commande' && $this->origin_id > 0) + { + $order = new Commande($this->db); + $order->fetch($this->origin_id); + + $order->loadReceptions(self::STATUS_CLOSED); // Fill $order->receptions = array(orderlineid => qty) + + $receptions_match_order = 1; + foreach($order->lines as $line) + { + $lineid = $line->id; + $qty = $line->qty; + if (($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) && $order->receptions[$lineid] != $qty) + { + $receptions_match_order = 0; + $text='Qty for order line id '.$lineid.' is '.$qty.'. However in the receptions with status Reception::STATUS_CLOSED='.self::STATUS_CLOSED.' we have qty = '.$order->receptions[$lineid].', so we can t close order'; + dol_syslog($text); + break; + } + } + if ($receptions_match_order) + { + dol_syslog("Qty for the ".count($order->lines)." lines of order have same value for receptions with status Reception::STATUS_CLOSED=".self::STATUS_CLOSED.', so we close order'); + $order->cloture($user); + } + } + + $this->statut=self::STATUS_CLOSED; + + + // If stock increment is done on closing + if (! $error && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + + $langs->load("agenda"); + + // Loop on each product line to add a stock movement + // TODO possibilite d'expedier a partir d'une propale ou autre origine ? + $sql = "SELECT cd.fk_product, cd.subprice,"; + $sql.= " ed.rowid, ed.qty, ed.fk_entrepot,"; + $sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock"; + $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,"; + $sql.= " ".MAIN_DB_PREFIX."receptiondet as ed"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."receptiondet_batch as edb on edb.fk_receptiondet = ed.rowid"; + $sql.= " WHERE ed.fk_reception = ".$this->id; + $sql.= " AND cd.rowid = ed.fk_origin_line"; + + dol_syslog(get_class($this)."::valid select details", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $cpt = $this->db->num_rows($resql); + for ($i = 0; $i < $cpt; $i++) + { + $obj = $this->db->fetch_object($resql); + if (empty($obj->edbrowid)) + { + $qty = $obj->qty; + } + else + { + $qty = $obj->edbqty; + } + if ($qty <= 0) continue; + dol_syslog(get_class($this)."::valid movement index ".$i." ed.rowid=".$obj->rowid." edb.rowid=".$obj->edbrowid); + + $mouvS = new MouvementStock($this->db); + $mouvS->origin = &$this; + + if (empty($obj->edbrowid)) + { + // line without batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionClassifyClosedInDolibarr",$numref)); + if ($result < 0) { + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; + } + } + else + { + // line with batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ReceptionClassifyClosedInDolibarr",$numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); + if ($result < 0) { + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; + } + } + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + } + + // Call trigger + if (! $error) + { + $result=$this->call_trigger('RECEPTION_CLOSED',$user); + if ($result < 0) { + $error++; + } + } + } + else + { + dol_print_error($this->db); + $error++; + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Classify the reception as invoiced (used when WORKFLOW_BILL_ON_RECEPTION is on) + * + * @return int <0 if ko, >0 if ok + */ + function set_billed() + { + global $user; + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'reception SET fk_statut=2, billed=1'; // TODO Update only billed + $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0'; + + $resql=$this->db->query($sql); + if ($resql) + { + $this->statut=2; + $this->billed=1; + + // Call trigger + $result=$this->call_trigger('RECEPTION_BILLED',$user); + if ($result < 0) { + $error++; + } + + } else { + $error++; + $this->errors[]=$this->db->lasterror; + } + + if (empty($error)) { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Classify the reception as validated/opened + * + * @return int <0 if ko, >0 if ok + */ + function reOpen() + { + global $conf,$langs,$user; + + $error=0; + + $this->db->begin(); + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'reception SET fk_statut=1'; + $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0'; + + $resql=$this->db->query($sql); + if ($resql) + { + $this->statut=1; + $this->billed=0; + + // If stock increment is done on closing + if (! $error && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + + $langs->load("agenda"); + + // Loop on each product line to add a stock movement + // TODO possibilite d'expedier a partir d'une propale ou autre origine + $sql = "SELECT cd.fk_product, cd.subprice,"; + $sql.= " ed.rowid, ed.qty, ed.fk_entrepot,"; + $sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock"; + $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,"; + $sql.= " ".MAIN_DB_PREFIX."receptiondet as ed"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."receptiondet_batch as edb on edb.fk_receptiondet = ed.rowid"; + $sql.= " WHERE ed.fk_reception = ".$this->id; + $sql.= " AND cd.rowid = ed.fk_origin_line"; + + dol_syslog(get_class($this)."::valid select details", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $cpt = $this->db->num_rows($resql); + for ($i = 0; $i < $cpt; $i++) + { + $obj = $this->db->fetch_object($resql); + if (empty($obj->edbrowid)) + { + $qty = $obj->qty; + } + else + { + $qty = $obj->edbqty; + } + if ($qty <= 0) continue; + dol_syslog(get_class($this)."::reopen reception movement index ".$i." ed.rowid=".$obj->rowid." edb.rowid=".$obj->edbrowid); + + //var_dump($this->lines[$i]); + $mouvS = new MouvementStock($this->db); + $mouvS->origin = &$this; + + if (empty($obj->edbrowid)) + { + // line without batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionUnClassifyCloseddInDolibarr",$numref)); + if ($result < 0) { + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; + } + } + else + { + // line with batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionUnClassifyCloseddInDolibarr",$numref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); + if ($result < 0) { + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; + } + } + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + } + + if (! $error) + { + // Call trigger + $result=$this->call_trigger('RECEPTION_REOPEN',$user); + if ($result < 0) { + $error++; + } + } + + } else { + $error++; + $this->errors[]=$this->db->lasterror(); + } + + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; + } + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @return int <0 if KO, >0 if OK + */ + function set_draft($user) + { + global $conf,$langs; + + $error=0; + + // Protection + if ($this->statut <= self::STATUS_DRAFT) + { + return 0; + } + + if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->reception->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->reception->reception_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + } + + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."reception"; + $sql.= " SET fk_statut = ".self::STATUS_DRAFT; + $sql.= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::set_draft", LOG_DEBUG); + if ($this->db->query($sql)) + { + // If stock increment is done on closing + if (! $error && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION)) + { + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; + + $langs->load("agenda"); + + // Loop on each product line to add a stock movement + // TODO possibilite d'expedier a partir d'une propale ou autre origine + $sql = "SELECT cd.fk_product, cd.subprice,"; + $sql.= " ed.rowid, ed.qty, ed.fk_entrepot,"; + $sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock"; + $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,"; + $sql.= " ".MAIN_DB_PREFIX."receptiondet as ed"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."receptiondet_batch as edb on edb.fk_receptiondet = ed.rowid"; + $sql.= " WHERE ed.fk_reception = ".$this->id; + $sql.= " AND cd.rowid = ed.fk_origin_line"; + + dol_syslog(get_class($this)."::valid select details", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $cpt = $this->db->num_rows($resql); + for ($i = 0; $i < $cpt; $i++) + { + $obj = $this->db->fetch_object($resql); + if (empty($obj->edbrowid)) + { + $qty = $obj->qty; + } + else + { + $qty = $obj->edbqty; + } + if ($qty <= 0) continue; + dol_syslog(get_class($this)."::reopen reception movement index ".$i." ed.rowid=".$obj->rowid." edb.rowid=".$obj->edbrowid); + + //var_dump($this->lines[$i]); + $mouvS = new MouvementStock($this->db); + $mouvS->origin = &$this; + + if (empty($obj->edbrowid)) + { + // line without batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionBackToDraftInDolibarr",$this->ref)); + if ($result < 0) { + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; + } + } + else + { + // line with batch detail + + // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, -$qty, $obj->subprice, $langs->trans("ReceptionBackToDraftInDolibarr",$this->ref), '', $this->db->jdate($obj->eatby), $this->db->jdate($obj->sellby), $obj->batch, $obj->fk_origin_stock); + if ($result < 0) { + $this->error = $mouvS->error; + $this->errors = $mouvS->errors; + $error++; break; + } + } + } + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + } + + if (!$error) { + // Call trigger + $result=$this->call_trigger('RECEPTION_UNVALIDATE',$user); + if ($result < 0) $error++; + } + if($this->origin == 'commande'){ + $commande = new Commande($this->db); + $commande->fetch($this->origin_id); + $commande->statut = Commande::STATUS_VALIDATED; + $commande->update(); + } + + + if (!$error) { + $this->statut=self::STATUS_DRAFT; + $this->db->commit(); + return 1; + }else { + $this->db->rollback(); + return -1; + } + } + else + { + $this->error=$this->db->error(); + $this->db->rollback(); + return -1; + } + } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force the model to using ('' to not force) + * @param Translate $outputlangs object lang to use for translations + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs,$hidedetails=0, $hidedesc=0, $hideref=0) + { + global $conf,$langs; + + $langs->load("receptions"); + + if (! dol_strlen($modele)) { + + $modele = 'rouget'; + + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (! empty($conf->global->RECEPTION_ADDON_PDF)) { + $modele = $conf->global->RECEPTION_ADDON_PDF; + } + } + + $modelpath = "core/modules/reception/doc/"; + + $this->fetch_origin(); + + return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + /** + * Function used to replace a thirdparty id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old thirdparty id + * @param int $dest_id New thirdparty id + * @return bool + */ + public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'reception' + ); + + return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); + } +} + + +/** + * Classe de gestion des lignes de bons d'reception + */ +class ReceptionLigne extends CommonObjectLine +{ + public $element='receptiondet'; + public $table_element='receptiondet'; + + public $fk_origin_line; + + /** + * Id of reception + * @var int + */ + public $fk_reception; + + var $db; + + // From llx_receptiondet + var $qty; + var $qty_shipped; + var $fk_product; + var $detail_batch; + /** + * Id of warehouse + * @var int + */ + public $entrepot_id; + + + // From llx_commandedet or llx_propaldet + var $qty_asked; + public $product_ref; + public $product_label; + public $product_desc; + + + // Invoicing + var $remise_percent; + var $total_ht; // Total net of tax + var $total_ttc; // Total with tax + var $total_tva; // Total VAT + var $total_localtax1; // Total Local tax 1 + var $total_localtax2; // Total Local tax 2 + + + + // Deprecated + /** + * @deprecated + * @see fk_origin_line + */ + var $origin_line_id; + /** + * @deprecated + * @see product_ref + */ + var $ref; + /** + * @deprecated + * @see product_label + */ + var $libelle; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db=$db; + } + + /** + * Load line reception + * + * @param int $rowid Id line order + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid) + { + $sql = 'SELECT ed.rowid, ed.fk_reception, ed.fk_entrepot, ed.fk_origin_line, ed.qty, ed.rang'; + $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as ed'; + $sql.= ' WHERE ed.rowid = '.$rowid; + $result = $this->db->query($sql); + if ($result) + { + $objp = $this->db->fetch_object($result); + $this->id = $objp->rowid; + $this->fk_reception = $objp->fk_reception; + $this->entrepot_id = $objp->fk_entrepot; + $this->fk_origin_line = $objp->fk_origin_line; + $this->qty = $objp->qty; + $this->rang = $objp->rang; + + $this->db->free($result); + + return 1; + } + else + { + $this->errors[] = $this->db->lasterror(); + $this->error = $this->db->lasterror(); + return -1; + } + } + + /** + * Insert line into database + * + * @param User $user User that modify + * @param int $notrigger 1 = disable triggers + * @return int <0 if KO, line id >0 if OK + */ + function insert($user=null, $notrigger=0) + { + global $langs, $conf; + + $error=0; + + // Check parameters + if (empty($this->fk_reception) || empty($this->fk_origin_line) || ! is_numeric($this->qty)) + { + $this->error = 'ErrorMandatoryParametersNotProvided'; + return -1; + } + // Clean parameters + if (empty($this->entrepot_id)) $this->entrepot_id='null'; + + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."receptiondet ("; + $sql.= "fk_reception"; + $sql.= ", fk_entrepot"; + $sql.= ", fk_origin_line"; + $sql.= ", qty"; + $sql.= ") VALUES ("; + $sql.= $this->fk_reception; + $sql.= ", ".$this->entrepot_id; + $sql.= ", ".$this->fk_origin_line; + $sql.= ", ".$this->qty; + $sql.= ")"; + + dol_syslog(get_class($this)."::insert", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."receptiondet"); + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINERECEPTION_INSERT',$user); + if ($result < 0) + { + $error++; + } + // End call triggers + } + + if (! $error) { + $this->db->commit(); + return $this->id; + } + + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + + $this->db->rollback(); + return -1*$error; + } + else + { + $error++; + } + } + + /** + * Delete reception line. + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int >0 if OK, <0 if KO + */ + function delete($user = null, $notrigger = 0) + { + global $conf; + + $error=0; + + $this->db->begin(); + + // delete batch reception line + if ($conf->productbatch->enabled) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."receptiondet_batch"; + $sql.= " WHERE fk_receptiondet = ".$this->id; + + if (!$this->db->query($sql)) + { + $this->errors[]=$this->db->lasterror()." - sql=$sql"; + $error++; + } + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."receptiondet"; + $sql.= " WHERE rowid = ".$this->id; + + if (! $error && $this->db->query($sql)) + { + // Remove extrafields + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $this->errors[]=$this->error; + $error++; + } + } + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINERECEPTION_DELETE',$user); + if ($result < 0) + { + $this->errors[]=$this->error; + $error++; + } + // End call triggers + } + } + else + { + $this->errors[]=$this->db->lasterror()." - sql=$sql"; + $error++; + } + + if (! $error) { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } + + /** + * Update a line in database + * + * @param User $user User that modify + * @param int $notrigger 1 = disable triggers + * @return int < 0 if KO, > 0 if OK + */ + function update($user = null, $notrigger = 0) + { + global $conf; + + $error=0; + + dol_syslog(get_class($this)."::update id=$this->id, entrepot_id=$this->entrepot_id, product_id=$this->fk_product, qty=$this->qty"); + + $this->db->begin(); + + // Clean parameters + if (empty($this->qty)) $this->qty=0; + $qty=price2num($this->qty); + $remainingQty = 0; + $batch = null; + $batch_id = null; + $reception_batch_id = null; + if (is_array($this->detail_batch)) // array of ReceptionLineBatch + { + if (count($this->detail_batch) > 1) + { + dol_syslog(get_class($this).'::update only possible for one batch', LOG_ERR); + $this->errors[]='ErrorBadParameters'; + $error++; + } + else + { + $batch = $this->detail_batch[0]->batch; + $batch_id = $this->detail_batch[0]->fk_origin_stock; + $reception_batch_id = $this->detail_batch[0]->id; + if ($this->entrepot_id != $this->detail_batch[0]->entrepot_id) + { + dol_syslog(get_class($this).'::update only possible for batch of same warehouse', LOG_ERR); + $this->errors[]='ErrorBadParameters'; + $error++; + } + $qty = price2num($this->detail_batch[0]->dluo_qty); + } + } + else if (! empty($this->detail_batch)) + { + $batch = $this->detail_batch->batch; + $batch_id = $this->detail_batch->fk_origin_stock; + $reception_batch_id = $this->detail_batch->id; + if ($this->entrepot_id != $this->detail_batch->entrepot_id) + { + dol_syslog(get_class($this).'::update only possible for batch of same warehouse', LOG_ERR); + $this->errors[]='ErrorBadParameters'; + $error++; + } + $qty = price2num($this->detail_batch->dluo_qty); + } + + // check parameters + if (! isset($this->id) || ! isset($this->entrepot_id)) + { + dol_syslog(get_class($this).'::update missing line id and/or warehouse id', LOG_ERR); + $this->errors[]='ErrorMandatoryParametersNotProvided'; + $error++; + return -1; + } + + // update lot + + if (! empty($batch) && $conf->productbatch->enabled) + { + dol_syslog(get_class($this)."::update reception batch id=$reception_batch_id, batch_id=$batch_id, batch=$batch"); + + if (empty($batch_id) || empty($this->fk_product)) { + dol_syslog(get_class($this).'::update missing fk_origin_stock (batch_id) and/or fk_product', LOG_ERR); + $this->errors[]='ErrorMandatoryParametersNotProvided'; + $error++; + } + + // fetch remaining lot qty + require_once DOL_DOCUMENT_ROOT.'/reception/class/receptionbatch.class.php'; + if (! $error && ($lotArray = ReceptionLineBatch::fetchAll($this->db, $this->id)) < 0) + { + $this->errors[]=$this->db->lasterror()." - ReceptionLineBatch::fetchAll"; + $error++; + } + else + { + // caculate new total line qty + foreach ($lotArray as $lot) + { + if ($reception_batch_id != $lot->id) + { + $remainingQty += $lot->dluo_qty; + } + } + $qty += $remainingQty; + + //fetch lot details + + // fetch from product_lot + require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; + $lot = new Productlot($this->db); + if ($lot->fetch(0,$this->fk_product,$batch) < 0) + { + $this->errors[] = $lot->errors; + $error++; + } + if (! $error && ! empty($reception_batch_id)) + { + // delete lot reception line + $sql = "DELETE FROM ".MAIN_DB_PREFIX."receptiondet_batch"; + $sql.= " WHERE fk_receptiondet = ".$this->id; + $sql.= " AND rowid = ".$reception_batch_id; + + if (!$this->db->query($sql)) + { + $this->errors[]=$this->db->lasterror()." - sql=$sql"; + $error++; + } + } + if (! $error && $this->detail_batch->dluo_qty > 0) + { + // create lot reception line + if (isset($lot->id)) + { + $receptionLot = new ReceptionLineBatch($this->db); + $receptionLot->batch = $lot->batch; + $receptionLot->eatby = $lot->eatby; + $receptionLot->sellby = $lot->sellby; + $receptionLot->entrepot_id = $this->detail_batch->entrepot_id; + $receptionLot->dluo_qty = $this->detail_batch->dluo_qty; + $receptionLot->fk_origin_stock = $batch_id; + if ($receptionLot->create($this->id) < 0) + { + $this->errors[]=$receptionLot->errors; + $error++; + } + } + } + } + } + if (! $error) + { + // update line + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql.= " fk_entrepot = ".($this->entrepot_id > 0 ? $this->entrepot_id : 'null'); + $sql.= " , qty = ".$qty; + $sql.= " WHERE rowid = ".$this->id; + + if (!$this->db->query($sql)) + { + $this->errors[]=$this->db->lasterror()." - sql=$sql"; + $error++; + } + else + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $this->errors[]=$this->error; + $error++; + } + } + } + } + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('LINERECEPTION_UPDATE',$user); + if ($result < 0) + { + $this->errors[]=$this->error; + $error++; + } + // End call triggers + } + if (!$error) { + $this->db->commit(); + return 1; + } + else + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + } +} + diff --git a/htdocs/reception/contact.php b/htdocs/reception/contact.php new file mode 100644 index 00000000000..7c721d7cf47 --- /dev/null +++ b/htdocs/reception/contact.php @@ -0,0 +1,274 @@ + + * Copyright (C) 2005-2011 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * + * 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 . + */ + +/** + * \file htdocs/expedition/contact.php + * \ingroup expedition + * \brief Onglet de gestion des contacts de expedition + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +if (! empty($conf->projet->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} + +$langs->load("orders"); +$langs->load("sendings"); +$langs->load("companies"); + +$id=GETPOST('id','int'); +$ref=GETPOST('ref','alpha'); +$action=GETPOST('action','alpha'); + +// Security check +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expedition', $id,''); + +$object = new Expedition($db); +if ($id > 0 || ! empty($ref)) +{ + $object->fetch($id, $ref); + $object->fetch_thirdparty(); + + if (!empty($object->origin)) + { + $typeobject = $object->origin; + $origin = $object->origin; + $object->fetch_origin(); + } + + // Linked documents + if ($typeobject == 'commande' && $object->$typeobject->id && ! empty($conf->commande->enabled)) + { + $objectsrc=new Commande($db); + $objectsrc->fetch($object->$typeobject->id); + } + if ($typeobject == 'propal' && $object->$typeobject->id && ! empty($conf->propal->enabled)) + { + $objectsrc=new Propal($db); + $objectsrc->fetch($object->$typeobject->id); + } +} + + +/* + * Actions + */ + +if ($action == 'addcontact' && $user->rights->expedition->creer) +{ + if ($result > 0 && $id > 0) + { + $result = $objectsrc->add_contact(GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'), $_POST["type"], $_POST["source"]); + } + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + if ($objectsrc->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + $mesg = $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"); + } else { + $mesg = $objectsrc->error; + $mesgs = $objectsrc->errors; + } + setEventMessages($mesg, $mesgs, 'errors'); + } +} + +// bascule du statut d'un contact +else if ($action == 'swapstatut' && $user->rights->expedition->creer) +{ + $result=$objectsrc->swapContactStatus(GETPOST('ligne')); +} + +// Efface un contact +else if ($action == 'deletecontact' && $user->rights->expedition->creer) +{ + $result = $objectsrc->delete_contact(GETPOST("lineid")); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else { + dol_print_error($db); + } +} +/* +else if ($action == 'setaddress' && $user->rights->expedition->creer) +{ + $object->fetch($id); + $result=$object->setDeliveryAddress($_POST['fk_address']); + if ($result < 0) dol_print_error($db,$object->error); +}*/ + + +/* + * View + */ + +llxHeader('',$langs->trans('Order'),'EN:Customers_Orders|FR:expeditions_Clients|ES:Pedidos de clientes'); + +$form = new Form($db); +$formcompany = new FormCompany($db); +$formother = new FormOther($db); +$contactstatic=new Contact($db); +$userstatic=new User($db); + + +/* *************************************************************************** */ +/* */ +/* Mode vue et edition */ +/* */ +/* *************************************************************************** */ + +if ($id > 0 || ! empty($ref)) +{ + $langs->trans("OrderCard"); + + $head = shipping_prepare_head($object); + dol_fiche_head($head, 'contact', $langs->trans("Shipment"), -1, 'sending'); + + + // Shipment card + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref='
'; + // Ref customer shipment + $morehtmlref.=$form->editfieldkey("RefCustomer", '', $object->ref_customer, $object, $user->rights->expedition->creer, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", '', $object->ref_customer, $object, $user->rights->expedition->creer, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1); + // Project + if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
' . $langs->trans('Project') . ' '; + if (0) { // Do not change on shipment + if ($action != 'classify') { + $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + } + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= ''; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + // We don't have project on shipment, so we will use the project or source object instead + // TODO Add project on shipment + $morehtmlref .= ' : '; + if (! empty($objectsrc->fk_project)) { + $proj = new Project($db); + $proj->fetch($objectsrc->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } + } + $morehtmlref.='
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + //print '
'; + print '
'; + + print ''; + + // Linked documents + if ($typeobject == 'commande' && $object->$typeobject->id && ! empty($conf->commande->enabled)) + { + print ''; + print '\n"; + print ''; + } + if ($typeobject == 'propal' && $object->$typeobject->id && ! empty($conf->propal->enabled)) + { + print ''; + print '\n"; + print ''; + } + + print "
'; + $objectsrc=new Commande($db); + $objectsrc->fetch($object->$typeobject->id); + print $langs->trans("RefOrder").''; + print $objectsrc->getNomUrl(1,'commande'); + print "
'; + $objectsrc=new Propal($db); + $objectsrc->fetch($object->$typeobject->id); + print $langs->trans("RefProposal").''; + print $objectsrc->getNomUrl(1,'expedition'); + print "
"; + + + //print '
'; + //print '
'; + //print '
'; + //print '
'; + + + //print '
'; + //print '
'; + print '
'; + + print '
'; + + + dol_fiche_end(); + + // Lignes de contacts + echo '
'; + + // Contacts lines (modules that overwrite templates must declare this into descriptor) + $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl')); + foreach($dirtpls as $reldir) + { + $res=@include dol_buildpath($reldir.'/contacts.tpl.php'); + if ($res) break; + } + +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/reception/index.php b/htdocs/reception/index.php new file mode 100644 index 00000000000..7eaba0b29ad --- /dev/null +++ b/htdocs/reception/index.php @@ -0,0 +1,296 @@ + + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * + * 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 . + */ + +/** + * \file htdocs/expedition/index.php + * \ingroup expedition + * \brief Home page of shipping area. + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; + +$langs->load("orders"); +$langs->load("sendings"); + +/* + * View + */ + +$orderstatic=new Commande($db); +$companystatic=new Societe($db); +$shipment=new Expedition($db); + +$helpurl='EN:Module_Shipments|FR:Module_Expéditions|ES:Módulo_Expediciones'; +llxHeader('',$langs->trans("Shipment"),$helpurl); + +print load_fiche_titre($langs->trans("SendingsArea")); + + +print '
'; + + +if (! empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is useless due to the global search combo +{ + print '
'; + print ''; + print ''; + print ''; + print ''; + print "
'.$langs->trans("Search").'
'; + print $langs->trans("Shipment").':

\n"; +} + +/* + * Shipments to validate + */ +$clause = " WHERE "; + +$sql = "SELECT e.rowid, e.ref, e.ref_customer,"; +$sql.= " s.nom as name, s.rowid as socid,"; +$sql.= " c.ref as commande_ref, c.rowid as commande_id"; +$sql.= " FROM ".MAIN_DB_PREFIX."expedition as e"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON e.rowid = el.fk_target AND el.targettype = 'shipping'"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON el.fk_source = c.rowid"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = e.fk_soc"; +if (!$user->rights->societe->client->voir && !$socid) +{ + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON e.fk_soc = sc.fk_soc"; + $sql.= $clause." sc.fk_user = " .$user->id; + $clause = " AND "; +} +$sql.= $clause." e.fk_statut = 0"; +$sql.= " AND e.entity IN (".getEntity('expedition').")"; +if ($socid) $sql.= " AND c.fk_soc = ".$socid; + +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + if ($num) + { + print ''; + print ''; + print ''; + $i = 0; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + $shipment->id=$obj->rowid; + $shipment->ref=$obj->ref; + $shipment->ref_customer=$obj->ref_customer; + + print '"; + print ''; + print ''; + $i++; + } + print "
'.$langs->trans("SendingsToValidate").'
'; + print $shipment->getNomUrl(1); + print "'; + print ''.$obj->name.''; + print ''; + if ($obj->commande_id) print ''.$obj->commande_ref.''; + print '

"; + } +} + + +/* + * Commandes a traiter + */ +$sql = "SELECT c.rowid, c.ref, c.ref_client as ref_customer, c.fk_statut, s.nom as name, s.rowid as socid"; +$sql.= " FROM ".MAIN_DB_PREFIX."commande as c,"; +$sql.= " ".MAIN_DB_PREFIX."societe as s"; +if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +$sql.= " WHERE c.fk_soc = s.rowid"; +$sql.= " AND c.entity = ".$conf->entity; +$sql.= " AND c.fk_statut = 1"; +if ($socid) $sql.= " AND c.fk_soc = ".$socid; +if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; +$sql.= " ORDER BY c.rowid ASC"; + +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + if ($num) + { + $langs->load("orders"); + + $i = 0; + print ''; + print ''; + print ''; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + $orderstatic->id=$obj->rowid; + $orderstatic->ref=$obj->ref; + $orderstatic->ref_customer=$obj->ref_customer; + $orderstatic->statut=$obj->fk_statut; + $orderstatic->facturee=0; + + $companystatic->name=$obj->name; + $companystatic->id=$obj->socid; + + print ''; + print ''; + print ''; + print ''; + print ''; + $i++; + } + print "
'.$langs->trans("OrdersToProcess").'
'; + print $orderstatic->getNomUrl(1); + print ''; + print $companystatic->getNomUrl(1,'customer',32); + print ''; + print $orderstatic->getLibStatut(3); + print '

"; + } +} + + +//print ''; +print '
'; + + +/* + * Commandes en traitement + */ +$sql = "SELECT c.rowid, c.ref, c.ref_client as ref_customer, c.fk_statut as status, c.facture as billed, s.nom as name, s.rowid as socid"; +$sql.= " FROM ".MAIN_DB_PREFIX."commande as c,"; +$sql.= " ".MAIN_DB_PREFIX."societe as s"; +if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +$sql.= " WHERE c.fk_soc = s.rowid"; +$sql.= " AND c.entity = ".$conf->entity; +$sql.= " AND c.fk_statut = 2"; +if ($socid) $sql.= " AND c.fk_soc = ".$socid; +if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + +$resql = $db->query($sql); +if ( $resql ) +{ + $langs->load("orders"); + + $num = $db->num_rows($resql); + if ($num) + { + $i = 0; + print ''; + print ''; + print ''; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + $orderstatic->id=$obj->rowid; + $orderstatic->ref=$obj->ref; + $orderstatic->ref_customer=$obj->ref_customer; + $orderstatic->statut=$obj->status; + $orderstatic->facturee=$obj->billed; + + $companystatic->name=$obj->name; + $companystatic->id=$obj->socid; + + print ''; + print ''; + print ''; + print ''; + $i++; + } + print "
'.$langs->trans("OrdersInProcess").'
'; + print $orderstatic->getNomUrl(1); + print ''; + print $companystatic->getNomUrl(1,'customer'); + print ''; + print $orderstatic->getLibStatut(3); + print '

"; + } +} +else dol_print_error($db); + + +/* + * Last shipments + */ +$sql = "SELECT e.rowid, e.ref, e.ref_customer,"; +$sql.= " s.nom as name, s.rowid as socid,"; +$sql.= " c.ref as commande_ref, c.rowid as commande_id"; +$sql.= " FROM ".MAIN_DB_PREFIX."expedition as e"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON e.rowid = el.fk_target AND el.targettype = 'shipping' AND el.sourcetype IN ('commande')"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON el.fk_source = c.rowid AND el.sourcetype IN ('commande') AND el.targettype = 'shipping'"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = e.fk_soc"; +if (! $user->rights->societe->client->voir && ! $socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON e.fk_soc = sc.fk_soc"; +$sql.= " WHERE e.entity IN (".getEntity('expedition').")"; +if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND sc.fk_user = " .$user->id; +$sql.= " AND e.fk_statut = 1"; +if ($socid) $sql.= " AND c.fk_soc = ".$socid; +$sql.= " ORDER BY e.date_delivery DESC"; +$sql.= $db->plimit(5, 0); + +$resql = $db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + if ($num) + { + $i = 0; + print ''; + print ''; + print ''; + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + $shipment->id=$obj->rowid; + $shipment->ref=$obj->ref; + $shipment->ref_customer=$obj->ref_customer; + + print ''; + print ''; + print ''; + $i++; + } + print "
'.$langs->trans("LastSendings", $num).'
'; + print $shipment->getNomUrl(1); + print ''.img_object($langs->trans("ShowCompany"),"company").' '.$obj->name.''; + if ($obj->commande_id > 0) + { + $orderstatic->id=$obj->commande_id; + $orderstatic->ref=$obj->commande_ref; + print $orderstatic->getNomUrl(1); + } + else print ' '; + print '

"; + } + $db->free($resql); +} +else dol_print_error($db); + + +print '
'; + + +llxFooter(); +$db->close(); diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php new file mode 100644 index 00000000000..ab5fa27b13f --- /dev/null +++ b/htdocs/reception/list.php @@ -0,0 +1,669 @@ + + * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2005-2010 Regis Houssin + * Copyright (C) 2016 Ferran Marcet + * + * 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 . + */ + +/** + * \file htdocs/expedition/list.php + * \ingroup expedition + * \brief Page to list all shipments + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; + +$langs->load("sendings"); +$langs->load("deliveries"); +$langs->load('companies'); + +$socid=GETPOST('socid','int'); +// Security check +$expeditionid = GETPOST('id','int'); +if ($user->societe_id) $socid=$user->societe_id; +$result = restrictedArea($user, 'expedition',$expeditionid,''); + +$diroutputmassaction=$conf->expedition->dir_output . '/temp/massgeneration/'.$user->id; + +$search_ref_exp = GETPOST("search_ref_exp"); +$search_ref_liv = GETPOST('search_ref_liv'); +$search_company = GETPOST("search_company"); +$search_town=GETPOST('search_town','alpha'); +$search_zip=GETPOST('search_zip','alpha'); +$search_state=trim(GETPOST("search_state")); +$search_country=GETPOST("search_country",'int'); +$search_type_thirdparty=GETPOST("search_type_thirdparty",'int'); +$search_billed=GETPOST("search_billed",'int'); +$sall = GETPOST('sall', 'alphanohtml'); +$optioncss = GETPOST('optioncss','alpha'); + +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (! $sortfield) $sortfield="e.ref"; +if (! $sortorder) $sortorder="DESC"; +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$contextpage='shipmentlist'; + +$viewstatut=GETPOST('viewstatut'); + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('shipmentlist')); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label('expedition'); +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); + +// List of fields to search into when doing a "search in all" +$fieldstosearchall = array( + 'e.ref'=>"Ref", + 's.nom'=>"ThirdParty", + 'e.note_public'=>'NotePublic', +); +if (empty($user->socid)) $fieldstosearchall["e.note_private"]="NotePrivate"; + +$checkedtypetiers=0; +$arrayfields=array( + 'e.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), + 'e.ref_customer'=>array('label'=>$langs->trans("RefCustomer"), 'checked'=>1), + 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), + 's.town'=>array('label'=>$langs->trans("Town"), 'checked'=>1), + 's.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>1), + 'state.nom'=>array('label'=>$langs->trans("StateShort"), 'checked'=>0), + 'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0), + 'typent.code'=>array('label'=>$langs->trans("ThirdPartyType"), 'checked'=>$checkedtypetiers), + 'e.date_delivery'=>array('label'=>$langs->trans("DateDeliveryPlanned"), 'checked'=>1), + 'e.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 'e.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), + 'e.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), + 'l.ref'=>array('label'=>$langs->trans("DeliveryRef"), 'checked'=>1, 'enabled'=>$conf->livraison_bon->enabled), + 'l.date_delivery'=>array('label'=>$langs->trans("DateReceived"), 'checked'=>1, 'enabled'=>$conf->livraison_bon->enabled), + 'e.billed'=>array('label'=>$langs->trans("Billed"), 'checked'=>1, 'position'=>1000, 'enabled'=>(!empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) +); + +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + } +} + + +/* + * Actions + */ + +if (GETPOST('cancel')) { $action='list'; $massaction=''; } +if (! GETPOST('confirmmassaction')) { $massaction=''; } + +$parameters=array('socid'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + +// Purge search criteria +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers +{ + $search_ref_exp=''; + $search_ref_liv=''; + $search_company=''; + $search_town=''; + $search_zip=""; + $search_state=""; + $search_type=''; + $search_country=''; + $search_type_thirdparty=''; + $search_billed=''; + $viewstatut=''; + $search_array_options=array(); +} + +if (empty($reshook)) +{ + // Mass actions. Controls on number of lines checked + $maxformassaction=1000; + if (! empty($massaction) && count($toselect) < 1) + { + $error++; + setEventMessages($langs->trans("NoLineChecked"), null, "warnings"); + } + if (! $error && count($toselect) > $maxformassaction) + { + setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors'); + $error++; + } + +} + + + + +/* + * View + */ + +$form=new Form($db); +$companystatic=new Societe($db); +$shipment=new Expedition($db); +$formcompany=new FormCompany($db); + +$helpurl='EN:Module_Shipments|FR:Module_Expéditions|ES:Módulo_Expediciones'; +llxHeader('',$langs->trans('ListOfSendings'),$helpurl); + +$sql = "SELECT e.rowid, e.ref, e.ref_customer, e.date_expedition as date_expedition, e.date_delivery as date_livraison, l.date_delivery as date_reception, e.fk_statut, e.billed,"; +$sql.= ' s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s.code_client, '; +$sql.= " typent.code as typent_code,"; +$sql.= " state.code_departement as state_code, state.nom as state_name,"; +$sql.= ' e.date_creation as date_creation, e.tms as date_update'; +// Add fields from extrafields +foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); +// Add fields from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; +$sql.= " FROM ".MAIN_DB_PREFIX."expedition as e"; +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."expedition_extrafields as ef on (e.rowid = ef.fk_object)"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = e.fk_soc"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as ee ON e.rowid = ee.fk_source AND ee.sourcetype = 'shipping' AND ee.targettype = 'delivery'"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."livraison as l ON l.rowid = ee.fk_target"; +if (!$user->rights->societe->client->voir && !$socid) // Internal user with no permission to see all +{ + $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +} +$sql.= " WHERE e.entity IN (".getEntity('expedition').")"; +if (!$user->rights->societe->client->voir && !$socid) // Internal user with no permission to see all +{ + $sql.= " AND e.fk_soc = sc.fk_soc"; + $sql.= " AND sc.fk_user = " .$user->id; +} +if ($socid) +{ + $sql.= " AND e.fk_soc = ".$socid; +} +if ($viewstatut <> '' && $viewstatut >= 0) { + $sql.= " AND e.fk_statut = ".$viewstatut; +} +if ($search_billed != '' && $search_billed >= 0) $sql.=' AND e.billed = '.$search_billed; +if ($search_town) $sql.= natural_search('s.town', $search_town); +if ($search_zip) $sql.= natural_search("s.zip",$search_zip); +if ($search_state) $sql.= natural_search("state.nom",$search_state); +if ($search_country) $sql .= " AND s.fk_pays IN (".$search_country.')'; +if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')'; +if ($search_ref_exp) $sql .= natural_search('e.ref', $search_ref_exp); +if ($search_ref_liv) $sql .= natural_search('l.ref', $search_ref_liv); +if ($search_company) $sql .= natural_search('s.nom', $search_company); +if ($sall) $sql .= natural_search(array_keys($fieldstosearchall), $sall); + +// Add where from extra fields +foreach ($search_array_options as $key => $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $typ=$extrafields->attribute_type[$tmpkey]; + $mode=0; + if (in_array($typ, array('int','double','real'))) $mode=1; // Search on a numeric + if (in_array($typ, array('sellist')) && $crit != '0' && $crit != '-1') $mode=2; // Search on a foreign key int + if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0')) + { + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); + } +} +// Add where from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; + +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} + +$sql.= $db->order($sortfield,$sortorder); +$sql.= $db->plimit($limit + 1,$offset); + +//print $sql; +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + + $expedition = new Expedition($db); + + $param=''; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; + if ($sall) $param.= "&sall=".$sall; + if ($search_ref_exp) $param.= "&search_ref_exp=".$search_ref_exp; + if ($search_ref_liv) $param.= "&search_ref_liv=".$search_ref_liv; + if ($search_company) $param.= "&search_company=".$search_company; + if ($optioncss != '') $param.='&optioncss='.$optioncss; + // Add $param from extra fields + foreach ($search_array_options as $key => $val) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); + } + + //$massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); + + $i = 0; + print '
'."\n"; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + print_barre_liste($langs->trans('ListOfSendings'), $page, $_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num, $nbtotalofrecords, '', 0, '', '', $limit); + + if ($sall) + { + foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); + print $langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall); + } + + $moreforfilter=''; + if (! empty($moreforfilter)) + { + print '
'; + print $moreforfilter; + $parameters=array('type'=>$type); + $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
'; + } + + $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; + $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + + print '
'; + print ''."\n"; + + // Lignes des champs de filtre + print ''; + // Ref + if (! empty($arrayfields['e.ref']['checked'])) + { + print ''; + } + // Ref customer + if (! empty($arrayfields['e.ref_customer']['checked'])) + { + print ''; + } + // Thirdparty + if (! empty($arrayfields['s.nom']['checked'])) + { + print ''; + } + // Town + if (! empty($arrayfields['s.town']['checked'])) print ''; + // Zip + if (! empty($arrayfields['s.zip']['checked'])) print ''; + // State + if (! empty($arrayfields['state.nom']['checked'])) + { + print ''; + } + // Country + if (! empty($arrayfields['country.code_iso']['checked'])) + { + print ''; + } + // Company type + if (! empty($arrayfields['typent.code']['checked'])) + { + print ''; + } + // Date delivery planned + if (! empty($arrayfields['e.date_delivery']['checked'])) + { + print ''; + } + if (! empty($arrayfields['l.ref']['checked'])) + { + // Delivery ref + print ''; + } + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Date creation + if (! empty($arrayfields['e.datec']['checked'])) + { + print ''; + } + // Date modification + if (! empty($arrayfields['e.tms']['checked'])) + { + print ''; + } + // Status + if (! empty($arrayfields['e.fk_statut']['checked'])) + { + print ''; + } + // Status billed + if (! empty($arrayfields['e.billed']['checked'])) + { + print ''; + } + // Action column + print ''; + print "\n"; + + print ''; + if (! empty($arrayfields['e.ref']['checked'])) print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"],"e.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['e.ref_customer']['checked'])) print_liste_field_titre($arrayfields['e.ref_customer']['label'], $_SERVER["PHP_SELF"],"e.ref_customer","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"],"s.nom", "", $param,'align="left"',$sortfield,$sortorder); + if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['e.date_delivery']['checked'])) print_liste_field_titre($arrayfields['e.date_delivery']['label'], $_SERVER["PHP_SELF"],"e.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['l.ref']['checked'])) print_liste_field_titre($arrayfields['l.ref']['label'], $_SERVER["PHP_SELF"],"l.ref","",$param, '',$sortfield,$sortorder); + if (! empty($arrayfields['l.date_delivery']['checked'])) print_liste_field_titre($arrayfields['l.date_delivery']['label'], $_SERVER["PHP_SELF"],"l.date_delivery","",$param, 'align="center"',$sortfield,$sortorder); + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $sortonfield = "ef.".$key; + if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; + print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); + } + } + } + // Hook fields + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (! empty($arrayfields['e.datec']['checked'])) print_liste_field_titre($arrayfields['e.datec']['label'],$_SERVER["PHP_SELF"],"e.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['e.tms']['checked'])) print_liste_field_titre($arrayfields['e.tms']['label'],$_SERVER["PHP_SELF"],"e.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['e.fk_statut']['checked'])) print_liste_field_titre($arrayfields['e.fk_statut']['label'],$_SERVER["PHP_SELF"],"e.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['e.billed']['checked'])) print_liste_field_titre($arrayfields['e.billed']['label'],$_SERVER["PHP_SELF"],"e.billed","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); + print "\n"; + + $i=0; + $var=true; + $totalarray=array(); + while ($i < min($num,$limit)) + { + $obj = $db->fetch_object($resql); + + $shipment->id=$obj->rowid; + $shipment->ref=$obj->ref; + + $companystatic->id=$obj->socid; + $companystatic->ref=$obj->name; + $companystatic->name=$obj->name; + + + print ''; + + // Ref + if (! empty($arrayfields['e.ref']['checked'])) + { + print "\n"; + if (! $i) $totalarray['nbfield']++; + } + + // Ref customer + if (! empty($arrayfields['e.ref_customer']['checked'])) + { + print "\n"; + if (! $i) $totalarray['nbfield']++; + } + + // Third party + if (! empty($arrayfields['s.nom']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Town + if (! empty($arrayfields['s.town']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Zip + if (! empty($arrayfields['s.zip']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // State + if (! empty($arrayfields['state.nom']['checked'])) + { + print "\n"; + if (! $i) $totalarray['nbfield']++; + } + // Country + if (! empty($arrayfields['country.code_iso']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Type ent + if (! empty($arrayfields['typent.code']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + + // Date delivery planed + if (! empty($arrayfields['e.date_delivery']['checked'])) + { + print '\n"; + } + + if (! empty($arrayfields['l.ref']['checked']) || ! empty($arrayfields['l.date_delivery']['checked'])) + { + $shipment->fetchObjectLinked($shipment->id,$shipment->element); + $receiving=''; + if (count($shipment->linkedObjects['delivery']) > 0) $receiving=reset($shipment->linkedObjects['delivery']); + + if (! empty($arrayfields['l.ref']['checked'])) + { + // Ref + print ''; + } + + if (! empty($arrayfields['l.date_delivery']['checked'])) + { + // Date received + print ''."\n"; + } + } + + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Date creation + if (! empty($arrayfields['e.datec']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Date modification + if (! empty($arrayfields['e.tms']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Status + if (! empty($arrayfields['e.fk_statut']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Billed + if (! empty($arrayfields['e.billed']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + + // Action column + print ''; + if (! $i) $totalarray['nbfield']++; + + print "\n"; + + $i++; + } + + print "
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print $form->select_country($search_country,'search_country','',0,'maxwidth100'); + print ''; + print $form->selectarray("search_type_thirdparty", $formcompany->typent_array(0), $search_type_thirdparty, 0, 0, 0, '', 0, 0, 0, (empty($conf->global->SOCIETE_SORT_ON_TYPEENT)?'ASC':$conf->global->SOCIETE_SORT_ON_TYPEENT)); + print ' '; + print ''; + } + if (! empty($arrayfields['l.date_delivery']['checked'])) + { + // Date received + print ' '; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + print ''; + print ''; + print ''; + print $form->selectarray('viewstatut', array('0'=>$langs->trans('StatusSendingDraftShort'),'1'=>$langs->trans('StatusSendingValidatedShort'),'2'=>$langs->trans('StatusSendingProcessedShort')),$viewstatut,1); + print ''; + print $form->selectyesno('search_billed', $search_billed, 1, 0, 1); + print ''; + $searchpicto=$form->showFilterAndCheckAddButtons(0); + print $searchpicto; + print '
"; + print $shipment->getNomUrl(1); + print ""; + print $obj->ref_customer; + print "'; + print $companystatic->getNomUrl(1); + print ''; + print $obj->town; + print ''; + print $obj->zip; + print '".$obj->state_name."'; + $tmparray=getCountry($obj->fk_pays,'all'); + print $tmparray['label']; + print ''; + if (count($typenArray)==0) $typenArray = $formcompany->typent_array(1); + print $typenArray[$obj->typent_code]; + print ''; + print dol_print_date($db->jdate($obj->date_livraison),"day"); + /*$now = time(); + if ( ($now - $db->jdate($obj->date_expedition)) > $conf->warnings->lim && $obj->statutid == 1 ) + { + }*/ + print "'; + print !empty($receiving) ? $receiving->getNomUrl($db) : ''; + print ''; + print dol_print_date($db->jdate($obj->date_reception),"day"); + print 'getAlignFlag($key); + if ($align) print ' align="'.$align.'"'; + print '>'; + $tmpkey='options_'.$key; + print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); + print ''; + print dol_print_date($db->jdate($obj->date_creation), 'dayhour'); + print ''; + print dol_print_date($db->jdate($obj->date_update), 'dayhour'); + print ''.$shipment->LibStatut($obj->fk_statut,5).''.yn($obj->billed).'
"; + print "
"; + print '
'; + $db->free($resql); +} +else +{ + dol_print_error($db); +} + +llxFooter(); +$db->close(); diff --git a/htdocs/reception/note.php b/htdocs/reception/note.php new file mode 100644 index 00000000000..c32ec5c5124 --- /dev/null +++ b/htdocs/reception/note.php @@ -0,0 +1,164 @@ + + * Copyright (C) 2004-2008 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry + * + * 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 . + */ + +/** + * \file htdocs/expedition/note.php + * \ingroup expedition + * \brief Note card expedition + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; +if (! empty($conf->projet->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} + +$langs->load("sendings"); +$langs->load("companies"); +$langs->load("bills"); +$langs->load('deliveries'); +$langs->load('orders'); +$langs->load('stocks'); +$langs->load('other'); +$langs->load('propal'); + +$id=(GETPOST('id','int')?GETPOST('id','int'):GETPOST('facid','int')); // For backward compatibility +$ref=GETPOST('ref','alpha'); +$action=GETPOST('action','alpha'); + +// Security check +$socid=''; +if ($user->societe_id) $socid=$user->societe_id; +$result=restrictedArea($user, $origin, $origin_id); + +$object = new Expedition($db); +if ($id > 0 || ! empty($ref)) +{ + $object->fetch($id, $ref); + $object->fetch_thirdparty(); + + if (!empty($object->origin)) + { + $typeobject = $object->origin; + $origin = $object->origin; + $object->fetch_origin(); + } + + // Linked documents + if ($typeobject == 'commande' && $object->$typeobject->id && ! empty($conf->commande->enabled)) + { + $objectsrc=new Commande($db); + $objectsrc->fetch($object->$typeobject->id); + } + if ($typeobject == 'propal' && $object->$typeobject->id && ! empty($conf->propal->enabled)) + { + $objectsrc=new Propal($db); + $objectsrc->fetch($object->$typeobject->id); + } +} + +$permissionnote=$user->rights->expedition->creer; // Used by the include of actions_setnotes.inc.php + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + +/* + * View + */ + +llxHeader(); + +$form = new Form($db); + +if ($id > 0 || ! empty($ref)) +{ + + $head=shipping_prepare_head($object); + dol_fiche_head($head, 'note', $langs->trans("Shipment"), -1, 'sending'); + + + // Shipment card + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref='
'; + // Ref customer shipment + $morehtmlref.=$form->editfieldkey("RefCustomer", '', $object->ref_customer, $object, $user->rights->expedition->creer, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", '', $object->ref_customer, $object, $user->rights->expedition->creer, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1); + // Project + if (! empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
' . $langs->trans('Project') . ' '; + if (0) { // Do not change on shipment + if ($action != 'classify') { + $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + } + if ($action == 'classify') { + // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
'; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + // We don't have project on shipment, so we will use the project or source object instead + // TODO Add project on shipment + $morehtmlref .= ' : '; + if (! empty($objectsrc->fk_project)) { + $proj = new Project($db); + $proj->fetch($objectsrc->fk_project); + $morehtmlref .= ''; + $morehtmlref .= $proj->ref; + $morehtmlref .= ''; + } else { + $morehtmlref .= ''; + } + } + } + $morehtmlref.='
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + + $cssclass='titlefield'; + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + + dol_fiche_end(); +} + + +llxFooter(); + +$db->close(); diff --git a/htdocs/reception/shipment.php b/htdocs/reception/shipment.php new file mode 100644 index 00000000000..849053c610c --- /dev/null +++ b/htdocs/reception/shipment.php @@ -0,0 +1,939 @@ + + * Copyright (C) 2005-2012 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2012-2015 Juanjo Menent + * + * 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 . + */ + +/** + * \file htdocs/expedition/shipment.php + * \ingroup expedition + * \brief Tab shipments/delivery receipts on the order + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +if (! empty($conf->projet->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; +} +if (! empty($conf->stock->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; +if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; +if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + +$langs->load('orders'); +$langs->load("companies"); +$langs->load("bills"); +$langs->load('propal'); +$langs->load('deliveries'); +$langs->load('stocks'); +$langs->load("productbatch"); + +$id=GETPOST('id','int'); // id of order +$ref= GETPOST('ref','alpha'); +$action=GETPOST('action','alpha'); + +// Security check +$socid=0; +if (! empty($user->societe_id)) $socid=$user->societe_id; +$result=restrictedArea($user,'commande',$id); + +$object = new Commande($db); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $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 + + + + +/* + * Actions + */ + +$parameters = array('socid' => $socid); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + // Categorisation dans projet + if ($action == 'classin') + { + $object = new Commande($db); + $object->fetch($id); + $object->setProject(GETPOST('projectid','int')); + } + + if ($action == 'confirm_cloture' && GETPOST('confirm','alpha') == 'yes') + { + $object = new Commande($db); + $object->fetch($id); + $result = $object->cloture($user); + } + + // Positionne ref commande client + else if ($action == 'setref_client' && $user->rights->commande->creer) { + $result = $object->set_ref_client($user, GETPOST('ref_client')); + if ($result < 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + if ($action == 'setdatedelivery' && $user->rights->commande->creer) + { + //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; + $datelivraison=dol_mktime(0, 0, 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'),GETPOST('liv_year','int')); + + $object = new Commande($db); + $object->fetch($id); + $result=$object->set_date_livraison($user,$datelivraison); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); + } + /* + if ($action == 'setdeliveryaddress' && $user->rights->commande->creer) + { + $object = new Commande($db); + $object->fetch($id); + $object->setDeliveryAddress(GETPOST('delivery_address_id','int')); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); + } + */ + if ($action == 'setmode' && $user->rights->commande->creer) + { + $object = new Commande($db); + $object->fetch($id); + $result = $object->setPaymentMethods(GETPOST('mode_reglement_id','int')); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); + } + + if ($action == 'setavailability' && $user->rights->commande->creer) { + $object = new Commande($db); + $object->fetch($id); + $result=$object->availability(GETPOST('availability_id')); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); + } + + if ($action == 'setdemandreason' && $user->rights->commande->creer) { + $object = new Commande($db); + $object->fetch($id); + $result=$object->demand_reason(GETPOST('demand_reason_id')); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); + } + + if ($action == 'setconditions' && $user->rights->commande->creer) + { + $object = new Commande($db); + $object->fetch($id); + $result=$object->setPaymentTerms(GETPOST('cond_reglement_id','int')); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); + } + + // shipping method + if ($action == 'setshippingmethod' && $user->rights->commande->creer) { + $object = new Commande($db); + $object->fetch($id); + $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int')); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); + } + + // warehouse + if ($action == 'setwarehouse' && $user->rights->commande->creer) { + $object = new Commande($db); + $object->fetch($id); + $result = $object->setWarehouse(GETPOST('warehouse_id', 'int')); + if ($result < 0) + setEventMessages($object->error, $object->errors, 'errors'); + } + + if ($action == 'update_extras') + { + // Fill array 'array_options' with data from update form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) $error++; + + if (! $error) + { + // Actions on extra fields (by external module or standard code) + $hookmanager->initHooks(array('orderdao')); + $parameters = array('id' => $object->id); + $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by + // some hooks + if (empty($reshook)) { + $result = $object->insertExtraFields(); + if ($result < 0) { + $error++; + } + } else if ($reshook < 0) + $error++; + } + + if ($error) + $action = 'edit_extras'; + } + + if ($action == 'set_thirdparty' && $user->rights->commande->creer) + { + $object->fetch($id); + $object->setValueFrom('fk_soc', $socid, '', '', 'date', '', $user, 'ORDER_MODIFY'); + + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id); + exit(); + } + + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + +} + +/* + * View + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formproduct = new FormProduct($db); +if (! empty($conf->projet->enabled)) { $formproject = new FormProjets($db); } + +llxHeader('',$langs->trans('OrderCard'),''); + + +if ($id > 0 || ! empty($ref)) +{ + $object = new Commande($db); + if ( $object->fetch($id,$ref) > 0) + { + $object->loadExpeditions(1); + + $product_static=new Product($db); + + $soc = new Societe($db); + $soc->fetch($object->socid); + + $author = new User($db); + $author->fetch($object->user_author_id); + + $res = $object->fetch_optionals($object->id, $extralabels); + + $head = commande_prepare_head($object); + dol_fiche_head($head, 'shipping', $langs->trans("CustomerOrder"), -1, 'order'); + + + $formconfirm = ''; + + // Confirm validation + if ($action == 'cloture') + { + $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$id,$langs->trans("CloseShipment"),$langs->trans("ConfirmCloseShipment"),"confirm_cloture"); + + } + + if (! $formconfirm) { + $parameters = array(); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) $formconfirm.=$hookmanager->resPrint; + elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; + + + // Order card + + $linkback = '' . $langs->trans("BackToList") . ''; + + + $morehtmlref='
'; + // Ref customer + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->commande->creer, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->commande->creer, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
'.$langs->trans('Project') . ' '; + if ($user->rights->commande->creer) + { + if ($action != 'classify') + $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.='
'; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.='
'; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref.=''; + $morehtmlref.=$proj->ref; + $morehtmlref.=''; + } else { + $morehtmlref.=''; + } + } + } + $morehtmlref.='
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + print '
'; + print '
'; + + print ''; + + // Discounts for third party + print ''; + + // Date + print ''; + print ''; + print ''; + + // Delivery date planned + print ''; + // Note on several rows + //print ''; + print ''; + + // Shipping Method + print ''; + print ''; + + // Warehouse + if (! empty($conf->stock->enabled) && ! empty($conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER)) { + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct=new FormProduct($db); + print ''; + print ''; + } + + // Terms of payment + /* + print ''; + + // Mode of payment + print '';*/ + + // Availability + print ''; + + // Source + print ''; + print ''; + print ''; + print ''; + } + + // TODO How record was recorded OrderMode (llx_c_input_method) + + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + print ''; + print ''; + } + + // Other attributes + $cols = 2; + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + + print '
'.$langs->trans('Discounts').''; + if ($soc->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_percent); + else print $langs->trans("CompanyHasNoRelativeDiscount"); + print '. '; + $absolute_discount=$soc->getAvailableDiscounts('','fk_facture_source IS NULL'); + $absolute_creditnote=$soc->getAvailableDiscounts('','fk_facture_source IS NOT NULL'); + $absolute_discount=price2num($absolute_discount,'MT'); + $absolute_creditnote=price2num($absolute_creditnote,'MT'); + if ($absolute_discount) + { + if ($object->statut > Commande::STATUS_DRAFT) + { + print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)); + } + else + { + // Remise dispo de type non avoir + $filter='fk_facture_source IS NULL'; + print '
'; + $form->form_remise_dispo($_SERVER["PHP_SELF"].'?id='.$object->id,0,'remise_id',$soc->id,$absolute_discount,$filter, 0, '', 1); + } + } + if ($absolute_creditnote) + { + print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'. '; + } + if (! $absolute_discount && ! $absolute_creditnote) print $langs->trans("CompanyHasNoAbsoluteDiscount").'.'; + print '
'.$langs->trans('Date').''; + print dol_print_date($object->date,'daytext'); + if ($object->hasDelay() && empty($object->date_livraison)) { + print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning"); + } + print '
'; + print ''; + + if ($action != 'editdate_livraison') print ''; + print '
'; + print $langs->trans('DateDeliveryPlanned'); + print 'id.'">'.img_edit($langs->trans('SetDeliveryDate'),1).'
'; + print '
'; + if ($action == 'editdate_livraison') + { + print '
'; + print ''; + print ''; + $form->select_date($object->date_livraison>0?$object->date_livraison:-1,'liv_','','','',"setdatedelivery"); + print ''; + print '
'; + } + else + { + print dol_print_date($object->date_livraison,'daytext'); + if ($object->hasDelay() && ! empty($object->date_livraison)) { + print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning"); + } + } + print '
'.$langs->trans('NotePublic').' :
'; + //print nl2br($object->note_public); + //print '
'; + print ''; + if ($action != 'editshippingmethod' && $user->rights->expedition->creer) + print ''; + print '
'; + print $langs->trans('SendingMethod'); + print 'id.'">'.img_edit($langs->trans('SetShippingMode'),1).'
'; + print '
'; + if ($action == 'editshippingmethod') { + $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1); + } else { + $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none'); + } + print '
'; + print ''; + if ($action != 'editwarehouse' && $user->rights->commande->creer) + print ''; + print '
'; + print $langs->trans('Warehouse'); + print 'id.'">'.img_edit($langs->trans('SetWarehouse'),1).'
'; + print '
'; + 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 '
'; + print ''; + + if ($action != 'editconditions' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('PaymentConditionsShort'); + print 'id.'">'.img_edit($langs->trans('SetConditions'),1).'
'; + print '
'; + if ($action == 'editconditions') + { + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'cond_reglement_id'); + } + else + { + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->cond_reglement_id,'none'); + } + print '
'; + print ''; + if ($action != 'editmode' && ! empty($object->brouillon)) print ''; + print '
'; + print $langs->trans('PaymentMode'); + print 'id.'">'.img_edit($langs->trans('SetMode'),1).'
'; + print '
'; + if ($action == 'editmode') + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'mode_reglement_id'); + } + else + { + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id,$object->mode_reglement_id,'none'); + } + print '
'; + print ''; + if ($action != 'editavailability') + print ''; + print '
'; + print $langs->trans('AvailabilityPeriod'); + print 'id . '">' . img_edit($langs->trans('SetAvailability'), 1) . '
'; + print '
'; + if ($action == 'editavailability') { + $form->form_availability($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->availability_id, 'availability_id', 1); + } else { + $form->form_availability($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->availability_id, 'none', 1); + } + print '
'; + print ''; + if ($action != 'editdemandreason') + print ''; + print '
'; + print $langs->trans('Source'); + print 'id . '">' . img_edit($langs->trans('SetDemandReason'), 1) . '
'; + print '
'; + if ($action == 'editdemandreason') { + $form->formInputReason($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->demand_reason_id, 'demand_reason_id', 1); + } else { + $form->formInputReason($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->demand_reason_id, 'none'); + } + + $tmparray=$object->getTotalWeightVolume(); + $totalWeight=$tmparray['weight']; + $totalVolume=$tmparray['volume']; + if ($totalWeight || $totalVolume) + { + print '
'.$langs->trans("CalculatedWeight").''; + print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, isset($conf->global->MAIN_WEIGHT_DEFAULT_ROUND)?$conf->global->MAIN_WEIGHT_DEFAULT_ROUND:-1, isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT)?$conf->global->MAIN_WEIGHT_DEFAULT_UNIT:'no'); + print '
'.$langs->trans("CalculatedVolume").''; + print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND)?$conf->global->MAIN_VOLUME_DEFAULT_ROUND:-1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT)?$conf->global->MAIN_VOLUME_DEFAULT_UNIT:'no'); + print '
'; + print '
'; + print $langs->trans('IncotermLabel'); + print ''; + if ($user->rights->commande->creer) print ''.img_edit().''; + else print ' '; + print '
'; + print '
'; + if ($action != 'editincoterm') + { + print $form->textwithpicto($object->display_incoterms(), $object->libelle_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 '
'; + + print '
'; + print '
'; + print '
'; + print '
'; + + print ''; + + if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency)) + { + // Multicurrency Amount HT + print ''; + print ''; + print ''; + + // Multicurrency Amount VAT + print ''; + print ''; + print ''; + + // Multicurrency Amount TTC + print ''; + print ''; + print ''; + } + + // Total HT + print ''; + print ''; + print ''; + + // Total VAT + print ''; + print ''; + + // Amount Local Taxes + if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) // Localtax1 + { + print ''; + print ''; + } + if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) // Localtax2 IRPF + { + print ''; + print ''; + } + + // Total TTC + print ''; + print ''; + + print '
' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . '' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . '' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . '' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
'.$langs->trans('AmountHT').''.price($object->total_ht, 0, '', 1, -1, -1, $conf->currency).'
'.$langs->trans('AmountVAT').''.price($object->total_tva, 0, '', 1, -1, -1, $conf->currency).'
' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '' . price($object->total_localtax1, 1, '', 1, - 1, - 1, $conf->currency) . '
' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '' . price($object->total_localtax2, 1, '', 1, - 1, - 1, $conf->currency) . '
'.$langs->trans('AmountTTC').''.price($object->total_ttc, 0, '', 1, -1, -1, $conf->currency).'
'; + + print '
'; + print '
'; + print '
'; + + print '

'; + + + + /** + * Lines or orders with quantity shipped and remain to ship + * Note: Qty shipped are already available into $object->expeditions[fk_product] + */ + print ''; + + $sql = "SELECT cd.rowid, cd.fk_product, cd.product_type as type, cd.label, cd.description,"; + $sql.= " cd.price, cd.tva_tx, cd.subprice,"; + $sql.= " cd.qty,"; + $sql.= ' cd.date_start,'; + $sql.= ' cd.date_end,'; + $sql.= ' p.rowid as prodid, p.label as product_label, p.entity, p.ref, p.fk_product_type as product_type, p.description as product_desc'; + $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid"; + $sql.= " WHERE cd.fk_commande = ".$object->id; + $sql.= " ORDER BY cd.rang, cd.rowid"; + + //print $sql; + dol_syslog("shipment.php", LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->stock->enabled)) + { + print ''; + } + else + { + print ''; + } + print "\n"; + + $var=true; + $toBeShipped=array(); + $toBeShippedTotal=0; + while ($i < $num) + { + $objp = $db->fetch_object($resql); + + + // Show product and description + $type=isset($objp->type)?$objp->type:$objp->product_type; + + // Try to enhance type detection using date_start and date_end for free lines where type + // was not saved. + if (! empty($objp->date_start)) $type=1; + if (! empty($objp->date_end)) $type=1; + + print ''; + + // Product label + if ($objp->fk_product > 0) + { + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) + { + $object->fetch_thirdparty(); + + $prod = new Product($db); + $prod->id = $objp->fk_product; + $prod->entity = $objp->entity; + $prod->getMultiLangs(); + + $outputlangs = $langs; + $newlang=''; + if (empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if (empty($newlang)) $newlang=$object->thirdparty->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $label = (! empty($prod->multilangs[$outputlangs->defaultlang]["label"])) ? $prod->multilangs[$outputlangs->defaultlang]["label"] : $objp->product_label; + } + else + $label = (! empty($objp->label)?$objp->label:$objp->product_label); + + print ''; + } + else + { + print "\n"; + } + + // Qty ordered + print ''; + + // Qty already shipped + $qtyProdCom=$objp->qty; + print ''; + + // Qty remains to ship + print ''; + + if ($objp->fk_product > 0) + { + $product = new Product($db); + $product->fetch($objp->fk_product); + $product->load_stock('warehouseopen'); + } + + if ($objp->fk_product > 0 && $type == 0 && ! empty($conf->stock->enabled)) + { + print ''; + } + else + { + print ''; + } + print "\n"; + + // Show subproducts lines + if ($objp->fk_product > 0 && ! empty($conf->global->PRODUIT_SOUSPRODUITS)) + { + // Set tree of subproducts in product->sousprods + $product->get_sousproduits_arbo(); + //var_dump($product->sousprods);exit; + + // Define a new tree with quantiies recalculated + $prods_arbo = $product->get_arbo_each_prod($qtyProdCom); + //var_dump($prods_arbo); + if (count($prods_arbo) > 0) + { + foreach($prods_arbo as $key => $value) + { + $img=''; + if ($value['stock'] < $value['stock_alert']) + { + $img=img_warning($langs->trans("StockTooLow")); + } + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + } + } + } + + $i++; + } + $db->free($resql); + + if (! $num) + { + print '
'.$langs->trans("Description").''.$langs->trans("QtyOrdered").''.$langs->trans("QtyShipped").''.$langs->trans("KeepToShip").''.$langs->trans("RealStock").' 
'; + print ''; // ancre pour retourner sur la ligne + + // Show product and description + $product_static->type=$type; + $product_static->id=$objp->fk_product; + $product_static->ref=$objp->ref; + $product_static->entity = $objp->entity; + $text=$product_static->getNomUrl(1); + $text.= ' - '.$label; + $description=($conf->global->PRODUIT_DESC_IN_FORM?'':dol_htmlentitiesbr($objp->description)).'
'; + $description.= $product_static->show_photos($conf->product->multidir_output[$product_static->entity],1,1,0,0,0,80); + print $form->textwithtooltip($text,$description,3,'','',$i); + + // Show range + print_date_range($db->jdate($objp->date_start),$db->jdate($objp->date_end)); + + // Add description in form + if (! empty($conf->global->PRODUIT_DESC_IN_FORM)) + { + print ($objp->description && $objp->description!=$objp->product_label)?'
'.dol_htmlentitiesbr($objp->description):''; + } + + print '
"; + if ($type==1) $text = img_object($langs->trans('Service'),'service'); + else $text = img_object($langs->trans('Product'),'product'); + + if (! empty($objp->label)) { + $text.= ' '.$objp->label.''; + print $form->textwithtooltip($text,$objp->description,3,'','',$i); + } else { + print $text.' '.nl2br($objp->description); + } + + // Show range + print_date_range($db->jdate($objp->date_start),$db->jdate($objp->date_end)); + print "' . $objp->qty . ''; + // Nb of sending products for this line of order + $qtyAlreadyShipped = (! empty($object->expeditions[$objp->rowid])?$object->expeditions[$objp->rowid]:0); + print $qtyAlreadyShipped; + print ''; + if ($type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + { + $toBeShipped[$objp->fk_product] = $objp->qty - $qtyAlreadyShipped; + $toBeShippedTotal += $toBeShipped[$objp->fk_product]; + print $toBeShipped[$objp->fk_product]; + } + else + { + print '0 ('.$langs->trans("Service").')'; + } + print ''; + print $product->stock_reel; + if ($product->stock_reel < $toBeShipped[$objp->fk_product]) + { + print ' '.img_warning($langs->trans("StockTooLow")); + } + print ' 
      -> '.$value['fullpath'].' ('.$value['nb'].') '.$value['nb_total'].'  '.$value['stock'].' '.$img.'
'.$langs->trans("NoArticleOfTypeProduct").'
'; + } + + print "
"; + } + else + { + dol_print_error($db); + } + + print '
'; + + + /* + * Boutons Actions + */ + + if (empty($user->societe_id)) + { + print '
'; + + // Bouton expedier sans gestion des stocks + if (empty($conf->stock->enabled) && ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED)) + { + if ($user->rights->expedition->creer) + { + print ''.$langs->trans("CreateShipment").''; + if ($toBeShippedTotal <= 0) + { + print ' '.img_warning($langs->trans("WarningNoQtyLeftToSend")); + } + } + else + { + print ''.$langs->trans("CreateShipment").''; + } + } + print "
"; + } + + + // Bouton expedier avec gestion des stocks + + if (! empty($conf->stock->enabled) && $object->statut == Commande::STATUS_DRAFT) + { + print $langs->trans("ValidateOrderFirstBeforeShipment"); + } + + if (! empty($conf->stock->enabled) && ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED)) + { + if ($user->rights->expedition->creer) + { + //print load_fiche_titre($langs->trans("CreateShipment")); + print '
'; + + print '
'; + print ''; + //print ''; + print ''; + print ''; + print ''; + print ''; + //print ''; + + $langs->load("stocks"); + + //print ''; + + if (! empty($conf->stock->enabled)) + { + //print ''; + //print ''; + } + //print ''; + + //print "
'; + print $langs->trans("WarehouseSource"); + //print ''; + print $formproduct->selectWarehouses(! empty($object->warehouse_id)?$object->warehouse_id:-1, 'entrepot_id', '', 1, 0, 0, '', 0, 0, array(), 'minwidth200'); + if (count($formproduct->cache_warehouses) <= 0) + { + print '   '.$langs->trans("WarehouseSourceNotDefined").' '.$langs->trans("AddOne").''; + } + //print ''; + print ''; + if ($toBeShippedTotal <= 0) + { + print ' '.img_warning($langs->trans("WarningNoQtyLeftToSend")); + } + //print '
"; + print "
\n"; + + print '
'; + + $somethingshown=1; + + } + else + { + print '
'; + print ''.$langs->trans("CreateShipment").''; + print '
'; + } + } + + show_list_sending_receive('commande',$object->id); + } + else + { + /* Commande non trouvee */ + print "Commande inexistante"; + } +} + + +llxFooter(); + +$db->close(); diff --git a/htdocs/reception/stats/index.php b/htdocs/reception/stats/index.php new file mode 100644 index 00000000000..53837c76fd1 --- /dev/null +++ b/htdocs/reception/stats/index.php @@ -0,0 +1,364 @@ + + * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * + * 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 . + */ + +/** + * \file htdocs/expedition/stats/index.php + * \ingroup expedition + * \brief Page with shipment statistics + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionstats.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + +$WIDTH=DolGraph::getDefaultGraphSizeForStats('width'); +$HEIGHT=DolGraph::getDefaultGraphSizeForStats('height'); + +$userid=GETPOST('userid','int'); +$socid=GETPOST('socid','int'); +// Security check +if ($user->societe_id > 0) +{ + $action = ''; + $socid = $user->societe_id; +} + +$nowyear=strftime("%Y", dol_now()); +$year = GETPOST('year')>0?GETPOST('year'):$nowyear; +//$startyear=$year-2; +$startyear=$year-1; +$endyear=$year; + +$langs->load("sendings"); +$langs->load("other"); +$langs->load("companies"); + + +/* + * View + */ + +$form=new Form($db); + +llxHeader(); + +print load_fiche_titre($langs->trans("StatisticsOfSendings"), $mesg); + + +dol_mkdir($dir); + +$stats = new ExpeditionStats($db, $socid, $mode, ($userid>0?$userid:0)); + +// Build graphic number of object +$data = $stats->getNbByMonthWithPrevYear($endyear,$startyear); +//var_dump($data);exit; +// $data = array(array('Lib',val1,val2,val3),...) + + +if (!$user->rights->societe->client->voir || $user->societe_id) +{ + $filenamenb = $dir.'/shipmentsnbinyear-'.$user->id.'-'.$year.'.png'; + if ($mode == 'customer') $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstats&file=shipmentsnbinyear-'.$user->id.'-'.$year.'.png'; + if ($mode == 'supplier') $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstatssupplier&file=shipmentsnbinyear-'.$user->id.'-'.$year.'.png'; +} +else +{ + $filenamenb = $dir.'/shipmentsnbinyear-'.$year.'.png'; + if ($mode == 'customer') $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstats&file=shipmentsnbinyear-'.$year.'.png'; + if ($mode == 'supplier') $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstatssupplier&file=shipmentsnbinyear-'.$year.'.png'; +} + +$px1 = new DolGraph(); +$mesg = $px1->isGraphKo(); +if (! $mesg) +{ + $px1->SetData($data); + $px1->SetPrecisionY(0); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px1->SetLegend($legend); + $px1->SetMaxValue($px1->GetCeilMaxValue()); + $px1->SetMinValue(min(0,$px1->GetFloorMinValue())); + $px1->SetWidth($WIDTH); + $px1->SetHeight($HEIGHT); + $px1->SetYLabel($langs->trans("NbOfSendings")); + $px1->SetShading(3); + $px1->SetHorizTickIncrement(1); + $px1->SetPrecisionY(0); + $px1->mode='depth'; + $px1->SetTitle($langs->trans("NumberOfShipmentsByMonth")); + + $px1->draw($filenamenb,$fileurlnb); +} + +// Build graphic amount of object +/* +$data = $stats->getAmountByMonthWithPrevYear($endyear,$startyear); +//var_dump($data); +// $data = array(array('Lib',val1,val2,val3),...) + +if (!$user->rights->societe->client->voir || $user->societe_id) +{ + $filenameamount = $dir.'/shipmentsamountinyear-'.$user->id.'-'.$year.'.png'; + if ($mode == 'customer') $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstats&file=shipmentsamountinyear-'.$user->id.'-'.$year.'.png'; + if ($mode == 'supplier') $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstatssupplier&file=shipmentsamountinyear-'.$user->id.'-'.$year.'.png'; +} +else +{ + $filenameamount = $dir.'/shipmentsamountinyear-'.$year.'.png'; + if ($mode == 'customer') $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstats&file=shipmentsamountinyear-'.$year.'.png'; + if ($mode == 'supplier') $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstatssupplier&file=shipmentsamountinyear-'.$year.'.png'; +} + +$px2 = new DolGraph(); +$mesg = $px2->isGraphKo(); +if (! $mesg) +{ + $px2->SetData($data); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px2->SetLegend($legend); + $px2->SetMaxValue($px2->GetCeilMaxValue()); + $px2->SetMinValue(min(0,$px2->GetFloorMinValue())); + $px2->SetWidth($WIDTH); + $px2->SetHeight($HEIGHT); + $px2->SetYLabel($langs->trans("AmountOfShipments")); + $px2->SetShading(3); + $px2->SetHorizTickIncrement(1); + $px2->SetPrecisionY(0); + $px2->mode='depth'; + $px2->SetTitle($langs->trans("AmountOfShipmentsByMonthHT")); + + $px2->draw($filenameamount,$fileurlamount); +} +*/ + +/* +$data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); + +if (!$user->rights->societe->client->voir || $user->societe_id) +{ + $filename_avg = $dir.'/shipmentsaverage-'.$user->id.'-'.$year.'.png'; + if ($mode == 'customer') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstats&file=shipmentsaverage-'.$user->id.'-'.$year.'.png'; + if ($mode == 'supplier') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstatssupplier&file=shipmentsaverage-'.$user->id.'-'.$year.'.png'; +} +else +{ + $filename_avg = $dir.'/shipmentsaverage-'.$year.'.png'; + if ($mode == 'customer') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstats&file=shipmentsaverage-'.$year.'.png'; + if ($mode == 'supplier') $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=shipmentstatssupplier&file=shipmentsaverage-'.$year.'.png'; +} + +$px3 = new DolGraph(); +$mesg = $px3->isGraphKo(); +if (! $mesg) +{ + $px3->SetData($data); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px3->SetLegend($legend); + $px3->SetYLabel($langs->trans("AmountAverage")); + $px3->SetMaxValue($px3->GetCeilMaxValue()); + $px3->SetMinValue($px3->GetFloorMinValue()); + $px3->SetWidth($WIDTH); + $px3->SetHeight($HEIGHT); + $px3->SetShading(3); + $px3->SetHorizTickIncrement(1); + $px3->SetPrecisionY(0); + $px3->mode='depth'; + $px3->SetTitle($langs->trans("AmountAverage")); + + $px3->draw($filename_avg,$fileurl_avg); +} +*/ + + +// Show array +$data = $stats->getAllByYear(); +$arrayyears=array(); +foreach($data as $val) { + if (! empty($val['year'])) { + $arrayyears[$val['year']]=$val['year']; + } +} +if (! count($arrayyears)) $arrayyears[$nowyear]=$nowyear; + +$h=0; +$head = array(); +$head[$h][0] = DOL_URL_ROOT . '/commande/stats/index.php?mode='.$mode; +$head[$h][1] = $langs->trans("ByMonthYear"); +$head[$h][2] = 'byyear'; +$h++; + +$type='shipment_stats'; + +complete_head_from_modules($conf,$langs,null,$head,$h,$type); + +dol_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1); + + +print '
'; + + +//if (empty($socid)) +//{ + // Show filter box + print '
'; + print ''; + + print ''; + print ''; + // Company + print ''; + // User + print ''; + // Year + print ''; + print ''; + print '
'.$langs->trans("Filter").'
'.$langs->trans("ThirdParty").''; + if ($mode == 'customer') $filter='s.client in (1,2,3)'; + if ($mode == 'supplier') $filter='s.fournisseur = 1'; + print $form->select_company($socid,'socid',$filter,1,0,0,array(),0,'','style="width: 95%"'); + print '
'.$langs->trans("CreatedBy").''; + print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); + print '
'.$langs->trans("Year").''; + if (! in_array($year,$arrayyears)) $arrayyears[$year]=$year; + if (! in_array($nowyear,$arrayyears)) $arrayyears[$nowyear]=$nowyear; + arsort($arrayyears); + print $form->selectarray('year',$arrayyears,$year,0); + print '
'; + print '
'; + print '

'; +//} + +print ''; +print ''; +print ''; +print ''; +/*print ''; +print '';*/ +print ''; + +$oldyear=0; +foreach ($data as $val) +{ + $year = $val['year']; + while (! empty($year) && $oldyear > $year+1) + { // If we have empty year + $oldyear--; + + + print ''; + print ''; + + print ''; + /*print ''; + print '';*/ + print ''; + } + + print ''; + print ''; + print ''; + /*print ''; + print '';*/ + print ''; + $oldyear=$year; +} + +print '
'.$langs->trans("Year").''.$langs->trans("NbOfSendings").''.$langs->trans("AmountTotal").''.$langs->trans("AmountAverage").'
'.$oldyear.'000
'; + if ($year) print ''.$year.''; + else print $langs->trans("ValidationDateNotDefinedEvenIfShipmentValidated"); + print ''.$val['nb'].''.price(price2num($val['total'],'MT'),1).''.price(price2num($val['avg'],'MT'),1).'
'; + + +print '
'; + + +// Show graphs +print '
'; +if ($mesg) { print $mesg; } +else { + print $px1->show(); + print "
\n"; + /*print $px2->show(); + print "
\n"; + print $px3->show();*/ +} +print '
'; + + +print '
'; +print '
'; + +dol_fiche_end(); + + + +// TODO USe code similar to commande/stats/index.php instead of this one. +/* +print ''; +print ''; +print ''; + +$sql = "SELECT count(*) as nb, date_format(date_expedition,'%Y') as dm"; +$sql.= " FROM ".MAIN_DB_PREFIX."expedition"; +$sql.= " WHERE fk_statut > 0"; +$sql.= " AND entity = ".$conf->entity; +$sql.= " GROUP BY dm DESC"; + +$resql=$db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $row = $db->fetch_row($resql); + $nbproduct = $row[0]; + $year = $row[1]; + print ""; + print ''; + $i++; + } +} +$db->free($resql); + +print '
'.$langs->trans("Year").''.$langs->trans("NbOfSendings").'
'.$year.''.$nbproduct.'
'; +*/ + +print '
'; +print ''.$langs->trans("StatsOnShipmentsOnlyValidated").''; + +llxFooter(); + +$db->close(); diff --git a/htdocs/reception/stats/month.php b/htdocs/reception/stats/month.php new file mode 100644 index 00000000000..b7d217217c2 --- /dev/null +++ b/htdocs/reception/stats/month.php @@ -0,0 +1,76 @@ + + * Copyright (C) 2004-2009 Laurent Destailleur + * + * 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 . + */ + +/** + * \file htdocs/expedition/stats/month.php + * \ingroup commande + * \brief Page des stats expeditions par mois + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionstats.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + + +/* + * View + */ + +llxHeader(); + +$WIDTH=DolGraph::getDefaultGraphSizeForStats('width'); +$HEIGHT=DolGraph::getDefaultGraphSizeForStats('height'); + +$mesg = ''; + +print load_fiche_titre($langs->trans("StatisticsOfSendings").' '.$_GET["year"], $mesg); + +$stats = new ExpeditionStats($db); +$data = $stats->getNbExpeditionByMonth($_GET["year"]); + +dol_mkdir($conf->expedition->dir_temp); + +$filename = $conf->expedition->dir_temp."/expedition".$year.".png"; +$fileurl = DOL_URL_ROOT.'/viewimage.php?modulepart=expeditionstats&file=expedition'.$year.'.png'; + +$px = new DolGraph(); +$mesg = $px->isGraphKo(); +if (! $mesg) +{ + $px->SetData($data); + $px->SetMaxValue($px->GetCeilMaxValue()); + $px->SetWidth($WIDTH); + $px->SetHeight($HEIGHT); + $px->SetYLabel($langs->trans("NbOfOrders")); + $px->SetShading(3); + $px->SetHorizTickIncrement(1); + $px->SetPrecisionY(0); + $px->draw($filename,$fileurl); +} + +print ''; +print ''; +print ''; +print '
Nombre d expedition par mois'; +print $px->show(); +print '
'; + +llxFooter(); + +$db->close(); diff --git a/htdocs/reception/tpl/index.html b/htdocs/reception/tpl/index.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/htdocs/reception/tpl/linkedobjectblock.tpl.php b/htdocs/reception/tpl/linkedobjectblock.tpl.php new file mode 100644 index 00000000000..b55654f4786 --- /dev/null +++ b/htdocs/reception/tpl/linkedobjectblock.tpl.php @@ -0,0 +1,80 @@ + + * Copyright (C) 2014 Marcos García + * + * 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 . + * + */ +?> + + + +load("sendings"); + +$total=0; $ilink=0; +$var=true; +foreach($linkedObjectBlock as $key => $objectlink) +{ + $ilink++; + + $trclass=($var?'pair':'impair'); + if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass.=' liste_sub_total'; +?> + + trans("Shipment"); ?> + getNomUrl(1); ?> + + date_delivery,'day'); ?> + rights->expedition->lire) { + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); + } ?> + getLibStatut(3); ?> + + element != 'commande') { + ?> + ">transnoentitiesnoconv("RemoveLink")); ?> + + + 1) +{ + ?> + + trans("Total"); ?> + + + + + + + + + + From 52717dbb651324d2ea82359c4f68a08b3f5eb45f Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Wed, 3 Oct 2018 18:05:22 +0200 Subject: [PATCH 005/307] NEW debut rename stock conf --- htdocs/admin/dict.php | 2 +- htdocs/admin/mails_templates.php | 1 + htdocs/admin/reception_extrafields.php | 127 ++++++++ htdocs/admin/reception_setup.php | 2 +- htdocs/admin/receptiondet_extrafields.php | 127 ++++++++ htdocs/admin/stock.php | 80 ++++- htdocs/core/class/conf.class.php | 6 +- htdocs/core/lib/fourn.lib.php | 2 +- htdocs/fourn/commande/card.php | 4 +- .../llx_commande_fournisseur_dispatch.sql | 1 + .../mysql/tables/llx_reception.key.sql | 18 +- htdocs/install/mysql/tables/llx_reception.sql | 7 +- .../tables/llx_reception_extrafields.key.sql | 2 +- .../tables/llx_reception_extrafields.sql | 2 +- .../mysql/tables/llx_receptiondet.key.sql | 4 +- .../install/mysql/tables/llx_receptiondet.sql | 4 +- .../tables/llx_receptiondet_batch.key.sql | 4 +- .../mysql/tables/llx_receptiondet_batch.sql | 4 +- .../llx_receptiondet_extrafields.key.sql | 2 +- .../tables/llx_receptiondet_extrafields.sql | 2 +- htdocs/langs/fr_FR/admin.lang | 4 +- htdocs/langs/fr_FR/stocks.lang | 9 +- htdocs/product/class/product.class.php | 3 + htdocs/product/list.php | 2 +- htdocs/product/reassort.php | 2 +- htdocs/product/stock/product.php | 2 + htdocs/product/stock/replenish.php | 4 +- htdocs/product/stock/replenishorders.php | 2 +- htdocs/reception/class/reception.class.php | 24 +- scripts/reception/create-table.php | 278 ++++++++++++++++++ 30 files changed, 667 insertions(+), 64 deletions(-) create mode 100644 htdocs/admin/reception_extrafields.php create mode 100644 htdocs/admin/receptiondet_extrafields.php create mode 100644 scripts/reception/create-table.php diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index ce87f507cc6..3bdeb742650 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -407,7 +407,7 @@ $tabcond[14]= (! empty($conf->product->enabled) && ! empty($conf->ecotax->enable $tabcond[15]= true; $tabcond[16]= (! empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)); $tabcond[17]= (! empty($conf->deplacement->enabled) || ! empty($conf->expensereport->enabled)); -$tabcond[18]= ! empty($conf->expedition->enabled); +$tabcond[18]= ! empty($conf->expedition->enabled) || ! empty($conf->reception->enabled); $tabcond[19]= ! empty($conf->societe->enabled); $tabcond[20]= ! empty($conf->fournisseur->enabled); $tabcond[21]= ! empty($conf->propal->enabled); diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index aae1b5db470..70e0ae268ba 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -148,6 +148,7 @@ if ($conf->propal->enabled) $elementList['propal_send']=$langs->trans('MailToSen if ($conf->commande->enabled) $elementList['order_send']=$langs->trans('MailToSendOrder'); if ($conf->facture->enabled) $elementList['facture_send']=$langs->trans('MailToSendInvoice'); if ($conf->expedition->enabled) $elementList['shipping_send']=$langs->trans('MailToSendShipment'); +if ($conf->reception->enabled) $elementList['reception_send']=$langs->trans('MailToSendReception'); if ($conf->ficheinter->enabled) $elementList['fichinter_send']=$langs->trans('MailToSendIntervention'); if ($conf->supplier_proposal->enabled) $elementList['supplier_proposal_send']=$langs->trans('MailToSendSupplierRequestForQuotation'); if ($conf->fournisseur->enabled) $elementList['order_supplier_send']=$langs->trans('MailToSendSupplierOrder'); diff --git a/htdocs/admin/reception_extrafields.php b/htdocs/admin/reception_extrafields.php new file mode 100644 index 00000000000..dbfccb60773 --- /dev/null +++ b/htdocs/admin/reception_extrafields.php @@ -0,0 +1,127 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2012 Florian Henry + * Copyright (C) 2013 Philippe Grand + * Copyright (C) 2015 Claudio Aschieri + * Copyright (C) 2018 Quentin Vial-Gouteyron + * + * 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 . + */ + +/** + * \file htdocs/admin/reception_extrafields.php + * \ingroup reception + * \brief Page to setup extra fields of reception + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/reception.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + + +if (!$user->admin) + accessforbidden(); + +$langs->load("admin"); +$langs->load("other"); +$langs->load("receptions"); +$langs->load("deliveries"); + + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label=ExtraFields::$type2label; +$type2label=array(''); +foreach ($tmptype2label as $key => $val) $type2label[$key]=$langs->trans($val); + +$action=GETPOST('action', 'alpha'); +$attrname=GETPOST('attrname', 'alpha'); +$elementtype='reception'; //Must be the $table_element of the class that manage extrafield + +if (!$user->admin) accessforbidden(); + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; + + + +/* + * View + */ + +$textobject=$langs->transnoentitiesnoconv("Receptions"); + +llxHeader('',$langs->trans("ReceptionsSetup")); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("ReceptionsSetup"),$linkback,'title_setup'); +print "
\n"; + +$head = reception_admin_prepare_head(); + +dol_fiche_head($head, 'attributes_reception', $langs->trans("Receptions"), -1, 'sending'); + +require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; + +dol_fiche_end(); + + +// Buttons +if ($action != 'create' && $action != 'edit') +{ + print '
'; + print "".$langs->trans("NewAttribute").""; + print "
"; +} + + +/* ************************************************************************** */ +/* */ +/* Creation of an optional field */ +/* */ +/* ************************************************************************** */ + +if ($action == 'create') +{ + print "
"; + print load_fiche_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* ************************************************************************** */ +/* */ +/* Edition of an optional field */ +/* */ +/* ************************************************************************** */ +if ($action == 'edit' && ! empty($attrname)) +{ + print "
"; + print load_fiche_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php'; +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/admin/reception_setup.php b/htdocs/admin/reception_setup.php index 710c1fb6ba1..4aa362932af 100644 --- a/htdocs/admin/reception_setup.php +++ b/htdocs/admin/reception_setup.php @@ -205,7 +205,7 @@ print load_fiche_titre($langs->trans("ReceptionsSetup"),$linkback,'title_setup') print '
'; $head = reception_admin_prepare_head(); -dol_fiche_head($head, 'reception', $langs->trans("Receptions"), -1, 'reception'); +dol_fiche_head($head, 'reception', $langs->trans("Receptions"), -1, 'sending'); // Reception numbering model diff --git a/htdocs/admin/receptiondet_extrafields.php b/htdocs/admin/receptiondet_extrafields.php new file mode 100644 index 00000000000..80bc3806b52 --- /dev/null +++ b/htdocs/admin/receptiondet_extrafields.php @@ -0,0 +1,127 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2012 Florian Henry + * Copyright (C) 2013 Philippe Grand + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2015 Claudio Aschieri + * Copyright (C) 2018 Quentin Vial-Gouteyron + * + * + * 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 . + */ + +/** + * \file htdocs/admin/receptiondet_extrafields.php + * \ingroup reception + * \brief Page to setup extra fields of reception + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/reception.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + + +if (!$user->admin) + accessforbidden(); + +$langs->load("admin"); +$langs->load("other"); +$langs->load("receptions"); + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label=ExtraFields::$type2label; +$type2label=array(''); +foreach ($tmptype2label as $key => $val) $type2label[$key]=$langs->trans($val); + +$action=GETPOST('action', 'alpha'); +$attrname=GETPOST('attrname', 'alpha'); +$elementtype='receptiondet'; //Must be the $table_element of the class that manage extrafield + +if (!$user->admin) accessforbidden(); + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; + + + +/* + * View + */ + +$textobject=$langs->transnoentitiesnoconv("Receptions"); + +llxHeader('',$langs->trans("ReceptionsSetup")); + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("ReceptionsSetup"),$linkback,'title_setup'); +print "
\n"; + +$head = reception_admin_prepare_head(); + +dol_fiche_head($head, 'attributeslines_reception', $langs->trans("Receptions"), -1, 'sending'); + +require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; + +dol_fiche_end(); + + +// Buttons +if ($action != 'create' && $action != 'edit') +{ + print '
'; + print "".$langs->trans("NewAttribute").""; + print "
"; +} + + +/* ************************************************************************** */ +/* */ +/* Creation of an optional field */ +/* */ +/* ************************************************************************** */ + +if ($action == 'create') +{ + print "
"; + print load_fiche_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* ************************************************************************** */ +/* */ +/* Edition of an optional field */ +/* */ +/* ************************************************************************** */ +if ($action == 'edit' && ! empty($attrname)) +{ + print "
"; + print load_fiche_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php'; +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 36a4ec697e6..cc77ea99e1a 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -74,16 +74,22 @@ if($action) // Mode of stock increase if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL' || $action == 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER' - || $action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') + || $action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER' + || $action == 'STOCK_CALCULATE_ON_RECEPTION' + || $action == 'STOCK_CALCULATE_ON_RECEPTION_CLOSE') { //Use variable cause empty(GETPOST()) do not work with php version < 5.4 $valdispatch=GETPOST('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER','alpha'); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", '','chaine',0,'',$conf->entity); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", '','chaine',0,'',$conf->entity); + $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_RECEPTION", '','chaine',0,'',$conf->entity); + $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_RECEPTION_CLOSE", '','chaine',0,'',$conf->entity); $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", '','chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_BILL') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_BILL", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_BILL','alpha'),'chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER", GETPOST('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER','alpha'),'chaine',0,'',$conf->entity); + if ($action == 'STOCK_CALCULATE_ON_RECEPTION') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_RECEPTION", GETPOST('STOCK_CALCULATE_ON_RECEPTION','alpha'),'chaine',0,'',$conf->entity); + if ($action == 'STOCK_CALCULATE_ON_RECEPTION_CLOSE') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_RECEPTION_CLOSE", GETPOST('STOCK_CALCULATE_ON_RECEPTION_CLOSE','alpha'),'chaine',0,'',$conf->entity); if ($action == 'STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') $res=dolibarr_set_const($db, "STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", $valdispatch,'chaine',0,'',$conf->entity); if (empty($valdispatch)) { $res=dolibarr_set_const($db, "SUPPLIER_ORDER_USE_DISPATCH_STATUS", '','chaine',0,'',$conf->entity); @@ -107,6 +113,9 @@ if($action) if($action == 'STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT') { $res = dolibarr_set_const($db, "STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT", GETPOST('STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT','alpha'),'chaine',0,'',$conf->entity); } + if($action == 'STOCK_MUST_BE_ENOUGH_FOR_RECEPTION') { + $res = dolibarr_set_const($db, "STOCK_MUST_BE_ENOUGH_FOR_RECEPTION", GETPOST('STOCK_MUST_BE_ENOUGH_FOR_RECEPTION','alpha'),'chaine',0,'',$conf->entity); + } if($action == 'INDEPENDANT_SUBPRODUCT_STOCK') { $res = dolibarr_set_const($db, "INDEPENDANT_SUBPRODUCT_STOCK", GETPOST('INDEPENDANT_SUBPRODUCT_STOCK','alpha'),'chaine',0,'',$conf->entity); } @@ -307,25 +316,58 @@ else print "\n\n"; $found++; - -print ''; -print ''.$langs->trans("ReStockOnDispatchOrder").''; -print ''; -if (! empty($conf->fournisseur->enabled)) +if (!empty($conf->reception->enabled)) { - print "
"; + print ''; + print ''.$langs->trans("StockOnReception").''; + print ''; + + print ""; print ''; - print ""; - print $form->selectyesno("STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER",$conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER,1,$disabled); + print ""; + print $form->selectyesno("STOCK_CALCULATE_ON_RECEPTION", $conf->global->STOCK_CALCULATE_ON_RECEPTION, 1, $disabled); print ''; print "
\n"; + + print "\n\n"; + $found++; + + + print ''; + print ''.$langs->trans("StockOnReceptionOnClosing").''; + print ''; + + print "
"; + print ''; + print ""; + print $form->selectyesno("STOCK_CALCULATE_ON_RECEPTION_CLOSE", $conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE, 1, $disabled); + print ''; + print "
\n"; + + print "\n\n"; + $found++; } else { - print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")); + print ''; + print ''.$langs->trans("ReStockOnDispatchOrder").''; + print ''; + if (!empty($conf->fournisseur->enabled)) + { + print "
"; + print ''; + print ""; + print $form->selectyesno("STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER", $conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER, 1, $disabled); + print ''; + print "
\n"; + } + else + { + print $langs->trans("ModuleMustBeEnabledFirst", $langs->transnoentitiesnoconv("Module40Name")); + } + print "\n\n"; + $found++; } -print "\n\n"; -$found++; /*if (! $found) { @@ -402,6 +444,20 @@ if($conf->expedition->enabled) { print "\n"; print "\n"; } +if($conf->reception->enabled) { + $var = !$var; + print ''; + print ''.$langs->trans("StockMustBeEnoughForReception").''; + print ''; + print "
"; + print ''; + print ""; + print $form->selectyesno("STOCK_MUST_BE_ENOUGH_FOR_RECEPTION",$conf->global->STOCK_MUST_BE_ENOUGH_FOR_RECEPTION,1); + print ''; + print '
'; + print "\n"; + print "\n"; +} print ''; $virtualdiffersfromphysical=0; diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index da44eeeb6f6..8e37bee0218 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -415,7 +415,11 @@ class Conf $this->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE=0; $this->global->STOCK_CALCULATE_ON_SUPPLIER_BILL=0; $this->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER=0; - $this->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER=1; + if(empty($this->reception->enabled))$this->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER=1; + else { + $this->global->STOCK_CALCULATE_ON_RECEPTION=1; + $this->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE=0; + } } // conf->currency diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php index 44e7774cae6..7be7bbea94e 100644 --- a/htdocs/core/lib/fourn.lib.php +++ b/htdocs/core/lib/fourn.lib.php @@ -111,7 +111,7 @@ function ordersupplier_prepare_head($object) $head[$h][2] = 'card'; $h++; - if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) + if (! empty($conf->stock->enabled) && (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE))) { $langs->load("stocks"); $head[$h][0] = DOL_URL_ROOT.'/fourn/commande/dispatch.php?id='.$object->id; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index a3ce8ba52df..48e533b93d5 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -2623,8 +2623,10 @@ elseif (! empty($object->id)) } // Ship - if (! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) + + if (! empty($conf->stock->enabled) && (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE))) { + if (in_array($object->statut, array(3,4))) { if ($conf->fournisseur->enabled && $user->rights->fournisseur->commande->receptionner) { print ''; diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql index 789ec3e7a9b..074dc0d4c16 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql @@ -25,6 +25,7 @@ create table llx_commande_fournisseur_dispatch fk_commande integer, fk_product integer, fk_commandefourndet integer, + fk_projet integer DEFAULT NULL, qty float, -- qty fk_entrepot integer, fk_user integer, diff --git a/htdocs/install/mysql/tables/llx_reception.key.sql b/htdocs/install/mysql/tables/llx_reception.key.sql index 736945193ff..a107c2a7d12 100644 --- a/htdocs/install/mysql/tables/llx_reception.key.sql +++ b/htdocs/install/mysql/tables/llx_reception.key.sql @@ -18,14 +18,14 @@ -- =================================================================== -ALTER TABLE llx_expedition ADD UNIQUE INDEX idx_expedition_uk_ref (ref, entity); +ALTER TABLE llx_reception ADD UNIQUE INDEX idx_reception_uk_ref (ref, entity); -ALTER TABLE llx_expedition ADD INDEX idx_expedition_fk_soc (fk_soc); -ALTER TABLE llx_expedition ADD INDEX idx_expedition_fk_user_author (fk_user_author); -ALTER TABLE llx_expedition ADD INDEX idx_expedition_fk_user_valid (fk_user_valid); -ALTER TABLE llx_expedition ADD INDEX idx_expedition_fk_shipping_method (fk_shipping_method); +ALTER TABLE llx_reception ADD INDEX idx_reception_fk_soc (fk_soc); +ALTER TABLE llx_reception ADD INDEX idx_reception_fk_user_author (fk_user_author); +ALTER TABLE llx_reception ADD INDEX idx_reception_fk_user_valid (fk_user_valid); +ALTER TABLE llx_reception ADD INDEX idx_reception_fk_shipping_method (fk_shipping_method); -ALTER TABLE llx_expedition ADD CONSTRAINT fk_expedition_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); -ALTER TABLE llx_expedition ADD CONSTRAINT fk_expedition_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); -ALTER TABLE llx_expedition ADD CONSTRAINT fk_expedition_fk_user_valid FOREIGN KEY (fk_user_valid) REFERENCES llx_user (rowid); -ALTER TABLE llx_expedition ADD CONSTRAINT fk_expedition_fk_shipping_method FOREIGN KEY (fk_shipping_method) REFERENCES llx_c_shipment_mode (rowid); +ALTER TABLE llx_reception ADD CONSTRAINT fk_reception_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); +ALTER TABLE llx_reception ADD CONSTRAINT fk_reception_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); +ALTER TABLE llx_reception ADD CONSTRAINT fk_reception_fk_user_valid FOREIGN KEY (fk_user_valid) REFERENCES llx_user (rowid); +ALTER TABLE llx_reception ADD CONSTRAINT fk_reception_fk_shipping_method FOREIGN KEY (fk_shipping_method) REFERENCES llx_c_shipment_mode (rowid); diff --git a/htdocs/install/mysql/tables/llx_reception.sql b/htdocs/install/mysql/tables/llx_reception.sql index 088e4893c06..34565f7f29a 100644 --- a/htdocs/install/mysql/tables/llx_reception.sql +++ b/htdocs/install/mysql/tables/llx_reception.sql @@ -19,7 +19,7 @@ -- -- =================================================================== -create table llx_expedition +create table llx_reception ( rowid integer AUTO_INCREMENT PRIMARY KEY, tms timestamp, @@ -30,7 +30,7 @@ create table llx_expedition ref_ext varchar(30), -- reference into an external system (not used by dolibarr) ref_int varchar(30), -- reference into an internal system (used by dolibarr to store extern id like paypal info) - ref_customer varchar(30), -- customer number + ref_supplier varchar(30), -- customer number date_creation datetime, -- date de creation fk_user_author integer, -- author of creation @@ -38,8 +38,7 @@ create table llx_expedition date_valid datetime, -- date de validation fk_user_valid integer, -- valideur date_delivery datetime DEFAULT NULL, -- date planned of delivery - date_expedition datetime, -- not used (deprecated) - fk_address integer DEFAULT NULL, -- delivery address (deprecated) + date_reception datetime, fk_shipping_method integer, tracking_number varchar(50), fk_statut smallint DEFAULT 0, -- 0 = draft, 1 = validated, 2 = billed or closed depending on WORKFLOW_BILL_ON_SHIPMENT option diff --git a/htdocs/install/mysql/tables/llx_reception_extrafields.key.sql b/htdocs/install/mysql/tables/llx_reception_extrafields.key.sql index b539f460a08..f3a35acd8a3 100644 --- a/htdocs/install/mysql/tables/llx_reception_extrafields.key.sql +++ b/htdocs/install/mysql/tables/llx_reception_extrafields.key.sql @@ -17,4 +17,4 @@ -- =================================================================== -ALTER TABLE llx_expedition_extrafields ADD INDEX idx_expedition_extrafields (fk_object); +ALTER TABLE llx_reception_extrafields ADD INDEX idx_reception_extrafields (fk_object); diff --git a/htdocs/install/mysql/tables/llx_reception_extrafields.sql b/htdocs/install/mysql/tables/llx_reception_extrafields.sql index eff8465fbf6..7a3126b2015 100644 --- a/htdocs/install/mysql/tables/llx_reception_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_reception_extrafields.sql @@ -16,7 +16,7 @@ -- -- ======================================================================== -create table llx_expedition_extrafields +create table llx_reception_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, tms timestamp, diff --git a/htdocs/install/mysql/tables/llx_receptiondet.key.sql b/htdocs/install/mysql/tables/llx_receptiondet.key.sql index 5f5b6a08183..3740f83d1d0 100644 --- a/htdocs/install/mysql/tables/llx_receptiondet.key.sql +++ b/htdocs/install/mysql/tables/llx_receptiondet.key.sql @@ -18,5 +18,5 @@ -- =================================================================== -ALTER TABLE llx_expeditiondet ADD INDEX idx_expeditiondet_fk_expedition (fk_expedition); -ALTER TABLE llx_expeditiondet ADD CONSTRAINT fk_expeditiondet_fk_expedition FOREIGN KEY (fk_expedition) REFERENCES llx_expedition (rowid); +ALTER TABLE llx_receptiondet ADD INDEX idx_receptiondet_fk_reception (fk_reception); +ALTER TABLE llx_receptiondet ADD CONSTRAINT fk_receptiondet_fk_reception FOREIGN KEY (fk_reception) REFERENCES llx_reception (rowid); diff --git a/htdocs/install/mysql/tables/llx_receptiondet.sql b/htdocs/install/mysql/tables/llx_receptiondet.sql index bd05bd08898..dd726c85eab 100644 --- a/htdocs/install/mysql/tables/llx_receptiondet.sql +++ b/htdocs/install/mysql/tables/llx_receptiondet.sql @@ -18,10 +18,10 @@ -- -- =================================================================== -create table llx_expeditiondet +create table llx_receptiondet ( rowid integer AUTO_INCREMENT PRIMARY KEY, - fk_expedition integer NOT NULL, + fk_reception integer NOT NULL, fk_origin_line integer, -- Correspondance de la ligne avec le document d'origine (propal, commande) fk_entrepot integer, -- Entrepot de depart du produit qty real, -- Quantity diff --git a/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql b/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql index 70bfe974f34..59928d1c278 100644 --- a/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql +++ b/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql @@ -16,5 +16,5 @@ -- -- ============================================================================ -ALTER TABLE llx_expeditiondet_batch ADD INDEX idx_fk_expeditiondet (fk_expeditiondet); -ALTER TABLE llx_expeditiondet_batch ADD CONSTRAINT fk_expeditiondet_batch_fk_expeditiondet FOREIGN KEY (fk_expeditiondet) REFERENCES llx_expeditiondet(rowid); +ALTER TABLE llx_receptiondet_batch ADD INDEX idx_fk_receptiondet (fk_receptiondet); +ALTER TABLE llx_receptiondet_batch ADD CONSTRAINT fk_receptiondet_batch_fk_receptiondet FOREIGN KEY (fk_receptiondet) REFERENCES llx_receptiondet(rowid); diff --git a/htdocs/install/mysql/tables/llx_receptiondet_batch.sql b/htdocs/install/mysql/tables/llx_receptiondet_batch.sql index 2a1234d9342..ef2537cc116 100644 --- a/htdocs/install/mysql/tables/llx_receptiondet_batch.sql +++ b/htdocs/install/mysql/tables/llx_receptiondet_batch.sql @@ -15,9 +15,9 @@ -- along with this program. If not, see . -- -- ============================================================================ -CREATE TABLE llx_expeditiondet_batch ( +CREATE TABLE llx_receptiondet_batch ( rowid integer AUTO_INCREMENT PRIMARY KEY, - fk_expeditiondet int NOT NULL, + fk_receptiondet int NOT NULL, eatby date DEFAULT NULL, sellby date DEFAULT NULL, batch varchar(30) DEFAULT NULL, diff --git a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql b/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql index 11e133442d5..5d5d52b5526 100644 --- a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql +++ b/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql @@ -17,4 +17,4 @@ -- =================================================================== -ALTER TABLE llx_expeditiondet_extrafields ADD INDEX idx_expeditiondet_extrafields (fk_object); +ALTER TABLE llx_receptiondet_extrafields ADD INDEX idx_receptiondet_extrafields (fk_object); diff --git a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql b/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql index e27c7f3e505..5fe823efd76 100644 --- a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql @@ -16,7 +16,7 @@ -- -- =================================================================== -create table llx_expeditiondet_extrafields +create table llx_receptiondet_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, tms timestamp, diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index bfe6e81858c..e72d093d543 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1439,11 +1439,9 @@ SendingsAbility=Prise en charge des bons d'expédition pour les livraisons clien NoNeedForDeliveryReceipts=Dans le plupart des cas, la fiche expédition est utilisée en tant que bon d'expédition (liste des produits expédiés) et bon de livraison (signée par le client). Le bon de réception est un doublon de fonctionnalité et est rarement utilisé. FreeLegalTextOnShippings=Mention complémentaire sur les expéditions ##### Reception ##### -ReceptionsSetup=Configuration du module Réception/Livraison +ReceptionsSetup=Configuration du module Réception ReceptionsReceiptModel=Modèles de bordereau de réception ReceptionsNumberingModules=Modèles de numérotation des réceptions -ReceptionsAbility=Prise en charge des bons d'réception pour les livraisons clients -NoNeedForDeliveryReceipts=Dans le plupart des cas, la fiche réception est utilisée en tant que bon d'réception (liste des produits expédiés) et bon de livraison (signée par le client). Le bon de réception est un doublon de fonctionnalité et est rarement utilisé. FreeLegalTextOnShippings=Mention complémentaire sur les réceptions ##### Deliveries ##### DeliveryOrderNumberingModules=Modèle de numérotation des bons de réception client diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index 9a79bf2f8bd..2fb7d558d8e 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -60,6 +60,8 @@ DeStockOnBill=Décrémente les stocks physiques sur validation des factures/avoi DeStockOnValidateOrder=Décrémente les stocks physiques sur validation des commandes clients DeStockOnShipment=Décrémenter les stocks physiques sur validation des expéditions DeStockOnShipmentOnClosing=Décrémenter les stocks réels au classement "clôturée" de l'expédition +StockOnReception=Incrémenter les stocks physiques sur validation des réceptions +StockOnReceptionOnClosing=Incrémenter les stocks réels au classement "clôturée" de la réception ReStockOnBill=Incrémente les stocks physiques sur validation des factures/avoirs fournisseurs ReStockOnValidateOrder=Incrémente les stocks physiques sur approbation des commandes fournisseurs ReStockOnDispatchOrder=Incrémente les stocks réels sur ventilation manuelle dans les entrepôts, après réception de la marchandise @@ -123,9 +125,10 @@ RecordMovement=Enregistrer transfert ReceivingForSameOrder=Réceptions pour cette commande StockMovementRecorded=Mouvement de stocks enregistré RuleForStockAvailability=Règles d'exigence sur les stocks -StockMustBeEnoughForInvoice=Le niveau de stock doit être suffisant pour ajouter ce produit/service à la facture (la vérification est faite sur le stock réel lors de l'ajout de la ligne de facture, quelquesoit la règle de modification automatique de stock) -StockMustBeEnoughForOrder=Le niveau de stock doit être suffisant pour ajouter ce produit/service à la commande (la vérification est faite sur le stock réel lors de l'ajout de la ligne de commande, quelquesoit la règle de modification automatique de stock) -StockMustBeEnoughForShipment= Le niveau de stock doit être suffisant pour ajouter ce produit/service à l'expédition (la vérification est faite sur le stock réel lors de l'ajout de la ligne à l'expédition, quelquesoit la règle de modification automatique de stock) +StockMustBeEnoughForInvoice=Le niveau de stock doit être suffisant pour ajouter ce produit/service à la facture (la vérification est faite sur le stock réel lors de l'ajout de la ligne de facture, quel que soit la règle de modification automatique de stock) +StockMustBeEnoughForOrder=Le niveau de stock doit être suffisant pour ajouter ce produit/service à la commande (la vérification est faite sur le stock réel lors de l'ajout de la ligne de commande, quel que soit la règle de modification automatique de stock) +StockMustBeEnoughForShipment= Le niveau de stock doit être suffisant pour ajouter ce produit/service à l'expédition (la vérification est faite sur le stock réel lors de l'ajout de la ligne à l'expédition, quel que soit la règle de modification automatique de stock) +StockMustBeEnoughForReception= Le niveau de stock doit être suffisant pour ajouter ce produit/service à la réception (la vérification est faite sur le stock réel lors de l'ajout de la ligne à la récepetion, quel que soit la règle de modification automatique de stock) MovementLabel=Libellé du mouvement InventoryCode=Code mouvement ou inventaire IsInPackage=Inclus dans un package diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 05adfc1b5c5..e11a1665866 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3839,6 +3839,9 @@ class Product extends CommonObject $this->stock_theorique=$this->stock_reel-$stock_commande_client; } // Stock Increase mode + if (! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || ! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)) { + $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur; + } if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) { $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur; } diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 5561d5778f6..3cd0b459f13 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -121,7 +121,7 @@ else $result=restrictedArea($user,'produit|service','','','','','',$objcanvas); // Define virtualdiffersfromphysical $virtualdiffersfromphysical=0; -if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) +if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) || ! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) ) { $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. } diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index e3983344cff..f5d8e358a66 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -75,7 +75,7 @@ if (! empty($canvas)) // Define virtualdiffersfromphysical $virtualdiffersfromphysical=0; -if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) +if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)|| ! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION)) { $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. } diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index f45f2b30a56..bf07fa244d2 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -638,6 +638,8 @@ if ($id > 0 || $ref) $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)?$langs->trans("ReStockOnBill").'
':''); $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)?$langs->trans("ReStockOnValidateOrder").'
':''); $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)?$langs->trans("ReStockOnDispatchOrder").'
':''); + $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || ! empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)?$langs->trans("StockOnReception").'
':''); + print ''; print $form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1); print ''; diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 28786f0d324..fe74df5e35e 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -80,7 +80,9 @@ if (!$sortorder) { $virtualdiffersfromphysical=0; if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) -|| ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) +|| ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) +|| !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) +|| !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)) { $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. } diff --git a/htdocs/product/stock/replenishorders.php b/htdocs/product/stock/replenishorders.php index 694f9cae1ad..3763dc2e8fc 100644 --- a/htdocs/product/stock/replenishorders.php +++ b/htdocs/product/stock/replenishorders.php @@ -113,7 +113,7 @@ $sql.= ' WHERE cf.fk_soc = s.rowid '; $sql.= ' AND cf.entity = ' . $conf->entity; if ($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) { $sql .= ' AND cf.fk_statut < 3'; -} elseif ($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) { +} elseif ($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER|| !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)) { $sql .= ' AND cf.fk_statut < 6'; // We want also status 5, we will keep them visible if dispatching is not yet finished (tested with function dolDispatchToDo). } else { $sql .= ' AND cf.fk_statut < 5'; diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 324714fee7c..5aabccb8347 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -51,7 +51,7 @@ class Reception extends CommonObject public $picto = 'reception'; var $socid; - var $ref_customer; + var $ref_supplier; var $ref_int; var $brouillon; var $entrepot_id; @@ -201,7 +201,7 @@ class Reception extends CommonObject $sql = "INSERT INTO ".MAIN_DB_PREFIX."reception ("; $sql.= "ref"; $sql.= ", entity"; - $sql.= ", ref_customer"; + $sql.= ", ref_supplier"; $sql.= ", ref_int"; $sql.= ", date_creation"; $sql.= ", fk_user_author"; @@ -210,7 +210,7 @@ class Reception extends CommonObject $sql.= ", fk_soc"; $sql.= ", fk_projet"; $sql.= ", fk_address"; - $sql.= ", fk_reception_method"; + $sql.= ", fk_shipping_method"; $sql.= ", tracking_number"; $sql.= ", weight"; $sql.= ", size"; @@ -225,7 +225,7 @@ class Reception extends CommonObject $sql.= ") VALUES ("; $sql.= "'(PROV)'"; $sql.= ", ".$conf->entity; - $sql.= ", ".($this->ref_customer?"'".$this->db->escape($this->ref_customer)."'":"null"); + $sql.= ", ".($this->ref_supplier?"'".$this->db->escape($this->ref_supplier)."'":"null"); $sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", ".$user->id; @@ -477,10 +477,10 @@ class Reception extends CommonObject // Check parameters if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; - $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut"; + $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_supplier, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut"; $sql.= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height"; $sql.= ", e.date_reception as date_reception, e.model_pdf, e.fk_address, e.date_delivery"; - $sql.= ", e.fk_reception_method, e.tracking_number"; + $sql.= ", e.fk_shipping_method, e.tracking_number"; $sql.= ", el.fk_source as origin_id, el.sourcetype as origin"; $sql.= ", e.note_private, e.note_public"; $sql.= ', e.fk_incoterms, e.location_incoterms'; @@ -505,7 +505,7 @@ class Reception extends CommonObject $this->id = $obj->rowid; $this->ref = $obj->ref; $this->socid = $obj->socid; - $this->ref_customer = $obj->ref_customer; + $this->ref_supplier = $obj->ref_supplier; $this->ref_ext = $obj->ref_ext; $this->ref_int = $obj->ref_int; $this->statut = $obj->fk_statut; @@ -517,7 +517,7 @@ class Reception extends CommonObject $this->date_delivery = $this->db->jdate($obj->date_delivery); // Date planed $this->fk_delivery_address = $obj->fk_address; $this->modelpdf = $obj->model_pdf; - $this->reception_method_id = $obj->fk_reception_method; + $this->shipping_method_id = $obj->fk_shipping_method; $this->tracking_number = $obj->tracking_number; $this->origin = ($obj->origin?$obj->origin:'commande'); // For compatibility $this->origin_id = $obj->origin_id; @@ -1007,7 +1007,7 @@ class Reception extends CommonObject if (isset($this->ref)) $this->ref=trim($this->ref); if (isset($this->entity)) $this->entity=trim($this->entity); - if (isset($this->ref_customer)) $this->ref_customer=trim($this->ref_customer); + if (isset($this->ref_supplier)) $this->ref_supplier=trim($this->ref_supplier); if (isset($this->socid)) $this->socid=trim($this->socid); if (isset($this->fk_user_author)) $this->fk_user_author=trim($this->fk_user_author); if (isset($this->fk_user_valid)) $this->fk_user_valid=trim($this->fk_user_valid); @@ -1035,7 +1035,7 @@ class Reception extends CommonObject $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").","; - $sql.= " ref_customer=".(isset($this->ref_customer)?"'".$this->db->escape($this->ref_customer)."'":"null").","; + $sql.= " ref_supplier=".(isset($this->ref_supplier)?"'".$this->db->escape($this->ref_supplier)."'":"null").","; $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").","; $sql.= " date_creation=".(dol_strlen($this->date_creation)!=0 ? "'".$this->db->idate($this->date_creation)."'" : 'null').","; $sql.= " fk_user_author=".(isset($this->fk_user_author)?$this->fk_user_author:"null").","; @@ -1044,7 +1044,7 @@ class Reception extends CommonObject $sql.= " date_reception=".(dol_strlen($this->date_reception)!=0 ? "'".$this->db->idate($this->date_reception)."'" : 'null').","; $sql.= " date_delivery=".(dol_strlen($this->date_delivery)!=0 ? "'".$this->db->idate($this->date_delivery)."'" : 'null').","; $sql.= " fk_address=".(isset($this->fk_delivery_address)?$this->fk_delivery_address:"null").","; - $sql.= " fk_reception_method=".((isset($this->reception_method_id) && $this->reception_method_id > 0)?$this->reception_method_id:"null").","; + $sql.= " fk_shipping_method=".((isset($this->reception_method_id) && $this->reception_method_id > 0)?$this->reception_method_id:"null").","; $sql.= " tracking_number=".(isset($this->tracking_number)?"'".$this->db->escape($this->tracking_number)."'":"null").","; $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").","; $sql.= " height=".(($this->trueHeight != '')?$this->trueHeight:"null").","; @@ -1498,7 +1498,7 @@ class Reception extends CommonObject $result=''; $label = '' . $langs->trans("ShowReception") . ''; $label .= '
' . $langs->trans('Ref') . ': '.$this->ref; - $label .= '
'.$langs->trans('RefCustomer').': '.($this->ref_customer ? $this->ref_customer : $this->ref_client); + $label .= '
'.$langs->trans('RefCustomer').': '.($this->ref_supplier ? $this->ref_supplier : $this->ref_client); $url = DOL_URL_ROOT.'/reception/card.php?id='.$this->id; diff --git a/scripts/reception/create-table.php b/scripts/reception/create-table.php new file mode 100644 index 00000000000..a9f3401f327 --- /dev/null +++ b/scripts/reception/create-table.php @@ -0,0 +1,278 @@ + '--') + { + $buf = preg_replace('/--(.+)*/', '', $buf); + $buffer .= $buf; + } + } + fclose($fp); + + $buffer = trim($buffer); + if ($conf->db->type == 'mysql' || $conf->db->type == 'mysqli') // For Mysql 5.5+, we must replace type=innodb with ENGINE=innodb + { + $buffer = preg_replace('/type=innodb/i', 'ENGINE=innodb', $buffer); + } + else if ($conf->db->type == 'mssql') + { + $buffer = preg_replace('/type=innodb/i', '', $buffer); + $buffer = preg_replace('/ENGINE=innodb/i', '', $buffer); + } + + // Replace the prefix tables + if ($dolibarr_main_db_prefix != 'llx_') + { + $buffer = preg_replace('/llx_/i', $dolibarr_main_db_prefix, $buffer); + } + + //print "Creation de la table $name/td>"; + $requestnb++; + + $resql = $db->query($buffer, 0, 'dml'); + if ($resql) + { + // print "OK requete ==== $buffer"; + $db->free($resql); + } + else + { + if ($db->errno() == 'DB_ERROR_TABLE_ALREADY_EXISTS' || + $db->errno() == 'DB_ERROR_TABLE_OR_KEY_ALREADY_EXISTS') + { + //print "Deja existante"; + } + else + { + print "".$langs->trans("CreateTableAndPrimaryKey", $name); + print "
\n".$langs->trans("Request").' '.$requestnb.' : '.$buffer.'
Executed query : '.$db->lastquery; + print "\n"; + print ''.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().''; + $error++; + } + } + } + else + { + print "".$langs->trans("CreateTableAndPrimaryKey", $name); + print ""; + print ''.$langs->trans("Error").' Failed to open file '.$dir.$file.''; + $error++; + } +} + +if ($tablefound) +{ + if ($error == 0) + { + print ''; + print $langs->trans("TablesAndPrimaryKeysCreation").'Ok'; + $ok = 1; + } +} +else +{ + print ''.$langs->trans("ErrorFailedToFindSomeFiles", $dir).'Error'; +} + + + +// We always choose in mysql directory (Conversion is done by driver to translate SQL syntax) + + +$okkeys = 0; +$handle = opendir($dir); +$tablefound = 0; +$tabledata = array(); +if (is_resource($handle)) +{ + while (($file = readdir($handle)) !== false) + { + if (preg_match('/\.sql$/i', $file) && preg_match('/^llx_/i', $file) && preg_match('/\.key\.sql$/i', $file)) + { + if (strpos($file, 'reception') !== false){ + $tablefound++; + $tabledata[] = $file; + } + } + } + closedir($handle); +} + +// Sort list of sql files on alphabetical order (load order is important) +sort($tabledata); +foreach ($tabledata as $file) +{ + $name = substr($file, 0, dol_strlen($file) - 4); + //print "Creation de la table $name"; + $buffer = ''; + $fp = fopen($dir.$file, "r"); + if ($fp) + { + while (!feof($fp)) + { + $buf = fgets($fp, 4096); + + // Cas special de lignes autorisees pour certaines versions uniquement + if ($choix == 1 && preg_match('/^--\sV([0-9\.]+)/i', $buf, $reg)) + { + $versioncommande = explode('.', $reg[1]); + //print var_dump($versioncommande); + //print var_dump($versionarray); + if (count($versioncommande) && count($versionarray) && versioncompare($versioncommande, $versionarray) <= 0) + { + // Version qualified, delete SQL comments + $buf = preg_replace('/^--\sV([0-9\.]+)/i', '', $buf); + //print "Ligne $i qualifiee par version: ".$buf.'
'; + } + } + if ($choix == 2 && preg_match('/^--\sPOSTGRESQL\sV([0-9\.]+)/i', $buf, $reg)) + { + $versioncommande = explode('.', $reg[1]); + //print var_dump($versioncommande); + //print var_dump($versionarray); + if (count($versioncommande) && count($versionarray) && versioncompare($versioncommande, $versionarray) <= 0) + { + // Version qualified, delete SQL comments + $buf = preg_replace('/^--\sPOSTGRESQL\sV([0-9\.]+)/i', '', $buf); + //print "Ligne $i qualifiee par version: ".$buf.'
'; + } + } + + // Ajout ligne si non commentaire + if (!preg_match('/^--/i', $buf)) + $buffer .= $buf; + } + fclose($fp); + + // Si plusieurs requetes, on boucle sur chaque + $listesql = explode(';', $buffer); + foreach ($listesql as $req) + { + $buffer = trim($req); + if ($buffer) + { + // Replace the prefix tables + if ($dolibarr_main_db_prefix != 'llx_') + { + $buffer = preg_replace('/llx_/i', $dolibarr_main_db_prefix, $buffer); + } + + //print "Creation des cles et index de la table $name: '$buffer'"; + $requestnb++; + + $resql = $db->query($buffer, 0, 'dml'); + if ($resql) + { + //print "OK requete ==== $buffer"; + $db->free($resql); + } + else + { + if ($db->errno() == 'DB_ERROR_KEY_NAME_ALREADY_EXISTS' || + $db->errno() == 'DB_ERROR_CANNOT_CREATE' || + $db->errno() == 'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS' || + $db->errno() == 'DB_ERROR_TABLE_OR_KEY_ALREADY_EXISTS' || + preg_match('/duplicate key name/i', $db->error())) + { + //print "Deja existante"; + $key_exists = 1; + } + else + { + print "".$langs->trans("CreateOtherKeysForTable", $name); + print "
\n".$langs->trans("Request").' '.$requestnb.' : '.$db->lastqueryerror(); + print "\n"; + print ''.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().''; + $error++; + } + } + } + } + } + else + { + print "".$langs->trans("CreateOtherKeysForTable", $name); + print ""; + print ''.$langs->trans("Error")." Failed to open file ".$dir.$file.""; + $error++; + } +} + +if ($tablefound && $error == 0) +{ + print ''; + print $langs->trans("OtherKeysCreation").'Ok'; + $okkeys = 1; +} + \ No newline at end of file From 00f532c43623443a8e8647f81e5a39772d9e4994 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Thu, 4 Oct 2018 09:50:39 +0200 Subject: [PATCH 006/307] =?UTF-8?q?validation=20mod=C3=A8le=20de=20donn?= =?UTF-8?q?=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ande_fournisseur_dispatch_extrafields.php} | 4 +-- htdocs/core/lib/reception.lib.php | 2 +- .../llx_commande_fournisseur_dispatch.key.sql | 4 ++- .../llx_commande_fournisseur_dispatch.sql | 1 + ..._fournisseur_dispatch_extrafields.key.sql} | 2 +- ...ande_fournisseur_dispatch_extrafields.sql} | 2 +- .../mysql/tables/llx_receptiondet.key.sql | 22 -------------- .../install/mysql/tables/llx_receptiondet.sql | 29 ------------------- .../tables/llx_receptiondet_batch.key.sql | 20 ------------- .../mysql/tables/llx_receptiondet_batch.sql | 27 ----------------- scripts/reception/create-table.php | 4 +-- 11 files changed, 11 insertions(+), 106 deletions(-) rename htdocs/admin/{receptiondet_extrafields.php => commande_fournisseur_dispatch_extrafields.php} (95%) rename htdocs/install/mysql/tables/{llx_receptiondet_extrafields.key.sql => llx_commande_fournisseur_dispatch_extrafields.key.sql} (87%) rename htdocs/install/mysql/tables/{llx_receptiondet_extrafields.sql => llx_commande_fournisseur_dispatch_extrafields.sql} (94%) delete mode 100644 htdocs/install/mysql/tables/llx_receptiondet.key.sql delete mode 100644 htdocs/install/mysql/tables/llx_receptiondet.sql delete mode 100644 htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql delete mode 100644 htdocs/install/mysql/tables/llx_receptiondet_batch.sql diff --git a/htdocs/admin/receptiondet_extrafields.php b/htdocs/admin/commande_fournisseur_dispatch_extrafields.php similarity index 95% rename from htdocs/admin/receptiondet_extrafields.php rename to htdocs/admin/commande_fournisseur_dispatch_extrafields.php index 80bc3806b52..68246b675e5 100644 --- a/htdocs/admin/receptiondet_extrafields.php +++ b/htdocs/admin/commande_fournisseur_dispatch_extrafields.php @@ -25,7 +25,7 @@ */ /** - * \file htdocs/admin/receptiondet_extrafields.php + * \file htdocs/admin/commandefournisseurdispatch_extrafields.php * \ingroup reception * \brief Page to setup extra fields of reception */ @@ -52,7 +52,7 @@ foreach ($tmptype2label as $key => $val) $type2label[$key]=$langs->trans($val); $action=GETPOST('action', 'alpha'); $attrname=GETPOST('attrname', 'alpha'); -$elementtype='receptiondet'; //Must be the $table_element of the class that manage extrafield +$elementtype='commande_fournisseur_dispatch'; //Must be the $table_element of the class that manage extrafield if (!$user->admin) accessforbidden(); diff --git a/htdocs/core/lib/reception.lib.php b/htdocs/core/lib/reception.lib.php index 34cd46026ed..b3c32ee60b4 100644 --- a/htdocs/core/lib/reception.lib.php +++ b/htdocs/core/lib/reception.lib.php @@ -85,7 +85,7 @@ function reception_admin_prepare_head() if (! empty($conf->global->MAIN_SUBMODULE_RECEPTION)) { - $head[$h][0] = DOL_URL_ROOT.'/admin/receptiondet_extrafields.php'; + $head[$h][0] = DOL_URL_ROOT.'/admin/commande_fournisseur_dispatch_extrafields.php'; $head[$h][1] = $langs->trans("ExtraFieldsLines"); $head[$h][2] = 'attributeslines_reception'; $h++; diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.key.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.key.sql index ba7c02280ec..369a25f2b32 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.key.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.key.sql @@ -16,4 +16,6 @@ -- -- =================================================================== -ALTER TABLE llx_commande_fournisseur_dispatch ADD INDEX idx_commande_fournisseur_dispatch_fk_commande (fk_commande); \ No newline at end of file +ALTER TABLE llx_commande_fournisseur_dispatch ADD INDEX idx_commande_fournisseur_dispatch_fk_commande (fk_commande); +ALTER TABLE llx_commande_fournisseur_dispatch ADD INDEX idx_commande_fournisseur_dispatch_fk_reception (fk_reception); +ALTER TABLE llx_commande_fournisseur_dispatch ADD CONSTRAINT fk_commande_fournisseur_dispatch_fk_reception FOREIGN KEY (fk_reception) REFERENCES llx_reception (rowid); \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql index 074dc0d4c16..9a6e05d1af1 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql @@ -26,6 +26,7 @@ create table llx_commande_fournisseur_dispatch fk_product integer, fk_commandefourndet integer, fk_projet integer DEFAULT NULL, + fk_reception integer DEFAULT NULL, qty float, -- qty fk_entrepot integer, fk_user integer, diff --git a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch_extrafields.key.sql similarity index 87% rename from htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql rename to htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch_extrafields.key.sql index 5d5d52b5526..c836fbaea6a 100644 --- a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.key.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch_extrafields.key.sql @@ -17,4 +17,4 @@ -- =================================================================== -ALTER TABLE llx_receptiondet_extrafields ADD INDEX idx_receptiondet_extrafields (fk_object); +ALTER TABLE llx_commande_fournisseur_dispatch_extrafields ADD INDEX idx_commande_fournisseur_dispatch_extrafields (fk_object); diff --git a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch_extrafields.sql similarity index 94% rename from htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql rename to htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch_extrafields.sql index 5fe823efd76..f00eabf42fa 100644 --- a/htdocs/install/mysql/tables/llx_receptiondet_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch_extrafields.sql @@ -16,7 +16,7 @@ -- -- =================================================================== -create table llx_receptiondet_extrafields +create table llx_commande_fournisseur_dispatch_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, tms timestamp, diff --git a/htdocs/install/mysql/tables/llx_receptiondet.key.sql b/htdocs/install/mysql/tables/llx_receptiondet.key.sql deleted file mode 100644 index 3740f83d1d0..00000000000 --- a/htdocs/install/mysql/tables/llx_receptiondet.key.sql +++ /dev/null @@ -1,22 +0,0 @@ --- =================================================================== --- Copyright (C) 2005 Laurent Destailleur --- Copyright (C) 2008 Regis Houssin --- --- 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 . --- --- =================================================================== - - -ALTER TABLE llx_receptiondet ADD INDEX idx_receptiondet_fk_reception (fk_reception); -ALTER TABLE llx_receptiondet ADD CONSTRAINT fk_receptiondet_fk_reception FOREIGN KEY (fk_reception) REFERENCES llx_reception (rowid); diff --git a/htdocs/install/mysql/tables/llx_receptiondet.sql b/htdocs/install/mysql/tables/llx_receptiondet.sql deleted file mode 100644 index dd726c85eab..00000000000 --- a/htdocs/install/mysql/tables/llx_receptiondet.sql +++ /dev/null @@ -1,29 +0,0 @@ --- =================================================================== --- Copyright (C) 2003 Rodolphe Quiedeville --- Copyright (C) 2008 Regis Houssin --- Copyright (C) 2011 Laurent Destailleur --- --- 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 . --- --- =================================================================== - -create table llx_receptiondet -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - fk_reception integer NOT NULL, - fk_origin_line integer, -- Correspondance de la ligne avec le document d'origine (propal, commande) - fk_entrepot integer, -- Entrepot de depart du produit - qty real, -- Quantity - rang integer DEFAULT 0 -)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql b/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql deleted file mode 100644 index 59928d1c278..00000000000 --- a/htdocs/install/mysql/tables/llx_receptiondet_batch.key.sql +++ /dev/null @@ -1,20 +0,0 @@ --- ============================================================================ --- Copyright (C) 2014 Cédric GROSS --- --- 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 . --- --- ============================================================================ - -ALTER TABLE llx_receptiondet_batch ADD INDEX idx_fk_receptiondet (fk_receptiondet); -ALTER TABLE llx_receptiondet_batch ADD CONSTRAINT fk_receptiondet_batch_fk_receptiondet FOREIGN KEY (fk_receptiondet) REFERENCES llx_receptiondet(rowid); diff --git a/htdocs/install/mysql/tables/llx_receptiondet_batch.sql b/htdocs/install/mysql/tables/llx_receptiondet_batch.sql deleted file mode 100644 index ef2537cc116..00000000000 --- a/htdocs/install/mysql/tables/llx_receptiondet_batch.sql +++ /dev/null @@ -1,27 +0,0 @@ --- ============================================================================ --- Copyright (C) 2014 Cédric GROSS --- --- 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 . --- --- ============================================================================ -CREATE TABLE llx_receptiondet_batch ( - rowid integer AUTO_INCREMENT PRIMARY KEY, - fk_receptiondet int NOT NULL, - eatby date DEFAULT NULL, - sellby date DEFAULT NULL, - batch varchar(30) DEFAULT NULL, - qty double NOT NULL DEFAULT '0', - fk_origin_stock integer NOT NULL -) ENGINE=InnoDB; - diff --git a/scripts/reception/create-table.php b/scripts/reception/create-table.php index a9f3401f327..c65292da04b 100644 --- a/scripts/reception/create-table.php +++ b/scripts/reception/create-table.php @@ -47,7 +47,7 @@ if (is_resource($handle)) { if (preg_match('/\.sql$/i', $file) && preg_match('/^llx_/i', $file) && !preg_match('/\.key\.sql$/i', $file)) { - if (strpos($file, 'reception') !== false){ + if (strpos($file, 'reception') !== false || strpos($file, 'commande_fournisseur_dispatch') !== false){ $tablefound++; $tabledata[] = $file; } @@ -160,7 +160,7 @@ if (is_resource($handle)) { if (preg_match('/\.sql$/i', $file) && preg_match('/^llx_/i', $file) && preg_match('/\.key\.sql$/i', $file)) { - if (strpos($file, 'reception') !== false){ + if (strpos($file, 'reception') !== false || strpos($file, 'commande_fournisseur_dispatch') !== false){ $tablefound++; $tabledata[] = $file; } From bc07936d4249b8eb2a60a91c8e8366cff33b30bc Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Thu, 4 Oct 2018 10:17:18 +0200 Subject: [PATCH 007/307] NEW list on dispatch --- htdocs/fourn/commande/dispatch.php | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index f4f05f96b78..0436c33f3ad 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -46,6 +46,7 @@ $langs->load('bills'); $langs->load('deliveries'); $langs->load('products'); $langs->load('stocks'); +$langs->load('receptions'); if (! empty($conf->productbatch->enabled)) $langs->load('productbatch'); @@ -738,6 +739,7 @@ if ($id > 0 || ! empty($ref)) { $sql = "SELECT p.ref, p.label,"; $sql .= " e.rowid as warehouse_id, e.label as entrepot,"; $sql .= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status"; + if($conf->reception->enabled)$sql.=" ,cfd.fk_reception"; $sql .= " FROM " . MAIN_DB_PREFIX . "product as p,"; $sql .= " " . MAIN_DB_PREFIX . "commande_fournisseur_dispatch as cfd"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "entrepot as e ON cfd.fk_entrepot = e.rowid"; @@ -759,6 +761,7 @@ if ($id > 0 || ! empty($ref)) { print ''; print ''; + if($conf->reception->enabled)print ''; print ''; if (! empty($conf->productbatch->enabled)) { print ''; @@ -769,7 +772,7 @@ if ($id > 0 || ! empty($ref)) { print ''; print ''; print ''; - if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) + if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS) || !empty($conf->reception->enabled)) print ''; print "\n"; @@ -777,9 +780,18 @@ if ($id > 0 || ! empty($ref)) { while ( $i < $num ) { $objp = $db->fetch_object($resql); - + + + print ""; print '"; + print '\n"; @@ -805,7 +817,7 @@ if ($id > 0 || ! empty($ref)) { print ''; // Status - if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) { + if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS) && empty($reception->rowid)) { print ''; + }else if(!empty($conf->reception->enabled)){ + print ''; + print ''; + } print "\n"; From 5fe767d7bdcf9007af06d834222bd169334401e5 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Thu, 4 Oct 2018 12:27:10 +0200 Subject: [PATCH 008/307] debut card create --- .../class/fournisseur.commande.class.php | 48 ++ htdocs/fourn/commande/dispatch.php | 39 +- htdocs/langs/fr_FR/receptions.lang | 30 +- htdocs/reception/card.php | 434 ++++++++++-------- 4 files changed, 328 insertions(+), 223 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 073f399e324..aa596170cbf 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2936,6 +2936,54 @@ class CommandeFournisseur extends CommonOrder } return 0; } + + /** + * Load array this->receptions of lines of shipments with nb of products sent for each order line + * Note: For a dedicated shipment, the fetch_lines can be used to load the qty_asked and qty_shipped. This function is use to return qty_shipped cumulated for the order + * + * @param int $filtre_statut Filter on shipment status + * @return int <0 if KO, Nb of lines found if OK + */ + function loadReceptions($filtre_statut=-1) + { + $this->receptions = array(); + + $sql = 'SELECT cd.rowid, cd.fk_product,'; + $sql.= ' sum(cfd.qty) as qty'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseur_dispatch as cfd,'; + if ($filtre_statut >= 0) $sql.= ' '.MAIN_DB_PREFIX.'reception as e,'; + $sql.= ' '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; + $sql.= ' WHERE'; + if ($filtre_statut >= 0) $sql.= ' cfd.fk_reception = e.rowid AND'; + $sql.= ' cfd.commandefourndet = cd.rowid'; + $sql.= ' AND cd.fk_commande =' .$this->id; + if ($this->fk_product > 0) $sql.= ' AND cd.fk_product = '.$this->fk_product; + if ($filtre_statut >= 0) $sql.=' AND e.fk_statut >= '.$filtre_statut; + $sql.= ' GROUP BY cd.rowid, cd.fk_product'; + //print $sql; + + dol_syslog(get_class($this)."::loadReceptions", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + $this->receptions[$obj->rowid] = $obj->qty; + $i++; + } + $this->db->free(); + return $num; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + + } } diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 0436c33f3ad..eba1df3bbf6 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -382,8 +382,8 @@ if ($id > 0 || ! empty($ref)) { $morehtmlref.=' : '; if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
'; - $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=''; $morehtmlref.=''; $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); $morehtmlref.=''; @@ -452,9 +452,13 @@ if ($id > 0 || ! empty($ref)) { $entrepot = new Entrepot($db); $listwarehouses = $entrepot->list_array(1); - print ''; + if(empty($conf->reception->enabled))print ''; + else print ''; + print ''; - print ''; + + if(empty($conf->reception->enabled))print ''; + else print ''; print '
'; print '
' . $langs->trans("Reception") . '' . $langs->trans("Product") . '' . $langs->trans("batch_number") . '' . $langs->trans("Warehouse") . '' . $langs->trans("Comment") . '' . $langs->trans("Status") . '
'; + if(!empty($conf->reception->enabled) && !empty($objp->fk_reception)){ + $reception = new Reception($db); + $reception->fetch($objp->fk_reception); + print $reception->getNomUrl(); + } + print "'; print '' . img_object($langs->trans("ShowProduct"), 'product') . ' ' . $objp->ref . ''; print ' - ' . $objp->label; print "' . $objp->comment . ''; $supplierorderdispatch->status = (empty($objp->status) ? 0 : $objp->status); // print $supplierorderdispatch->status; @@ -841,6 +853,15 @@ if ($id > 0 || ! empty($ref)) { } } print ''; + if(!empty($reception->rowid)){ + print $reception->getLibStatut(5); + } + print ''; + print '
'; @@ -703,7 +707,7 @@ if ($id > 0 || ! empty($ref)) { if ($nbproduct) { - $checkboxlabel=$langs->trans("CloseReceivedSupplierOrdersAutomatically", $langs->transnoentitiesnoconv($object->statuts[5])); + $checkboxlabel=$langs->trans("CloseReceivedSupplierOrdersAutomatically", $langs->transnoentitiesnoconv($object->statuts[5])); print '
'; print $langs->trans("Comment") . ' : '; @@ -712,9 +716,11 @@ if ($id > 0 || ! empty($ref)) { // print ' / '.$object->ref_supplier; // Not yet available print '" class="flat">
'; - print ' '.$checkboxlabel; - - print '
reception->enabled))print ' '.$checkboxlabel; + + empty($conf->reception->enabled)?$dispatchBt=$langs->trans("DispatchVerb"):$dispatchBt=$langs->trans("Receive"); + + print '
'; @@ -784,13 +790,18 @@ if ($id > 0 || ! empty($ref)) { print "
"; - print '"; } - print ""; + print ''; print "\n"; - // Ref client print ''; print ''; @@ -1073,8 +1075,8 @@ if ($action == 'create') // Delivery method print ""; print '\n"; @@ -1086,7 +1088,7 @@ if ($action == 'create') // Other attributes $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"', 'socid'=>$socid); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$expe,$action); // Note that $action and $object may have been modified by hook + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$recept,$action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (empty($reshook) && ! empty($extrafields->attribute_label)) { @@ -1094,7 +1096,7 @@ if ($action == 'create') $orderExtrafields = new Extrafields($db); $orderExtrafieldLabels = $orderExtrafields->fetch_name_optionals_label($object->table_element); if ($object->fetch_optionals($object->id, $orderExtrafieldLabels) > 0) { - $expe->array_options = array_merge($expe->array_options, $object->array_options); + $recept->array_options = array_merge($recept->array_options, $object->array_options); } print $object->showOptionals($extrafields, 'edit'); } @@ -1111,13 +1113,13 @@ if ($action == 'create') } // Document model - include_once DOL_DOCUMENT_ROOT . '/core/modules/expedition/modules_expedition.php'; - $liste = ModelePdfExpedition::liste_modeles($db); + include_once DOL_DOCUMENT_ROOT . '/core/modules/reception/modules_reception.php'; + $liste = ModelePdfReception::liste_modeles($db); if (count($liste) > 1) { print ""; print '\n"; } @@ -1126,9 +1128,48 @@ if ($action == 'create') dol_fiche_end(); - // Shipment lines + // Reception lines + $numAsked=0; + $dispatchLines = array(); + foreach ($_POST as $key => $value) + { + // without batch module enabled + if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) + { + - $numAsked = count($object->lines); + // $numline=$reg[2] + 1; // line of product + $numline = $numAsked; + $prod = "product_".$reg[1].'_'.$reg[2]; + $qty = "qty_".$reg[1].'_'.$reg[2]; + $ent = "entrepot_".$reg[1].'_'.$reg[2]; + $pu = "pu_".$reg[1].'_'.$reg[2]; // This is unit price including discount + $fk_commandefourndet = "fk_commandefourndet_".$reg[1].'_'.$reg[2]; + $dispatchLines[$numAsked]=array('prod' => GETPOST($prod, 'int'), 'qty' =>GETPOST($qty), 'ent' =>GETPOST($ent, 'int'), 'pu' =>GETPOST($pu), 'comment' =>GETPOST('comment'),'fk_commandefourndet' => GETPOST($fk_commandefourndet, 'int')); + + $numAsked ++; + } + // with batch module enabled + if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) + { + + + // eat-by date dispatch + // $numline=$reg[2] + 1; // line of product + $numline = $numAsked; + $prod = 'product_batch_'.$reg[1].'_'.$reg[2]; + $qty = 'qty_'.$reg[1].'_'.$reg[2]; + $ent = 'entrepot_'.$reg[1].'_'.$reg[2]; + $pu = 'pu_'.$reg[1].'_'.$reg[2]; + $lot = 'lot_number_'.$reg[1].'_'.$reg[2]; + $dDLUO = dol_mktime(12, 0, 0, $_POST['dluo_'.$reg[1].'_'.$reg[2].'month'], $_POST['dluo_'.$reg[1].'_'.$reg[2].'day'], $_POST['dluo_'.$reg[1].'_'.$reg[2].'year']); + $dDLC = dol_mktime(12, 0, 0, $_POST['dlc_'.$reg[1].'_'.$reg[2].'month'], $_POST['dlc_'.$reg[1].'_'.$reg[2].'day'], $_POST['dlc_'.$reg[1].'_'.$reg[2].'year']); + $fk_commandefourndet = 'fk_commandefourndet_'.$reg[1].'_'.$reg[2]; + $dispatchLines[$numAsked]=array('prod' => GETPOST($prod, 'int'), 'qty' =>GETPOST($qty), 'ent' =>GETPOST($ent, 'int'), 'pu' =>GETPOST($pu), 'comment' =>GETPOST('comment'),'fk_commandefourndet' => GETPOST($fk_commandefourndet, 'int'),'DLC'=> $dDLC,'DLUO'=> $dDLUO,'lot'=> GETPOST($lot, 'alpha')); + $numAsked ++; + } + } + $numAsked --; print ' +'; +print ''; +print ''; +if(count($echeance->lines)>0) +{ + print ''; +}else{ + print ''; +} +print '
'; - if(!empty($conf->reception->enabled) && !empty($objp->fk_reception)){ - $reception = new Reception($db); - $reception->fetch($objp->fk_reception); - print $reception->getNomUrl(); + + if(!empty($conf->reception->enabled) ){ + print ''; + if (!empty($objp->fk_reception)){ + $reception = new Reception($db); + $reception->fetch($objp->fk_reception); + print $reception->getNomUrl(); + } + + print "'; print '' . img_object($langs->trans("ShowProduct"), 'product') . ' ' . $objp->ref . ''; print ' - ' . $objp->label; diff --git a/htdocs/langs/fr_FR/receptions.lang b/htdocs/langs/fr_FR/receptions.lang index 7522dc6eb51..0939ae18319 100644 --- a/htdocs/langs/fr_FR/receptions.lang +++ b/htdocs/langs/fr_FR/receptions.lang @@ -3,8 +3,8 @@ RefReception=Réf. réception Reception=Réception Receptions=Réceptions AllReceptions=Toutes les réceptions -Shipment=Réception -Shipments=Réceptions +Reception=Réception +Receptions=Réceptions ShowReception=Afficher Réceptions Receivings=Bons de réceptions ReceptionsArea=Espace réceptions @@ -13,15 +13,15 @@ ReceptionMethod=Méthode d'réception LastReceptions=Les %s dernières réceptions StatisticsOfReceptions=Statistiques des réceptions NbOfReceptions=Nombre d'réceptions -NumberOfShipmentsByMonth=Nombre d'réceptions par mois +NumberOfReceptionsByMonth=Nombre d'réceptions par mois ReceptionCard=Fiche réception NewReception=Nouvelle réception -CreateShipment=Créer réception +CreateReception=Créer réception QtyShipped=Qté. expédiée QtyPreparedOrShipped=Quantité préparée ou envoyée -QtyToShip=Qté. à expédier +QtyToReceive=Qté. à recevoir QtyReceived=Qté. reçue -QtyInOtherShipments=Qté dans les autres réceptions +QtyInOtherReceptions=Qté dans les autres réceptions KeepToShip=Reste à expédier OtherReceptionsForSameOrder=Autres réceptions pour cette commande ReceptionsAndReceivingForSameOrder=Réceptions et réceptions pour cette commande @@ -39,24 +39,24 @@ ConfirmValidateReception=Êtes-vous sûr de vouloir valider cette réception sou ConfirmCancelReception=Êtes-vous sûr de vouloir annuler cette réception ? DocumentModelMerou=Modèle Merou A5 WarningNoQtyLeftToSend=Alerte, aucun produit en attente d'réception. -StatsOnShipmentsOnlyValidated=Statistiques effectuées sur les réceptions validées uniquement. La date prise en compte est la date de validation (la date de prévision de livraison n'étant pas toujours renseignée). +StatsOnReceptionsOnlyValidated=Statistiques effectuées sur les réceptions validées uniquement. La date prise en compte est la date de validation (la date de prévision de livraison n'étant pas toujours renseignée). DateDeliveryPlanned=Date prévue de livraison RefDeliveryReceipt=Ref bon de réception StatusReceipt=Status du bon de réception DateReceived=Date de réception réelle -SendShippingByEMail=Envoyer bon d'réception par email -SendShippingRef=Envoi du bordereau d'réception %s -ActionsOnShipping=Événements sur l'réception +SendReceptionByEMail=Envoyer bon d'réception par email +SendReceptionRef=Envoi du bordereau d'réception %s +ActionsOnReception=Événements sur l'réception LinkToTrackYourPackage=Lien pour le suivi de votre colis -ShipmentCreationIsDoneFromOrder=Pour le moment, la création d'une nouvelle réception se fait depuis la fiche commande. -ShipmentLine=Ligne d'réception +ReceptionCreationIsDoneFromOrder=Pour le moment, la création d'une nouvelle réception se fait depuis la fiche commande fournisseur. +ReceptionLine=Ligne d'réception ProductQtyInCustomersOrdersRunning=Quantité de produit en commandes client ouvertes ProductQtyInSuppliersOrdersRunning=Quantité de produit en commandes fournisseur ouvertes -ProductQtyInShipmentAlreadySent=Quantité de produit en commande client ouverte déjà expédiée -ProductQtyInSuppliersShipmentAlreadyRecevied=Quantité de produit déjà reçu en commandes fournisseur ouvertes +ProductQtyInReceptionAlreadySent=Quantité de produit en commande client ouverte déjà expédiée +ProductQtyInSuppliersReceptionAlreadyRecevied=Quantité de produit déjà reçu en commandes fournisseur ouvertes NoProductToShipFoundIntoStock=Aucun produit à expédier n'a été trouver dans l'entrepôt %s. Corrigez l'inventaire ou retourner choisir un autre entrepôt. WeightVolShort=Poids/vol. -ValidateOrderFirstBeforeShipment=Vous devez d'abord valider la commande pour pouvoir créer une réception. +ValidateOrderFirstBeforeReception=Vous devez d'abord valider la commande pour pouvoir créer une réception. # Reception methods # ModelDocument diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index fbe7d81622c..4be1dc7f822 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -27,41 +27,42 @@ */ /** - * \file htdocs/expedition/card.php - * \ingroup expedition - * \brief Card of a shipment + * \file htdocs/reception/card.php + * \ingroup reception + * \brief Card of a reception */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/reception/class/reception.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/reception.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.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.'/product/stock/class/entrepot.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; -if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; +if (! empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; if (! empty($conf->productbatch->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; if (! empty($conf->projet->enabled)) { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; } -$langs->loadLangs(array("sendings","companies","bills",'deliveries','orders','stocks','other','propal')); +$langs->loadLangs(array("receptions","companies","bills",'deliveries','orders','stocks','other','propal')); if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); if (! empty($conf->productbatch->enabled)) $langs->load('productbatch'); -$origin = GETPOST('origin','alpha')?GETPOST('origin','alpha'):'expedition'; // Example: commande, propal +$origin = GETPOST('origin','alpha')?GETPOST('origin','alpha'):'reception'; // Example: commande, propal $origin_id = GETPOST('id','int')?GETPOST('id','int'):''; $id = $origin_id; if (empty($origin_id)) $origin_id = GETPOST('origin_id','int'); // Id of order or propal if (empty($origin_id)) $origin_id = GETPOST('object_id','int'); // Id of order or propal +if (empty($origin_id)) $origin_id = GETPOST('originid','int'); // Id of order or propal $ref=GETPOST('ref','alpha'); $line_id = GETPOST('lineid','int')?GETPOST('lineid','int'):''; @@ -69,10 +70,12 @@ $line_id = GETPOST('lineid','int')?GETPOST('lineid','int'):''; $socid=''; if ($user->societe_id) $socid=$user->societe_id; -if ($origin == 'expedition') $result=restrictedArea($user, $origin, $id); +if ($origin == 'reception') $result=restrictedArea($user, $origin, $id); else { - $result=restrictedArea($user, 'expedition'); - if (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) accessforbidden(); + $result=restrictedArea($user, 'reception'); + if($origin == 'supplierorder'){ + if (empty($user->rights->fournisseur->commande->lire) && empty($user->rights->fournisseur->commande->read)) accessforbidden(); + }else if (empty($user->rights->{$origin}->lire) && empty($user->rights->{$origin}->read)) accessforbidden(); } $action = GETPOST('action','alpha'); @@ -84,7 +87,7 @@ $hidedetails = (GETPOST('hidedetails','int') ? GETPOST('hidedetails','int') : (! $hidedesc = (GETPOST('hidedesc','int') ? GETPOST('hidedesc','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); $hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); -$object = new Expedition($db); +$object = new Reception($db); $extrafields = new ExtraFields($db); $extrafieldsline = new ExtraFields($db); @@ -99,9 +102,9 @@ $extralabelslines=$extrafieldsline->fetch_name_optionals_label($object->table_el include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('expeditioncard','globalcard')); +$hookmanager->initHooks(array('receptioncard','globalcard')); -$permissiondellink=$user->rights->expedition->livraison->creer; // Used by the include of actions_dellink.inc.php +$permissiondellink=$user->rights->reception->livraison->creer; // Used by the include of actions_dellink.inc.php //var_dump($object->lines[0]->detail_batch); @@ -118,20 +121,20 @@ if (empty($reshook)) if ($cancel) { $action = ''; - $object->fetch($id); // show shipment also after canceling modification + $object->fetch($id); // show reception also after canceling modification } include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once // Reopen - if ($action == 'reopen' && $user->rights->expedition->creer) + if ($action == 'reopen' && $user->rights->reception->creer) { $object->fetch($id); $result = $object->reOpen(); } // Confirm back to draft status - if ($action == 'modif' && $user->rights->expedition->creer) + if ($action == 'modif' && $user->rights->reception->creer) { $result = $object->set_draft($user); if ($result >= 0) @@ -167,7 +170,7 @@ if (empty($reshook)) setEventMessages($object->error, $object->errors, 'errors'); } - $result = $object->setValueFrom('ref_customer', GETPOST('ref_customer','alpha'), '', null, 'text', '', $user, 'SHIPMENT_MODIFY'); + $result = $object->setValueFrom('ref_customer', GETPOST('ref_customer','alpha'), '', null, 'text', '', $user, 'RECEPTION_MODIFY'); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $action = 'editref_customer'; @@ -188,7 +191,7 @@ if (empty($reshook)) { // Actions on extra fields (by external module or standard code) // TODO le hook fait double emploi avec le trigger !! - $hookmanager->initHooks(array('expeditiondao')); + $hookmanager->initHooks(array('receptiondao')); $parameters = array('id' => $object->id); $reshook = $hookmanager->executeHooks('insertExtraFields', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { @@ -206,8 +209,8 @@ if (empty($reshook)) $action = 'edit_extras'; } - // Create shipment - if ($action == 'add' && $user->rights->expedition->creer) + // Create reception + if ($action == 'add' && $user->rights->reception->creer) { $error=0; $predef=''; @@ -227,7 +230,7 @@ if (empty($reshook)) $date_delivery = dol_mktime(GETPOST('date_deliveryhour','int'), GETPOST('date_deliverymin','int'), 0, GETPOST('date_deliverymonth','int'), GETPOST('date_deliveryday','int'), GETPOST('date_deliveryyear','int')); - // On va boucler sur chaque ligne du document d'origine pour completer objet expedition + // On va boucler sur chaque ligne du document d'origine pour completer objet reception // avec info diverses + qte a livrer $classname = ucfirst($object->origin); $objectsrc = new $classname($db); @@ -238,7 +241,7 @@ if (empty($reshook)) $object->model_pdf = GETPOST('model'); $object->date_delivery = $date_delivery; // Date delivery planed $object->fk_delivery_address = $objectsrc->fk_delivery_address; - $object->shipping_method_id = GETPOST('shipping_method_id','int'); + $object->reception_method_id = GETPOST('reception_method_id','int'); $object->tracking_number = GETPOST('tracking_number','alpha'); $object->ref_int = GETPOST('ref_int','alpha'); $object->note_private = GETPOST('note_private','none'); @@ -269,7 +272,7 @@ if (empty($reshook)) { if (isset($_POST[$batch])) { - //shipment line with batch-enable product + //reception line with batch-enable product $qty .= '_'.$j; while (isset($_POST[$batch])) { @@ -305,7 +308,7 @@ if (empty($reshook)) } else if (isset($_POST[$stockLocation])) { - //shipment line from multiple stock locations + //reception line from multiple stock locations $qty .= '_'.$j; while (isset($_POST[$stockLocation])) { @@ -324,7 +327,7 @@ if (empty($reshook)) else { //var_dump(GETPOST($qty,'int')); var_dump($_POST); var_dump($batch);exit; - //shipment line for product with no batch management and no multiple stock location + //reception line for product with no batch management and no multiple stock location if (GETPOST($qty,'int') > 0) $totalqty+=GETPOST($qty,'int'); } @@ -354,7 +357,7 @@ if (empty($reshook)) // not batch mode if (isset($stockLine[$i])) { - //shipment from multiple stock locations + //reception from multiple stock locations $nbstockline = count($stockLine[$i]); for($j = 0; $j < $nbstockline; $j++) { @@ -371,7 +374,7 @@ if (empty($reshook)) } else { - if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS)) + if (GETPOST($qty,'int') > 0 || (GETPOST($qty,'int') == 0 && $conf->global->RECEPTION_GETS_ALL_ORDER_PRODUCTS)) { $ent = "entl".$i; $idl = "idl".$i; @@ -408,7 +411,7 @@ if (empty($reshook)) if (! $error) { - $ret=$object->create($user); // This create shipment (like Odoo picking) and line of shipments. Stock movement will when validating shipment. + $ret=$object->create($user); // This create reception (like Odoo picking) and line of receptions. Stock movement will when validating reception. if ($ret <= 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -418,7 +421,7 @@ if (empty($reshook)) } else { - setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("QtyToShip").'/'.$langs->transnoentitiesnoconv("Warehouse")), null, 'errors'); + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("QtyToReceive").'/'.$langs->transnoentitiesnoconv("Warehouse")), null, 'errors'); $error++; } @@ -439,7 +442,7 @@ if (empty($reshook)) /* * Build a receiving receipt */ - else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer) + else if ($action == 'create_delivery' && $conf->livraison_bon->enabled && $user->rights->reception->livraison->creer) { $result = $object->create_delivery($user); if ($result > 0) @@ -454,8 +457,8 @@ if (empty($reshook)) } else if ($action == 'confirm_valid' && $confirm == 'yes' && - ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expedition->shipping_advance->validate))) + ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->reception->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->reception->reception_advance->validate))) ) { $object->fetch_thirdparty(); @@ -489,12 +492,12 @@ if (empty($reshook)) } } - else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer) + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->reception->supprimer) { $result = $object->delete(); if ($result > 0) { - header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); + header("Location: ".DOL_URL_ROOT.'/reception/index.php'); exit; } else @@ -503,7 +506,7 @@ if (empty($reshook)) } } // TODO add alternative status - /*else if ($action == 'reopen' && (! empty($user->rights->expedition->creer) || ! empty($user->rights->expedition->shipping_advance->validate))) + /*else if ($action == 'reopen' && (! empty($user->rights->reception->creer) || ! empty($user->rights->reception->reception_advance->validate))) { $result = $object->setStatut(0); if ($result < 0) @@ -512,7 +515,7 @@ if (empty($reshook)) } }*/ - else if ($action == 'setdate_livraison' && $user->rights->expedition->creer) + else if ($action == 'setdate_livraison' && $user->rights->reception->creer) { //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; $datedelivery=dol_mktime(GETPOST('liv_hour','int'), GETPOST('liv_min','int'), 0, GETPOST('liv_month','int'), GETPOST('liv_day','int'), GETPOST('liv_year','int')); @@ -531,7 +534,7 @@ if (empty($reshook)) || $action == 'settrueWidth' || $action == 'settrueHeight' || $action == 'settrueDepth' - || $action == 'setshipping_method_id') + || $action == 'setreception_method_id') { $error=0; @@ -547,7 +550,7 @@ if (empty($reshook)) $object->size_units = GETPOST('size_units','int'); } if ($action == 'settrueDepth') $object->trueDepth = trim(GETPOST('trueDepth','int')); - if ($action == 'setshipping_method_id') $object->shipping_method_id = trim(GETPOST('shipping_method_id','int')); + if ($action == 'setreception_method_id') $object->reception_method_id = trim(GETPOST('reception_method_id','int')); if (! $error) { @@ -572,7 +575,7 @@ if (empty($reshook)) $outputlangs = $langs; $newlang=''; if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang=GETPOST('lang_id','aZ09'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$shipment->thirdparty->default_lang; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$reception->thirdparty->default_lang; if (! empty($newlang)) { $outputlangs = new Translate("",$conf); @@ -591,7 +594,7 @@ if (empty($reshook)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $upload_dir = $conf->expedition->dir_output . "/sending"; + $upload_dir = $conf->reception->dir_output . "/reception"; $file = $upload_dir . '/' . GETPOST('file'); $ret=dol_delete_file($file,0,0,0,$object); if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); @@ -625,7 +628,7 @@ if (empty($reshook)) { $object->fetch($id); $lines = $object->lines; - $line = new ExpeditionLigne($db); + $line = new ReceptionLigne($db); $num_prod = count($lines); for ($i = 0 ; $i < $num_prod ; $i++) @@ -669,7 +672,7 @@ if (empty($reshook)) /* * Update a line */ - else if ($action == 'updateline' && $user->rights->expedition->creer && GETPOST('save')) + else if ($action == 'updateline' && $user->rights->reception->creer && GETPOST('save')) { // Clean parameters $qty=0; @@ -682,7 +685,7 @@ if (empty($reshook)) { if ($lines[$i]->id == $line_id) // we have found line to update { - $line = new ExpeditionLigne($db); + $line = new ReceptionLigne($db); // Extrafields Lines $extrafieldsline = new ExtraFields($db); $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); @@ -700,21 +703,21 @@ if (empty($reshook)) foreach ($lines[$i]->detail_batch as $detail_batch) { $lotStock = new Productbatch($db); - $batch="batchl".$detail_batch->fk_expeditiondet."_".$detail_batch->fk_origin_stock; - $qty = "qtyl".$detail_batch->fk_expeditiondet.'_'.$detail_batch->id; + $batch="batchl".$detail_batch->fk_receptiondet."_".$detail_batch->fk_origin_stock; + $qty = "qtyl".$detail_batch->fk_receptiondet.'_'.$detail_batch->id; $batch_id = GETPOST($batch,'int'); $batch_qty = GETPOST($qty, 'int'); if (! empty($batch_id) && ($batch_id != $detail_batch->fk_origin_stock || $batch_qty != $detail_batch->dluo_qty)) { - if ($lotStock->fetch($batch_id) > 0 && $line->fetch($detail_batch->fk_expeditiondet) > 0) // $line is ExpeditionLine + if ($lotStock->fetch($batch_id) > 0 && $line->fetch($detail_batch->fk_receptiondet) > 0) // $line is ReceptionLine { if ($lines[$i]->entrepot_id != 0) { - // allow update line entrepot_id if not multi warehouse shipping + // allow update line entrepot_id if not multi warehouse reception $line->entrepot_id = $lotStock->warehouseid; } - // detail_batch can be an object with keys, or an array of ExpeditionLineBatch + // detail_batch can be an object with keys, or an array of ReceptionLineBatch if (empty($line->detail_batch)) $line->detail_batch=new stdClass(); $line->detail_batch->fk_origin_stock = $batch_id; @@ -750,7 +753,7 @@ if (empty($reshook)) // check if lotStock warehouse id is same as line warehouse id if ($lines[$i]->entrepot_id > 0) { - // single warehouse shipment line + // single warehouse reception line if ($lines[i]->entrepot_id == $lotStock->warehouseid) { $lineIdToAddLot = $line_id; @@ -758,7 +761,7 @@ if (empty($reshook)) } else if (count($lines[$i]->details_entrepot) > 1) { - // multi warehouse shipment lines + // multi warehouse reception lines foreach ($lines[$i]->details_entrepot as $detail_entrepot) { if ($detail_entrepot->entrepot_id == $lotStock->warehouseid) @@ -792,7 +795,7 @@ if (empty($reshook)) // create new line with new lot $line->origin_line_id = $lines[$i]->origin_line_id; $line->entrepot_id = $lotStock->warehouseid; - $line->detail_batch[0] = new ExpeditionLineBatch($db); + $line->detail_batch[0] = new ReceptionLineBatch($db); $line->detail_batch[0]->fk_origin_stock = $batch_id; $line->detail_batch[0]->batch = $lotStock->batch; $line->detail_batch[0]->entrepot_id = $lotStock->warehouseid; @@ -818,7 +821,7 @@ if (empty($reshook)) // line without lot if ($lines[$i]->entrepot_id > 0) { - // single warehouse shipment line + // single warehouse reception line $stockLocation="entl".$line_id; $qty = "qtyl".$line_id; $line->id = $line_id; @@ -833,7 +836,7 @@ if (empty($reshook)) } else if (count($lines[$i]->details_entrepot) > 1) { - // multi warehouse shipment lines + // multi warehouse reception lines foreach ($lines[$i]->details_entrepot as $detail_entrepot) { if (! $error) { @@ -899,7 +902,7 @@ if (empty($reshook)) } } - else if ($action == 'updateline' && $user->rights->expedition->creer && GETPOST('cancel','alpha') == $langs->trans('Cancel')) { + else if ($action == 'updateline' && $user->rights->reception->creer && GETPOST('cancel','alpha') == $langs->trans('Cancel')) { header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition exit(); } @@ -908,9 +911,9 @@ if (empty($reshook)) // Actions to send emails if (empty($id)) $id=$facid; - $trigger_name='SHIPPING_SENTBYMAIL'; + $trigger_name='RECEPTION_SENTBYMAIL'; $paramname='id'; - $mode='emailfromshipment'; + $mode='emailfromreception'; $trackid='shi'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; @@ -921,7 +924,7 @@ if (empty($reshook)) * View */ -llxHeader('',$langs->trans('Shipment'),'Expedition'); +llxHeader('',$langs->trans('Reception'),'Reception'); $form = new Form($db); $formfile = new FormFile($db); @@ -929,22 +932,22 @@ $formproduct = new FormProduct($db); if (! empty($conf->projet->enabled)) { $formproject = new FormProjets($db); } $product_static = new Product($db); -$shipment_static = new Expedition($db); +$reception_static = new Reception($db); $warehousestatic = new Entrepot($db); if ($action == 'create2') { - print load_fiche_titre($langs->trans("CreateShipment")).'
'; - print $langs->trans("ShipmentCreationIsDoneFromOrder"); + print load_fiche_titre($langs->trans("CreateReception")).'
'; + print $langs->trans("ReceptionCreationIsDoneFromOrder"); $action=''; $id=''; $ref=''; } // Mode creation. if ($action == 'create') { - $expe = new Expedition($db); + $recept = new Reception($db); - print load_fiche_titre($langs->trans("CreateShipment")); + print load_fiche_titre($langs->trans("CreateReception")); if (! $origin) { setEventMessages($langs->trans("ErrorBadParameters"), null, 'errors'); @@ -952,8 +955,9 @@ if ($action == 'create') if ($origin) { - $classname = ucfirst($origin); - + if($origin == 'supplierorder')$classname = 'CommandeFournisseur'; + else $classname = ucfirst($origin); + $object = new $classname($db); if ($object->fetch($origin_id)) // This include the fetch_lines { @@ -982,9 +986,9 @@ if ($action == 'create') // Ref print '
'; - if ($origin == 'commande' && ! empty($conf->commande->enabled)) + if ($origin == 'supplierorder' && ! empty($conf->fournisseur->enabled)) { - print $langs->trans("RefOrder").''.img_object($langs->trans("ShowOrder"),'order').' '.$object->ref; + print $langs->trans("RefOrder").''.img_object($langs->trans("ShowOrder"),'order').' '.$object->ref; } if ($origin == 'propal' && ! empty($conf->propal->enabled)) { @@ -992,14 +996,12 @@ if ($action == 'create') } print '
'; - if ($origin == 'commande') print $langs->trans('RefCustomerOrder'); - else if ($origin == 'propal') print $langs->trans('RefCustomerOrder'); - else print $langs->trans('RefCustomer'); + if ($origin == 'supplier_order') print $langs->trans('RefSupplierOrder'); + else print $langs->trans('RefSupplier'); print ''; - print ''; + print ''; print '
".$langs->trans("DeliveryMethod")."'; - $expe->fetch_delivery_methods(); - print $form->selectarray("shipping_method_id", $expe->meths, GETPOST('shipping_method_id','int'),1,0,0,"",1); + $recept->fetch_delivery_methods(); + print $form->selectarray("reception_method_id", $recept->meths, GETPOST('reception_method_id','int'),1,0,0,"",1); if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); print "
".$langs->trans("DefaultModel")."'; - print $form->selectarray('model', $liste, $conf->global->EXPEDITION_ADDON_PDF); + print $form->selectarray('model', $liste, $conf->global->RECEPTION_ADDON_PDF); print "
'; +print ''; +$colspan = 6; +if (count($echeance->lines)>0) $colspan++; +print ''; +print ''; + +print ''; +Print ''; +Print ''; +print ''; +Print ''; +Print ''; +if (count($echeance->lines)>0) print ''; +print ''."\n"; + +if ($object->nbterm > 0 && count($echeance->lines)==0) +{ + $i=1; + $capital = $object->capital; + $insurance = $object->insurance_amount/$object->nbterm; + $insurance = price2num($insurance, 'MT'); + $regulInsurance = price2num($object->insurance_amount - ($insurance * $object->nbterm)); + while($i <$object->nbterm+1) + { + $mens = price2num($echeance->calcMonthlyPayments($capital, $object->rate/100, $object->nbterm-$i+1), 'MT'); + $int = ($capital*($object->rate/12))/100; + $int = price2num($int, 'MT'); + $cap_rest = price2num($capital - ($mens-$int), 'MT'); + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + $i++; + $capital = $cap_rest; + } +} +elseif(count($echeance->lines)>0) +{ + $i=1; + $capital = $object->capital; + $insurance = $object->insurance_amount/$object->nbterm; + $insurance = price2num($insurance, 'MT'); + $regulInsurance = price2num($object->insurance_amount - ($insurance * $object->nbterm)); + foreach ($echeance->lines as $line){ + $mens = $line->amount_capital+$line->amount_insurance+$line->amount_interest; + $int = $line->amount_interest; + $cap_rest = price2num($capital - ($mens-$int), 'MT'); + print ''; + print ''; + print ''; + print ''; + print ''; + if($line->datep > dol_now()){ + print ''; + }else{ + print ''; + } + + print ''; + print ''; + print ''."\n"; + $i++; + $capital = $cap_rest; + } +} + +print '
'; +print $langs->trans("FinancialCommitment"); +print '
'.$langs->trans("Term").''.$langs->trans("Date").''.$langs->trans("Insurance"); +Print ''.$langs->trans("InterestAmount").''.$langs->trans("Amount").''.$langs->trans("CapitalRemain"); +print ' ('.price2num($object->capital).')'; +print ''; +print ''.$langs->trans('DoPayment').'
' . $i .'' . dol_print_date(dol_time_plus_duree($object->datestart, $i-1, 'm'),'day') . ''.price($insurance+(($i == 1) ? $regulInsurance : 0),0,'',1).' €'.price($int,0,'',1).' €'.price($cap_rest).' €
' . $i .'' . dol_print_date($line->datep,'day') . ''.price($insurance+(($i == 1) ? $regulInsurance : 0),0,'',1).' €'.price($int,0,'',1).' €' . price($mens) . ' €'.price($cap_rest).' €'; + print ''.$langs->trans('DoPayment').''; + print '
'; +print '
'; +print '
'; +if (count($echeance->lines)==0) $label = $langs->trans("Create"); +else $label = $langs->trans("Save"); +print '
'; +print ''; + +// End of page +llxFooter(); +$db->close(); From db2937715df40c1177567a03906482b760e059e3 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Thu, 18 Oct 2018 17:27:08 +0200 Subject: [PATCH 045/307] create payment from loan schedule --- htdocs/loan/schedule.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/loan/schedule.php b/htdocs/loan/schedule.php index 58130c2c26a..d775ebaca84 100644 --- a/htdocs/loan/schedule.php +++ b/htdocs/loan/schedule.php @@ -208,10 +208,11 @@ elseif(count($echeance->lines)>0) $mens = $line->amount_capital+$line->amount_insurance+$line->amount_interest; $int = $line->amount_interest; $cap_rest = price2num($capital - ($mens-$int), 'MT'); + $insu = ($insurance+(($i == 1) ? $regulInsurance : 0)); print ''; print '' . $i .''; print '' . dol_print_date($line->datep,'day') . ''; - print ''.price($insurance+(($i == 1) ? $regulInsurance : 0),0,'',1).' €'; + print ''.price($insu,0,'',1).' €'; print ''.price($int,0,'',1).' €'; if($line->datep > dol_now()){ print ' €'; @@ -221,7 +222,7 @@ elseif(count($echeance->lines)>0) print ''.price($cap_rest).' €'; print ''; - print ''.$langs->trans('DoPayment').''; + print ''.$langs->trans('DoPayment').''; print ''; print ''."\n"; $i++; From 582608cc572a982deb02a3969d8765898793dbe5 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Fri, 19 Oct 2018 15:36:13 +0200 Subject: [PATCH 046/307] manage fk_bank on loanschedule --- htdocs/loan/class/paymentloan.class.php | 1 + htdocs/loan/payment/card.php | 3 +++ htdocs/loan/payment/payment.php | 26 ++++++++++++++++++++++--- htdocs/loan/schedule.php | 14 ++++++++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/htdocs/loan/class/paymentloan.class.php b/htdocs/loan/class/paymentloan.class.php index c4c29c99dce..7bed069cec2 100644 --- a/htdocs/loan/class/paymentloan.class.php +++ b/htdocs/loan/class/paymentloan.class.php @@ -530,6 +530,7 @@ class PaymentLoan extends CommonObject $result = $this->db->query($sql); if ($result) { + $this->fk_bank = $id_bank; return 1; } else diff --git a/htdocs/loan/payment/card.php b/htdocs/loan/payment/card.php index 919139bd6e3..110ad8d891c 100644 --- a/htdocs/loan/payment/card.php +++ b/htdocs/loan/payment/card.php @@ -54,6 +54,9 @@ if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->loan->del { $db->begin(); + $sql = "UPDATE ".MAIN_DB_PREFIX."loan_schedule SET fk_bank = 0 WHERE fk_bank = ".$payment->fk_bank; + $db->query($sql); + $result = $payment->delete($user); if ($result > 0) { diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php index ba6650c9c03..2d81f95d034 100644 --- a/htdocs/loan/payment/payment.php +++ b/htdocs/loan/payment/payment.php @@ -24,6 +24,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php'; require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; @@ -32,6 +33,7 @@ $langs->loadLangs(array("bills","loan")); $chid=GETPOST('id','int'); $action=GETPOST('action','aZ09'); $cancel=GETPOST('cancel','alpha'); +$line_id = GETPOST('line_id', 'int'); // Security check $socid=0; @@ -43,6 +45,17 @@ if ($user->societe_id > 0) $loan = new Loan($db); $loan->fetch($chid); +if (!empty($line_id)) +{ + $line = new LoanSchedule($db); + $res = $line->fetch($line_id); + if ($res > 0){ + $amount_capital = price($line->amount_capital); + $amount_insurance = price($line->amount_insurance); + $amount_interest = price($line->amount_interest); + } +} + /* * Actions */ @@ -121,6 +134,12 @@ if ($action == 'add_payment') setEventMessages($payment->error, $payment->errors, 'errors'); $error++; } + elseif(isset($line)) + { + $line->fk_bank = $payment->fk_bank; + $line->update($user); + } + } if (! $error) @@ -161,6 +180,7 @@ if ($action == 'create') print ''; print ''; print ''; + print ''; print ''; dol_fiche_head(); @@ -264,7 +284,7 @@ if ($action == 'create') print ''; if ($sumpaid < $loan->capital) { - print $langs->trans("LoanCapital") .': '; + print $langs->trans("LoanCapital") .': '; } else { @@ -273,7 +293,7 @@ if ($action == 'create') print '
'; if ($sumpaid < $loan->capital) { - print $langs->trans("Insurance") .': '; + print $langs->trans("Insurance") .': '; } else { @@ -282,7 +302,7 @@ if ($action == 'create') print '
'; if ($sumpaid < $loan->capital) { - print $langs->trans("Interest") .': '; + print $langs->trans("Interest") .': '; } else { diff --git a/htdocs/loan/schedule.php b/htdocs/loan/schedule.php index d775ebaca84..9fb5a4397ee 100644 --- a/htdocs/loan/schedule.php +++ b/htdocs/loan/schedule.php @@ -184,6 +184,7 @@ if ($object->nbterm > 0 && count($echeance->lines)==0) $mens = price2num($echeance->calcMonthlyPayments($capital, $object->rate/100, $object->nbterm-$i+1), 'MT'); $int = ($capital*($object->rate/12))/100; $int = price2num($int, 'MT'); + $insu = ($insurance+(($i == 1) ? $regulInsurance : 0)); $cap_rest = price2num($capital - ($mens-$int), 'MT'); print ''; print '' . $i .''; @@ -204,17 +205,19 @@ elseif(count($echeance->lines)>0) $insurance = $object->insurance_amount/$object->nbterm; $insurance = price2num($insurance, 'MT'); $regulInsurance = price2num($object->insurance_amount - ($insurance * $object->nbterm)); + $printed = false; foreach ($echeance->lines as $line){ $mens = $line->amount_capital+$line->amount_insurance+$line->amount_interest; $int = $line->amount_interest; - $cap_rest = price2num($capital - ($mens-$int), 'MT'); $insu = ($insurance+(($i == 1) ? $regulInsurance : 0)); + $cap_rest = price2num($capital - ($mens-$int-$insu), 'MT'); + print ''; print '' . $i .''; print '' . dol_print_date($line->datep,'day') . ''; print ''.price($insu,0,'',1).' €'; print ''.price($int,0,'',1).' €'; - if($line->datep > dol_now()){ + if($line->datep > dol_now() && empty($line->fk_bank)){ print ' €'; }else{ print '' . price($mens) . ' €'; @@ -222,7 +225,12 @@ elseif(count($echeance->lines)>0) print ''.price($cap_rest).' €'; print ''; - print ''.$langs->trans('DoPayment').''; + if (!empty($line->fk_bank)) print $langs->trans('Paid'); + elseif (!$printed) + { + print ''.$langs->trans('DoPayment').''; + $printed = true; + } print ''; print ''."\n"; $i++; From 6a3661586ffdf9d6b3aa7b7d1ff471ea0d3b0644 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Fri, 19 Oct 2018 16:12:21 +0200 Subject: [PATCH 047/307] create payment for the last loanschedule --- htdocs/loan/card.php | 2 +- htdocs/loan/payment/payment.php | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 8fef98075b1..c8da0262f38 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -795,7 +795,7 @@ if ($id > 0) // Emit payment if ($object->paid == 0 && ((price2num($object->capital) > 0 && round($staytopay) < 0) || (price2num($object->capital) > 0 && round($staytopay) > 0)) && $user->rights->loan->write) { - print ''.$langs->trans("DoPayment").''; + print ''.$langs->trans("DoPayment").''; } // Classify 'paid' diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php index 2d81f95d034..b38a058126f 100644 --- a/htdocs/loan/payment/payment.php +++ b/htdocs/loan/payment/payment.php @@ -34,6 +34,7 @@ $chid=GETPOST('id','int'); $action=GETPOST('action','aZ09'); $cancel=GETPOST('cancel','alpha'); $line_id = GETPOST('line_id', 'int'); +$last=GETPOST('last'); // Security check $socid=0; @@ -45,6 +46,26 @@ if ($user->societe_id > 0) $loan = new Loan($db); $loan->fetch($chid); +if($last) +{ + $ls = new LoanSchedule($db); + // grab all loanschedule + $res = $ls->fetchAll($chid); + if ($res > 0) + { + foreach ($ls->lines as $l) + { + // get the last unpaid loanschedule + if (empty($l->fk_bank)) + { + $line_id = $l->id; + break; + } + } + } + +} + if (!empty($line_id)) { $line = new LoanSchedule($db); From 44b317e03e9dd9b4b87945904627ec66021915f0 Mon Sep 17 00:00:00 2001 From: atm-greg Date: Fri, 19 Oct 2018 16:49:32 +0200 Subject: [PATCH 048/307] fix display --- htdocs/loan/schedule.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/loan/schedule.php b/htdocs/loan/schedule.php index 9fb5a4397ee..30ba126aefb 100644 --- a/htdocs/loan/schedule.php +++ b/htdocs/loan/schedule.php @@ -207,10 +207,10 @@ elseif(count($echeance->lines)>0) $regulInsurance = price2num($object->insurance_amount - ($insurance * $object->nbterm)); $printed = false; foreach ($echeance->lines as $line){ - $mens = $line->amount_capital+$line->amount_insurance+$line->amount_interest; + $mens = $line->amount_capital+$line->amount_interest; $int = $line->amount_interest; $insu = ($insurance+(($i == 1) ? $regulInsurance : 0)); - $cap_rest = price2num($capital - ($mens-$int-$insu), 'MT'); + $cap_rest = price2num($capital - ($mens-$int), 'MT'); print ''; print '' . $i .''; From bfadd39e8cda84dd477e8812829c177e71a19154 Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Fri, 19 Oct 2018 12:46:54 +0100 Subject: [PATCH 049/307] Fix: Grant right to child classes to use Category methods --- htdocs/categories/class/categorie.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index a9432234793..97bceaf082c 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -65,7 +65,7 @@ class Categorie extends CommonObject * * @note This array should be remove in future, once previous constants are moved to the string value. Deprecated */ - private $MAP_ID = array( + protected $MAP_ID = array( 'product' => 0, 'supplier' => 1, 'customer' => 2, @@ -93,7 +93,7 @@ class Categorie extends CommonObject * * @note Move to const array when PHP 5.6 will be our minimum target */ - private $MAP_CAT_FK = array( + protected $MAP_CAT_FK = array( 'product' => 'product', 'customer' => 'soc', 'supplier' => 'soc', @@ -109,7 +109,7 @@ class Categorie extends CommonObject * * @note Move to const array when PHP 5.6 will be our minimum target */ - private $MAP_CAT_TABLE = array( + protected $MAP_CAT_TABLE = array( 'product' => 'product', 'customer' => 'societe', 'supplier' => 'fournisseur', @@ -125,7 +125,7 @@ class Categorie extends CommonObject * * @note Move to const array when PHP 5.6 will be our minimum target */ - private $MAP_OBJ_CLASS = array( + protected $MAP_OBJ_CLASS = array( 'product' => 'Product', 'customer' => 'Societe', 'supplier' => 'Fournisseur', @@ -141,7 +141,7 @@ class Categorie extends CommonObject * * @note Move to const array when PHP 5.6 will be our minimum target */ - private $MAP_OBJ_TABLE = array( + protected $MAP_OBJ_TABLE = array( 'product' => 'product', 'customer' => 'societe', 'supplier' => 'societe', @@ -931,7 +931,7 @@ class Categorie extends CommonObject * * @return int <0 if KO, >0 if OK */ - private function load_motherof() + protected function load_motherof() { // phpcs:enable global $conf; From cfff4c7df89b72415fcef39d07535617aaf15981 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Mon, 22 Oct 2018 14:32:50 +0200 Subject: [PATCH 050/307] NEW add ref supplier on supplier invoice --- htdocs/fourn/class/fournisseur.facture.class.php | 8 +++++--- htdocs/fourn/facture/card.php | 5 +++-- htdocs/reception/class/reception.class.php | 4 +++- htdocs/reception/list.php | 4 +++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 64374f563d3..417ecec6653 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1363,11 +1363,12 @@ class FactureFournisseur extends CommonInvoice * @param string $fk_unit Code of the unit to use. Null to use the default one * @param int $origin_id id origin document * @param double $pu_ht_devise Amount in currency + * @param string $ref_supplier Supplier ref * @return int >0 if OK, <0 if KO * * FIXME Add field ref (that should be named ref_supplier) and label into update. For example can be filled when product line created from order. */ - public function addline($desc, $pu, $txtva, $txlocaltax1, $txlocaltax2, $qty, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits='', $price_base_type='HT', $type=0, $rang=-1, $notrigger=false, $array_options=0, $fk_unit=null, $origin_id=0, $pu_ht_devise=0) + public function addline($desc, $pu, $txtva, $txlocaltax1, $txlocaltax2, $qty, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits='', $price_base_type='HT', $type=0, $rang=-1, $notrigger=false, $array_options=0, $fk_unit=null, $origin_id=0, $pu_ht_devise=0,$ref_supplier='') { dol_syslog(get_class($this)."::addline $desc,$pu,$qty,$txtva,$fk_product,$remise_percent,$date_start,$date_end,$ventil,$info_bits,$price_base_type,$type,$fk_unit", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; @@ -1426,7 +1427,7 @@ class FactureFournisseur extends CommonInvoice //$this->line->label=$label; // deprecated $this->line->desc=$desc; $this->line->qty= ($this->type==self::TYPE_CREDIT_NOTE?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative - + $this->line->ref_supplier=$ref_supplier; $this->line->vat_src_code=$vat_src_code; $this->line->tva_tx=$txtva; $this->line->localtax1_tx=$txlocaltax1; @@ -2718,7 +2719,7 @@ class SupplierInvoiceLine extends CommonObjectLine // Insertion dans base de la ligne $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element; - $sql.= ' (fk_facture_fourn, fk_parent_line, label, description, qty,'; + $sql.= ' (fk_facture_fourn, fk_parent_line, label, description, ref, qty,'; $sql.= ' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,'; $sql.= ' fk_product, product_type, remise_percent, pu_ht, pu_ttc,'; $sql.= ' date_start, date_end, fk_code_ventilation, rang, special_code,'; @@ -2729,6 +2730,7 @@ class SupplierInvoiceLine extends CommonObjectLine $sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").","; $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; $sql.= " '".$this->db->escape($this->desc)."',"; + $sql.= " '".$this->db->escape($this->ref_supplier)."',"; $sql.= " ".price2num($this->qty).","; $sql.= " ".(empty($this->vat_src_code)?"''":"'".$this->vat_src_code."'").","; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index b2ab0f7dacc..9cc08e1e851 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -708,7 +708,6 @@ if (empty($reshook)) $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; - // FIXME Missing $lines[$i]->ref_supplier and $lines[$i]->label into addline and updateline methods. They are filled when coming from order for example. $result = $object->addline( $desc, @@ -729,7 +728,9 @@ if (empty($reshook)) 0, $lines[$i]->array_options, $lines[$i]->fk_unit, - $lines[$i]->id + $lines[$i]->id, + 0, + $lines[$i]->ref_supplier ); if ($result < 0) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index ad067e47cf4..04fb4ab8406 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1044,7 +1044,7 @@ class Reception extends CommonObject $line = new CommandeFournisseurDispatch($db); $line->fetch($obj->rowid); $line->fetch_product(); - $sql_commfourndet = 'SELECT qty, label, tva_tx, vat_src_code, subprice, multicurrency_subprice, remise_percent FROM llx_commande_fournisseurdet WHERE rowid='.$line->fk_commandefourndet; + $sql_commfourndet = 'SELECT qty, ref, label, tva_tx, vat_src_code, subprice, multicurrency_subprice, remise_percent FROM llx_commande_fournisseurdet WHERE rowid='.$line->fk_commandefourndet; $resql_commfourndet = $db->query($sql_commfourndet); if(!empty($resql_commfourndet)){ $obj = $db->fetch_object($resql_commfourndet); @@ -1057,6 +1057,8 @@ class Reception extends CommonObject $line->multicurrency_subprice = $obj->multicurrency_subprice; $line->remise_percent = $obj->remise_percent; $line->label = $obj->label; + $line->ref_supplier = $obj->ref; + }else { $line->qty_asked = 0; $line->description = ''; diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index 43dd318ef95..f2da1adb62a 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -327,7 +327,9 @@ if (empty($reshook)) false, 0, null, - $lines[$i]->rowid + $lines[$i]->rowid, + 0, + $lines[$i]->ref_supplier ); From 39f34dd36b3d06a656f67234e827e531b4b2b9c5 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 22 Oct 2018 14:49:21 +0200 Subject: [PATCH 051/307] fix script migrate table --- htdocs/reception/create-table.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/htdocs/reception/create-table.php b/htdocs/reception/create-table.php index 5bf00a34abc..f311fd49d4d 100644 --- a/htdocs/reception/create-table.php +++ b/htdocs/reception/create-table.php @@ -44,14 +44,25 @@ if(empty($resql)){ var_dump($db->error); } -$sql=" insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECEPTION_VALIDATE','Reception validated','Executed when a reception is validated','reception',22); - insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECEPTION_SENTBYMAIL','Reception sent by mail','Executed when a reception is sent by mail','reception',22);"; +$sql=" insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECEPTION_VALIDATE','Reception validated','Executed when a reception is validated','reception',22);"; $resql = $db->query($sql); if(empty($resql)){ + print '
';
 	var_dump($db->error);
+	print '
'; } +$sql="insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECEPTION_SENTBYMAIL','Reception sent by mail','Executed when a reception is sent by mail','reception',22); "; + +$resql = $db->query($sql); +if(empty($resql)){ + print '
';
+        var_dump($db->error);
+        print '
'; +} + + $sql=" ALTER TABLE ".MAIN_DB_PREFIX."commande_fournisseur_dispatch CHANGE comment comment TEXT;"; $resql = $db->query($sql); if(empty($resql)){ From 0c61162698f2a32029e2790b333910c4639184fb Mon Sep 17 00:00:00 2001 From: root Date: Mon, 22 Oct 2018 14:56:13 +0200 Subject: [PATCH 052/307] fix langs workflow reception --- htdocs/langs/fr_FR/workflow.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/fr_FR/workflow.lang b/htdocs/langs/fr_FR/workflow.lang index c38f17cff04..bdeed2138ff 100644 --- a/htdocs/langs/fr_FR/workflow.lang +++ b/htdocs/langs/fr_FR/workflow.lang @@ -13,6 +13,6 @@ descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classer la/les proposition(s) commer descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classer la/les commande(s) client(s) source(s) facturée à la validation de la facture client (et si le montant des deux documents est le même) descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classer la/les commande(s) client(s) source(s) facturée au classement payé de la facture client (et si le montant des deux documents est le même) descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classer la commande source expédiée à la validation d'une expédition (si les quantité des documents sont les mêmes) -descWORKFLOW_BILL_ON_RECEPTION=Classer la/les réception(s) facturée(s) à la validation d'une facture fournisseur (si la facture est du même montant que la commande) +descWORKFLOW_BILL_ON_RECEPTION=Classer la/les réception(s) facturée(s) à la validation d'une facture fournisseur AutomaticCreation=Création automatique AutomaticClassification=Classification automatique From dc6a30997cafbfa775e6e2c5137b3ee3bd57bef6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 22 Oct 2018 15:47:42 +0200 Subject: [PATCH 053/307] add missing require --- htdocs/reception/list.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index f2da1adb62a..878966f1440 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -28,6 +28,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/reception/class/reception.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; From 7684d7bddd26576f6116a2b30b1b4419cc409e22 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Mon, 22 Oct 2018 15:51:47 +0200 Subject: [PATCH 054/307] FIX export comment better than desc of order line --- htdocs/core/modules/modReception.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modReception.class.php b/htdocs/core/modules/modReception.class.php index c2a04371755..1c8cfd45900 100644 --- a/htdocs/core/modules/modReception.class.php +++ b/htdocs/core/modules/modReception.class.php @@ -181,11 +181,11 @@ class modReception extends DolibarrModules $this->export_code[$r]=$this->rights_class.'_'.$r; $this->export_label[$r]='Receptions'; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("reception","reception","export")); - $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'ThirdParty','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','d.nom'=>'State','co.label'=>'Country','co.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6','c.rowid'=>"Id",'c.ref'=>"Ref",'c.ref_supplier'=>"RefSupplier",'c.fk_soc'=>"IdCompany",'c.date_creation'=>"DateCreation",'c.date_delivery'=>"DateDeliveryPlanned",'c.tracking_number'=>"TrackingNumber",'c.height'=>"Height",'c.width'=>"Width",'c.size'=>"Depth",'c.size_units'=>'SizeUnits','c.weight'=>"Weight",'c.weight_units'=>"WeightUnits",'c.fk_statut'=>'Status','c.note_public'=>"NotePublic",'ed.rowid'=>'LineId','cd.description'=>'Description','ed.qty'=>"Qty",'p.rowid'=>'ProductId','p.ref'=>'ProductRef','p.label'=>'ProductLabel','p.weight'=>'ProductWeight','p.weight_units'=>'WeightUnits','p.volume'=>'ProductVolume','p.volume_units'=>'VolumeUnits'); + $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'ThirdParty','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','d.nom'=>'State','co.label'=>'Country','co.code'=>'CountryCode','s.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6','c.rowid'=>"Id",'c.ref'=>"Ref",'c.ref_supplier'=>"RefSupplier",'c.fk_soc'=>"IdCompany",'c.date_creation'=>"DateCreation",'c.date_delivery'=>"DateDeliveryPlanned",'c.tracking_number'=>"TrackingNumber",'c.height'=>"Height",'c.width'=>"Width",'c.size'=>"Depth",'c.size_units'=>'SizeUnits','c.weight'=>"Weight",'c.weight_units'=>"WeightUnits",'c.fk_statut'=>'Status','c.note_public'=>"NotePublic",'ed.rowid'=>'LineId','ed.comment'=>'Description','ed.qty'=>"Qty",'p.rowid'=>'ProductId','p.ref'=>'ProductRef','p.label'=>'ProductLabel','p.weight'=>'ProductWeight','p.weight_units'=>'WeightUnits','p.volume'=>'ProductVolume','p.volume_units'=>'VolumeUnits'); if ($idcontacts && ! empty($conf->global->RECEPTION_ADD_CONTACTS_IN_EXPORT)) $this->export_fields_array[$r]+=array('sp.rowid'=>'IdContact','sp.lastname'=>'Lastname','sp.firstname'=>'Firstname','sp.note_public'=>'NotePublic'); //$this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','co.label'=>'List:c_country:label:label','co.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','c.ref'=>"Text",'c.ref_client'=>"Text",'c.date_creation'=>"Date",'c.date_commande'=>"Date",'c.amount_ht'=>"Numeric",'c.remise_percent'=>"Numeric",'c.total_ht'=>"Numeric",'c.total_ttc'=>"Numeric",'c.facture'=>"Boolean",'c.fk_statut'=>'Status','c.note_public'=>"Text",'c.date_livraison'=>'Date','ed.qty'=>"Text"); $this->export_TypeFields_array[$r]=array('s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','co.label'=>'List:c_country:label:label','co.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','c.ref'=>"Text",'c.ref_supplier'=>"Text",'c.date_creation'=>"Date",'c.date_delivery'=>"Date",'c.tracking_number'=>"Numeric",'c.height'=>"Numeric",'c.width'=>"Numeric",'c.weight'=>"Numeric",'c.fk_statut'=>'Status','c.note_public'=>"Text",'ed.qty'=>"Numeric",'d.nom'=>'Text'); - $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','d.nom'=>'company','co.label'=>'company','co.code'=>'company','s.fk_pays'=>'company','s.phone'=>'company','s.siren'=>'company','s.ape'=>'company','s.siret'=>'company','s.idprof4'=>'company','s.idprof5'=>'company','s.idprof6'=>'company','c.rowid'=>"reception",'c.ref'=>"reception",'c.ref_supplier'=>"reception",'c.fk_soc'=>"reception",'c.date_creation'=>"reception",'c.date_delivery'=>"reception",'c.tracking_number'=>'reception','c.height'=>"reception",'c.width'=>"reception",'c.size'=>'reception','c.size_units'=>'reception','c.weight'=>"reception",'c.weight_units'=>'reception','c.fk_statut'=>"reception",'c.note_public'=>"reception",'ed.rowid'=>'reception_line','cd.description'=>'reception_line','ed.qty'=>"reception_line",'p.rowid'=>'product','p.ref'=>'product','p.label'=>'product','p.weight'=>'product','p.weight_units'=>'product','p.volume'=>'product','p.volume_units'=>'product'); + $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','d.nom'=>'company','co.label'=>'company','co.code'=>'company','s.fk_pays'=>'company','s.phone'=>'company','s.siren'=>'company','s.ape'=>'company','s.siret'=>'company','s.idprof4'=>'company','s.idprof5'=>'company','s.idprof6'=>'company','c.rowid'=>"reception",'c.ref'=>"reception",'c.ref_supplier'=>"reception",'c.fk_soc'=>"reception",'c.date_creation'=>"reception",'c.date_delivery'=>"reception",'c.tracking_number'=>'reception','c.height'=>"reception",'c.width'=>"reception",'c.size'=>'reception','c.size_units'=>'reception','c.weight'=>"reception",'c.weight_units'=>'reception','c.fk_statut'=>"reception",'c.note_public'=>"reception",'ed.rowid'=>'reception_line','ed.comment'=>'reception_line','ed.qty'=>"reception_line",'p.rowid'=>'product','p.ref'=>'product','p.label'=>'product','p.weight'=>'product','p.weight_units'=>'product','p.volume'=>'product','p.volume_units'=>'product'); if ($idcontacts && ! empty($conf->global->RECEPTION_ADD_CONTACTS_IN_EXPORT)) $this->export_entities_array[$r]+=array('sp.rowid'=>'contact','sp.lastname'=>'contact','sp.firstname'=>'contact','sp.note_public'=>'contact'); $this->export_dependencies_array[$r]=array('reception_line'=>'ed.rowid','product'=>'ed.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them if ($idcontacts && ! empty($conf->global->RECEPTION_ADD_CONTACTS_IN_EXPORT)) From 5b693572331fc1aff74b8044632c7f990b68cb59 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Mon, 22 Oct 2018 16:08:43 +0200 Subject: [PATCH 055/307] FIX keep search value while changing page --- htdocs/reception/list.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index 878966f1440..e2c0f59bf2e 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -523,6 +523,14 @@ if ($resql) if ($search_ref_liv) $param.= "&search_ref_liv=".$search_ref_liv; if ($search_company) $param.= "&search_company=".$search_company; if ($optioncss != '') $param.='&optioncss='.$optioncss; + if ($search_billed != '' && $search_billed >= 0)$param.= "&search_billed=".$search_billed; + if ($search_town) $param.= "&search_town=".$search_town; + if ($search_zip) $param.= "&search_zip=".$search_zip; + if ($search_state) $param.= "&search_state=".$search_state; + if ($viewstatut) $param.= "&viewstatut=".$viewstatut; + if ($search_country) $param.= "&search_country=".$search_country; + if ($search_type_thirdparty) $param.= "&search_type_thirdparty=".$search_type_thirdparty; + if ($search_ref_supplier) $param.= "&search_ref_supplier=".$search_ref_supplier; // Add $param from extra fields foreach ($search_array_options as $key => $val) { From 0a033f4cfda196f232115b994db70e932aa44783 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Mon, 22 Oct 2018 16:49:36 +0200 Subject: [PATCH 056/307] FIX : manage error --- htdocs/langs/fr_FR/receptions.lang | 1 + htdocs/reception/list.php | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/fr_FR/receptions.lang b/htdocs/langs/fr_FR/receptions.lang index 3dab5a0500e..2102e282668 100644 --- a/htdocs/langs/fr_FR/receptions.lang +++ b/htdocs/langs/fr_FR/receptions.lang @@ -61,6 +61,7 @@ NoProductToShipFoundIntoStock=Aucun produit à expédier n'a été trouver dans WeightVolShort=Poids/vol. ValidateOrderFirstBeforeReception=Vous devez d'abord valider la commande pour pouvoir créer une réception. CreateInvoiceForThisSupplier=Facturer réceptions +ErrorRefAlreadyExists = La référence fournisseur existe déjà # Reception methods # ModelDocument diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index e2c0f59bf2e..f05debc8858 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -181,7 +181,8 @@ if (empty($reshook)) $object = new FactureFournisseur($db); if (!empty($createbills_onebythird) && !empty($TFactThird[$rcp->socid])){ $object = $TFactThird[$rcp->socid]; // If option "one bill per third" is set, we use already created reception. - $object->fetchObjectLinked(); + if(empty($object->rowid)&&$object->id != null)$object->rowid = $object->id; + if(!empty($object->rowid))$object->fetchObjectLinked(); $rcp->fetchObjectLinked(); if (count($rcp->linkedObjectsIds['order_supplier']) > 0) @@ -234,7 +235,7 @@ if (empty($reshook)) $nb_bills_created++; $object->id = $res; }else { - $errors[]=$object->error; + $errors[]=$rcp->ref.' : '.$langs->trans($object->error); $error++; } } From d01faeee89ad1e0dd66b6a6b7ad4f86fc5f1002c Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Tue, 23 Oct 2018 09:22:13 +0200 Subject: [PATCH 057/307] FIX set ordered if no more validate reception --- htdocs/reception/class/reception.class.php | 37 ++++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 04fb4ab8406..67ee854ec30 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1878,14 +1878,39 @@ class Reception extends CommonObject $result=$this->call_trigger('RECEPTION_UNVALIDATE',$user); if ($result < 0) $error++; } - if($this->origin == 'order_supplier'){ - $commande = new CommandeFournisseur($this->db); - $commande->fetch($this->origin_id); - $commande->setStatus($user,3); + if ($this->origin == 'order_supplier') + { + if (!empty($this->origin) && $this->origin_id > 0) + { + $this->fetch_origin(); + $origin = $this->origin; + if ($this->$origin->statut == 4) // If order source of reception is "partially received" + { + // Check if there is no more reception validated. + $this->$origin->fetchObjectLinked(); + $setStatut = 1; + if (!empty($this->$origin->linkedObjects['reception'])) + { + foreach ($this->$origin->linkedObjects['reception'] as $rcption) + { + if ($rcption->statut > 0) + { + $setStatut = 0; + break; + } + } + //var_dump($this->$origin->receptions);exit; + if ($setStatut) + { + $this->$origin->setStatut(3); // ordered + } + } + } + } } - - if (!$error) { + + if (!$error) { $this->statut=self::STATUS_DRAFT; $this->db->commit(); return 1; From 96d0bb8f2ee2910a0d5c72ab58bf261791db1414 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Tue, 23 Oct 2018 14:31:58 +0200 Subject: [PATCH 058/307] FIX adapt develop --- htdocs/admin/workflow.php | 5 +- htdocs/core/class/commonobject.class.php | 1 + htdocs/core/modules/modReception.class.php | 4 +- htdocs/filefunc.inc.php | 2 +- .../fournisseur.commande.dispatch.class.php | 6 +- htdocs/fourn/commande/dispatch.php | 2 +- .../install/mysql/migration/8.0.0-9.0.0.sql | 86 +++++ htdocs/langs/fr_FR/receptions.lang | 2 +- htdocs/reception/card.php | 4 +- htdocs/reception/class/reception.class.php | 33 +- htdocs/reception/create-table.php | 316 ------------------ .../reception/tpl/linkedobjectblock.tpl.php | 2 +- 12 files changed, 125 insertions(+), 338 deletions(-) delete mode 100644 htdocs/reception/create-table.php diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index 8269d75b961..244b9951f54 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -28,7 +28,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("admin","workflow","propal","workflow","orders","supplier_proposals")); +$langs->loadLangs(array("admin","workflow","propal","workflow","orders","supplier_proposals","receptions")); if (! $user->admin) accessforbidden(); @@ -87,7 +87,7 @@ $workflowcodes=array( // Automatic classification supplier order 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER'=>array('family'=>'classify_supplier_order', 'position'=>62, 'enabled'=>'! empty($conf->fournisseur->enabled)', 'picto'=>'order','warning'=>''), //Automatic classification reception - 'WORKFLOW_BILL_ON_RECEPTION'=>array('family'=>'classify', 'position'=>30, 'enabled'=>'! empty($conf->reception->enabled) && ! empty($conf->fournisseur->enabled)', 'picto'=>'bill'), + 'WORKFLOW_BILL_ON_RECEPTION'=>array('family'=>'classify_reception', 'position'=>30, 'enabled'=>'! empty($conf->reception->enabled) && ! empty($conf->fournisseur->enabled)', 'picto'=>'bill'), ); if (! empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts['workflow'])) @@ -140,6 +140,7 @@ foreach($workflowcodes as $key => $params) if ($reg[1] == 'order') print ' - '.$langs->trans('Order'); if ($reg[1] == 'supplier_proposal') print ' - '.$langs->trans('SupplierProposal'); if ($reg[1] == 'supplier_order') print ' - '.$langs->trans('SupplierOrder'); + if ($reg[1] == 'reception') print ' - '.$langs->trans('Reception'); } else { diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index cbf9f127fb7..7dfaf590178 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4225,6 +4225,7 @@ abstract class CommonObject }else { $this->tpl['label'].= ($line->label ? ' '.$line->label : ''); } + // Dates if ($line->product_type == 1 && ($date_start || $date_end)) { diff --git a/htdocs/core/modules/modReception.class.php b/htdocs/core/modules/modReception.class.php index 1c8cfd45900..77557a41bff 100644 --- a/htdocs/core/modules/modReception.class.php +++ b/htdocs/core/modules/modReception.class.php @@ -44,14 +44,14 @@ class modReception extends DolibarrModules $this->db = $db; $this->numero = 104160; - $this->family = "crm"; + $this->family = "srm"; $this->module_position = 40; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); $this->description = "Gestion des réceptions fournisseurs"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'dolibarr'; + $this->version = 'experimental'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); $this->special = 0; diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 18c5dd4962a..0c9a6d39e0f 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.0-alpha'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index d3e927c8173..8cd453836fb 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -25,6 +25,7 @@ // Put here all includes required by your class file require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php"; +require_once DOL_DOCUMENT_ROOT."/reception/class/reception.class.php"; //require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php"; //require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php"; @@ -185,10 +186,10 @@ class CommandeFournisseurDispatch extends CommonObject $sql.= " ".(! isset($this->status)?'NULL':"'".$this->db->escape($this->status)."'").","; $sql.= " ".(! isset($this->batch)?'NULL':"'".$this->db->escape($this->batch)."'").","; $sql.= " ".(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':"'".$this->db->idate($this->eatby)."'").","; - $sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':"'".$this->db->idate($this->sellby)."'").""; + $sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':"'".$this->db->idate($this->sellby)."'").","; $sql.= " ".(! isset($this->fk_reception)?'NULL':"'".$this->fk_reception."'").""; $sql.= ")"; - + $this->db->begin(); dol_syslog(__METHOD__, LOG_DEBUG); @@ -221,6 +222,7 @@ class CommandeFournisseurDispatch extends CommonObject if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used { $result=$this->insertExtraFields(); + if ($result < 0) { $error++; diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 125bee1850c..780aac3aba6 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -889,8 +889,8 @@ if ($id > 0 || ! empty($ref)) { }else if(!empty($conf->reception->enabled)){ print ''; if(!empty($reception->id)){ - print $reception->getLibStatut(5); + } } print ''; print ''; diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql index 09908ac86f5..41698a1a614 100644 --- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql +++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql @@ -129,3 +129,89 @@ CREATE TABLE llx_takepos_floor_tables( UPDATE llx_c_payment_term SET decalage = nbjour, nbjour = 0 where decalage IS NULL AND type_cdr = 2; + +-- Reception + +ALTER TABLE llx_commande_fournisseur_dispatch ADD COLUMN fk_reception integer DEFAULT NULL; +ALTER TABLE llx_commande_fournisseur_dispatch CHANGE comment comment TEXT; +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECEPTION_VALIDATE','Reception validated','Executed when a reception is validated','reception',22); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECEPTION_SENTBYMAIL','Reception sent by mail','Executed when a reception is sent by mail','reception',22); + +create table llx_commande_fournisseur_dispatch_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, -- object id + import_key varchar(14) -- import key +)ENGINE=innodb; + +ALTER TABLE llx_commande_fournisseur_dispatch_extrafields ADD INDEX idx_commande_fournisseur_dispatch_extrafields (fk_object); + + +create table llx_reception +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + ref varchar(30) NOT NULL, + entity integer DEFAULT 1 NOT NULL, -- multi company id + fk_soc integer NOT NULL, + fk_projet integer DEFAULT NULL, + + ref_ext varchar(30), -- reference into an external system (not used by dolibarr) + ref_int varchar(30), -- reference into an internal system (used by dolibarr to store extern id like paypal info) + ref_supplier varchar(30), -- customer number + + date_creation datetime, -- date de creation + fk_user_author integer, -- author of creation + fk_user_modif integer, -- author of last change + date_valid datetime, -- date de validation + fk_user_valid integer, -- valideur + date_delivery datetime DEFAULT NULL, -- date planned of delivery + date_reception datetime, + fk_shipping_method integer, + tracking_number varchar(50), + fk_statut smallint DEFAULT 0, -- 0 = draft, 1 = validated, 2 = billed or closed depending on WORKFLOW_BILL_ON_SHIPMENT option + billed smallint DEFAULT 0, + + height float, -- height + width float, -- with + size_units integer, -- unit of all sizes (height, width, depth) + size float, -- depth + weight_units integer, -- unit of weight + weight float, -- weight + note_private text, + note_public text, + model_pdf varchar(255), + fk_incoterms integer, -- for incoterms + location_incoterms varchar(255), -- for incoterms + + import_key varchar(14), + extraparams varchar(255) -- for other parameters with json format +)ENGINE=innodb; + +ALTER TABLE llx_reception ADD UNIQUE INDEX idx_reception_uk_ref (ref, entity); + +ALTER TABLE llx_reception ADD INDEX idx_reception_fk_soc (fk_soc); +ALTER TABLE llx_reception ADD INDEX idx_reception_fk_user_author (fk_user_author); +ALTER TABLE llx_reception ADD INDEX idx_reception_fk_user_valid (fk_user_valid); +ALTER TABLE llx_reception ADD INDEX idx_reception_fk_shipping_method (fk_shipping_method); + +ALTER TABLE llx_reception ADD CONSTRAINT fk_reception_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe (rowid); +ALTER TABLE llx_reception ADD CONSTRAINT fk_reception_fk_user_author FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid); +ALTER TABLE llx_reception ADD CONSTRAINT fk_reception_fk_user_valid FOREIGN KEY (fk_user_valid) REFERENCES llx_user (rowid); +ALTER TABLE llx_reception ADD CONSTRAINT fk_reception_fk_shipping_method FOREIGN KEY (fk_shipping_method) REFERENCES llx_c_shipment_mode (rowid); + +create table llx_reception_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_reception_extrafields ADD INDEX idx_reception_extrafields (fk_object); + +ALTER TABLE llx_commande_fournisseur_dispatch ADD INDEX idx_commande_fournisseur_dispatch_fk_reception (fk_reception); +ALTER TABLE llx_commande_fournisseur_dispatch ADD CONSTRAINT fk_commande_fournisseur_dispatch_fk_reception FOREIGN KEY (fk_reception) REFERENCES llx_reception (rowid); + + diff --git a/htdocs/langs/fr_FR/receptions.lang b/htdocs/langs/fr_FR/receptions.lang index 2102e282668..8e766344d94 100644 --- a/htdocs/langs/fr_FR/receptions.lang +++ b/htdocs/langs/fr_FR/receptions.lang @@ -30,7 +30,7 @@ ReceptionsAndReceivingForSameOrder=Réceptions et réceptions pour cette command ReceptionsToValidate=Réceptions à valider StatusReceptionCanceled=Annulée StatusReceptionDraft=Brouillon -StatusReceptionValidated=Validée (produits à envoyer ou envoyés) +StatusReceptionValidated=Validée StatusReceptionProcessed=Traitée StatusReceptionDraftShort=Brouillon StatusReceptionValidatedShort=Validée diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index bb0875c0cbf..0610430ba13 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -348,7 +348,7 @@ if (empty($reshook)) $sellbydate = str_replace('/','-',$sellby); - $ret = $object->addline($entrepot_id, GETPOST($idl, 'int'), GETPOST($qty, 'int'), $array_options[$i], GETPOST($comment, 'alpha'), strtotime($eatbydate),strtotime($sellbydate), GETPOST($batch, 'alpha')); + $ret = $object->addline($entrepot_id, GETPOST($idl, 'int'), GETPOST($qty, 'int'), $array_options[$i], GETPOST($comment, 'alpha'), strtotime($eatbydate),strtotime($sellbydate), GETPOST($batch, 'alpha')); if ($ret < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -2248,7 +2248,7 @@ else if ($id || $ref) $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object,$langs); $formmail->substit['__RECEPTIONREF__']=$object->ref; $formmail->substit['__RECEPTIONTRACKNUM__']=$object->tracking_number; $formmail->substit['__RECEPTIONTRACKNUMURL__']=$object->tracking_url; diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 67ee854ec30..06b35efd940 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -264,7 +264,7 @@ class Reception extends CommonObject for ($i = 0; $i < $num; $i++) { $this->lines[$i]->fk_reception = $this->id; - + if (! $this->lines[$i]->create($user) > 0) { $error++; @@ -1025,7 +1025,7 @@ class Reception extends CommonObject } } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * Load lines * @@ -1033,6 +1033,7 @@ class Reception extends CommonObject */ function fetch_lines() { + // phpcs:enable global $db; dol_include_once('/fourn/class/fournisseur.commande.dispatch.class.php'); $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'commande_fournisseur_dispatch WHERE fk_reception='.$this->id; @@ -1056,9 +1057,8 @@ class Reception extends CommonObject $line->subprice = $obj->subprice; $line->multicurrency_subprice = $obj->multicurrency_subprice; $line->remise_percent = $obj->remise_percent; - $line->label = $obj->label; + $line->label = !empty($obj->label)?$obj->label:$line->product->label; $line->ref_supplier = $obj->ref; - }else { $line->qty_asked = 0; $line->description = ''; @@ -1260,7 +1260,8 @@ class Reception extends CommonObject } } - + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * Set the planned delivery date * @@ -1270,6 +1271,7 @@ class Reception extends CommonObject */ function set_date_livraison($user, $date_livraison) { + // phpcs:enable if ($user->rights->reception->creer) { $sql = "UPDATE ".MAIN_DB_PREFIX."reception"; @@ -1294,7 +1296,7 @@ class Reception extends CommonObject return -2; } } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * Fetch deliveries method and return an array. Load array this->meths(rowid=>label). * @@ -1302,6 +1304,7 @@ class Reception extends CommonObject */ function fetch_delivery_methods() { + // phpcs:enable global $langs; $this->meths = array(); @@ -1320,7 +1323,7 @@ class Reception extends CommonObject } } } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * Fetch all deliveries method and return an array. Load array this->listmeths. * @@ -1329,6 +1332,7 @@ class Reception extends CommonObject */ function list_delivery_methods($id='') { + // phpcs:enable global $langs; $this->listmeths = array(); @@ -1355,6 +1359,7 @@ class Reception extends CommonObject } } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * Update/create delivery method. * @@ -1364,6 +1369,7 @@ class Reception extends CommonObject */ function update_delivery_method($id='') { + // phpcs:enable if ($id=='') { $sql = "INSERT INTO ".MAIN_DB_PREFIX."c_shipment_mode (code, libelle, description, tracking)"; @@ -1382,7 +1388,8 @@ class Reception extends CommonObject } if ($resql < 0) dol_print_error($this->db,''); } - + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * Activate delivery method. * @@ -1392,13 +1399,15 @@ class Reception extends CommonObject */ function activ_delivery_method($id) { + // phpcs:enable $sql = 'UPDATE '.MAIN_DB_PREFIX.'c_shipment_mode SET active=1'; $sql.= ' WHERE rowid='.$id; $resql = $this->db->query($sql); } - + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * DesActivate delivery method. * @@ -1408,6 +1417,7 @@ class Reception extends CommonObject */ function disable_delivery_method($id) { + // phpcs:enable $sql = 'UPDATE '.MAIN_DB_PREFIX.'c_shipment_mode SET active=0'; $sql.= ' WHERE rowid='.$id; @@ -1598,7 +1608,7 @@ class Reception extends CommonObject return -1; } } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * Classify the reception as invoiced (used when WORKFLOW_BILL_ON_RECEPTION is on) * @@ -1606,6 +1616,7 @@ class Reception extends CommonObject */ function set_billed() { + // phpcs:enable global $user; $error=0; @@ -1768,6 +1779,7 @@ class Reception extends CommonObject } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** * Set draft status * @@ -1776,6 +1788,7 @@ class Reception extends CommonObject */ function set_draft($user) { + // phpcs:enable global $conf,$langs; $error=0; diff --git a/htdocs/reception/create-table.php b/htdocs/reception/create-table.php deleted file mode 100644 index f311fd49d4d..00000000000 --- a/htdocs/reception/create-table.php +++ /dev/null @@ -1,316 +0,0 @@ -query($sql); -if(empty($resql)){ - var_dump($db->error); -} - -$sql=" insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECEPTION_VALIDATE','Reception validated','Executed when a reception is validated','reception',22);"; - -$resql = $db->query($sql); -if(empty($resql)){ - print '
';
-	var_dump($db->error);
-	print '
'; -} - -$sql="insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('RECEPTION_SENTBYMAIL','Reception sent by mail','Executed when a reception is sent by mail','reception',22); "; - -$resql = $db->query($sql); -if(empty($resql)){ - print '
';
-        var_dump($db->error);
-        print '
'; -} - - -$sql=" ALTER TABLE ".MAIN_DB_PREFIX."commande_fournisseur_dispatch CHANGE comment comment TEXT;"; -$resql = $db->query($sql); -if(empty($resql)){ - var_dump($db->error); -} - - - - -$ok = 0; -$handle = opendir($dir); -$tablefound = 0; -$tabledata = array(); -if (is_resource($handle)) -{ - while (($file = readdir($handle)) !== false) - { - if (preg_match('/\.sql$/i', $file) && preg_match('/^llx_/i', $file) && !preg_match('/\.key\.sql$/i', $file)) - { - if (strpos($file, 'reception') !== false || strpos($file, 'commande_fournisseur_dispatch') !== false){ - $tablefound++; - $tabledata[] = $file; - } - } - } - - closedir($handle); -} - - - -// Sort list of sql files on alphabetical order (load order is important) -sort($tabledata); -foreach ($tabledata as $file) -{ - $name = substr($file, 0, dol_strlen($file) - 4); - $buffer = ''; - $fp = fopen($dir.$file, "r"); - if ($fp) - { - while (!feof($fp)) - { - $buf = fgets($fp, 4096); - if (substr($buf, 0, 2) <> '--') - { - $buf = preg_replace('/--(.+)*/', '', $buf); - $buffer .= $buf; - } - } - fclose($fp); - - $buffer = trim($buffer); - if ($conf->db->type == 'mysql' || $conf->db->type == 'mysqli') // For Mysql 5.5+, we must replace type=innodb with ENGINE=innodb - { - $buffer = preg_replace('/type=innodb/i', 'ENGINE=innodb', $buffer); - } - else if ($conf->db->type == 'mssql') - { - $buffer = preg_replace('/type=innodb/i', '', $buffer); - $buffer = preg_replace('/ENGINE=innodb/i', '', $buffer); - } - - // Replace the prefix tables - if ($dolibarr_main_db_prefix != 'llx_') - { - $buffer = preg_replace('/llx_/i', $dolibarr_main_db_prefix, $buffer); - } - - //print "Creation de la table $name/td>"; - $requestnb++; - - $resql = $db->query($buffer, 0, 'dml'); - if ($resql) - { - // print "OK requete ==== $buffer"; - $db->free($resql); - } - else - { - if ($db->errno() == 'DB_ERROR_TABLE_ALREADY_EXISTS' || - $db->errno() == 'DB_ERROR_TABLE_OR_KEY_ALREADY_EXISTS') - { - //print "Deja existante"; - } - else - { - print "".$langs->trans("CreateTableAndPrimaryKey", $name); - print "
\n".$langs->trans("Request").' '.$requestnb.' : '.$buffer.'
Executed query : '.$db->lastquery; - print "\n"; - print ''.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().''; - $error++; - } - } - } - else - { - print "".$langs->trans("CreateTableAndPrimaryKey", $name); - print ""; - print ''.$langs->trans("Error").' Failed to open file '.$dir.$file.''; - $error++; - } -} - -if ($tablefound) -{ - if ($error == 0) - { - print ''; - print $langs->trans("TablesAndPrimaryKeysCreation").'Ok'; - $ok = 1; - } -} -else -{ - print ''.$langs->trans("ErrorFailedToFindSomeFiles", $dir).'Error'; -} - - - -// We always choose in mysql directory (Conversion is done by driver to translate SQL syntax) - - -$okkeys = 0; -$handle = opendir($dir); -$tablefound = 0; -$tabledata = array(); -if (is_resource($handle)) -{ - while (($file = readdir($handle)) !== false) - { - if (preg_match('/\.sql$/i', $file) && preg_match('/^llx_/i', $file) && preg_match('/\.key\.sql$/i', $file)) - { - if (strpos($file, 'reception') !== false || strpos($file, 'commande_fournisseur_dispatch') !== false){ - $tablefound++; - $tabledata[] = $file; - } - } - } - closedir($handle); -} - -// Sort list of sql files on alphabetical order (load order is important) -sort($tabledata); -foreach ($tabledata as $file) -{ - $name = substr($file, 0, dol_strlen($file) - 4); - //print "Creation de la table $name"; - $buffer = ''; - $fp = fopen($dir.$file, "r"); - if ($fp) - { - while (!feof($fp)) - { - $buf = fgets($fp, 4096); - - // Cas special de lignes autorisees pour certaines versions uniquement - if ($choix == 1 && preg_match('/^--\sV([0-9\.]+)/i', $buf, $reg)) - { - $versioncommande = explode('.', $reg[1]); - //print var_dump($versioncommande); - //print var_dump($versionarray); - if (count($versioncommande) && count($versionarray) && versioncompare($versioncommande, $versionarray) <= 0) - { - // Version qualified, delete SQL comments - $buf = preg_replace('/^--\sV([0-9\.]+)/i', '', $buf); - //print "Ligne $i qualifiee par version: ".$buf.'
'; - } - } - if ($choix == 2 && preg_match('/^--\sPOSTGRESQL\sV([0-9\.]+)/i', $buf, $reg)) - { - $versioncommande = explode('.', $reg[1]); - //print var_dump($versioncommande); - //print var_dump($versionarray); - if (count($versioncommande) && count($versionarray) && versioncompare($versioncommande, $versionarray) <= 0) - { - // Version qualified, delete SQL comments - $buf = preg_replace('/^--\sPOSTGRESQL\sV([0-9\.]+)/i', '', $buf); - //print "Ligne $i qualifiee par version: ".$buf.'
'; - } - } - - // Ajout ligne si non commentaire - if (!preg_match('/^--/i', $buf)) - $buffer .= $buf; - } - fclose($fp); - - // Si plusieurs requetes, on boucle sur chaque - $listesql = explode(';', $buffer); - foreach ($listesql as $req) - { - $buffer = trim($req); - if ($buffer) - { - // Replace the prefix tables - if ($dolibarr_main_db_prefix != 'llx_') - { - $buffer = preg_replace('/llx_/i', $dolibarr_main_db_prefix, $buffer); - } - - //print "Creation des cles et index de la table $name: '$buffer'"; - $requestnb++; - - $resql = $db->query($buffer, 0, 'dml'); - if ($resql) - { - //print "OK requete ==== $buffer"; - $db->free($resql); - } - else - { - if ($db->errno() == 'DB_ERROR_KEY_NAME_ALREADY_EXISTS' || - $db->errno() == 'DB_ERROR_CANNOT_CREATE' || - $db->errno() == 'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS' || - $db->errno() == 'DB_ERROR_TABLE_OR_KEY_ALREADY_EXISTS' || - preg_match('/duplicate key name/i', $db->error())) - { - //print "Deja existante"; - $key_exists = 1; - } - else - { - print "".$langs->trans("CreateOtherKeysForTable", $name); - print "
\n".$langs->trans("Request").' '.$requestnb.' : '.$db->lastqueryerror(); - print "\n"; - print ''.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().''; - $error++; - } - } - } - } - } - else - { - print "".$langs->trans("CreateOtherKeysForTable", $name); - print ""; - print ''.$langs->trans("Error")." Failed to open file ".$dir.$file.""; - $error++; - } -} - -if ($tablefound && $error == 0) -{ - print ''; - print $langs->trans("OtherKeysCreation").'Ok'; - $okkeys = 1; -} - - - - diff --git a/htdocs/reception/tpl/linkedobjectblock.tpl.php b/htdocs/reception/tpl/linkedobjectblock.tpl.php index d6dd383ccc8..50069f0a14f 100644 --- a/htdocs/reception/tpl/linkedobjectblock.tpl.php +++ b/htdocs/reception/tpl/linkedobjectblock.tpl.php @@ -54,7 +54,7 @@ foreach($linkedObjectBlock as $key => $objectlink) // For now, receptions must stay linked to order, so link is not deletable if($object->element != 'order_supplier') { ?> - ">transnoentitiesnoconv("RemoveLink")); ?> + ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> From 52236d1f0c28048a5ca47021b1f4fa78581bd3ad Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Tue, 23 Oct 2018 15:58:38 +0200 Subject: [PATCH 059/307] set to development module --- htdocs/core/modules/modReception.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modReception.class.php b/htdocs/core/modules/modReception.class.php index 77557a41bff..be2e1cc8d62 100644 --- a/htdocs/core/modules/modReception.class.php +++ b/htdocs/core/modules/modReception.class.php @@ -51,7 +51,7 @@ class modReception extends DolibarrModules $this->description = "Gestion des réceptions fournisseurs"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'experimental'; + $this->version = 'development'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); $this->special = 0; From 04eb9ca16795f619fde12174d05e536c15c1ff2e Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Tue, 23 Oct 2018 17:06:21 +0200 Subject: [PATCH 060/307] fix dont change num version --- htdocs/admin/commande_fournisseur_dispatch_extrafields.php | 2 +- htdocs/core/class/commonobject.class.php | 2 +- htdocs/filefunc.inc.php | 2 +- htdocs/fourn/class/fournisseur.commande.class.php | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/commande_fournisseur_dispatch_extrafields.php b/htdocs/admin/commande_fournisseur_dispatch_extrafields.php index 68246b675e5..9abc3dc23c7 100644 --- a/htdocs/admin/commande_fournisseur_dispatch_extrafields.php +++ b/htdocs/admin/commande_fournisseur_dispatch_extrafields.php @@ -8,7 +8,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Claudio Aschieri * Copyright (C) 2018 Quentin Vial-Gouteyron - * + * * * 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 diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 7dfaf590178..255e7c6c311 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3586,7 +3586,7 @@ abstract class CommonObject $totalToShip+=$line->qty_shipped; // defined for shipment only }else if ($line->element == 'commandefournisseurdispatch' && isset($line->qty)) { - if (empty($totalToShip)) $totalToShip=0; + if (empty($totalToShip)) $totalToShip=0; $totalToShip+=$line->qty; // defined for reception only } diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 0c9a6d39e0f..18c5dd4962a 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.1'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.0-alpha'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 2a54da48ad6..782e040dca9 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3187,7 +3187,6 @@ class CommandeFournisseur extends CommonOrder $this->error=$this->db->lasterror(); return -1; } - } } From 200702a53cf006b1cc3b6a170d77a2417700e396 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Wed, 24 Oct 2018 09:35:18 +0200 Subject: [PATCH 061/307] FIX Display edit batch only if product handle it --- htdocs/reception/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 0610430ba13..ffbb5dbd765 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -1918,7 +1918,7 @@ else if ($id || $ref) // Warehouse source print '' . $formproduct->selectWarehouses($lines[$i]->fk_entrepot, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1). ''; // Batch number managment - if($conf->productbatch->enabled){ + if($conf->productbatch->enabled && !empty($lines[$i]->product->status_batch)){ print '
'; print $langs->trans('EatByDate').' : '; print $form->select_date($lines[$i]->eatby,'dlc' .$line_id , '', '', 1, ""). '
'; From 759b2b6ccff6100edbfb11259bc9d17a8c1878d6 Mon Sep 17 00:00:00 2001 From: atm-john Date: Thu, 25 Oct 2018 21:39:22 +0200 Subject: [PATCH 062/307] Extend import option to Order's card and Propal's card --- htdocs/comm/propal/card.php | 90 +++++++++++++++++- htdocs/commande/card.php | 91 ++++++++++++++++++- .../tpl/ajax/objectlinked_lineimport.tpl.php | 8 +- 3 files changed, 186 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 1e6df0b014f..a0aa864ebc6 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -695,6 +695,88 @@ if (empty($reshook)) } } } + + // add lines from objectlinked + elseif($action == 'import_lines_from_object' + && $user->rights->propal->creer + && $object->statut == Propal::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'; + } + $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($lineId); + $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; + $ventil = 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, $price_base_type, $pu_ttc, $info_bits, $type, $rang, $special_code, $fk_parent_line, $fk_fournprice, $pa_ht, $label,$date_start, $date_end,$array_options, $fk_unit, $origin, $origin_id, $pu_ht_devise, $fk_remise_except); + + if($res > 0){ + $importCount++; + }else{ + $error++; + } + } + else{ + $error++; + } + } + + if($error) + { + setEventMessages($langs->trans('ErrorsOnXLines',$error), null, 'errors'); + } + } + } include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; @@ -2490,7 +2572,13 @@ if ($action == 'create') // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('propal')); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + $compatibleImportElementsList = false; + if($user->rights->propal->creer && $object->statut == Propal::STATUS_DRAFT) + { + $compatibleImportElementsList = array('commande','propal'); // import from linked elements + } + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, $compatibleImportElementsList); // Show online signature link $useonlinesignature = $conf->global->MAIN_FEATURES_LEVEL; // Replace this with 1 when feature to make online signature is ok diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 75b949ff203..4e12c32e65b 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1319,6 +1319,88 @@ if (empty($reshook)) exit(); } + // add lines from objectlinked + if($action == 'import_lines_from_object' + && $user->rights->commande->creer + && $object->statut == 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'; + } + $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($lineId); + $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; + $ventil = 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'; @@ -2639,7 +2721,14 @@ if ($action == 'create' && $user->rights->commande->creer) // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('order')); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + $compatibleImportElementsList = false; + if($user->rights->commande->creer + && $object->statut == Commande::STATUS_DRAFT) + { + $compatibleImportElementsList = array('commande','propal'); // import from linked elements + } + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem,$compatibleImportElementsList); // Show online payment link $useonlinepayment = (! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)); diff --git a/htdocs/core/tpl/ajax/objectlinked_lineimport.tpl.php b/htdocs/core/tpl/ajax/objectlinked_lineimport.tpl.php index ad32f1b9aa8..73981ed017c 100644 --- a/htdocs/core/tpl/ajax/objectlinked_lineimport.tpl.php +++ b/htdocs/core/tpl/ajax/objectlinked_lineimport.tpl.php @@ -22,6 +22,12 @@ if (empty($conf) || ! is_object($conf)) exit; } +$objectUrl = $object->getNomUrl(0,'',0,1); +if($object->element == 'propal') +{ + $objectUrl = DOL_URL_ROOT.'/comm/propal/card.php?id='.$object->id; +} + ?> @@ -47,7 +53,7 @@ $(document).ready(function(){ }); - var $dialog = $('
') + var $dialog = $('
') .load( page + " #tablelines", function() { $("#" + formId + " #tablelines").prop("id", "ajaxloaded_tablelines"); // change id attribute From f29ee25ea751400a84c80a6f519052a3aa587a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 27 Oct 2018 11:06:45 +0200 Subject: [PATCH 063/307] remove fieldlabel and add fieldeditkey --- htdocs/commande/card.php | 142 ++++++++++------------------------ htdocs/core/tpl/notes.tpl.php | 3 +- 2 files changed, 44 insertions(+), 101 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index f468bd4b146..3036722c3aa 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1687,7 +1687,7 @@ if ($action == 'create' && $user->rights->commande->creer) if (! empty($conf->multicurrency->enabled)) { print ''; - print ''.fieldLabel('Currency','multicurrency_code').''; + print ''.$form->editfieldkey("Currency", 'multicurrency_code', '', $object, 0).''; print ''; print $form->selectMultiCurrency($currency_code, 'multicurrency_code'); print ''; @@ -2074,13 +2074,8 @@ if ($action == 'create' && $user->rights->commande->creer) // Date print ''; - print ''; - - if ($action != 'editdate' && $object->brouillon) - print ''; - print '
'; - print $langs->trans('Date'); - print 'id . '">' . img_edit($langs->trans('SetDate'), 1) . '
'; + $editenable = $user->rights->commande->creer && $object->statut == Commande::STATUS_DRAFT; + print $form->editfieldkey("Date", 'date', '', $object, $editenable); print ''; if ($action == 'editdate') { print '
'; @@ -2100,12 +2095,8 @@ if ($action == 'create' && $user->rights->commande->creer) // Delivery date planed print ''; - print ''; - if ($action != 'editdate_livraison') - print ''; - print '
'; - print $langs->trans('DateDeliveryPlanned'); - print 'id . '">' . img_edit($langs->trans('SetDeliveryDate'), 1) . '
'; + $editenable = $user->rights->commande->creer && $object->statut == Commande::STATUS_DRAFT; + print $form->editfieldkey("DateDeliveryPlanned", 'date_livraison', '', $object, $editenable); print ''; if ($action == 'editdate_livraison') { print ''; @@ -2125,13 +2116,9 @@ if ($action == 'create' && $user->rights->commande->creer) // Shipping Method if (! empty($conf->expedition->enabled)) { - print ''; - print ''; - if ($action != 'editshippingmethod' && $user->rights->commande->creer) - print ''; - print '
'; - print $langs->trans('SendingMethod'); - print 'id.'">'.img_edit($langs->trans('SetShippingMode'),1).'
'; + print ''; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("SendingMethod", 'shippingmethod', '', $object, $editenable); print ''; if ($action == 'editshippingmethod') { $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1); @@ -2144,15 +2131,12 @@ if ($action == 'create' && $user->rights->commande->creer) // Warehouse if (! empty($conf->expedition->enabled) && ! empty($conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER)) { + $langs->load('stocks'); require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; $formproduct=new FormProduct($db); print ''; - print ''; - if ($action != 'editwarehouse' && $user->rights->commande->creer) - print ''; - print '
'; - print $langs->trans('Warehouse'); - print 'id.'">'.img_edit($langs->trans('SetWarehouse'),1).'
'; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("Warehouse", 'warehouse', '', $object, $editenable); print ''; if ($action == 'editwarehouse') { $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'warehouse_id', 1); @@ -2165,12 +2149,8 @@ if ($action == 'create' && $user->rights->commande->creer) // Terms of payment print ''; - print ''; - if ($action != 'editconditions') - print ''; - print '
'; - print $langs->trans('PaymentConditionsShort'); - print 'id . '">' . img_edit($langs->trans('SetConditions'), 1) . '
'; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("PaymentConditionsShort", 'conditions', '', $object, $editenable); print ''; if ($action == 'editconditions') { $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->cond_reglement_id, 'cond_reglement_id', 1); @@ -2183,12 +2163,8 @@ if ($action == 'create' && $user->rights->commande->creer) // Mode of payment print ''; - print ''; - if ($action != 'editmode') - print ''; - print '
'; - print $langs->trans('PaymentMode'); - print 'id . '">' . img_edit($langs->trans('SetMode'), 1) . '
'; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("PaymentMode", 'mode', '', $object, $editenable); print ''; if ($action == 'editmode') { $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id'); @@ -2203,12 +2179,8 @@ if ($action == 'create' && $user->rights->commande->creer) // Multicurrency code print ''; print ''; - print ''; - if ($action != 'editmulticurrencycode' && ! empty($object->brouillon)) - print ''; - print '
'; - print fieldLabel('Currency','multicurrency_code'); - print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
'; + $editenable = $user->rights->commande->creer && $object->statut == Commande::STATUS_DRAFT; + print $form->editfieldkey("Currency", 'multicurrencycode', '', $object, $editenable); print ''; if ($action == 'editmulticurrencycode') { $form->form_multicurrency_code($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_code, 'multicurrency_code'); @@ -2220,12 +2192,8 @@ if ($action == 'create' && $user->rights->commande->creer) // Multicurrency rate print ''; print ''; - print ''; - if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) - print ''; - print '
'; - print fieldLabel('CurrencyRate','multicurrency_tx'); - print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
'; + $editenable = $user->rights->commande->creer && $object->multicurrency_code && $object->multicurrency_code != $conf->currency && $object->statut == Commande::STATUS_DRAFT; + print $form->editfieldkey("CurrencyRate", 'multicurrencyrate', '', $object, $editenable); print ''; if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') { if($action == 'actualizemulticurrencyrate') { @@ -2244,13 +2212,9 @@ if ($action == 'create' && $user->rights->commande->creer) } // Delivery delay - print ''; - print ''; - if ($action != 'editavailability') - print ''; - print '
'; - print $langs->trans('AvailabilityPeriod'); - print 'id . '">' . img_edit($langs->trans('SetAvailability'), 1) . '
'; + print ''; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("AvailabilityPeriod", 'availability', '', $object, $editenable); print ''; if ($action == 'editavailability') { $form->form_availability($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->availability_id, 'availability_id', 1); @@ -2260,13 +2224,9 @@ if ($action == 'create' && $user->rights->commande->creer) print ''; // Source reason (why we have an ordrer) - print ''; - print ''; - if ($action != 'editdemandreason') - print ''; - print '
'; - print $langs->trans('Channel'); - print 'id . '">' . img_edit($langs->trans('SetDemandReason'), 1) . '
'; + print ''; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("Channel", 'demandreason', '', $object, $editenable); print ''; if ($action == 'editdemandreason') { $form->formInputReason($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->demand_reason_id, 'demand_reason_id', 1); @@ -2277,13 +2237,9 @@ if ($action == 'create' && $user->rights->commande->creer) // TODO Order mode (how we receive order). Not yet implemented /* - print ''; - print ''; - if ($action != 'editinputmode') - print ''; - print '
'; - print $langs->trans('SourceMode'); - print 'id . '">' . img_edit($langs->trans('SetInputMode'), 1) . '
'; + print ''; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("SourceMode", 'inputmode', '', $object, $editenable); print ''; if ($action == 'editinputmode') { $form->formInputMode($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->source, 'input_mode_id', 1); @@ -2296,15 +2252,13 @@ if ($action == 'create' && $user->rights->commande->creer) $tmparray=$object->getTotalWeightVolume(); $totalWeight=$tmparray['weight']; $totalVolume=$tmparray['volume']; - if ($totalWeight) - { + if ($totalWeight) { print ''.$langs->trans("CalculatedWeight").''; print ''; print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, isset($conf->global->MAIN_WEIGHT_DEFAULT_ROUND)?$conf->global->MAIN_WEIGHT_DEFAULT_ROUND:-1, isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT)?$conf->global->MAIN_WEIGHT_DEFAULT_UNIT:'no'); print ''; } - if ($totalVolume) - { + if ($totalVolume) { print ''.$langs->trans("CalculatedVolume").''; print ''; print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND)?$conf->global->MAIN_VOLUME_DEFAULT_ROUND:-1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT)?$conf->global->MAIN_VOLUME_DEFAULT_UNIT:'no'); @@ -2314,15 +2268,10 @@ if ($action == 'create' && $user->rights->commande->creer) // TODO How record was recorded OrderMode (llx_c_input_method) // Incoterms - if (!empty($conf->incoterm->enabled)) - { + if (!empty($conf->incoterm->enabled)) { print ''; - print '
'; - print $langs->trans('IncotermLabel'); - print ''; - if ($user->rights->commande->creer) print ''.img_edit().''; - else print ' '; - print '
'; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("IncotermLabel", 'incoterm', '', $object, $editenable); print ''; print ''; if ($action != 'editincoterm') @@ -2337,15 +2286,10 @@ if ($action == 'create' && $user->rights->commande->creer) } // Bank Account - if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ORDER) && ! empty($conf->banque->enabled)) - { - print ''; - print ''; - print '
'; - print $langs->trans('BankAccount'); - print ''; - if ($action != 'editbankaccount' && $user->rights->commande->creer) - print 'id.'">'.img_edit($langs->trans('SetBankAccount'),1).'
'; + if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ORDER) && ! empty($conf->banque->enabled)) { + print ''; + $editenable = $user->rights->commande->creer; + print $form->editfieldkey("BankAccount", 'bankaccount', '', $object, $editenable); print ''; if ($action == 'editbankaccount') { $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1); @@ -2446,12 +2390,11 @@ if ($action == 'create' && $user->rights->commande->creer) */ $result = $object->getLinesArray(); - print ' + print ' - - '; + '; if (! empty($conf->use_javascript_ajax) && $object->statut == Commande::STATUS_DRAFT) { include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; @@ -2518,10 +2461,11 @@ if ($action == 'create' && $user->rights->commande->creer) print ''; } // Create event - /*if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a - // "workflow" action so should appears somewhere else on - // page. + /*if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) { + // Add hidden condition because this is not a + // "workflow" action so should appears somewhere else on + // page. print '' . $langs->trans("AddAction") . ''; }*/ diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index 39132dd1af7..0d2151ab62d 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -18,8 +18,7 @@ */ // Protection to avoid direct call of template -if (empty($object) || ! is_object($object)) -{ +if (empty($object) || ! is_object($object)) { print "Error, template page can't be called as URL"; exit; } From d67c40dffe3cb637d1d51335d430fad9fa652585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 27 Oct 2018 13:01:01 +0200 Subject: [PATCH 064/307] remove fieldlabel and add fieldeditkey --- htdocs/adherents/card.php | 28 +++++++--------------------- htdocs/commande/card.php | 25 +++++++++++++++---------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index e7b36b77ad9..84667d9032e 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1017,7 +1017,7 @@ else // Categories if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) { - print '' . fieldLabel('Categories', 'memcars') . ''; + print '' .$form->editfieldkey("Categories", 'memcats', '', $object, 0) . ''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_MEMBER, null, 'parent', null, null, 1); print $form->multiselectarray('memcats', $cate_arbo, GETPOST('memcats', 'array'), null, null, null, null, '100%'); print ""; @@ -1140,7 +1140,7 @@ else print ''.$langs->trans("Login").' / '.$langs->trans("Id").'login).'">'; } - // Password + // Password if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) { print ''.$langs->trans("Password").'pass).'">'; @@ -1267,7 +1267,7 @@ else // Categories if (! empty( $conf->categorie->enabled ) && !empty( $user->rights->categorie->lire )) { - print '' . fieldLabel('Categories', 'memcats') . ''; + print '' . $form->editfieldkey("Categories", 'memcats', '', $object, 0) . ''; print ''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_MEMBER, null, null, null, null, 1); $c = new Categorie($db); @@ -1620,11 +1620,8 @@ else if (! empty($conf->societe->enabled)) { print ''; - print ''; - if ($action != 'editthirdparty' && $user->rights->adherent->creer) print ''; - print '
'; - print $langs->trans("LinkedToDolibarrThirdParty"); - print 'id.'">'.img_edit($langs->trans('SetLinkToThirdParty'),1).'
'; + $editenable = $user->rights->adherent->creer; + print $form->editfieldkey('LinkedToDolibarrThirdParty', 'thirdparty', '', $object, $editenable); print ''; if ($action == 'editthirdparty') { @@ -1658,19 +1655,8 @@ else // Login Dolibarr print ''; - print ''; - if ($action != 'editlogin' && $user->rights->adherent->creer) - { - print ''; - } - print '
'; - print $langs->trans("LinkedToDolibarrUser"); - print ''; - if ($user->rights->user->user->creer) - { - print 'id.'">'.img_edit($langs->trans('SetLinkToUser'),1).''; - } - print '
'; + $editenable = $user->rights->adherent->creer && $user->rights->user->user->creer; + print $form->editfieldkey('LinkedToDolibarrUser', 'login', '', $object, $editenable); print ''; if ($action == 'editlogin') { diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 3036722c3aa..d02e5c28858 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -106,7 +106,8 @@ $permissionedit = $user->rights->commande->creer; // Used by the include of ac */ $parameters = array('socid' => $socid); -$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +// 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)) @@ -419,10 +420,11 @@ if (empty($reshook)) // Hooks $parameters = array('objFrom' => $srcobject); - $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook - if ($reshook < 0) + // Note that $action and $object may have be modified by hook + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); + if ($reshook < 0) { $error++; + } } else { setEventMessages($object->error, $object->errors, 'errors'); $error++; @@ -1669,7 +1671,8 @@ if ($action == 'create' && $user->rights->commande->creer) // Other attributes $parameters = array('objectsrc' => $objectsrc, 'socid'=>$socid); - $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by + // Note that $action and $object may be modified by hook + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); print $hookmanager->resPrint; if (empty($reshook)) { print $object->showOptionals($extrafields, 'edit'); @@ -1969,7 +1972,8 @@ if ($action == 'create' && $user->rights->commande->creer) // Call Hook formConfirm $parameters = array('lineid' => $lineid); - $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + // 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; @@ -2095,7 +2099,7 @@ if ($action == 'create' && $user->rights->commande->creer) // Delivery date planed print ''; - $editenable = $user->rights->commande->creer && $object->statut == Commande::STATUS_DRAFT; + $editenable = $user->rights->commande->creer; print $form->editfieldkey("DateDeliveryPlanned", 'date_livraison', '', $object, $editenable); print ''; if ($action == 'editdate_livraison') { @@ -2420,7 +2424,8 @@ if ($action == 'create' && $user->rights->commande->creer) $object->formAddObjectLine(1, $mysoc, $soc); $parameters = array(); - $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + // Note that $action and $object may be modified by hook + $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); } } print ''; @@ -2437,8 +2442,8 @@ if ($action == 'create' && $user->rights->commande->creer) print '
'; $parameters = array(); - $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been - // modified by hook + // Note that $action and $object may be modified by hook + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); if (empty($reshook)) { // Send if ($object->statut > Commande::STATUS_DRAFT) { From 9c7ec434b74398862336246527e20817f99b1ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 27 Oct 2018 13:48:30 +0200 Subject: [PATCH 065/307] remove fieldlabel and add fieldeditkey --- htdocs/admin/holiday.php | 1 - htdocs/commande/card.php | 6 +-- htdocs/societe/card.php | 84 +++++++++++++++++++++------------------- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/htdocs/admin/holiday.php b/htdocs/admin/holiday.php index c02c9bd480d..81becbaa37c 100644 --- a/htdocs/admin/holiday.php +++ b/htdocs/admin/holiday.php @@ -513,7 +513,6 @@ print ''; print '
'; print ''; - } diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index d02e5c28858..026e7ac2c3f 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2319,17 +2319,17 @@ if ($action == 'create' && $user->rights->commande->creer) if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency)) { // Multicurrency Amount HT - print '' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . ''; + print '' . $form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0) . ''; print '' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . ''; print ''; // Multicurrency Amount VAT - print '' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . ''; + print '' . $form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0) . ''; print '' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . ''; print ''; // Multicurrency Amount TTC - print '' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . ''; + print '' . $form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0) . ''; print '' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . ''; print ''; } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 5935a1d01a1..941bd263b73 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1148,7 +1148,7 @@ else } else { - print ''.fieldLabel('ThirdPartyName','name').''; + print ''.$form->editfieldkey('ThirdPartyName', 'name', '', $object, 0).''; } print 'global->SOCIETE_USEPREFIX)?' colspan="3"':'').'>'; print ''; @@ -1161,11 +1161,11 @@ else // If javascript on, we show option individual if ($conf->use_javascript_ajax) { - print ''.fieldLabel('FirstName','firstname').''; + print ''.$form->editfieldkey('FirstName', 'firstname', '', $object, 0).''; print ''; print ''; // Title - print ''.fieldLabel('UserTitle','civility_id').''; + print ''.$form->editfieldkey('UserTitle', 'civility_id', '', $object, 0).''; print $formcompany->select_civility($object->civility_id, 'civility_id', 'maxwidth100').''; print ''; } @@ -1175,7 +1175,7 @@ else print ''; // Prospect/Customer - print ''.fieldLabel('ProspectCustomer','customerprospect',1).''; + print ''.$form->editfieldkey('ProspectCustomer', 'customerprospect', '', $object, 0, 'string', '', 1).''; print ''; $selected=GETPOST('client','int')!=''?GETPOST('client','int'):$object->client; print ''; - print ''.fieldLabel('CustomerCode','customer_code').''; + print ''.$form->editfieldkey('CustomerCode', 'customer_code', '', $object, 0).''; print ''; - print ''; // Barcode if (! empty($conf->barcode->enabled)) { - print ''; + print ''; print ''; } // Address - print ''; + print ''; print ''; // Zip / Town - print ''; // Country - print ''; @@ -1264,11 +1264,11 @@ else { if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && ($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 2)) { - print ''; + print ''; print ''; - print ''; + print ''; print ''; if (! empty($conf->socialnetworks->enabled)) @@ -1287,27 +1287,33 @@ else // Skype if (! empty($conf->global->SOCIALNETWORKS_SKYPE)) { - print ''; - print ''; + print ''; + print ''; } // Twitter if (! empty($conf->global->SOCIALNETWORKS_TWITTER)) { - print ''; - print ''; + print ''; + print ''; } // Facebook if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK)) { - print ''; - print ''; + print ''; + print ''; } } // Phone / Fax - print ''; + print ''; print ''; - print ''; + print ''; print ''; // Prof ids @@ -1322,7 +1328,7 @@ else if (($j % 2) == 0) print ''; $idprof_mandatory ='SOCIETE_IDPROF'.($i).'_MANDATORY'; - print ''; @@ -1334,11 +1340,11 @@ else if ($j % 2 == 1) print ''; // Vat is used - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; // Legal Form - print ''; + print ''; print ''; // Capital - print ''; + print ''; print ''; if (! empty($conf->global->MAIN_MULTILANGS)) { - print ''; print ''; @@ -1429,7 +1435,7 @@ else // Assign a sale representative print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; @@ -1453,7 +1459,7 @@ else // Customer //if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) { - print '"; @@ -1461,7 +1467,7 @@ else // Supplier //if ($object->fournisseur) { - print '"; @@ -1472,7 +1478,7 @@ else if (! empty($conf->multicurrency->enabled)) { print ''; - print ''; + print ''; print ''; @@ -1489,7 +1495,7 @@ else // Ajout du logo print ''; - print ''; + print ''; print ''; From c92a2084f1e5a14ec80e9567e6c7bbddbb7edcec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 27 Oct 2018 14:50:27 +0200 Subject: [PATCH 066/307] remove fieldlabel and add fieldeditkey --- htdocs/commande/card.php | 2 +- htdocs/societe/card.php | 91 +++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 48 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 026e7ac2c3f..6ea34c1c619 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -420,7 +420,7 @@ if (empty($reshook)) // Hooks $parameters = array('objFrom' => $srcobject); - // Note that $action and $object may have be modified by hook + // Note that $action and $object may be modified by hook $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); if ($reshook < 0) { $error++; diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 941bd263b73..4530b5a61c1 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -12,6 +12,7 @@ * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2018 Frédéric France * * 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 @@ -1742,7 +1743,7 @@ else } // Name - print ''; + print ''; print ''; // Alias names (commercial, trademark or alias names) @@ -1752,7 +1753,7 @@ else // Prefix if (! empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field { - print ''; + print ''; print ''; - print '
'; $tmpcode=$object->code_client; if (empty($tmpcode) && ! empty($modCodeClient->code_auto)) $tmpcode=$modCodeClient->getNextValue($object,0); @@ -1202,7 +1202,7 @@ else { // Supplier print '
'.fieldLabel('Supplier','fournisseur',1).''; + print ''.$form->editfieldkey('Supplier', 'fournisseur', '', $object, 0, 'string', '', 1).''; $default = -1; if (! empty($conf->global->THIRDPARTY_SUPPLIER_BY_DEFAULT)) $default=1; print $form->selectyesno("fournisseur", (GETPOST('fournisseur','int')!=''?GETPOST('fournisseur','int'):(GETPOST("type",'alpha') == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type",'alpha') == '' ? 1 : 0)); @@ -1210,7 +1210,7 @@ else print ''; if (! empty($conf->fournisseur->enabled) && ! empty($user->rights->fournisseur->lire)) { - print fieldLabel('SupplierCode','supplier_code'); + print $form->editfieldkey('SupplierCode', 'supplier_code', '', $object, 0); } print ''; if (! empty($conf->fournisseur->enabled) && ! empty($user->rights->fournisseur->lire)) @@ -1228,33 +1228,33 @@ else } // Status - print '
'.fieldLabel('Status','status').''; + print '
'.$form->editfieldkey('Status', 'status', '', $object, 0).''; print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'),'1'=>$langs->trans('InActivity')),1); print '
'.fieldLabel('Gencod','barcode').'
'.$form->editfieldkey('Gencod', 'barcode', '', $object, 0).''; print '
'.fieldLabel('Address','address').'
'.$form->editfieldkey('Address', 'address', '', $object, 0).'
'.fieldLabel('Zip','zipcode').''; + print '
'.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).''; print $formcompany->select_ziptown($object->zip,'zipcode',array('town','selectcountry_id','state_id'), 0, 0, '', 'maxwidth100 quatrevingtpercent'); - print ''.fieldLabel('Town','town').''; + print ''.$form->editfieldkey('Town', 'town', '', $object, 0).''; print $formcompany->select_ziptown($object->town,'town',array('zipcode','selectcountry_id','state_id'), 0, 0, '', 'maxwidth100 quatrevingtpercent'); print '
'.fieldLabel('Country','selectcountry_id').''; + print '
'.$form->editfieldkey('Country', 'selectcountry_id', '', $object, 0).''; print $form->select_country((GETPOST('country_id')!=''?GETPOST('country_id'):$object->country_id)); if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); print '
'.fieldLabel('Region-State','state_id').''; + print '
'.$form->editfieldkey('Region-State', 'state_id', '', $object, 0).''; } else { - print '
'.fieldLabel('State','state_id').''; + print '
'.$form->editfieldkey('State', 'state_id', '', $object, 0).''; } if ($object->country_id) print $formcompany->select_state($object->state_id,$object->country_code); @@ -1277,9 +1277,9 @@ else } // Email / Web - print '
'.fieldLabel('EMail','email',$conf->global->SOCIETE_EMAIL_MANDATORY).'
'.$form->editfieldkey('EMail', 'email', '', $object, 0, 'string', '', $conf->global->SOCIETE_EMAIL_MANDATORY).'
'.fieldLabel('Web','url').'
'.$form->editfieldkey('Web', 'url', '', $object, 0).'
'.fieldLabel('Skype','skype').'skype).'">
'.$form->editfieldkey('Skype', 'skype', '', $object, 0).''; + print 'skype).'">'; + print '
'.fieldLabel('Twitter','twitter').'twitter).'">
'.$form->editfieldkey('Twitter', 'twitter', '', $object, 0).''; + print 'twitter).'">'; + print '
'.fieldLabel('Facebook','facebook').'facebook).'">
'.$form->editfieldkey('Facebook', 'facebook', '', $object, 0).''; + print 'facebook).'">'; + print '
'.fieldLabel('Phone','phone').'
'.$form->editfieldkey('Phone', 'phone', '', $object, 0).''.fieldLabel('Fax','fax').''.$form->editfieldkey('Fax', 'fax', '', $object, 0).'
'.fieldLabel($idprof,$key, (empty($conf->global->$idprof_mandatory)?0:1)).''; + print ''.$form->editfieldkey($idprof, $key, '', $object, 0, 'string', '', (empty($conf->global->$idprof_mandatory)?0:1)).''; print $formcompany->get_input_id_prof($i, $key, $object->$key, $object->country_code); print '
'.fieldLabel('VATIsUsed','assujtva_value').'
'.$form->editfieldkey('VATIsUsed', 'assujtva_value', '', $object, 0).''; print $form->selectyesno('assujtva_value', GETPOSTISSET('assujtva_value')?GETPOST('assujtva_value','int'):1, 1); // Assujeti par defaut en creation print ''.fieldLabel('VATIntra','intra_vat').''.$form->editfieldkey('VATIntra', 'intra_vat', '', $object, 0).''; $s = ''; @@ -1391,18 +1397,18 @@ else } // Type - Size - print '
'.fieldLabel('ThirdPartyType','typent_id').''."\n"; + print '
'.$form->editfieldkey('ThirdPartyType', 'typent_id', '', $object, 0).''."\n"; $sortparam=(empty($conf->global->SOCIETE_SORT_ON_TYPEENT)?'ASC':$conf->global->SOCIETE_SORT_ON_TYPEENT); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label. print $form->selectarray("typent_id", $formcompany->typent_array(0), $object->typent_id, 0, 0, 0, '', 0, 0, 0, $sortparam); if ($user->admin) print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); print ''.fieldLabel('Staff','effectif_id').''; + print ''.$form->editfieldkey('Staff', 'effectif_id', '', $object, 0).''; print $form->selectarray("effectif_id", $formcompany->effectif_array(0), $object->effectif_id); if ($user->admin) print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); print '
'.fieldLabel('JuridicalStatus','forme_juridique_code').'
'.$form->editfieldkey('JuridicalStatus', 'forme_juridique_code', '', $object, 0).''; if ($object->country_id) { @@ -1415,13 +1421,13 @@ else print '
'.fieldLabel('Capital','capital').'
'.$form->editfieldkey('Capital', 'capital', '', $object, 0).' '; print ''.$langs->trans("Currency".$conf->currency).'
'.fieldLabel('DefaultLang','default_lang').''."\n"; + print '
'.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; print $formadmin->select_language(($object->default_lang?$object->default_lang:$conf->global->MAIN_LANG_DEFAULT),'default_lang',0,0,1,0,0,'maxwidth200onsmartphone'); print '
'.fieldLabel('AllocateCommercial','commercial_id').''.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, '', 0, '', '', 0, 1); // Note: If user has no right to "see all thirdparties", we for selection of sale representative to him, so after creation he can see the record. @@ -1440,7 +1446,7 @@ else if (!empty($conf->incoterm->enabled)) { print '
'.fieldLabel('IncotermLabel','incoterm_id').''.$form->editfieldkey('IncotermLabel', 'incoterm_id', '', $object, 0).''; print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:'')); print '
' . fieldLabel('CustomersCategoriesShort', 'custcats') . ''; + print '
' . $form->editfieldkey('CustomersCategoriesShort', 'custcats', '', $object, 0) . ''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, 'parent', null, null, 1); print $form->multiselectarray('custcats', $cate_arbo, GETPOST('custcats', 'array'), null, null, null, null, "90%"); print "
' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . ''; + print '
' . $form->editfieldkey('SuppliersCategoriesShort', 'suppcats', '', $object, 0) . ''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, 'parent', null, null, 1); print $form->multiselectarray('suppcats', $cate_arbo, GETPOST('suppcats', 'array'), null, null, null, null, "90%"); print "
'.fieldLabel('Currency','multicurrency_code').''.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).''; print $form->selectMultiCurrency(($object->multicurrency_code ? $object->multicurrency_code : $conf->currency), 'multicurrency_code', 1); print '
'.fieldLabel('Logo','photoinput').''.$form->editfieldkey('Logo', 'photoinput', '', $object, 0).''; print ''; print '
'.fieldLabel('ThirdPartyName','name',1).'
'.$form->editfieldkey('ThirdPartyName', 'name', '', $object, 0, 'string', '', 1).'
'.fieldLabel('Prefix','prefix').''; + print '
'.$form->editfieldkey('Prefix', 'prefix', '', $object, 0).''; // It does not change the prefix mode using the auto numbering prefix if (($prefixCustomerIsUsed || $prefixSupplierIsUsed) && $object->prefix_comm) { @@ -1767,14 +1768,14 @@ else } // Prospect/Customer - print '
'.fieldLabel('ProspectCustomer','customerprospect',1).'
'.$form->editfieldkey('ProspectCustomer', 'customerprospect', '', $object, 0, 'string', '', 1).''.fieldLabel('CustomerCode','customer_code').''; + print ''.$form->editfieldkey('CustomerCode', 'customer_code', '', $object, 0).''; print ''; - print ''; print ''; + print ''; print ''; } // Status - print ''; // Address - print ''; + print ''; print ''; // Zip / Town - print ''; // Country - print ''; @@ -1878,11 +1879,11 @@ else { if(!empty($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT) && ($conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 1 || $conf->global->MAIN_SHOW_REGION_IN_STATE_SELECT == 2)) { - print ''; + print ''; print ''; - print ''; + print ''; print ''; if (! empty($conf->socialnetworks->enabled)) @@ -1900,27 +1901,27 @@ else // Skype if (! empty($conf->global->SOCIALNETWORKS_SKYPE)) { - print ''; + print ''; print ''; } // Twitter if (! empty($conf->global->SOCIALNETWORKS_TWITTER)) { - print ''; + print ''; print ''; } // Facebook if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK)) { - print ''; + print ''; print ''; } } // Phone / Fax - print ''; + print ''; print ''; - print ''; + print ''; print ''; // Prof ids @@ -1935,12 +1936,8 @@ else if (($j % 2) == 0) print ''; $idprof_mandatory ='SOCIETE_IDPROF'.($i).'_MANDATORY'; - if (empty($conf->global->$idprof_mandatory) || ! $object->isACompany()) - print ''; if (($j % 2) == 1) print ''; $j++; @@ -1950,7 +1947,7 @@ else if ($j % 2 == 1) print ''; // VAT is used - print ''; @@ -1958,7 +1955,7 @@ else //TODO: Place into a function to control showing by country or study better option if($mysoc->localtax1_assuj=="1" && $mysoc->localtax2_assuj=="1") { - print ''; - print ''; + print ''; print ''; // Type - Size - print ''; - print ''; // Juridical type - print ''; // Capital - print ''; + print ''; print ''; // Assign a Name print ''; - print ''; + print ''; print ''; print ''; @@ -2077,7 +2074,7 @@ else if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) { // Customer - print ''; + print ''; print '"; // Supplier - print ''; + print ''; print ''; - print ''; + print ''; print ''; @@ -2124,9 +2121,9 @@ else // Webservices url/key if (!empty($conf->syncsupplierwebservices->enabled)) { - print ''; + print ''; print ''; - print ''; + print ''; print ''; } @@ -2134,7 +2131,7 @@ else if (!empty($conf->incoterm->enabled)) { print ''; - print ''; + print ''; print ''; @@ -2142,7 +2139,7 @@ else // Logo print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; From 546a353e58145c04454e29b17198f64fcfbdf646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 27 Oct 2018 15:16:01 +0200 Subject: [PATCH 067/307] remove fieldlabel and add fieldeditkey --- htdocs/expedition/shipment.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index 920b5508e59..bd520f5f9d2 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -551,17 +551,17 @@ if ($id > 0 || ! empty($ref)) if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency)) { // Multicurrency Amount HT - print ''; + print ''; print ''; print ''; // Multicurrency Amount VAT - print ''; + print ''; print ''; print ''; // Multicurrency Amount TTC - print ''; + print ''; print ''; print ''; } From 42a9abad56635612efc84e9cdbfef9f445a8ae4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 27 Oct 2018 17:45:29 +0200 Subject: [PATCH 068/307] remove fieldlabel and add fieldeditkey --- htdocs/compta/bank/ligne.php | 2 +- htdocs/compta/facture/card.php | 12 +++---- htdocs/compta/facture/prelevement.php | 7 ++-- htdocs/compta/salaries/card.php | 26 +++++++-------- htdocs/contact/card.php | 47 +++++++++++++-------------- htdocs/datapolicy/admin/setupmail.php | 5 +-- htdocs/hrm/establishment/card.php | 36 ++++++++++++-------- htdocs/supplier_proposal/card.php | 15 ++++----- htdocs/user/card.php | 26 +++++++-------- 9 files changed, 90 insertions(+), 86 deletions(-) diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 1587c5c10e8..2d4ac69c288 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -596,7 +596,7 @@ if ($result) $langs->load('categories'); // Bank line - print '"; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 050f8786c3a..ab654ad2e7c 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3196,7 +3196,7 @@ if ($action == 'create') if (! empty($conf->multicurrency->enabled)) { print ''; - print ''; + print ''; print ''; @@ -3899,7 +3899,7 @@ else if ($id > 0 || ! empty($ref)) print ''; print '
'; if ((!$object->code_client || $object->code_client == -1) && $modCodeClient->code_auto) @@ -1805,13 +1806,13 @@ else || (! empty($conf->supplier_proposal->enabled) && ! empty($user->rights->supplier_proposal->lire))) { print '
'.fieldLabel('Supplier','fournisseur',1).''; + print ''.$form->editfieldkey('Supplier', 'fournisseur', '', $object, 0, 'string', '', 1).''; print $form->selectyesno("fournisseur",$object->fournisseur,1); print ''; if (! empty($conf->fournisseur->enabled) && ! empty($user->rights->fournisseur->lire)) { - print fieldLabel('SupplierCode','supplier_code'); + print $form->editfieldkey('SupplierCode', 'supplier_code', '', $object, 0); } print ''; if (! empty($conf->fournisseur->enabled) && ! empty($user->rights->fournisseur->lire)) @@ -1844,31 +1845,31 @@ else // Barcode if (! empty($conf->barcode->enabled)) { - print '
'.fieldLabel('Gencod','barcode').'
'.$form->editfieldkey('Gencod', 'barcode', '', $object, 0).''; print '
'.fieldLabel('Status','status').''; + print '
'.$form->editfieldkey('Status', 'status', '', $object, 0).''; print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'),'1'=>$langs->trans('InActivity')),$object->status); print '
'.fieldLabel('Address','address').'
'.$form->editfieldkey('Address', 'address', '', $object, 0).'
'.fieldLabel('Zip','zipcode').''; + print '
'.$form->editfieldkey('Zip', 'zipcode', '', $object, 0).''; print $formcompany->select_ziptown($object->zip, 'zipcode', array('town', 'selectcountry_id', 'state_id'), 0, 0, '', 'maxwidth50onsmartphone'); - print ''.fieldLabel('Town','town').''; + print ''.$form->editfieldkey('Town', 'town', '', $object, 0).''; print $formcompany->select_ziptown($object->town, 'town', array('zipcode', 'selectcountry_id', 'state_id')); print '
'.fieldLabel('Country','selectcounty_id').''; + print '
'.$form->editfieldkey('Country', 'selectcounty_id', '', $object, 0).''; print $form->select_country((GETPOST('country_id')!=''?GETPOST('country_id'):$object->country_id),'country_id'); if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); print '
'.fieldLabel('Region-State','state_id').''; + print '
'.$form->editfieldkey('Region-State', 'state_id', '', $object, 0).''; } else { - print '
'.fieldLabel('State','state_id').''; + print '
'.$form->editfieldkey('State', 'state_id', '', $object, 0).''; } print $formcompany->select_state($object->state_id,$object->country_code); @@ -1890,9 +1891,9 @@ else } // EMail / Web - print '
'.fieldLabel('EMail','email',(! empty($conf->global->SOCIETE_EMAIL_MANDATORY))).'
'.$form->editfieldkey('EMail', 'email', '', $object, 0, 'string', '', (! empty($conf->global->SOCIETE_EMAIL_MANDATORY))).'
'.fieldLabel('Web','url').'
'.$form->editfieldkey('Web', 'url', '', $object, 0).'
'.fieldLabel('Skype','skype').'
'.$form->editfieldkey('Skype', 'skype', '', $object, 0).'
'.fieldLabel('Twitter','twitter').'
'.$form->editfieldkey('Twitter', 'twitter', '', $object, 0).'
'.fieldLabel('Facebook','facebook').'
'.$form->editfieldkey('Facebook', 'facebook', '', $object, 0).'
'.fieldLabel('Phone','phone').'
'.$form->editfieldkey('Phone', 'phone', '', $object, 0).''.fieldLabel('Fax','fax').''.$form->editfieldkey('Fax', 'fax', '', $object, 0).'
'.fieldLabel($idprof,$key).''; - else - print ''.fieldLabel($idprof,$key).''; - - print $formcompany->get_input_id_prof($i,$key,$object->$key,$object->country_code); + print ''.$form->editfieldkey($idprof, $key, '', $object, 0, 'string', '', ! (empty($conf->global->$idprof_mandatory) || ! $object->isACompany())).''; + print $formcompany->get_input_id_prof($i, $key, $object->$key, $object->country_code); print '
'.fieldLabel('VATIsUsed','assujtva_value').''; + print '
'.$form->editfieldkey('VATIsUsed', 'assujtva_value', '', $object, 0).''; print $form->selectyesno('assujtva_value',$object->tva_assuj,1); print '
'.fieldLabel($langs->transcountry("LocalTax1IsUsed",$mysoc->country_code),'localtax1assuj_value').''; + print '
'.$form->editfieldkey($langs->transcountry("LocalTax1IsUsed",$mysoc->country_code), 'localtax1assuj_value', '', $object, 0).''; print $form->selectyesno('localtax1assuj_value',$object->localtax1_assuj,1); if(! isOnlyOneLocalTax(1)) { @@ -1968,7 +1965,7 @@ else } print ''.fieldLabel($langs->transcountry("LocalTax2IsUsed",$mysoc->country_code),'localtax2assuj_value').''; + print ''.$form->editfieldkey($langs->transcountry("LocalTax2IsUsed",$mysoc->country_code), 'localtax2assuj_value', '', $object, 0).''; print $form->selectyesno('localtax2assuj_value',$object->localtax2_assuj,1); if (! isOnlyOneLocalTax(2)) { @@ -1980,7 +1977,7 @@ else } elseif($mysoc->localtax1_assuj=="1" && $mysoc->localtax2_assuj!="1") { - print '
'.fieldLabel($langs->transcountry("LocalTax1IsUsed",$mysoc->country_code),'localtax1assuj_value').''; + print '
'.$form->editfieldkey($langs->transcountry("LocalTax1IsUsed",$mysoc->country_code), 'localtax1assuj_value', '', $object, 0).''; print $form->selectyesno('localtax1assuj_value',$object->localtax1_assuj,1); if(! isOnlyOneLocalTax(1)) { @@ -1992,7 +1989,7 @@ else } elseif($mysoc->localtax2_assuj=="1" && $mysoc->localtax1_assuj!="1") { - print '
'.fieldLabel($langs->transcountry("LocalTax2IsUsed",$mysoc->country_code),'localtax2assuj_value').''; + print '
'.$form->editfieldkey($langs->transcountry("LocalTax2IsUsed",$mysoc->country_code), 'localtax2assuj_value', '', $object, 0).''; print $form->selectyesno('localtax2assuj_value',$object->localtax2_assuj,1); if(! isOnlyOneLocalTax(2)) { @@ -2004,7 +2001,7 @@ else } // VAT Code - print '
'.fieldLabel('VATIntra','intra_vat').'
'.$form->editfieldkey('VATIntra', 'intra_vat', '', $object, 0).''; $s =''; @@ -2034,29 +2031,29 @@ else print '
'.fieldLabel('ThirdPartyType','typent_id').''; + print '
'.$form->editfieldkey('ThirdPartyType', 'typent_id', '', $object, 0).''; print $form->selectarray("typent_id",$formcompany->typent_array(0), $object->typent_id, 0, 0, 0, '', 0, 0, 0, (empty($conf->global->SOCIETE_SORT_ON_TYPEENT)?'ASC':$conf->global->SOCIETE_SORT_ON_TYPEENT)); if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); print ''.fieldLabel('Staff','effectif_id').''; + print ''.$form->editfieldkey('Staff', 'effectif_id', '', $object, 0).''; print $form->selectarray("effectif_id",$formcompany->effectif_array(0), $object->effectif_id); if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); print '
'.fieldLabel('JuridicalStatus','forme_juridique_code').''; + print '
'.$form->editfieldkey('JuridicalStatus', 'forme_juridique_code', '', $object, 0).''; print $formcompany->select_juridicalstatus($object->forme_juridique_code, $object->country_code, '', 'forme_juridique_code'); print '
'.fieldLabel('Capital','capital').'
'.$form->editfieldkey('Capital', 'capital', '', $object, 0).' '.$langs->trans("Currency".$conf->currency).'
'.fieldLabel('AllocateCommercial','commercial_id').''.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, '', 0, '', '', 0, 1); $arrayselected = GETPOST('commercial', 'array'); @@ -2067,7 +2064,7 @@ else // Default language if (! empty($conf->global->MAIN_MULTILANGS)) { - print '
'.fieldLabel('DefaultLang','default_lang').''."\n"; + print '
'.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; print $formadmin->select_language($object->default_lang,'default_lang',0,0,1); print '
' . fieldLabel('CustomersCategoriesShort', 'custcats') . '
' . $form->editfieldkey('CustomersCategoriesShort', 'custcats', '', $object, 0) . ''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, null, null, null, 1); $c = new Categorie($db); @@ -2090,7 +2087,7 @@ else print "
' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '
' . $form->editfieldkey('SuppliersCategoriesShort', 'suppcats', '', $object, 0) . ''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, null, null, null, 1); $c = new Categorie($db); @@ -2107,7 +2104,7 @@ else if (! empty($conf->multicurrency->enabled)) { print '
'.fieldLabel('Currency','multicurrency_code').''.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).''; print $form->selectMultiCurrency(($object->multicurrency_code ? $object->multicurrency_code : $conf->currency), 'multicurrency_code', 1); print '
'.fieldLabel('WebServiceURL','webservices_url').'
'.$form->editfieldkey('WebServiceURL', 'webservices_url', '', $object, 0).''.fieldLabel('WebServiceKey','webservices_key').''.$form->editfieldkey('WebServiceKey', 'webservices_key', '', $object, 0).'
'.fieldLabel('IncotermLabel','incoterm_id').''.$form->editfieldkey('IncotermLabel', 'incoterm_id', '', $object, 0).''; print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:'')); print '
'.fieldLabel('Logo','photoinput').''.$form->editfieldkey('Logo', 'photoinput', '', $object, 0).''; if ($object->logo) print $form->showphoto('societe',$object); $caneditfield=1; @@ -2530,7 +2527,7 @@ else if (! empty($conf->multicurrency->enabled)) { print '
'.fieldLabel('Currency','multicurrency_code').''.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).''; print !empty($object->multicurrency_code) ? currency_name($object->multicurrency_code,1) : ''; print '
' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . '
' . $form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0) . '' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . '
' . $form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0) . '' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . '
' . $form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0) . '' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
' . fieldLabel('RubriquesTransactions', 'custcats') . ''; + print '
' . $form->editfieldkey('RubriquesTransactions', 'custcats', '', $object, 0) . ''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_BANK_LINE, null, 'parent', null, null, 1); print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, null, null, null, null, "90%"); print "
'.fieldLabel('Currency','multicurrency_code').''.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).''; print $form->selectMultiCurrency($currency_code, 'multicurrency_code'); print '
'; print ''; if ($action != 'editmulticurrencycode' && ! empty($object->brouillon)) print ''; @@ -3915,7 +3915,7 @@ else if ($id > 0 || ! empty($ref)) print ''; print '
'; - print fieldLabel('Currency','multicurrency_code'); + print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0); print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
'; print ''; if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) print ''; @@ -4001,17 +4001,17 @@ else if ($id > 0 || ! empty($ref)) if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency)) { // Multicurrency Amount HT - print ''; + print ''; print ''; print ''; // Multicurrency Amount VAT - print ''; + print ''; print ''; print ''; // Multicurrency Amount TTC - print ''; + print ''; print ''; print ''; } diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index d7766268989..7c8ffb7d417 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -5,6 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2018 Frédéric France * * 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 @@ -402,17 +403,17 @@ if ($object->id > 0) if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency)) { // Multicurrency Amount HT - print ''; + print ''; print ''; print ''; // Multicurrency Amount VAT - print ''; + print ''; print ''; print ''; // Multicurrency Amount TTC - print ''; + print ''; print ''; print ''; } diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php index f50d940a51a..c67982ed9c5 100644 --- a/htdocs/compta/salaries/card.php +++ b/htdocs/compta/salaries/card.php @@ -1,8 +1,8 @@ - * Copyright (C) 2014 Laurent Destailleur - * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2015 Charlie BENKE +/* Copyright (C) 2011-2018 Alexandre Spangaro + * Copyright (C) 2014 Laurent Destailleur + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Charlie BENKE * Copyright (C) 2018 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -255,44 +255,44 @@ if ($action == 'create') // Date payment print ''; // Date value for bank print ''; // Employee print ''; // Label print ''; // Date start period print ''; // Date end period print ''; // Amount print ''; @@ -312,14 +312,14 @@ if ($action == 'create') if (! empty($conf->banque->enabled)) { print ''; } // Type payment print ''; diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index a43127c9a32..e995352c38d 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -227,7 +227,7 @@ if (empty($reshook)) $action = 'create'; } else { // Categories association - $contcats = GETPOST( 'contcats', 'array'); + $contcats = GETPOST('contcats', 'array'); $object->setCategories($contcats); } } @@ -383,10 +383,10 @@ if (empty($reshook)) // First we delete all categories association $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'categorie_contact'; $sql .= ' WHERE fk_socpeople = ' . $object->id; - $db->query( $sql ); + $db->query($sql); // Then we add the associated categories - $categories = GETPOST( 'contcats', 'array'); + $categories = GETPOST('contcats', 'array'); $object->setCategories($categories); $object->old_lastname=''; @@ -669,19 +669,19 @@ else // Skype if (! empty($conf->global->SOCIALNETWORKS_SKYPE)) { - print ''; + print ''; print ''; } // Twitter if (! empty($conf->global->SOCIALNETWORKS_TWITTER)) { - print ''; + print ''; print ''; } // Facebook if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK)) { - print ''; + print ''; print ''; } } @@ -694,10 +694,9 @@ else // Categories if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) { - print '"; } @@ -938,19 +937,19 @@ else // Skype if (! empty($conf->global->SOCIALNETWORKS_SKYPE)) { - print ''; + print ''; print ''; } // Twitter if (! empty($conf->global->SOCIALNETWORKS_TWITTER)) { - print ''; + print ''; print ''; } // Facebook if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK)) { - print ''; + print ''; print ''; } } @@ -980,16 +979,16 @@ else print ''; // Categories - if (!empty( $conf->categorie->enabled ) && !empty( $user->rights->categorie->lire )) { - print ''; + if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { + print ''; print '"; } @@ -1101,10 +1100,10 @@ else $password=$generated_password; // Create a form array - $formquestion=array( - array('label' => $langs->trans("LoginToCreate"), 'type' => 'text', 'name' => 'login', 'value' => $login), - array('label' => $langs->trans("Password"), 'type' => 'text', 'name' => 'password', 'value' => $password), - //array('label' => $form->textwithpicto($langs->trans("Type"),$langs->trans("InternalExternalDesc")), 'type' => 'select', 'name' => 'intern', 'default' => 1, 'values' => array(0=>$langs->trans('Internal'),1=>$langs->trans('External'))) + $formquestion = array( + array('label' => $langs->trans("LoginToCreate"), 'type' => 'text', 'name' => 'login', 'value' => $login), + array('label' => $langs->trans("Password"), 'type' => 'text', 'name' => 'password', 'value' => $password), + //array('label' => $form->textwithpicto($langs->trans("Type"),$langs->trans("InternalExternalDesc")), 'type' => 'select', 'name' => 'intern', 'default' => 1, 'values' => array(0=>$langs->trans('Internal'),1=>$langs->trans('External'))) ); $text=$langs->trans("ConfirmCreateContact").'
'; if (! empty($conf->societe->enabled)) @@ -1176,7 +1175,7 @@ else if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) { print ''; print ''; } diff --git a/htdocs/datapolicy/admin/setupmail.php b/htdocs/datapolicy/admin/setupmail.php index 214f673a15f..f50fa08d31c 100644 --- a/htdocs/datapolicy/admin/setupmail.php +++ b/htdocs/datapolicy/admin/setupmail.php @@ -91,9 +91,6 @@ $head = datapolicyAdminPrepareHead(); dol_fiche_head($head, 'settings', '', -1, "datapolicy@datapolicy"); - - - print "'."\n"; + } + print load_fiche_titre($langs->trans("DoPayment")); print ''; @@ -298,7 +312,12 @@ if ($action == 'create' || empty($action)) if ($sumpaid < $objp->total_ttc) { $namef = "amount_".$objp->id; - print ''; + $nameRemain = "remain_".$objp->id; // autofill remainder amount + if (!empty($conf->use_javascript_ajax)) // autofill remainder amount + print img_picto("Auto fill",'rightarrow', "class='AutoFillAmount' data-rowid='".$namef."' data-value='".($objp->total_ttc - $sumpaid)."'"); // autofill remainder amount + $remaintopay=$objp->total_ttc - $sumpaid; // autofill remainder amount + print ''; // autofill remainder amount + print ''; } else { From 6ab12b59119b4f665b91e4caaef535d815802f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 1 Dec 2018 00:26:51 +0100 Subject: [PATCH 107/307] Update llx_paiementfourn.sql --- htdocs/install/mysql/tables/llx_paiementfourn.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/install/mysql/tables/llx_paiementfourn.sql b/htdocs/install/mysql/tables/llx_paiementfourn.sql index 0e9b1885c97..511febcf1fa 100644 --- a/htdocs/install/mysql/tables/llx_paiementfourn.sql +++ b/htdocs/install/mysql/tables/llx_paiementfourn.sql @@ -28,6 +28,7 @@ create table llx_paiementfourn amount real DEFAULT 0, -- montant multicurrency_amount double(24,8) DEFAULT 0, -- multicurrency amount fk_user_author integer, -- auteur + fk_user_modif integer, fk_paiement integer NOT NULL, -- moyen de paiement num_paiement varchar(50), -- numero de paiement (cheque) note text, From 0270da7d8c8a6d95936ff5ca96b0906f13e27888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 1 Dec 2018 00:28:58 +0100 Subject: [PATCH 108/307] Update 5.0.0-6.0.0.sql --- htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 06d006230a0..740cba9d914 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -317,6 +317,7 @@ ALTER TABLE llx_accounting_bookkeeping MODIFY COLUMN multicurrency_amount double ALTER TABLE llx_paiementfourn ADD COLUMN model_pdf varchar(255); +ALTER TABLE llx_paiementfourn ADD COLUMN fk_user_modif integer AFTER fk_user_author; insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_CREATE','Expense report created','Executed when an expense report is created','expensereport',201); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',202); From 085101376c4491bee45fa933777514a844740695 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 1 Dec 2018 00:41:46 +0100 Subject: [PATCH 109/307] Introduce standard sql date format filter refactoring standard sql filter for date --- htdocs/core/lib/date.lib.php | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 7ad40349589..b75de970b19 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -3,7 +3,8 @@ * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2011-2015 Juanjo Menent * Copyright (C) 2017 Ferran Marcet - * + * Copyright (C) 2018 Charlene Benke +* * 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 @@ -274,6 +275,36 @@ function convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengt } +/** + * générate standard filter date + * + * @param string $datefield fields where apply sql date filter + * @param int $day_date day date + * @param int $month_date month date + * @param int $year_date year date + + * @return string $sqldate sql part of date + */ + +function dol_sql_datefilter($datefield, $day_date, $month_date, $year_date) { + global $db; + $sqldate="" + if ($month_date > 0) { + if ($year_date > 0 && empty($day_date)) { + $sqldate.= " AND ".$datefield." BETWEEN '".$db->idate(dol_get_first_day($year_date, $month_date, false)); + $sqldate.= "' AND '".$db->idate(dol_get_last_day($year_date, $month_date, false))."'"; + } else if ($year_date > 0 && ! empty($day_date)) { + $sqldate.= " AND ".$datefield." BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_date, $day_date, $year_date)); + $sqldate.= "' AND '".$db->idate(dol_mktime(23, 59, 59, $month_date, $day_date, $year_date))."'"; + } else + $sqldate.= " AND date_format( ".$datefield.", '%m') = '".$db->escape($month_date)."'"; + } else if ($year_date > 0){ + $sqldate.= " AND ".$datefield." BETWEEN '".$db->idate(dol_get_first_day($year_date, 1, false)); + $sqldate.= "' AND '".$db->idate(dol_get_last_day($year_date, 12, false))."'"; + } + return $sqldate; +} + /** * Convert a string date into a GM Timestamps date * Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not supported. If parameter gm is 1, we will use no TZ, if not we will use TZ of server, not the one inside string. From 19e4698488fba83253a7477c0045de259a8aa0c6 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 1 Dec 2018 10:32:37 +0100 Subject: [PATCH 110/307] Update date.lib.php --- htdocs/core/lib/date.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index b75de970b19..e9dcc91ced7 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -288,7 +288,7 @@ function convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengt function dol_sql_datefilter($datefield, $day_date, $month_date, $year_date) { global $db; - $sqldate="" + $sqldate=""; if ($month_date > 0) { if ($year_date > 0 && empty($day_date)) { $sqldate.= " AND ".$datefield." BETWEEN '".$db->idate(dol_get_first_day($year_date, $month_date, false)); From 60d0a5efabe5e26786f959ffcc70081c7a067941 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 1 Dec 2018 14:44:34 +0100 Subject: [PATCH 111/307] massfilesarea feature for plugin modules --- htdocs/core/lib/files.lib.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 1bca14827e6..725cbefabbb 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2807,6 +2807,19 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_output.'/'.$fuser->id.'/'.$original_file; } + else if (preg_match('/^massfilesarea_([a-z]+)$/i', $modulepart, $reg)) + { + if (empty($conf->{$reg[1]}->dir_output)) // modulepart not supported + { + dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + exit; + } + if ($fuser->rights->{$reg[1]}->{$lire} || preg_match('/^specimen/i', $original_file)) + { + $accessallowed=1; + } + $original_file=$conf->{$reg[1]}->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + } else { if (empty($conf->$modulepart->dir_output)) // modulepart not supported From d9283722394bd086353cfd82468a9f8051136959 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Sat, 1 Dec 2018 14:51:22 +0100 Subject: [PATCH 112/307] fix https://scrutinizer-ci.com/g/Dolibarr/dolibarr/issues/develop/files/htdocs/commande/class/commande.class.php?selectedAuthors%5B0%5D=florian.henry%40atm-consulting.fr&orderField=path&order=asc&honorSelectedPaths=0 --- htdocs/commande/class/commande.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 3dc168f14c5..5f6ac9752cc 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -4021,9 +4021,9 @@ class OrderLine extends CommonOrderLine * @param int $notrigger 0=launch triggers after, 1=disable triggers * @return int <0 si ko, >0 si ok */ - function delete($user=null, $notrigger=0) + function delete(User $user, $notrigger=0) { - global $conf, $user, $langs; + global $conf, $langs; $error=0; From f94f7e15ca92ca59c7d23605436a0ac05eef733e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Dec 2018 15:07:55 +0100 Subject: [PATCH 113/307] Update date.lib.php --- htdocs/core/lib/date.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index e9dcc91ced7..253b2814977 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -286,7 +286,7 @@ function convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengt * @return string $sqldate sql part of date */ -function dol_sql_datefilter($datefield, $day_date, $month_date, $year_date) { +function dolSqlDatefilter($datefield, $day_date, $month_date, $year_date) { global $db; $sqldate=""; if ($month_date > 0) { From dacc959937f44f1c8adecf7bd58b0acd68e286a6 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Sat, 1 Dec 2018 15:18:51 +0100 Subject: [PATCH 114/307] fix https://scrutinizer-ci.com/g/Dolibarr/dolibarr/issues/develop/files/htdocs/core/class/comment.class.php?selectedAuthors%5B0%5D=florian.henry%40atm-consulting.fr&orderField=path&order=asc&honorSelectedPaths=0 --- htdocs/core/class/comment.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/comment.class.php b/htdocs/core/class/comment.class.php index b731eb77169..332f7e115ef 100644 --- a/htdocs/core/class/comment.class.php +++ b/htdocs/core/class/comment.class.php @@ -357,7 +357,7 @@ class Comment extends CommonObject } $db->free($resql); } else { - $error++; $this->errors[]="Error ".$this->db->lasterror(); + $this->errors[]="Error ".$this->db->lasterror(); return -1; } } From faf7ea345fbc3b37a9212b47725685b87a80813e Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Sat, 1 Dec 2018 15:23:46 +0100 Subject: [PATCH 115/307] fix https://scrutinizer-ci.com/g/Dolibarr/dolibarr/issues/develop/files/htdocs/core/class/commonobject.class.php?selectedAuthors%5B0%5D=florian.henry%40atm-consulting.fr&orderField=path&order=asc&honorSelectedPaths=0 --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 307923e9bef..a274047f54f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6114,13 +6114,13 @@ abstract class CommonObject { $value_arr=explode(',',$value); $value=''; - if (is_array($value_arr)) + if (is_array($value_arr) && count($value_arr)>0) { foreach ($value_arr as $keyval=>$valueval) { $toprint[]='
  • '.$param['options'][$valueval].'
  • '; } + $value='
      '.implode(' ', $toprint).'
    '; } - $value='
      '.implode(' ', $toprint).'
    '; } elseif ($type == 'chkbxlst') { From b9046b91745498a9e9575b92c2ad1f2a76f11ed4 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Sat, 1 Dec 2018 15:42:07 +0100 Subject: [PATCH 116/307] fix https://scrutinizer-ci.com/g/Dolibarr/dolibarr/issues/develop/files/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php?selectedAuthors%5B0%5D=florian.henry%40atm-consulting.fr&orderField=path&order=asc&honorSelectedPaths=0 --- .../doc/doc_generic_project_odt.modules.php | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php index 76aa73e960e..6292008c54d 100644 --- a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php @@ -164,27 +164,27 @@ class doc_generic_project_odt extends ModelePDFProjects * @param Translate $outputlangs Lang object to use for output * @return array Return a substitution array */ - function get_substitutionarray_tasks($task,$outputlangs) + function get_substitutionarray_tasks(Task $task,$outputlangs) { // phpcs:enable global $conf; $resarray = array( - 'task_ref'=>$task->ref, - 'task_fk_project'=>$task->fk_project, - 'task_projectref'=>$task->projectref, - 'task_projectlabel'=>$task->projectlabel, - 'task_label'=>$task->label, - 'task_description'=>$task->description, - 'task_fk_parent'=>$task->fk_parent, - 'task_duration'=>$task->duration, - 'task_duration_hour'=>convertSecondToTime($task->duration,'all'), - 'task_progress'=>$task->progress, - 'task_public'=>$task->public, - 'task_date_start'=>dol_print_date($task->date_start,'day'), - 'task_date_end'=>dol_print_date($task->date_end,'day'), - 'task_note_private'=>$task->note_private, - 'task_note_public'=>$task->note_public + 'task_ref'=>$task->ref, + 'task_fk_project'=>$task->fk_project, + 'task_projectref'=>$task->projectref, + 'task_projectlabel'=>$task->projectlabel, + 'task_label'=>$task->label, + 'task_description'=>$task->description, + 'task_fk_parent'=>$task->fk_parent, + 'task_duration'=>$task->duration, + 'task_duration_hour'=>convertSecondToTime($task->duration,'all'), + 'task_progress'=>$task->progress, + 'task_public'=>$task->public, + 'task_date_start'=>dol_print_date($task->date_start,'day'), + 'task_date_end'=>dol_print_date($task->date_end,'day'), + 'task_note_private'=>$task->note_private, + 'task_note_public'=>$task->note_public ); require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; @@ -750,6 +750,7 @@ class doc_generic_project_odt extends ModelePDFProjects $num = $this->db->num_rows($resql); $i = 0; $tasks = array(); + $row=array(); $listlinestasktime = $listlines->__get('taskstimes'); if (empty($num)) { $row['rowid']=''; @@ -1064,7 +1065,7 @@ class doc_generic_project_odt extends ModelePDFProjects 'title' => "ListSocialContributionAssociatedProject", 'class' => 'ChargeSociales', 'table' => 'chargesociales', - 'urlnew' => DOL_URL_ROOT . '/compta/sociales/card.php?action=create&projectid=' . $id, + 'urlnew' => DOL_URL_ROOT . '/compta/sociales/card.php?action=create&projectid=' . $object->id, 'test' => $conf->tax->enabled && $user->rights->tax->charges->lire ), 'stock_mouvement' => array( From c422904b990cb329276a72e430c471a658c782aa Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Sat, 1 Dec 2018 16:51:40 +0100 Subject: [PATCH 117/307] fix #9964 --- htdocs/commande/list.php | 4 ++-- htdocs/core/class/extrafields.class.php | 5 ++++- .../core/tpl/extrafields_list_search_sql.tpl.php | 16 ++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 4841e9be410..bbdf59a295c 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -468,8 +468,8 @@ if ($resql) print ''; print ''; print ''; - - + + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, $newcardbutton, '', $limit); $topicmail="SendOrderRef"; diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 1840f62ca5d..ee87426ddcb 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1927,7 +1927,10 @@ class ExtraFields // Get extra fields foreach ($extralabels as $key => $value) { - $key_type = $this->attributes[$object->table_element]['type'][$key]; + $key_type=$this->attribute_type[$key]; + if (! empty($object->table_element)) { + $key_type=$this->attributes[$extrafieldsobjectkey]['type'][$key]; + } if (in_array($key_type,array('date','datetime'))) { diff --git a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php index a8e43d6429f..8492160c185 100644 --- a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php @@ -17,13 +17,17 @@ if (! empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_ $crit=$val; $tmpkey=preg_replace('/search_options_/','',$key); $typ=$extrafields->attributes[$extrafieldsobjectkey]['type'][$tmpkey]; - - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if (in_array($typ, array('chkbxlst','checkbox'))) $mode_search=4; // Search on a multiselect field with sql type = text - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) + if ($crit != '' && in_array($typ, array('date', 'datetime', 'timestamp'))) { + $sql .= " AND ef.".$tmpkey." = '".$db->idate($crit)."'"; + } + elseif ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) + { + $mode_search=0; + if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric + if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int + if (in_array($typ, array('chkbxlst','checkbox'))) $mode_search=4; // Search on a multiselect field with sql type = text + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); } } From 5e2f3a53c9ab309d35f4a3179c30be7ef5abc374 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 1 Dec 2018 19:39:00 +0100 Subject: [PATCH 118/307] Fix expense report in ecm auto dir --- htdocs/core/ajax/ajaxdirpreview.php | 4 +++- htdocs/core/class/html.formfile.class.php | 8 +++++++- htdocs/ecm/index_auto.php | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php index 4d72b576429..04c16c75fe0 100644 --- a/htdocs/core/ajax/ajaxdirpreview.php +++ b/htdocs/core/ajax/ajaxdirpreview.php @@ -172,7 +172,7 @@ if ($type == 'directory') $sorting = (strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC); // Right area. If module is defined here, we are in automatic ecm. - $automodules = array('company', 'invoice', 'invoice_supplier', 'propal', 'supplier_proposal', 'order', 'order_supplier', 'contract', 'product', 'tax', 'project', 'fichinter', 'user', 'expensereport'); + $automodules = array('company', 'invoice', 'invoice_supplier', 'propal', 'supplier_proposal', 'order', 'order_supplier', 'contract', 'product', 'tax', 'project', 'fichinter', 'user', 'expensereport', 'holiday'); // TODO change for multicompany sharing // Auto area for suppliers invoices @@ -203,6 +203,8 @@ if ($type == 'directory') else if ($module == 'user') $upload_dir = $conf->user->dir_output; // Auto area for expense report else if ($module == 'expensereport') $upload_dir = $conf->expensereport->dir_output; + // Auto area for holiday + else if ($module == 'holiday') $upload_dir = $conf->holiday->dir_output; // Automatic list if (in_array($module, $automodules)) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 9219d242151..09e70d4201a 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1392,6 +1392,11 @@ class FormFile include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; $object_instance=new ExpenseReport($this->db); } + else if ($modulepart == 'holiday') + { + include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; + $object_instance=new Holiday($this->db); + } foreach($filearray as $key => $file) { @@ -1421,7 +1426,8 @@ class FormFile if ($modulepart == 'project') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:'');} if ($modulepart == 'fichinter') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:'');} if ($modulepart == 'user') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:'');} - if ($modulepart == 'expensereport') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:'');} + if ($modulepart == 'expensereport') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $ref=(isset($reg[1])?$reg[1]:'');} + if ($modulepart == 'holiday') { preg_match('/(.*)\/[^\/]+$/',$relativefile,$reg); $id=(isset($reg[1])?$reg[1]:'');} if (! $id && ! $ref) continue; $found=0; diff --git a/htdocs/ecm/index_auto.php b/htdocs/ecm/index_auto.php index 19c607b1612..3ff4ce64887 100644 --- a/htdocs/ecm/index_auto.php +++ b/htdocs/ecm/index_auto.php @@ -331,6 +331,7 @@ if (! empty($conf->global->ECM_AUTO_TREE_ENABLED)) if (! empty($conf->projet->enabled)) { $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'project', 'test'=>$conf->projet->enabled, 'label'=>$langs->trans("Projects"), 'desc'=>$langs->trans("ECMDocsByProjects")); } if (! empty($conf->ficheinter->enabled)) { $langs->load("interventions"); $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'fichinter', 'test'=>$conf->ficheinter->enabled, 'label'=>$langs->trans("Interventions"), 'desc'=>$langs->trans("ECMDocsByInterventions")); } if (! empty($conf->expensereport->enabled)) { $langs->load("trips"); $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'expensereport', 'test'=>$conf->expensereport->enabled, 'label'=>$langs->trans("ExpenseReports"), 'desc'=>$langs->trans("ECMDocsByExpenseReports")); } + if (! empty($conf->holiday->enabled)) { $langs->load("holiday"); $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'holiday', 'test'=>$conf->holiday->enabled, 'label'=>$langs->trans("Holidays"), 'desc'=>$langs->trans("ECMDocsByHolidays")); } $rowspan++; $sectionauto[]=array('level'=>1, 'module'=>'user', 'test'=>1, 'label'=>$langs->trans("Users"), 'desc'=>$langs->trans("ECMDocsByUsers")); } From 658e295a94dd2335c120149d620ec1e453198854 Mon Sep 17 00:00:00 2001 From: atm-ph Date: Sat, 1 Dec 2018 20:26:17 +0100 Subject: [PATCH 119/307] New bash to convert snake case function into camel case --- dev/tools/snakeCaseToCamelCase.sh | 130 ++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100755 dev/tools/snakeCaseToCamelCase.sh diff --git a/dev/tools/snakeCaseToCamelCase.sh b/dev/tools/snakeCaseToCamelCase.sh new file mode 100755 index 00000000000..fa8a76cc613 --- /dev/null +++ b/dev/tools/snakeCaseToCamelCase.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +## Need "rpl" package +RPL_INSTALLED=$(dpkg -s rpl) +if [[ -z ${RPL_INSTALLED} ]]; then + echo "This bash need rpl command, you can install it with: sudo apt install rpl" +fi + +DIR_HTDOCS=$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../htdocs" >/dev/null && pwd ) + +PATTERN="" +if [[ -f $1 ]]; then + TFile=("$1") # specific file +elif [[ -n $1 ]]; then + PATTERN=$1 # name of a particular file or pattern (ex: societe.class.php) +else + PATTERN="*.class.php" # *.lib.php +fi + +if [[ -n ${PATTERN} ]]; then + TCLASSFILE=$(find "${DIR_HTDOCS}" -name "${PATTERN}" | grep -v "/custom/" | grep -v "/includes/" | grep -v -F -f "${DIR_HTDOCS}/../.gitignore") + TFile=() + I=0 + for f in ${TCLASSFILE}; do + TFile[${I}]="${f}" + ((I++)) + done +fi + + +REGEX_FNC_W='^([[:blank:]]*)(public|private|protected)?[ \t]*(static)?[ \t]*[^\$\(]function[ \t]*([a-zA-Z0-9\-\_]*)[\(](.*)[\)][ \t]*([\{]?)$' +INDENT=" " + +for f in ${TFile[@]}; do +# echo ${f} + + IFS=$'\n' + TLine=($(cat "${f}" | grep -E "${REGEX_FNC_W}")) + + for LINE in ${TLine[@]}; do + + if [[ ${LINE} =~ ^${REGEX_FNC_W}$ ]]; then + FIRST_INDENT=${BASH_REMATCH[1]} # seem not work + FNC_TYPE=${BASH_REMATCH[2]} + STATIC=${BASH_REMATCH[3]} + FNC_NAME=${BASH_REMATCH[4]} + PARAMETERS_ORIGIN=${BASH_REMATCH[5]} + BRACKET_END=${BASH_REMATCH[6]} + + if [[ ${LINE} =~ ^([[:blank:]]*) ]]; then # but this seems work to get indentation + FIRST_INDENT=${BASH_REMATCH[1]} + fi + + [[ ${FNC_NAME} =~ ^__ ]] && continue # skip magic function + + CAMEL_CASE=$(echo "${FNC_NAME}" | sed -r 's/(_)([a-zA-Z0-9])/\U\2/g') + [[ ${CAMEL_CASE} = ${FNC_NAME} ]] && continue # skip if no difference + +#echo A: ${#FIRST_INDENT} +#printf "${FIRST_INDENT}TEST INDENT\n" +#echo B: ${FNC_TYPE} +#echo C: ${STATIC} +#echo D: ${FNC_NAME} +#echo D: ${CAMEL_CASE} +#echo E: ${PARAMETERS_ORIGIN} +#echo F: ${BRACKET_END} +#exit + + [[ -n $(cat "${f}" | grep -i "function[[:blank:]]*${CAMEL_CASE}") ]] && continue # skip if already exists + + TCommentLine=() + J=1 + while :; do + COMMENT=$(cat ${f} | grep -B ${J} ${LINE/\$/\\$} | head -n1 | grep -P '^[\t\ ]*(/\*\*|\*[^/]?|\*/)') + if [[ -n ${COMMENT} ]]; then + TCommentLine[${J}]="${COMMENT}" + ((J++)) + else + break + fi + done + + COMMENT_ORIGIN="" + COMMENT_ORIGIN_WITH_DEPRECATED="" + COMMENT_DUPLICATE="" + if [[ ${#TCommentLine[@]} -gt 0 ]]; then + for (( idx=${#TCommentLine[@]} ; idx>0 ; idx-- )) ; do + COMMENT_ORIGIN="${COMMENT_ORIGIN}\n${TCommentLine[idx]}" + done + + COMMENT_DUPLICATE=${COMMENT_ORIGIN} + + COMMENT_ORIGIN_WITH_DEPRECATED=$(echo "${COMMENT_ORIGIN%?} @deprecated\n${FIRST_INDENT} * @see ${CAMEL_CASE}\n${FIRST_INDENT} */") + fi + + PARAMETERS=${PARAMETERS_ORIGIN} + TParam=() + I=0 + while [[ ${PARAMETERS} =~ (\$[a-zA-Z0-9\_\-]+) ]]; do + TParam[${I}]=${BASH_REMATCH[1]} + PARAMETERS=${PARAMETERS#*"${BASH_REMATCH[1]}"} + ((I++)) + done + + PARAMS_STR=$(printf ", %s" "${TParam[@]}") + PARAMS_STR=${PARAMS_STR:2} + + REPLACE=${LINE} + [[ -z ${BRACKET_END} ]] && REPLACE="${LINE}\n${FIRST_INDENT}{\n${FIRST_INDENT}${INDENT}" || REPLACE="${LINE}\n${FIRST_INDENT}${INDENT}" + [[ -n ${STATIC} ]] && REPLACE="${REPLACE}self::" || REPLACE="${REPLACE}\$this->" + REPLACE="${REPLACE}${CAMEL_CASE}(${PARAMS_STR});\n${FIRST_INDENT}}\n\n" + REPLACE="${REPLACE}${FIRST_INDENT}${COMMENT_ORIGIN}\n${FIRST_INDENT}" + [[ -n ${STATIC} ]] && REPLACE="${REPLACE}${STATIC} " + [[ -n ${FNC_TYPE} ]] && REPLACE="${REPLACE}${FNC_TYPE} " + REPLACE="${REPLACE}function ${CAMEL_CASE}(${PARAMETERS_ORIGIN})" + [[ -n ${BRACKET_END} ]] && REPLACE="${REPLACE}\n${FIRST_INDENT}{" + + echo " ${FNC_NAME} -> ${CAMEL_CASE}" + + if [[ -n ${COMMENT_ORIGIN_WITH_DEPRECATED} ]]; then + rpl -e --quiet "${COMMENT_ORIGIN}" ${COMMENT_ORIGIN_WITH_DEPRECATED} "${f}" + fi + rpl -e --quiet "${LINE}" ${REPLACE} "${f}" + + fi + + done +done + + From edb2283e3a524e7faa34ac25abd3a213ac07a7ca Mon Sep 17 00:00:00 2001 From: atm-ph Date: Sat, 1 Dec 2018 20:41:19 +0100 Subject: [PATCH 120/307] Fix missing return --- dev/tools/snakeCaseToCamelCase.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tools/snakeCaseToCamelCase.sh b/dev/tools/snakeCaseToCamelCase.sh index fa8a76cc613..9196c130755 100755 --- a/dev/tools/snakeCaseToCamelCase.sh +++ b/dev/tools/snakeCaseToCamelCase.sh @@ -107,7 +107,7 @@ for f in ${TFile[@]}; do REPLACE=${LINE} [[ -z ${BRACKET_END} ]] && REPLACE="${LINE}\n${FIRST_INDENT}{\n${FIRST_INDENT}${INDENT}" || REPLACE="${LINE}\n${FIRST_INDENT}${INDENT}" - [[ -n ${STATIC} ]] && REPLACE="${REPLACE}self::" || REPLACE="${REPLACE}\$this->" + [[ -n ${STATIC} ]] && REPLACE="${REPLACE}return self::" || REPLACE="${REPLACE}return \$this->" REPLACE="${REPLACE}${CAMEL_CASE}(${PARAMS_STR});\n${FIRST_INDENT}}\n\n" REPLACE="${REPLACE}${FIRST_INDENT}${COMMENT_ORIGIN}\n${FIRST_INDENT}" [[ -n ${STATIC} ]] && REPLACE="${REPLACE}${STATIC} " From 21b55f3a8358bcc81f69a5c2a4a7ecaeb141a16e Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 1 Dec 2018 23:30:58 +0100 Subject: [PATCH 121/307] refactoring dol_sql_datefilter --- htdocs/comm/propal/list.php | 53 ++++++++++--------------------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 98ff1c45194..f9fbba16eae 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -329,45 +329,20 @@ if ($viewstatut != '' && $viewstatut != '-1') { $sql.= ' AND p.fk_statut IN ('.$db->escape($viewstatut).')'; } -if ($search_month > 0) -{ - if ($search_year > 0 && empty($search_day)) - $sql.= " AND p.datep BETWEEN '".$db->idate(dol_get_first_day($search_year,$search_month,false))."' AND '".$db->idate(dol_get_last_day($search_year,$search_month,false))."'"; - else if ($search_year > 0 && ! empty($search_day)) - $sql.= " AND p.datep BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $search_year))."'"; - else - $sql.= " AND date_format(p.datep, '%m') = '".$db->escape($search_month)."'"; -} -else if ($search_year > 0) -{ - $sql.= " AND p.datep BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'"; -} -if ($search_month_end > 0) -{ - if ($search_yearfin > 0 && empty($search_dayfin)) - $sql.= " AND p.fin_validite BETWEEN '".$db->idate(dol_get_first_day($search_yearfin,$search_month_end,false))."' AND '".$db->idate(dol_get_last_day($search_yearfin,$search_month_end,false))."'"; - else if ($search_yearfin > 0 && ! empty($search_dayfin)) - $sql.= " AND p.fin_validite BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month_end, $search_dayfin, $search_yearfin))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month_end, $search_dayfin, $search_yearfin))."'"; - else - $sql.= " AND date_format(p.fin_validite, '%m') = '".$db->escape($search_month_end)."'"; -} -else if ($search_yearfin > 0) -{ - $sql.= " AND p.fin_validite BETWEEN '".$db->idate(dol_get_first_day($search_yearfin,1,false))."' AND '".$db->idate(dol_get_last_day($search_yearfin,12,false))."'"; -} -if ($search_monthdelivery > 0) -{ - if ($search_yeardelivery > 0 && empty($search_daydelivery)) - $sql.= " AND p.date_livraison BETWEEN '".$db->idate(dol_get_first_day($search_yeardelivery,$search_monthdelivery,false))."' AND '".$db->idate(dol_get_last_day($search_yeardelivery,$search_monthdelivery,false))."'"; - else if ($search_yeardelivery > 0 && ! empty($search_daydelivery)) - $sql.= " AND p.date_livraison BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_monthdelivery, $search_daydelivery, $search_yeardelivery))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_monthdelivery, $search_daydelivery, $search_yeardelivery))."'"; - else - $sql.= " AND date_format(p.date_livraison, '%m') = '".$db->escape($search_monthdelivery)."'"; -} -else if ($search_yeardelivery > 0) -{ - $sql.= " AND p.date_livraison BETWEEN '".$db->idate(dol_get_first_day($search_yeardelivery,1,false))."' AND '".$db->idate(dol_get_last_day($search_yeardelivery,12,false))."'"; -} + +$sql.= dol_sql_datefilter( + "p.datep", + $search_day, $search_month, $search_year +); +$sql.= dol_sql_datefilter( + "p.fin_validite", + $search_dayfin, $search_month_end, $search_yearfin +); +$sql.= dol_sql_datefilter( + "p.date_livraison", + $search_daydelivery, $search_monthdelivery, $search_yeardelivery +); + if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$db->escape($search_sale); if ($search_user > 0) { From 0d35f04cb7289f79f8190db63bd347f99909b324 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 1 Dec 2018 23:36:26 +0100 Subject: [PATCH 122/307] Update list.php --- htdocs/commande/list.php | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index f26d7b86b44..51581c612a1 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -10,6 +10,8 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2016 Ferran Marcet + * Copyright (C) 2018 Charlene Benke + * * 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 @@ -301,32 +303,17 @@ if ($viewstatut <> '') $sql .= ' AND ((c.fk_statut IN (1,2)) OR (c.fk_statut = 3 AND c.facture = 0))'; // validated, in process or closed but not billed } } -if ($search_ordermonth > 0) -{ - if ($search_orderyear > 0 && empty($search_orderday)) - $sql.= " AND c.date_commande BETWEEN '".$db->idate(dol_get_first_day($search_orderyear,$search_ordermonth,false))."' AND '".$db->idate(dol_get_last_day($search_orderyear,$search_ordermonth,false))."'"; - else if ($search_orderyear > 0 && ! empty($search_orderday)) - $sql.= " AND c.date_commande BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_ordermonth, $search_orderday, $search_orderyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_ordermonth, $search_orderday, $search_orderyear))."'"; - else - $sql.= " AND date_format(c.date_commande, '%m') = '".$search_ordermonth."'"; -} -else if ($search_orderyear > 0) -{ - $sql.= " AND c.date_commande BETWEEN '".$db->idate(dol_get_first_day($search_orderyear,1,false))."' AND '".$db->idate(dol_get_last_day($search_orderyear,12,false))."'"; -} -if ($search_deliverymonth > 0) -{ - if ($search_deliveryyear > 0 && empty($search_deliveryday)) - $sql.= " AND c.date_livraison BETWEEN '".$db->idate(dol_get_first_day($search_deliveryyear,$search_deliverymonth,false))."' AND '".$db->idate(dol_get_last_day($search_deliveryyear,$search_deliverymonth,false))."'"; - else if ($search_deliveryyear > 0 && ! empty($search_deliveryday)) - $sql.= " AND c.date_livraison BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_deliverymonth, $search_deliveryday, $search_deliveryyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_deliverymonth, $search_deliveryday, $search_deliveryyear))."'"; - else - $sql.= " AND date_format(c.date_livraison, '%m') = '".$search_deliverymonth."'"; -} -else if ($search_deliveryyear > 0) -{ - $sql.= " AND c.date_livraison BETWEEN '".$db->idate(dol_get_first_day($search_deliveryyear,1,false))."' AND '".$db->idate(dol_get_last_day($search_deliveryyear,12,false))."'"; -} + +$sql.= dol_sql_datefilter( + "c.date_commande", + $search_orderday, $search_ordermonth, $search_orderyear +); + +$sql.= dol_sql_datefilter( + "c.date_livraison", + $search_deliveryday, $search_deliverymonth, $search_deliveryyear +); + if ($search_town) $sql.= natural_search('s.town', $search_town); if ($search_zip) $sql.= natural_search("s.zip",$search_zip); if ($search_state) $sql.= natural_search("state.nom",$search_state); From f07d1411aa984ec1767f5f2d37ad23a6aad83106 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 1 Dec 2018 23:41:15 +0100 Subject: [PATCH 123/307] Update list.php --- htdocs/compta/deplacement/list.php | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/htdocs/compta/deplacement/list.php b/htdocs/compta/deplacement/list.php index 3dfbac0e726..b04fd1388b6 100644 --- a/htdocs/compta/deplacement/list.php +++ b/htdocs/compta/deplacement/list.php @@ -4,6 +4,7 @@ * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2018 charlene Benke * * 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 @@ -55,6 +56,7 @@ if (! $sortfield) $sortfield="d.dated"; $year=GETPOST("year"); $month=GETPOST("month"); +$day=GETPOST("day"); if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter','alpha')) // Both test are required to be compatible with all browsers { @@ -64,6 +66,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter','a // $search_amount=""; $year=""; $month=""; + $day=""; } /* @@ -103,19 +106,10 @@ if ($search_company) $sql .= natural_search('s.nom', $search_company); } // if ($search_amount) $sql.=" AND d.km='".$db->escape(price2num(trim($search_amount)))."'"; -if ($month > 0) -{ - if ($year > 0 && empty($day)) - $sql.= " AND d.dated BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'"; - else if ($year > 0 && ! empty($day)) - $sql.= " AND d.dated BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; - else - $sql.= " AND date_format(d.dated, '%m') = '".$month."'"; -} -else if ($year > 0) -{ - $sql.= " AND d.dated BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; -} + +$sql.= dol_sql_datefilter( + "d.dated", $day, $month, $year +); $sql.= $db->order($sortfield,$sortorder); $sql.= $db->plimit($limit + 1, $offset); From b104c0889dfd8dfbc99acebf0d4a84ccfd71b2ab Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 1 Dec 2018 23:44:24 +0100 Subject: [PATCH 124/307] Update list.php --- htdocs/compta/facture/list.php | 39 +++++++++++----------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 6b0164058c2..161d23f8ac7 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -12,6 +12,7 @@ * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2015-2016 Ferran Marcet * Copyright (C) 2017 Josep Lluís Amador + * Copyright (C) 2018 Charlene Benke * * 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 @@ -88,7 +89,7 @@ $search_country=GETPOST("search_country",'int'); $search_type_thirdparty=GETPOST("search_type_thirdparty",'int'); $search_user = GETPOST('search_user','int'); $search_sale = GETPOST('search_sale','int'); -$search_day = GETPOST('search_day','int'); +$search_day = GETPOST('search_day','int'); $search_month = GETPOST('search_month','int'); $search_year = GETPOST('search_year','int'); $search_day_lim = GETPOST('search_day_lim','int'); @@ -450,32 +451,16 @@ if ($search_status != '-1' && $search_status != '') } } if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$db->escape($search_paymentmode); -if ($search_month > 0) -{ - if ($search_year > 0 && empty($search_day)) - $sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,$search_month,false))."' AND '".$db->idate(dol_get_last_day($search_year,$search_month,false))."'"; - else if ($search_year > 0 && ! empty($search_day)) - $sql.= " AND f.datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $search_year))."'"; - else - $sql.= " AND date_format(f.datef, '%m') = '".$search_month."'"; -} -else if ($search_year > 0) -{ - $sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'"; -} -if ($search_month_lim > 0) -{ - if ($search_year_lim > 0 && empty($search_day_lim)) - $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($search_year_lim,$search_month_lim,false))."' AND '".$db->idate(dol_get_last_day($search_year_lim,$search_month_lim,false))."'"; - else if ($search_year_lim > 0 && ! empty($search_day_lim)) - $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month_lim, $search_day_lim, $search_year_lim))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month_lim, $search_day_lim, $search_year_lim))."'"; - else - $sql.= " AND date_format(f.date_lim_reglement, '%m') = '".$db->escape($search_month_lim)."'"; -} -else if ($search_year_lim > 0) -{ - $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($search_year_lim,1,false))."' AND '".$db->idate(dol_get_last_day($search_year_lim,12,false))."'"; -} + +$sql.= dol_sql_datefilter( + "f.datef", + $search_day, $search_month, $search_year +); +$sql.= dol_sql_datefilter( + "f.date_lim_reglement", + $search_day_lim, $search_month_lim, $search_year_lim +); + if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->client->warning_delay)."'"; if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; if ($search_user > 0) From 6ac3cfdd9928d7c0bf68830251639175983fbb6e Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sat, 1 Dec 2018 23:48:36 +0100 Subject: [PATCH 125/307] Update list.php --- htdocs/compta/paiement/list.php | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index 4536cb98520..63e7adcc4c2 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -7,6 +7,7 @@ * Copyright (C) 2015 Juanjo Menent * Copyright (C) 2017 Alexandre Spangaro * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2018 Charlene Benke * * 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 @@ -163,19 +164,8 @@ else else $sql.= " AND f.fk_user_author = ".$userid; } // Search criteria - if ($month > 0) - { - if ($year > 0 && empty($day)) - $sql.= " AND p.datep BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'"; - else if ($year > 0 && ! empty($day)) - $sql.= " AND p.datep BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; - else - $sql.= " AND date_format(p.datep, '%m') = '".$month."'"; - } - else if ($year > 0) - { - $sql.= " AND p.datep BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; - } + $sql.= dol_sql_datefilter("p.datep", $day, $month, $year); + if ($search_ref) $sql .= natural_search('p.ref', $search_ref); if ($search_account > 0) $sql .=" AND b.fk_account=".$search_account; if ($search_paymenttype != "") $sql .=" AND c.code='".$db->escape($search_paymenttype)."'"; From 7378a2f1c635143e6831cd2cb8776600f4a13fde Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sun, 2 Dec 2018 00:02:10 +0100 Subject: [PATCH 126/307] Update list.php --- htdocs/expensereport/list.php | 55 +++++++++++++++-------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index b2b8e46d668..7b417f07c80 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -3,8 +3,9 @@ * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2015 Alexandre Spangaro - * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2015 Alexandre Spangaro + * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2018 Charlene Benke * * 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 @@ -76,6 +77,8 @@ $search_amount_ttc = GETPOST('search_amount_ttc','alpha'); $search_status = (GETPOST('search_status','intcomma')!=''?GETPOST('search_status','intcomma'):GETPOST('statut','intcomma')); $month_start = GETPOST("month_start","int"); $year_start = GETPOST("year_start","int"); +$day_start = GETPOST("day_start","int"); +$day_end = GETPOST("day_end","int"); $month_end = GETPOST("month_end","int"); $year_end = GETPOST("year_end","int"); $optioncss = GETPOST('optioncss','alpha'); @@ -158,8 +161,10 @@ if (empty($reshook)) $search_status=""; $month_start=""; $year_start=""; + $day =""; $month_end=""; $year_end=""; + $day_end = ""; $toselect=''; $search_array_options=array(); } @@ -271,34 +276,17 @@ if (!empty($sall)) $sql.= natural_search(array_keys($fieldstosearchall), $sall); // Ref if (!empty($search_ref)) $sql.= natural_search('d.ref', $search_ref); // Date Start -if ($month_start > 0) -{ - if ($year_start > 0 && empty($day)) - $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_get_first_day($year_start,$month_start,false))."' AND '".$db->idate(dol_get_last_day($year_start,$month_start,false))."'"; - else if ($year_start > 0 && ! empty($day)) - $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_start, $day, $year_start))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_start, $day, $year_start))."'"; - else - $sql.= " AND date_format(d.date_debut, '%m') = '".$month_start."'"; -} -else if ($year_start > 0) -{ - $sql.= " AND d.date_debut BETWEEN '".$db->idate(dol_get_first_day($year_start,1,false))."' AND '".$db->idate(dol_get_last_day($year_start,12,false))."'"; -} -// Date Start -if ($month_end > 0) -{ - if ($year_end > 0 && empty($day)) - $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_get_first_day($year_end,$month_end,false))."' AND '".$db->idate(dol_get_last_day($year_end,$month_end,false))."'"; - else if ($year_end > 0 && ! empty($day)) - $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_end, $day, $year_end))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_end, $day, $year_end))."'"; - else - $sql.= " AND date_format(d.date_fin, '%m') = '".$month_end."'"; -} -else if ($year_end > 0) -{ - $sql.= " AND d.date_fin BETWEEN '".$db->idate(dol_get_first_day($year_end,1,false))."' AND '".$db->idate(dol_get_last_day($year_end,12,false))."'"; -} -// Amount +$sql.= dol_sql_datefilter( + "d.date_debut", + $day_start, $month_start, $year_start +); + +// Date End +$sql.= dol_sql_datefilter( + "d.date_fin", + $day_end, $month_end, $year_end +); + if ($search_amount_ht != '') $sql.= natural_search('d.total_ht', $search_amount_ht, 1); if ($search_amount_ttc != '') $sql.= natural_search('d.total_ttc', $search_amount_ttc, 1); // User @@ -538,6 +526,9 @@ if ($resql) if (! empty($arrayfields['d.date_debut']['checked'])) { print '
    '; @@ -546,7 +537,9 @@ if ($resql) if (! empty($arrayfields['d.date_fin']['checked'])) { print ''; } From 6ea0919ebb2868c68bc31a0bd6077389fffda39f Mon Sep 17 00:00:00 2001 From: Chl Date: Fri, 17 Aug 2018 20:47:01 +0200 Subject: [PATCH 127/307] facture-rec.class.php: reindent --- .../facture/class/facture-rec.class.php | 93 ++++++++++--------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 56f87d2eac3..bf4360a57f3 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -1025,30 +1025,33 @@ class FactureRec extends CommonInvoice $sql.= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)'; $sql.= ' AND suspended = 0'; $sql.= ' AND entity = '.$conf->entity; // MUST STAY = $conf->entity here - if ($restictoninvoiceid > 0) $sql.=' AND rowid = '.$restictoninvoiceid; + if ($restictoninvoiceid > 0) + $sql.=' AND rowid = '.$restictoninvoiceid; $sql.= $db->order('entity', 'ASC'); //print $sql;exit; $resql = $db->query($sql); if ($resql) { - $i=0; - $num = $db->num_rows($resql); + $i=0; + $num = $db->num_rows($resql); - if ($num) $this->output.=$langs->trans("FoundXQualifiedRecurringInvoiceTemplate", $num)."\n"; - else $this->output.=$langs->trans("NoQualifiedRecurringInvoiceTemplateFound"); + if ($num) + $this->output.=$langs->trans("FoundXQualifiedRecurringInvoiceTemplate", $num)."\n"; + else + $this->output.=$langs->trans("NoQualifiedRecurringInvoiceTemplateFound"); - $saventity = $conf->entity; + $saventity = $conf->entity; - while ($i < $num) // Loop on each template invoice. If $num = 0, test is false at first pass. + while ($i < $num) // Loop on each template invoice. If $num = 0, test is false at first pass. { $line = $db->fetch_object($resql); - $db->begin(); + $db->begin(); - $invoiceidgenerated = 0; + $invoiceidgenerated = 0; - $facturerec = new FactureRec($db); + $facturerec = new FactureRec($db); $facturerec->fetch($line->rowid); if ($facturerec->id > 0) @@ -1058,44 +1061,44 @@ class FactureRec extends CommonInvoice dol_syslog("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref.", entity=".$facturerec->entity); - $facture = new Facture($db); + $facture = new Facture($db); $facture->fac_rec = $facturerec->id; // We will create $facture from this recurring invoice $facture->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice - $facture->type = self::TYPE_STANDARD; - $facture->brouillon = 1; - $facture->date = (empty($facturerec->date_when)?$now:$facturerec->date_when); // We could also use dol_now here but we prefer date_when so invoice has real date when we would like even if we generate later. - $facture->socid = $facturerec->socid; + $facture->type = self::TYPE_STANDARD; + $facture->brouillon = 1; + $facture->date = (empty($facturerec->date_when)?$now:$facturerec->date_when); // We could also use dol_now here but we prefer date_when so invoice has real date when we would like even if we generate later. + $facture->socid = $facturerec->socid; - $invoiceidgenerated = $facture->create($user); - if ($invoiceidgenerated <= 0) - { - $this->errors = $facture->errors; - $this->error = $facture->error; - $error++; - } - if (! $error && ($facturerec->auto_validate || $forcevalidation)) - { - $result = $facture->validate($user); - if ($result <= 0) - { - $this->errors = $facture->errors; - $this->error = $facture->error; - $error++; - } - } - if (! $error && $facturerec->generate_pdf) - { - // We refresh the object in order to have all necessary data (like date_lim_reglement) - $facture->fetch($facture->id); - $result = $facture->generateDocument($facturerec->modelpdf, $langs); - if ($result <= 0) - { - $this->errors = $facture->errors; - $this->error = $facture->error; - $error++; - } - } + $invoiceidgenerated = $facture->create($user); + if ($invoiceidgenerated <= 0) + { + $this->errors = $facture->errors; + $this->error = $facture->error; + $error++; + } + if (! $error && ($facturerec->auto_validate || $forcevalidation)) + { + $result = $facture->validate($user); + if ($result <= 0) + { + $this->errors = $facture->errors; + $this->error = $facture->error; + $error++; + } + } + if (! $error && $facturerec->generate_pdf) + { + // We refresh the object in order to have all necessary data (like date_lim_reglement) + $facture->fetch($facture->id); + $result = $facture->generateDocument($facturerec->modelpdf, $langs); + if ($result <= 0) + { + $this->errors = $facture->errors; + $this->error = $facture->error; + $error++; + } + } } else { @@ -1114,7 +1117,7 @@ class FactureRec extends CommonInvoice } else { - $db->rollback("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref); + $db->rollback("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref); } $i++; From 95b5d8790d27e856934f630873267d29f8b18489 Mon Sep 17 00:00:00 2001 From: Chl Date: Fri, 17 Aug 2018 19:56:29 +0200 Subject: [PATCH 128/307] corr. typo --- htdocs/compta/facture/class/facture-rec.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index bf4360a57f3..f35d8f88835 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -998,11 +998,11 @@ class FactureRec extends CommonInvoice * * WARNING: This method change temporarly context $conf->entity to be in correct context for each recurring invoice found. * - * @param int $restictoninvoiceid 0=All qualified template invoices found. > 0 = restrict action on invoice ID + * @param int $restrictioninvoiceid 0=All qualified template invoices found. > 0 = restrict action on invoice ID * @param int $forcevalidation 1=Force validation of invoice whatever is template auto_validate flag. * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ - function createRecurringInvoices($restictoninvoiceid=0, $forcevalidation=0) + function createRecurringInvoices($restrictioninvoiceid=0, $forcevalidation=0) { global $conf, $langs, $db, $user; @@ -1017,7 +1017,7 @@ class FactureRec extends CommonInvoice $tmparray=dol_getdate($now); $today = dol_mktime(23,59,59,$tmparray['mon'],$tmparray['mday'],$tmparray['year']); // Today is last second of current day - dol_syslog("createRecurringInvoices restictoninvoiceid=".$restictoninvoiceid." forcevalidation=".$forcevalidation); + dol_syslog("createRecurringInvoices restrictioninvoiceid=".$restrictioninvoiceid." forcevalidation=".$forcevalidation); $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facture_rec'; $sql.= ' WHERE frequency > 0'; // A recurring invoice is an invoice with a frequency @@ -1025,8 +1025,8 @@ class FactureRec extends CommonInvoice $sql.= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)'; $sql.= ' AND suspended = 0'; $sql.= ' AND entity = '.$conf->entity; // MUST STAY = $conf->entity here - if ($restictoninvoiceid > 0) - $sql.=' AND rowid = '.$restictoninvoiceid; + if ($restrictioninvoiceid > 0) + $sql.=' AND rowid = '.$restrictioninvoiceid; $sql.= $db->order('entity', 'ASC'); //print $sql;exit; From 864ce8534120747acc62c5d5d1ada43460056a1b Mon Sep 17 00:00:00 2001 From: Chl Date: Fri, 17 Aug 2018 20:39:46 +0200 Subject: [PATCH 129/307] NEW adding hooks to createRecurringInvoices() For example : send the newly generated invoice by mail. We send the counter and the total so launching some action on the last loop (generated invoice or error) is possible. (bonus: correcting error reporting $this->errors to $this->errors[] ) --- .../facture/class/facture-rec.class.php | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index f35d8f88835..6cff7e5ef57 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once(DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'); /** @@ -1004,14 +1005,16 @@ class FactureRec extends CommonInvoice */ function createRecurringInvoices($restrictioninvoiceid=0, $forcevalidation=0) { - global $conf, $langs, $db, $user; + global $conf, $langs, $db, $user, $hookmanager; + $error=0; + $nb_create=0; // Load translation files required by the page - $langs->loadLangs(array("main","bills")); + $langs->loadLangs(array("main","bills")); - $nb_create=0; + $hookmanager->initHooks(array('createrecurringinvoices')); $now = dol_now(); $tmparray=dol_getdate($now); @@ -1029,6 +1032,12 @@ class FactureRec extends CommonInvoice $sql.=' AND rowid = '.$restrictioninvoiceid; $sql.= $db->order('entity', 'ASC'); //print $sql;exit; + $parameters = array( + 'entity' => $conf->entity, + 'restrictioninvoiceid' => $restrictioninvoiceid, + 'forcevalidation' => $forcevalidation, + ); + $reshook = $hookmanager->executeHooks('writeSQL', $parameters, $sql); // note that $sql might be modified by hooks $resql = $db->query($sql); if ($resql) @@ -1051,6 +1060,7 @@ class FactureRec extends CommonInvoice $invoiceidgenerated = 0; + $facture = null; $facturerec = new FactureRec($db); $facturerec->fetch($line->rowid); @@ -1073,7 +1083,7 @@ class FactureRec extends CommonInvoice $invoiceidgenerated = $facture->create($user); if ($invoiceidgenerated <= 0) { - $this->errors = $facture->errors; + $this->errors[] = $facture->errors; $this->error = $facture->error; $error++; } @@ -1082,7 +1092,7 @@ class FactureRec extends CommonInvoice $result = $facture->validate($user); if ($result <= 0) { - $this->errors = $facture->errors; + $this->errors[] = $facture->errors; $this->error = $facture->error; $error++; } @@ -1094,7 +1104,7 @@ class FactureRec extends CommonInvoice $result = $facture->generateDocument($facturerec->modelpdf, $langs); if ($result <= 0) { - $this->errors = $facture->errors; + $this->errors[] = $facture->errors; $this->error = $facture->error; $error++; } @@ -1120,6 +1130,16 @@ class FactureRec extends CommonInvoice $db->rollback("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref); } + $parameters = array( + 'cpt' => $i, + 'total' => $num, + 'errorCount' => $error, + 'invoiceidgenerated' => $invoiceidgenerated, + 'facturerec' => $facturerec, // it's an object which PHP passes by "reference", so modifiable by hooks. + 'this' => $this, // it's an object which PHP passes by "reference", so modifiable by hooks. + ); + $reshook = $hookmanager->executeHooks('generatedInvoice', $parameters, $facture); // note: $facture can be modified by hooks (warning: $facture can be null) + $i++; } From 1bc0defb31b80852cdbd5a76da60e96cc9f708ff Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sun, 2 Dec 2018 09:55:26 +0100 Subject: [PATCH 130/307] Update list.php --- htdocs/fourn/commande/list.php | 44 ++++++++++------------------------ 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 729899a8ff2..d2e84dd234d 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -6,7 +6,8 @@ * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2016 Ferran Marcet - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018 Charlene Benke * * 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 @@ -522,39 +523,20 @@ if ($search_product_category > 0) $sql.= " AND cp.fk_categorie = ".$search_produ //Required triple check because statut=0 means draft filter if (GETPOST('statut', 'intcomma') !== '') -{ $sql .= " AND cf.fk_statut IN (".$db->escape($db->escape(GETPOST('statut', 'intcomma'))).")"; -} + if ($search_status != '' && $search_status >= 0) -{ $sql.=" AND cf.fk_statut IN (".$db->escape($search_status).")"; -} -if ($search_ordermonth > 0) -{ - if ($search_orderyear > 0 && empty($search_orderday)) - $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_get_first_day($search_orderyear,$search_ordermonth,false))."' AND '".$db->idate(dol_get_last_day($search_orderyear,$search_ordermonth,false))."'"; - else if ($search_orderyear > 0 && ! empty($search_orderday)) - $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_ordermonth, $search_orderday, $search_orderyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_ordermonth, $search_orderday, $search_orderyear))."'"; - else - $sql.= " AND date_format(cf.date_commande, '%m') = '".$db->escape($search_ordermonth)."'"; -} -else if ($search_orderyear > 0) -{ - $sql.= " AND cf.date_commande BETWEEN '".$db->idate(dol_get_first_day($search_orderyear,1,false))."' AND '".$db->idate(dol_get_last_day($search_orderyear,12,false))."'"; -} -if ($search_deliverymonth > 0) -{ - if ($search_deliveryyear > 0 && empty($search_deliveryday)) - $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_get_first_day($search_deliveryyear,$search_deliverymonth,false))."' AND '".$db->idate(dol_get_last_day($search_deliveryyear,$search_deliverymonth,false))."'"; - else if ($search_deliveryyear > 0 && ! empty($search_deliveryday)) - $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_eliverymonth, $search_deliveryday, $search_deliveryyear))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_deliverymonth, $search_deliveryday, $search_deliveryyear))."'"; - else - $sql.= " AND date_format(cf.date_livraison, '%m') = '".$db->escape($search_deliverymonth)."'"; -} -else if ($search_deliveryyear > 0) -{ - $sql.= " AND cf.date_livraison BETWEEN '".$db->idate(dol_get_first_day($search_deliveryyear,1,false))."' AND '".$db->idate(dol_get_last_day($search_deliveryyear,12,false))."'"; -} + +$sql.= dol_sql_datefilter( + "cf.date_commande", + $search_orderday, $search_ordermonth, $search_orderyear +); +$sql.= dol_sql_datefilter( + "cf.date_livraison", + $search_deliveryday, $search_deliverymonth, $search_deliveryyear +); + if ($search_town) $sql.= natural_search('s.town', $search_town); if ($search_zip) $sql.= natural_search("s.zip",$search_zip); if ($search_state) $sql.= natural_search("state.nom",$search_state); From ad1ca07085d635af0dda51188069060897e66c9d Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sun, 2 Dec 2018 09:58:18 +0100 Subject: [PATCH 131/307] Update list.php --- htdocs/fourn/facture/list.php | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 9a53b31c8a1..ddea73ce419 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -10,7 +10,8 @@ * Copyright (C) 2015 Abbes Bahfir * Copyright (C) 2015-2016 Ferran Marcet * Copyright (C) 2017 Josep Lluís Amador - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018 Charlene Benke + * Copyright (C) 2018 Frédéric France * * 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 @@ -329,32 +330,10 @@ if ($search_montant_localtax2 != '') $sql.= natural_search('f.localtax2', $searc if ($search_montant_ttc != '') $sql.= natural_search('f.total_ttc', $search_montant_ttc, 1); if ($search_status != '' && $search_status >= 0) $sql.= " AND f.fk_statut = ".$db->escape($search_status); if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$search_paymentmode.""; -if ($month > 0) -{ - if ($year > 0 && empty($day)) - $sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'"; - else if ($year > 0 && ! empty($day)) - $sql.= " AND f.datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; - else - $sql.= " AND date_format(f.datef, '%m') = '".$month."'"; -} -else if ($year > 0) -{ - $sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; -} -if ($month_lim > 0) -{ - if ($year_lim > 0 && empty($day_lim)) - $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($year_lim,$month_lim,false))."' AND '".$db->idate(dol_get_last_day($year_lim,$month_lim,false))."'"; - else if ($year_lim > 0 && ! empty($day_lim)) - $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_lim, $day_lim, $year_lim))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_lim, $day_lim, $year_lim))."'"; - else - $sql.= " AND date_format(f.date_lim_reglement, '%m') = '".$db->escape($month_lim)."'"; -} -else if ($year_lim > 0) -{ - $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($year_lim,1,false))."' AND '".$db->idate(dol_get_last_day($year_lim,12,false))."'"; -} + +$sql.= dol_sql_datefilter( "f.datef", $day, $month, $year); +$sql.= dol_sql_datefilter( "f.date_lim_reglement", $day_lim, $month_lim, $year_lim); + if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->fournisseur->warning_delay)."'"; if ($search_label) $sql .= natural_search('f.libelle', $search_label); if ($search_status != '' && $search_status >= 0) From 65dc066352c4182be08b9808687bbd3299e04138 Mon Sep 17 00:00:00 2001 From: BENKE Charlene <1179011+defrance@users.noreply.github.com> Date: Sun, 2 Dec 2018 10:01:38 +0100 Subject: [PATCH 132/307] Update list.php --- htdocs/holiday/list.php | 54 +++++++++++------------------------------ 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index a2bdcb2a5b3..c88dd1f4776 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -1,7 +1,8 @@ * Copyright (C) 2013-2018 Laurent Destailleur - * Copyright (C) 2012-2016 Regis Houssin + * Copyright (C) 2012-2016 Regis Houssin + * Copyright (C) 2018 Charlene Benke * * 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 @@ -190,49 +191,22 @@ if(!empty($search_ref)) } // Start date -if($search_year_start > 0) { - if($search_month_start > 0) { - $filter .= " AND (cp.date_debut BETWEEN '".$db->idate(dol_get_first_day($search_year_start,$search_month_start,1))."' AND '".$db->idate(dol_get_last_day($search_year_start,$search_month_start,1))."')"; - //$filter.= " AND date_format(cp.date_debut, '%Y-%m') = '$search_year_start-$search_month_start'"; - } else { - $filter .= " AND (cp.date_debut BETWEEN '".$db->idate(dol_get_first_day($search_year_start,1,1))."' AND '".$db->idate(dol_get_last_day($search_year_start,12,1))."')"; - //$filter.= " AND date_format(cp.date_debut, '%Y') = '$search_year_start'"; - } -} else { - if($search_month_start > 0) { - $filter.= " AND date_format(cp.date_debut, '%m') = '".$db->escape($search_month_start)."'"; - } -} +$sql.= dol_sql_datefilter( + "cp.date_debut", + $search_day_start, $search_month_start, $search_year_start +); // End date -if($search_year_end > 0) { - if($search_month_end > 0) { - $filter .= " AND (cp.date_fin BETWEEN '".$db->idate(dol_get_first_day($search_year_end,$search_month_end,1))."' AND '".$db->idate(dol_get_last_day($search_year_end,$search_month_end,1))."')"; - //$filter.= " AND date_format(cp.date_fin, '%Y-%m') = '$search_year_end-$search_month_end'"; - } else { - $filter .= " AND (cp.date_fin BETWEEN '".$db->idate(dol_get_first_day($search_year_end,1,1))."' AND '".$db->idate(dol_get_last_day($search_year_end,12,1))."')"; - //$filter.= " AND date_format(cp.date_fin, '%Y') = '$search_year_end'"; - } -} else { - if($search_month_end > 0) { - $filter.= " AND date_format(cp.date_fin, '%m') = '".$db->escape($search_month_end)."'"; - } -} +$sql.= dol_sql_datefilter( + "cp.date_fin", + $search_day_end, $search_month_end, $search_year_end +); // Create date -if($search_year_create > 0) { - if($search_month_create > 0) { - $filter .= " AND (cp.date_create BETWEEN '".$db->idate(dol_get_first_day($search_year_create,$search_month_create,1))."' AND '".$db->idate(dol_get_last_day($search_year_create,$search_month_create,1))."')"; - //$filter.= " AND date_format(cp.date_create, '%Y-%m') = '$search_year_create-$search_month_create'"; - } else { - $filter .= " AND (cp.date_create BETWEEN '".$db->idate(dol_get_first_day($search_year_create,1,1))."' AND '".$db->idate(dol_get_last_day($search_year_create,12,1))."')"; - //$filter.= " AND date_format(cp.date_create, '%Y') = '$search_year_create'"; - } -} else { - if($search_month_create > 0) { - $filter.= " AND date_format(cp.date_create, '%m') = '".$db->escape($search_month_create)."'"; - } -} +$sql.= dol_sql_datefilter( + "cp.date_create", + $search_day_create, $search_month_create, $search_year_create +); // Employee if(!empty($search_employee) && $search_employee != -1) { From 8ec2bac36a06421971bffb7baa45aa6ec082fdd0 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sun, 2 Dec 2018 10:02:05 +0100 Subject: [PATCH 133/307] FIX #3234 --- htdocs/admin/barcode.php | 64 ++++++++++++++------ htdocs/core/class/html.formbarcode.class.php | 26 +++++--- 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php index 313a852e384..75c82157ddf 100644 --- a/htdocs/admin/barcode.php +++ b/htdocs/admin/barcode.php @@ -70,18 +70,8 @@ else if ($action == 'update') $res = dolibarr_set_const($db, "PRODUIT_DEFAULT_BARCODE_TYPE", $coder_id,'chaine',0,'',$conf->entity); $coder_id = GETPOST('GENBARCODE_BARCODETYPE_THIRDPARTY','alpha'); $res = dolibarr_set_const($db, "GENBARCODE_BARCODETYPE_THIRDPARTY", $coder_id,'chaine',0,'',$conf->entity); -} -else if ($action == 'updateengine') -{ - // TODO Update engines. - -} - -if ($action && $action != 'setcoder' && $action != 'setModuleOptions') -{ - if (! $res > 0) $error++; - - if (! $error) + + if ($res > 0) { setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } @@ -90,6 +80,42 @@ if ($action && $action != 'setcoder' && $action != 'setModuleOptions') setEventMessages($langs->trans("Error"), null, 'errors'); } } +else if ($action == 'updateengine') +{ + $sql = "SELECT rowid, coder"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_barcode_type"; + $sql.= " WHERE entity = ".$conf->entity; + $sql.= " ORDER BY code"; + + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + if (GETPOST('coder'.$obj->rowid, 'alpha')) + { + $coder = GETPOST('coder'.$obj->rowid,'alpha'); + $code_id = $obj->rowid; + + $sqlp = "UPDATE ".MAIN_DB_PREFIX."c_barcode_type"; + $sqlp.= " SET coder = '" . $coder."'"; + $sqlp.= " WHERE rowid = ". $code_id; + $sqlp.= " AND entity = ".$conf->entity; + + $upsql=$db->query($sqlp); + if (! $upsql) dol_print_error($db); + } + + $i++; + } + } + +} /* * View @@ -162,9 +188,12 @@ $var=true; print '
    '; print load_fiche_titre($langs->trans("BarcodeEncodeModule"),'',''); -//print ""; -//print ''; -//print ""; +if (empty($conf->use_javascript_ajax)) +{ + print ''; + print ''; + print ''; +} print '
    '; - print fieldLabel('CurrencyRate','multicurrency_tx'); + print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0); print 'id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '
    ' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . '
    ' . $form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0) . '' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
    ' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . '
    ' . $form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0) . '' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
    ' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . '
    ' . $form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0) . '' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
    ' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . '
    ' . $form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0) . '' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
    ' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . '
    ' . $form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0) . '' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
    ' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . '
    ' . $form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0) . '' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '
    '; - print fieldLabel('DatePayment','datep',1).''; + print $form->editfieldkey('DatePayment', 'datep', '', $object, 0, 'string', '', 1).''; print $form->selectDate((empty($datep)?-1:$datep), "datep", '', '', '', 'add', 1, 1); print '
    '; - print fieldLabel('DateValue','datev',0).''; + print $form->editfieldkey('DateValue', 'datev', '', $object, 0).''; print $form->selectDate((empty($datev)?-1:$datev), "datev", '', '', '', 'add', 1, 1); print '
    '; - print fieldLabel('Employee','fk_user',1).''; + print $form->editfieldkey('Employee', 'fk_user', '', $object, 0, 'string', '', 1).''; $noactive=0; // We keep active and unactive users print $form->select_dolusers(GETPOST('fk_user','int'), 'fk_user', 1, '', 0, '', '', 0, 0, 0, 'AND employee=1', 0, '', 'maxwidth300', $noactive); print '
    '; - print fieldLabel('Label','label',1).''; + print $form->editfieldkey('Label', 'label', '', $object, 0, 'string', '', 1).''; print 'trans("SalaryPayment")).'">'; print '
    '; - print fieldLabel('DateStartPeriod','datesp',1).''; + print $form->editfieldkey('DateStartPeriod', 'datesp', '', $object, 0, 'string', '', 1).''; print $form->selectDate($datesp, "datesp", '', '', '', 'add'); print '
    '; - print fieldLabel('DateEndPeriod','dateep',1).''; + print $form->editfieldkey('DateEndPeriod', 'dateep', '', $object, 0, 'string', '', 1).''; print $form->selectDate($dateep, "dateep", '', '', '', 'add'); print '
    '; - print fieldLabel('Amount','amount',1).''; + print $form->editfieldkey('Amount', 'amount', '', $object, 0, 'string', '', 1).''; print ''; print '
    '; - print fieldLabel('BankAccount','selectaccountid',1).''; + print $form->editfieldkey('BankAccount', 'selectaccountid', '', $object, 0, 'string', '', 1).''; $form->select_comptes($_POST["accountid"],"accountid",0,'',1); // Affiche liste des comptes courant print '
    '; - print fieldLabel('PaymentMode','selectpaymenttype',1).''; + print $form->editfieldkey('PaymentMode', 'selectpaymenttype', '', $object, 0, 'string', '', 1).''; $form->select_types_paiements(GETPOST("paymenttype"), "paymenttype", '', 2); print '
    skype).'">
    twitter).'">
    facebook).'">
    ' . fieldLabel( 'Categories', 'contcats' ) . ''; - $cate_arbo = $form->select_all_categories( Categorie::TYPE_CONTACT, null, 'parent', null, null, 1 ); - print $form->multiselectarray( 'contcats', $cate_arbo, GETPOST( 'contcats', 'array' ), null, null, null, - null, '90%' ); + print '
    ' . $form->editfieldkey('Categories', 'contcats', '', $object, 0) . ''; + $cate_arbo = $form->select_all_categories(Categorie::TYPE_CONTACT, null, 'parent', null, null, 1); + print $form->multiselectarray('contcats', $cate_arbo, GETPOST('contcats', 'array'), null, null, null, null, '90%'); print "
    skype).'">
    twitter).'">
    facebook).'">
    ' . fieldLabel( 'Categories', 'contcats' ) . '
    ' . $form->editfieldkey('Categories', 'contcats', '', $object, 0) . ''; - $cate_arbo = $form->select_all_categories( Categorie::TYPE_CONTACT, null, null, null, null, 1 ); - $c = new Categorie( $db ); - $cats = $c->containing( $object->id, 'contact' ); + $cate_arbo = $form->select_all_categories(Categorie::TYPE_CONTACT, null, null, null, null, 1); + $c = new Categorie($db); + $cats = $c->containing($object->id, 'contact'); foreach ($cats as $cat) { $arrayselected[] = $cat->id; } - print $form->multiselectarray( 'contcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%' ); + print $form->multiselectarray('contcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%'); print "
    ' . $langs->trans("Categories") . ''; - print $form->showCategories( $object->id, 'contact', 1 ); + print $form->showCategories($object->id, 'contact', 1); print '
    '; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) + print ''; + print ''; $formother->select_year($year_start,'year_start',1, $min_year, $max_year); print ''; - print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) + print ''; + print ''; $formother->select_year($year_end,'year_end',1, $min_year, $max_year); print '
    '; print ''; @@ -260,10 +289,9 @@ print "
    \n"; if (empty($conf->use_javascript_ajax)) { - // TODO Implement code behind action updateengine - //print '
    '; + print '
    '; + print ''; } -//print ''; print "
    "; diff --git a/htdocs/core/class/html.formbarcode.class.php b/htdocs/core/class/html.formbarcode.class.php index e1ee7ae04ff..d155c8a1a0c 100644 --- a/htdocs/core/class/html.formbarcode.class.php +++ b/htdocs/core/class/html.formbarcode.class.php @@ -59,7 +59,7 @@ class FormBarCode $disable = ''; - if ($conf->use_javascript_ajax) + if (!empty($conf->use_javascript_ajax)) { print "\n".'