diff --git a/ChangeLog b/ChangeLog index 82f82c0b051..8b3b3c97157 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,7 @@ NEW: Accountancy - change menu disposition NEW: Accountancy - on transfers, select the periodicity by default NEW: Accountancy - Add export for Gestinum (v3 & v5) NEW: new currency rate editor +NEW: Solve blocking feature. Can increase stock of a Kit without changing subproduct stock. NEW: add a widget to show the customers with outstanding limits reached NEW: add 2 rules for emailcollector: Message send/not sent from Dolibarr NEW: add a counter of number of words for pages in website module diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 92de49d66ed..b3cec7710a4 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -642,6 +642,7 @@ if (empty($reshook)) { $newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php', '', 1, array('morecss' => 'marginleftonly')); $url = './card.php?action=create'; if (!empty($socid)) $url .= '&socid='.$socid; diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index cd15eea52be..325ed0c473c 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -39,8 +39,14 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; $langs->loadLangs(array("accountancy", "compta")); $action = GETPOST('action', 'aZ09'); -$search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int')); -$search_date_end = dol_mktime(0, 0, 0, GETPOST('search_date_endmonth', 'int'), GETPOST('search_date_endday', 'int'), GETPOST('search_date_endyear', 'int')); +$search_date_startyear = GETPOST('search_date_startyear', 'int'); +$search_date_startmonth = GETPOST('search_date_startmonth', 'int'); +$search_date_startday = GETPOST('search_date_startday', 'int'); +$search_date_endyear = GETPOST('search_date_endyear', 'int'); +$search_date_endmonth = GETPOST('search_date_endmonth', 'int'); +$search_date_endday = GETPOST('search_date_endday', 'int'); +$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); +$search_date_end = dol_mktime(0, 0, 0, $search_date_endmonth, $search_date_endday, $search_date_endyear); $search_doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); $search_accountancy_code = GETPOST("search_accountancy_code"); @@ -126,9 +132,24 @@ $arrayfields = array( if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) unset($arrayfields['t.lettering_code']); +if ($search_date_start && empty($search_date_startyear)) { + $tmparray = dol_getdate($search_date_start); + $search_date_startyear = $tmparray['year']; + $search_date_startmonth = $tmparray['mon']; + $search_date_startday = $tmparray['mday']; +} +if ($search_date_end && empty($search_date_endyear)) { + $tmparray = dol_getdate($search_date_end); + $search_date_endyear = $tmparray['year']; + $search_date_endmonth = $tmparray['mon']; + $search_date_endday = $tmparray['mday']; +} + + /* * Action */ + if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; } @@ -172,11 +193,11 @@ if (empty($reshook)) if (!empty($search_date_start)) { $filter['t.doc_date>='] = $search_date_start; - $param .= '&search_date_startmonth='.GETPOST('search_date_startmonth', 'int').'&search_date_startday='.GETPOST('search_date_startday', 'int').'&search_date_startyear='.GETPOST('search_date_startyear', 'int'); + $param .= '&search_date_startmonth='.$search_date_startmonth.'&search_date_startday='.$search_date_startday.'&search_date_startyear='.$search_date_startyear; } if (!empty($search_date_end)) { $filter['t.doc_date<='] = $search_date_end; - $param .= '&search_date_endmonth='.GETPOST('search_date_endmonth', 'int').'&search_date_endday='.GETPOST('search_date_endday', 'int').'&search_date_endyear='.GETPOST('search_date_endyear', 'int'); + $param .= '&search_date_endmonth='.$search_date_endmonth.'&search_date_endday='.$search_date_endday.'&search_date_endyear='.$search_date_endyear; } if (!empty($search_doc_date)) { $filter['t.doc_date'] = $search_doc_date; @@ -242,7 +263,7 @@ if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->suppri } // Make a redirect to avoid to launch the delete later after a back button - header("Location: listbyaccount.php".($param ? '?'.$param : '')); + header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); exit; } } @@ -267,7 +288,7 @@ if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouveme } // Make a redirect to avoid to launch the delete later after a back button - header("Location: listbyaccount.php".($param ? '?'.$param : '')); + header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); exit; } else { setEventMessages("NoRecordDeleted", null, 'warnings'); @@ -284,7 +305,7 @@ if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->suppri setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); } - header("Location: listbyaccount.php?noreset=1".($param ? '&'.$param : '')); + header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : '')); exit; } } @@ -303,7 +324,6 @@ $title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccou llxHeader('', $title_page); - // List $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { @@ -380,10 +400,8 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); - $newcardbutton .= dolGetButtonTitle($langs->trans('VueBySubAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); - - $newcardbutton .= '   '; - + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php', '', 1, array('morecss' => 'marginleftonly')); $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); } diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php index 3bc0351b09b..48c449df43e 100644 --- a/htdocs/accountancy/bookkeeping/listbysubaccount.php +++ b/htdocs/accountancy/bookkeeping/listbysubaccount.php @@ -39,8 +39,14 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; $langs->loadLangs(array("accountancy", "compta")); $action = GETPOST('action', 'aZ09'); -$search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int')); -$search_date_end = dol_mktime(0, 0, 0, GETPOST('search_date_endmonth', 'int'), GETPOST('search_date_endday', 'int'), GETPOST('search_date_endyear', 'int')); +$search_date_startyear = GETPOST('search_date_startyear', 'int'); +$search_date_startmonth = GETPOST('search_date_startmonth', 'int'); +$search_date_startday = GETPOST('search_date_startday', 'int'); +$search_date_endyear = GETPOST('search_date_endyear', 'int'); +$search_date_endmonth = GETPOST('search_date_endmonth', 'int'); +$search_date_endday = GETPOST('search_date_endday', 'int'); +$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); +$search_date_end = dol_mktime(0, 0, 0, $search_date_endmonth, $search_date_endday, $search_date_endyear); $search_doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); $search_accountancy_code = GETPOST("search_accountancy_code"); @@ -126,6 +132,20 @@ $arrayfields = array( if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) unset($arrayfields['t.lettering_code']); +if ($search_date_start && empty($search_date_startyear)) { + $tmparray = dol_getdate($search_date_start); + $search_date_startyear = $tmparray['year']; + $search_date_startmonth = $tmparray['mon']; + $search_date_startday = $tmparray['mday']; +} +if ($search_date_end && empty($search_date_endyear)) { + $tmparray = dol_getdate($search_date_end); + $search_date_endyear = $tmparray['year']; + $search_date_endmonth = $tmparray['mon']; + $search_date_endday = $tmparray['mday']; +} + + /* * Action */ @@ -172,11 +192,11 @@ if (empty($reshook)) if (!empty($search_date_start)) { $filter['t.doc_date>='] = $search_date_start; - $param .= '&search_date_startmonth='.GETPOST('search_date_startmonth', 'int').'&search_date_startday='.GETPOST('search_date_startday', 'int').'&search_date_startyear='.GETPOST('search_date_startyear', 'int'); + $param .= '&search_date_startmonth='.$search_date_startmonth.'&search_date_startday='.$search_date_startday.'&search_date_startyear='.$search_date_startyear; } if (!empty($search_date_end)) { $filter['t.doc_date<='] = $search_date_end; - $param .= '&search_date_endmonth='.GETPOST('search_date_endmonth', 'int').'&search_date_endday='.GETPOST('search_date_endday', 'int').'&search_date_endyear='.GETPOST('search_date_endyear', 'int'); + $param .= '&search_date_endmonth='.$search_date_endmonth.'&search_date_endday='.$search_date_endday.'&search_date_endyear='.$search_date_endyear; } if (!empty($search_doc_date)) { $filter['t.doc_date'] = $search_doc_date; @@ -242,7 +262,7 @@ if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->suppri } // Make a redirect to avoid to launch the delete later after a back button - header("Location: listbyaccount.php".($param ? '?'.$param : '')); + header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); exit; } } @@ -380,7 +400,10 @@ print ''; $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { - $newcardbutton = dolGetButtonTitle($langs->trans('ViewAccountList'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php', '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); + $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php', '', 1, array('morecss' => 'marginleftonly')); + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php', '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); + $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); } @@ -389,6 +412,8 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($l print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit); +print info_admin($langs->trans("WarningRecordWithoutSubledgerAreExcluded")); + $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields if ($massactionbutton) $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); @@ -554,8 +579,16 @@ while ($i < min($num, $limit)) // Show the break account print ""; print ''; - if ($line->subledger_account != "" && $line->subledger_account != '-1') print length_accounta($line->subledger_account).' : '.$object->get_compte_desc($line->numero_compte); - else print ''.$langs->trans("Unknown").''; + if ($line->subledger_account != "" && $line->subledger_account != '-1') { + print $object->get_compte_desc($line->numero_compte).' : '.length_accounta($line->subledger_account); + } else { + // Should not happen: subledger account must be null or a non empty value + print ''.$langs->trans("Unknown"); + if ($line->subledger_label) print ' ('.$line->subledger_label.')'; + $htmltext = 'EmptyStringForSubledgerAccountButSubledgerLabelDefined'; + print $form->textwithpicto('', $htmltext); + print ''; + } print ''; print ''; diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index da9545aa248..bdf86a5c2c9 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -535,13 +535,14 @@ class Documents extends DolibarrApi * Test sample for supplier invoice: { "filename": "mynewfile.txt", "modulepart": "supplier_invoice", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. * Test sample for medias file: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "image/mywebsite", "filecontent": "Y29udGVudCB0ZXh0Cg==", "fileencoding": "base64", "overwriteifexists": "0" }. * - * @param string $filename Name of file to create ('FA1705-0123.txt') - * @param string $modulepart Name of module or area concerned by file upload ('facture', 'project', 'project_task', ...) - * @param string $ref Reference of object (This will define subdir automatically and store submited file into it) - * @param string $subdir Subdirectory (Only if ref not provided) - * @param string $filecontent File content (string with file content. An empty file will be created if this parameter is not provided) - * @param string $fileencoding File encoding (''=no encoding, 'base64'=Base 64) - * @param int $overwriteifexists Overwrite file if exists (1 by default) + * @param string $filename Name of file to create ('FA1705-0123.txt') + * @param string $modulepart Name of module or area concerned by file upload ('facture', 'project', 'project_task', ...) + * @param string $ref Reference of object (This will define subdir automatically and store submited file into it) + * @param string $subdir Subdirectory (Only if ref not provided) + * @param string $filecontent File content (string with file content. An empty file will be created if this parameter is not provided) + * @param string $fileencoding File encoding (''=no encoding, 'base64'=Base 64) + * @param int $overwriteifexists Overwrite file if exists (1 by default) + * @param int $createdirifnotexists Create subdirectories if the doesn't exists (1 by default) * @return string * * @throws RestException 400 @@ -551,7 +552,7 @@ class Documents extends DolibarrApi * * @url POST /upload */ - public function post($filename, $modulepart, $ref = '', $subdir = '', $filecontent = '', $fileencoding = '', $overwriteifexists = 0) + public function post($filename, $modulepart, $ref = '', $subdir = '', $filecontent = '', $fileencoding = '', $overwriteifexists = 0, $createdirifnotexists = 1) { global $db, $conf; @@ -578,6 +579,8 @@ class Documents extends DolibarrApi // Define $uploadir $object = null; $entity = DolibarrApiAccess::$user->entity; + if (empty($entity)) $entity = 1; + if ($ref) { $tmpreldir = ''; @@ -663,8 +666,7 @@ class Documents extends DolibarrApi } } - if (!($object->id > 0)) - { + if (!($object->id > 0)) { throw new RestException(404, 'The object '.$modulepart." with ref '".$ref."' was not found."); } @@ -681,29 +683,32 @@ class Documents extends DolibarrApi if (empty($upload_dir) || $upload_dir == '/') { - throw new RestException(500, 'This value of modulepart does not support yet usage of ref. Check modulepart parameter or try to use subdir parameter instead of ref.'); + throw new RestException(500, 'This value of modulepart ('.$modulepart.') does not support yet usage of ref. Check modulepart parameter or try to use subdir parameter instead of ref.'); } } else { if ($modulepart == 'invoice') $modulepart = 'facture'; if ($modulepart == 'member') $modulepart = 'adherent'; $relativefile = $subdir; - $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write'); $upload_dir = $tmp['original_file']; // No dirname here, tmp['original_file'] is already the dir because dol_check_secure_access_document was called with param original_file that is only the dir - if (empty($upload_dir) || $upload_dir == '/') - { - throw new RestException(500, 'This value of modulepart does not support yet usage of ref. Check modulepart parameter or try to use subdir parameter instead of ref.'); + if (empty($upload_dir) || $upload_dir == '/') { + if (!empty($tmp['error'])) { + throw new RestException(401, 'Error returned by dol_check_secure_access_document: '.$tmp['error']); + } else { + throw new RestException(500, 'This value of modulepart ('.$modulepart.') is not allowed with this value of subdir ('.$relativefile.')'); + } } } // $original_file here is still value of filename without any dir. $upload_dir = dol_sanitizePathName($upload_dir); - if (dol_mkdir($upload_dir) < 0) // needed by products - { - throw new RestException(500, 'Error while trying to create directory.'); + if (!empty($createdirifnotexists)) { + if (dol_mkdir($upload_dir) < 0) { // needed by products + throw new RestException(500, 'Error while trying to create directory.'); + } } $destfile = $upload_dir.'/'.$original_file; @@ -715,8 +720,7 @@ class Documents extends DolibarrApi throw new RestException(401, 'Directory not exists : '.dirname($destfile)); } - if (!$overwriteifexists && dol_is_file($destfile)) - { + if (!$overwriteifexists && dol_is_file($destfile)) { throw new RestException(500, "File with name '".$original_file."' already exists."); } diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 274c04b0698..f572f6110bf 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -598,6 +598,7 @@ class Propal extends CommonObject $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); // Clean vat code + $reg = array(); $vat_src_code = ''; if (preg_match('/\((.*)\)/', $txtva, $reg)) { diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 9ea05a13065..00cba2055f7 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -492,26 +492,21 @@ class Commande extends CommonOrder $error++; } - if (!$error) - { + if (!$error) { // If stock is incremented on validate order, we must increment it - if ($result >= 0 && !empty($conf->stock->enabled) && $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER == 1) - { + if ($result >= 0 && !empty($conf->stock->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) && $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER == 1) { require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; $langs->load("agenda"); // Loop on each line $cpt = count($this->lines); - for ($i = 0; $i < $cpt; $i++) - { - if ($this->lines[$i]->fk_product > 0) - { + for ($i = 0; $i < $cpt; $i++) { + if ($this->lines[$i]->fk_product > 0) { $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; // We decrement stock of product (and sub-products) $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("OrderValidatedInDolibarr", $num)); - if ($result < 0) - { + if ($result < 0) { $error++; $this->error = $mouvP->error; } @@ -521,16 +516,14 @@ class Commande extends CommonOrder } } - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { // Call trigger $result = $this->call_trigger('ORDER_VALIDATE', $user); if ($result < 0) $error++; // End call triggers } - if (!$error) - { + if (!$error) { $this->oldref = $this->ref; // Rename directory if dir was a temporary ref diff --git a/htdocs/compta/cashcontrol/report.php b/htdocs/compta/cashcontrol/report.php index 515067900e3..04cdea52f7f 100644 --- a/htdocs/compta/cashcontrol/report.php +++ b/htdocs/compta/cashcontrol/report.php @@ -133,7 +133,8 @@ if ($resql) { print "

"; if ($cashcontrol->status != $cashcontrol::STATUS_DRAFT) print $langs->trans("CashControl")." ".$cashcontrol->id; else print $langs->trans("CashControl")." - ".$langs->trans("Draft"); - print "
".$langs->trans("DateCreationShort").": ".dol_print_date($cashcontrol->date_creation, 'dayhour')."

"; + print "
".$langs->trans("DateCreationShort").": ".dol_print_date($cashcontrol->date_creation, 'dayhour'); + print ""; $invoicetmp = new Facture($db); @@ -156,8 +157,6 @@ if ($resql) { print_liste_field_titre($arrayfields['b.credit']['label'], $_SERVER['PHP_SELF'], 'b.amount', '', $param, '', $sortfield, $sortorder, 'right '); print "\n"; - $posconciliatecol = 0; - // Loop on each record $sign = 1; $cash = $bank = $cheque = $other = 0; @@ -263,7 +262,7 @@ if ($resql) { print ""; //$cash = $amountpertype['LIQ'] + $cashcontrol->opening; - $cash = $cash + $cashcontrol->opening; + $cash = price2num($cash + $cashcontrol->opening, 'MT'); print "

"; print $langs->trans("Cash").": ".price($cash); diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 5a93a6ded0b..1c874fd2418 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -261,7 +261,7 @@ if ($action == 'confirm_delete' && !empty($permissiontodelete)) // Remove a line if ($action == 'confirm_deleteline' && $confirm == 'yes' && !empty($permissiontoadd)) { - if (method_exists('deleteline', $object)) { + if (method_exists($object, 'deleteline')) { $result = $object->deleteline($user, $lineid); // For backward compatibility } else { $result = $object->deleteLine($user, $lineid); diff --git a/htdocs/core/boxes/box_scheduled_jobs.php b/htdocs/core/boxes/box_scheduled_jobs.php index 81e73f4e0c1..23d520e9a8a 100644 --- a/htdocs/core/boxes/box_scheduled_jobs.php +++ b/htdocs/core/boxes/box_scheduled_jobs.php @@ -71,7 +71,7 @@ class box_scheduled_jobs extends ModeleBoxes */ public function loadBox($max = 5) { - global $user, $langs, $conf; + global $user, $langs, $conf, $form; $langs->load("cron"); $this->info_box_head = array('text' => $langs->trans("BoxScheduledJobs", $max)); @@ -151,7 +151,7 @@ class box_scheduled_jobs extends ModeleBoxes ); $this->info_box_contents[$line][] = array( 'td' => 'class="right"', - 'textnoformat' => dol_print_date($resultarray[$line][2], "dayhoursec") + 'textnoformat' => (empty($resultarray[$line][2]) ? '' : $form->textwithpicto(dol_print_date($resultarray[$line][2], "dayhoursec"), $langs->trans("CurrentTimeZone"))) ); $this->info_box_contents[$line][] = array( 'td' => 'class="right" ', diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 36638be33c1..4495c5ae50d 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -1215,6 +1215,7 @@ class DolGraph } else { $textoflegend = $this->Legend[$i]; } + if ($usecolorvariantforgroupby) { $newcolor = $this->datacolor[$arrayofgroupslegend[$i]['stacknum']]; // If we change the stack @@ -1243,6 +1244,7 @@ class DolGraph $bordercolor = 'rgb(' . $newcolor[0] . ', ' . $newcolor[1] . ', ' . $newcolor[2] . ')'; } else { // We do not use a 'group by' if ($isfunnel) { + $bordercolor == 'null'; if (is_array($this->datacolor[$i])) { $color = 'rgb(' . $this->datacolor[$i][0] . ', ' . $this->datacolor[$i][1] . ', ' . $this->datacolor[$i][2] . ', 0.9)'; // If datacolor is array(R, G, B) } else { @@ -1262,9 +1264,9 @@ class DolGraph if (strpos($tmp, '-') !== false) $bordercolor = '#' . str_replace('-', '', $tmp); // If $val is '-123' else $bordercolor = 'null'; // If $val is '123' or '#123' } - $bordercolor == 'null' ? "'rgba(0,0,0,0.2)'" : "'" . $bordercolor . "'"; } } + $bordercolor == 'null' ? "'rgba(0,0,0,0.2)'" : "'" . $bordercolor . "'"; } else { $color = 'rgb('.$this->datacolor[$i][0].', '.$this->datacolor[$i][1].', '.$this->datacolor[$i][2].', 0.9)'; $bordercolor = $color; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index fdcdc89e53e..57e48242ce3 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3611,15 +3611,14 @@ class Form * * @param string $selected Id pre-selectionne * @param string $htmlname Nom de la zone select + * @param string $addjscombo Add js combo * @return string Code of HTML select to chose tax or not */ - public function selectPriceBaseType($selected = '', $htmlname = 'price_base_type') + public function selectPriceBaseType($selected = '', $htmlname = 'price_base_type', $addjscombo = 0) { global $langs; - $return = ''; - - $return .= ''; $options = array( 'HT'=>$langs->trans("HT"), 'TTC'=>$langs->trans("TTC") @@ -3635,6 +3634,7 @@ class Form $return .= ''; } $return .= ''; + if ($addjscombo) $return .= ajax_combobox('select_'.$htmlname); return $return; } diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index 0b4c4e499e3..26e184eb614 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -1008,4 +1008,44 @@ class FormCompany extends Form return $out; } + + /** + * Output html select to select third-party type + * + * @param string $page Page + * @param string $selected Id preselected + * @param string $htmlname Name of HTML select + * @param string $filter optional filters criteras + * @param int $nooutput No print output. Return it only. + * @return void|string + */ + public function formThirdpartyType($page, $selected = '', $htmlname = 'socid', $filter = '', $nooutput = 0) + { + // phpcs:enable + global $langs; + + $out = ''; + if ($htmlname != "none") + { + $out .= '
'; + $out .= ''; + $out .= ''; + $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. + $out .= $this->selectarray($htmlname, $this->typent_array(0, $filter), $selected, 0, 0, 0, '', 0, 0, 0, $sortparam, '', 1); + $out .= ''; + $out .= '
'; + } else { + if ($selected) + { + $arr = $this->typent_array(0); + $typent = $arr[$selected]; + $out .= $typent; + } else { + $out .= " "; + } + } + + if ($nooutput) return $out; + else print $out; + } } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 0be1cfbc3bc..22545b78cf8 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2231,7 +2231,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Fix modulepart if ($modulepart == 'users') $modulepart = 'user'; - dol_syslog('modulepart='.$modulepart.' original_file='.$original_file.' entity='.$entity); + dol_syslog('dol_check_secure_access_document modulepart='.$modulepart.' original_file='.$original_file.' entity='.$entity); // We define $accessallowed and $sqlprotectagainstexternals $accessallowed = 0; diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index 8cfc08222cd..7e93623f3c1 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -33,7 +33,7 @@ * @param string[] $addheaders Array of string to add into header. Example: ('Accept: application/xrds+xml', ....) * @param string[] $allowedschemes List of schemes that are allowed ('http' + 'https' only by default) * @param int $localurl 0=Only external URL are possible, 1=Only local URL, 2=Both external and local URL are allowed. - * @return array Returns an associative array containing the response from the server array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...) + * @return array Returns an associative array containing the response from the server array('content'=>response, 'curl_error_no'=>errno, 'curl_error_msg'=>errmsg...) */ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation = 1, $addheaders = array(), $allowedschemes = array('http', 'https'), $localurl = 0) { diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index 909e51dc6d7..9ce8d84d7e3 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -546,16 +546,17 @@ function show_stats_for_company($product, $socid) * Return translation label of a unit key. * Function kept for backward compatibility. * - * @param string $scale Scale of unit: '0', '-3', '6', ... - * @param string $measuring_style Style of unit: weight, volume,... - * @param int $unit ID of unit (rowid in llx_c_units table) - * @param int $use_short_label 1=Use short label ('g' instead of 'gram'). Short labels are not translated. - * @return string Unit string + * @param string $scale Scale of unit: '0', '-3', '6', ... + * @param string $measuring_style Style of unit: weight, volume,... + * @param int $unit ID of unit (rowid in llx_c_units table) + * @param int $use_short_label 1=Use short label ('g' instead of 'gram'). Short labels are not translated. + * @param Translate $outputlangs Language object + * @return string Unit string * @see measuringUnitString() formproduct->selectMeasuringUnits() */ -function measuring_units_string($scale = '', $measuring_style = '', $unit = 0, $use_short_label = 0) +function measuring_units_string($scale = '', $measuring_style = '', $unit = 0, $use_short_label = 0, $outputlangs = null) { - return measuringUnitString($unit, $measuring_style, $scale, $use_short_label); + return measuringUnitString($unit, $measuring_style, $scale, $use_short_label, $outputlangs); } /** @@ -565,14 +566,19 @@ function measuring_units_string($scale = '', $measuring_style = '', $unit = 0, $ * @param string $measuring_style Style of unit: 'weight', 'volume', ..., '' = 'net_measure' for option PRODUCT_ADD_NET_MEASURE * @param string $scale Scale of unit: '0', '-3', '6', ... * @param int $use_short_label 1=Use short label ('g' instead of 'gram'). Short labels are not translated. + * @param Translate $outputlangs Language object * @return string Unit string * @see formproduct->selectMeasuringUnits() */ -function measuringUnitString($unit, $measuring_style = '', $scale = '', $use_short_label = 0) +function measuringUnitString($unit, $measuring_style = '', $scale = '', $use_short_label = 0, $outputlangs = null) { global $langs, $db; global $measuring_unit_cache; + if (empty($outputlangs)) { + $outputlangs = $langs; + } + if (empty($measuring_unit_cache[$unit.'_'.$measuring_style.'_'.$scale.'_'.$use_short_label])) { require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php'; @@ -605,7 +611,7 @@ function measuringUnitString($unit, $measuring_style = '', $scale = '', $use_sho } else { if (is_array($measuringUnits->records) && count($measuringUnits->records) > 0) { if ($use_short_label) $labeltoreturn = $measuringUnits->records[key($measuringUnits->records)]->short_label; - else $labeltoreturn = $langs->transnoentitiesnoconv($measuringUnits->records[key($measuringUnits->records)]->label); + else $labeltoreturn = $outputlangs->transnoentitiesnoconv($measuringUnits->records[key($measuringUnits->records)]->label); } else { $labeltoreturn = ''; } diff --git a/htdocs/core/modules/product/doc/pdf_standard.modules.php b/htdocs/core/modules/product/doc/pdf_standard.modules.php index 82143123c40..dcd8419bca6 100644 --- a/htdocs/core/modules/product/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/product/doc/pdf_standard.modules.php @@ -265,7 +265,7 @@ class pdf_standard extends ModelePDFProduct $tab_height = 130; $tab_height_newpage = 150; - // + // Label of product $pdf->SetFont('', 'B', $default_font_size); $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $tab_top, dol_htmlentitiesbr($object->label), 0, 1); $nexY = $pdf->GetY(); @@ -276,29 +276,34 @@ class pdf_standard extends ModelePDFProduct $nexY += 5; + $outputlangs->load("other"); if ($object->weight) { - $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $nexY, $langs->trans("Weight").': '.dol_htmlentitiesbr($object->weight), 0, 1); + $texttoshow = $langs->trans("Weight").': '.dol_htmlentitiesbr($object->weight); + if (isset($object->weight_units)) $texttoshow .= ' '.measuring_units_string($object->weight_units, 'weight', 0, 0, $outputlangs); + $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $nexY, $texttoshow, 0, 1); $nexY = $pdf->GetY(); } if ($object->weight) { - $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $nexY, $langs->trans("Length").' x '.$langs->trans("Width").' x '.$langs->trans("Height").': '.($object->length != '' ? $object->length : '?').' x '.($object->width != '' ? $object->width : '?').' x '.($object->height != '' ? $object->height : '?'), 0, 1); + $texttoshow = $langs->trans("Length").' x '.$langs->trans("Width").' x '.$langs->trans("Height").': '.($object->length != '' ? $object->length : '?').' x '.($object->width != '' ? $object->width : '?').' x '.($object->height != '' ? $object->height : '?'); + $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $nexY, $texttoshow, 0, 1); $nexY = $pdf->GetY(); } if ($object->surface) { - $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $nexY, $langs->trans("Area").': '.dol_htmlentitiesbr($object->surface), 0, 1); + $texttoshow = $langs->trans("Area").': '.dol_htmlentitiesbr($object->surface); + $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $nexY, $texttoshow, 0, 1); $nexY = $pdf->GetY(); } if ($object->volume) { - $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $nexY, $langs->trans("Volume").': '.dol_htmlentitiesbr($object->volume), 0, 1); + $texttoshow = $langs->trans("Volume").': '.dol_htmlentitiesbr($object->volume); + $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $nexY, $texttoshow, 0, 1); $nexY = $pdf->GetY(); } - - // Affiche notes + // Show notes // TODO There is no public note on product yet $notetoshow = empty($object->note_public) ? '' : $object->note_public; if (!empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index b0e5936d326..facb5976f85 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -623,12 +623,12 @@ if (($action == "create") || ($action == "edit")) print ''; print $langs->trans('CronDtStart').""; - if (!empty($object->datestart)) {print dol_print_date($object->datestart, 'dayhoursec'); } + if (!empty($object->datestart)) {print $form->textwithpicto(dol_print_date($object->datestart, 'dayhoursec'), $langs->trans("CurrentTimeZone")); } print ""; print ""; print $langs->trans('CronDtEnd').""; - if (!empty($object->dateend)) {print dol_print_date($object->dateend, 'dayhoursec'); } + if (!empty($object->dateend)) {print $form->textwithpicto(dol_print_date($object->dateend, 'dayhoursec'), $langs->trans("CurrentTimeZone")); } print ""; print ""; @@ -653,7 +653,7 @@ if (($action == "create") || ($action == "edit")) print ' ('.$langs->trans('CronFrom').')'; print ""; if (!$object->status) print $langs->trans("Disabled"); - elseif (!empty($object->datenextrun)) { print img_picto('', 'object_calendarday').' '.dol_print_date($object->datenextrun, 'dayhoursec'); } else { print $langs->trans('CronNone'); } + elseif (!empty($object->datenextrun)) { print img_picto('', 'object_calendarday').' '.$form->textwithpicto(dol_print_date($object->datenextrun, 'dayhoursec'), $langs->trans("CurrentTimeZone")); } else { print $langs->trans('CronNone'); } if ($object->status == Cronjob::STATUS_ENABLED) { if ($object->maxrun && $object->nbrun >= $object->maxrun) print img_warning($langs->trans("MaxRunReached")); @@ -672,12 +672,12 @@ if (($action == "create") || ($action == "edit")) print ''; print $langs->trans('CronDtLastLaunch').""; - if (!empty($object->datelastrun)) {print dol_print_date($object->datelastrun, 'dayhoursec'); } else {print $langs->trans('CronNone'); } + if (!empty($object->datelastrun)) {print $form->textwithpicto(dol_print_date($object->datelastrun, 'dayhoursec'), $langs->trans("CurrentTimeZone")); } else {print $langs->trans('CronNone'); } print ""; print ''; print $langs->trans('CronDtLastResult').""; - if (!empty($object->datelastresult)) {print dol_print_date($object->datelastresult, 'dayhoursec'); } else {print $langs->trans('CronNone'); } + if (!empty($object->datelastresult)) {print $form->textwithpicto(dol_print_date($object->datelastresult, 'dayhoursec'), $langs->trans("CurrentTimeZone")); } else {print $langs->trans('CronNone'); } print ""; print ''; diff --git a/htdocs/intracommreport/card.php b/htdocs/intracommreport/card.php index f0a4bd5f070..077f793d649 100644 --- a/htdocs/intracommreport/card.php +++ b/htdocs/intracommreport/card.php @@ -27,28 +27,41 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; require_once DOL_DOCUMENT_ROOT.'/intracommreport/class/intracommreport.class.php'; $langs->loadLangs(array("intracommreport")); - +var_dump($_POST); $action = GETPOST('action'); -$exporttype = GETPOST('exporttype'); // DEB ou DES -if (empty($exporttype)) { - $exporttype = 'deb'; -} - -$form = new Form($db); -$formother = new FormOther($db); -$year = GETPOST('year'); -$month = GETPOST('month'); +$exporttype = GETPOSTISSET('exporttype') ? GETPOST('exporttype', 'alphanohtml') : 'deb'; // DEB ou DES +$year = GETPOSTINT('year'); +$month = GETPOSTINT('month'); $label = (string) GETPOST('label', 'alphanohtml'); -$type_declaration = GETPOSTINT('type'); +$type_declaration = (string) GETPOST('type_declaration', 'alphanohtml'); $backtopage = GETPOST('backtopage', 'alpha'); $declaration = array( "deb" => $langs->trans("DEB"), "des" => $langs->trans("DES"), ); +$typeOfDeclaration = array( + "introduction" => $langs->trans("Introduction"), + "expedition" => $langs->trans("Expedition"), +); +$object = new IntracommReport($db); +if ($id > 0) { + $object->fetch($id); +} +$form = new Form($db); +$formother = new FormOther($db); + +// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array +$hookmanager->initHooks(array('intracommcard', 'globalcard')); /* * Actions */ +$parameters = array('id' => $id); +// Note that $action and $object may have been modified by some hooks +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} if ($user->rights->intracommreport->delete && $action == 'confirm_delete' && $confirm == 'yes') { $result = $object->delete($id, $user); @@ -72,16 +85,16 @@ if ($action == 'add' && $user->rights->intracommreport->write) { $object->subscription = (int) $subscription; // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) { - $error++; - } + // $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + // if ($ret < 0) { + // $error++; + // } if (empty($object->label)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); } else { - $sql = "SELECT libelle FROM ".MAIN_DB_PREFIX."adherent_type WHERE libelle='".$db->escape($object->label)."'"; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."intracommreport WHERE ref='".$db->escape($object->label)."'"; $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); @@ -96,7 +109,7 @@ if ($action == 'add' && $user->rights->intracommreport->write) { if (!$error) { $id = $object->create($user); if ($id > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); + header("Location: ".$_SERVER["PHP_SELF"].'?id='.$id); exit; } else { setEventMessages($object->error, $object->errors, 'errors'); @@ -145,10 +158,8 @@ if ($action == 'create') { print ''; // Type of declaration - $typeOfDeclaration["introduction"] = $langs->trans("Introduction"); - $typeOfDeclaration["expedition"] = $langs->trans("Expedition"); print ''.$langs->trans("TypeOfDeclaration")."\n"; - print $form->selectarray("type_declaration", $typeOfDeclaration, GETPOST('type_declaration', 'alpha') ?GETPOST('type_declaration', 'alpha') : $object->type_declaration, 0); + print $form->selectarray("type_declaration", $typeOfDeclaration, GETPOST('type_declaration', 'alpha') ? GETPOST('type_declaration', 'alpha') : $object->type_declaration, 0); print "\n"; print ''; @@ -177,9 +188,9 @@ if ($id > 0 && $action != 'edit') { /* * Show tabs */ - $head = intracommreport_prepare_head($object); + //$head = intracommreport_prepare_head($object); - print dol_get_fiche_head($head, 'general', $langs->trans("IntracommReport"), -1, 'user'); + print dol_get_fiche_head("", 'general', $langs->trans("IntracommReport"), -1, 'user'); // Confirm remove report if ($action == 'delete') { diff --git a/htdocs/intracommreport/class/intracommreport.class.php b/htdocs/intracommreport/class/intracommreport.class.php index d1145dcf806..0cf5a71c27a 100644 --- a/htdocs/intracommreport/class/intracommreport.class.php +++ b/htdocs/intracommreport/class/intracommreport.class.php @@ -81,13 +81,46 @@ class IntracommReport extends CommonObject $this->exporttype = 'deb'; } + /** + * Fonction create + * @param User $user User + * @param int $notrigger notrigger + * @return int + */ + public function create($user, $notrigger = 0) + { + return 1; + } + + /** + * Fonction fetch + * @param int $id object ID + * @return int + */ + public function fetch($id) + { + return 1; + } + + /** + * Fonction delete + * @param int $id object ID + * @param User $user User + * @param int $notrigger notrigger + * @return int + */ + public function delete($id, $user, $notrigger = 0) + { + return 1; + } + /** * Generate XML file * - * @param int $mode O for create, R for regenerate (Look always 0 ment toujours 0 within the framework of XML exchanges according to documentation) - * @param string $type Declaration type by default - introduction or expedition (always 'expedition' for Des) - * @param string $period_reference Period of reference - * @return void + * @param int $mode O for create, R for regenerate (Look always 0 ment toujours 0 within the framework of XML exchanges according to documentation) + * @param string $type Declaration type by default - introduction or expedition (always 'expedition' for Des) + * @param string $period_reference Period of reference + * @return SimpleXMLElement|int */ public function getXML($mode = 'O', $type = 'introduction', $period_reference = '') { @@ -149,7 +182,7 @@ class IntracommReport extends CommonObject * @param int $period_year Year of declaration * @param int $period_month Month of declaration * @param string $type_declaration Declaration type by default - introduction or expedition (always 'expedition' for Des) - * @return void + * @return SimpleXMLElement|int */ public function getXMLDes($period_year, $period_month, $type_declaration = 'expedition') { @@ -246,7 +279,7 @@ class IntracommReport extends CommonObject * @param string $type Declaration type by default - introduction or expedition (always 'expedition' for Des) * @param int $period_reference Reference declaration * @param string $exporttype deb=DEB, des=DES - * @return int <0 if KO, >0 if OK + * @return string <0 if KO, >0 if OK */ public function getSQLFactLines($type, $period_reference, $exporttype = 'deb') { @@ -325,7 +358,7 @@ class IntracommReport extends CommonObject * Add item for DES * * @param SimpleXMLElement $declaration Reference declaration - * @param esurce $res Result of request SQL + * @param Resource $res Result of request SQL * @param int $i Line Id * @return void */ diff --git a/htdocs/intracommreport/list.php b/htdocs/intracommreport/list.php index 1530e07d84e..d3346e344f4 100644 --- a/htdocs/intracommreport/list.php +++ b/htdocs/intracommreport/list.php @@ -121,8 +121,8 @@ $isInEEC = isInEEC($mysoc); // Definition of fields for lists $arrayfields = array( - 'i.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), - 'i.label'=>array('label'=>$langs->trans("Label"), 'checked'=>1), + 'i.ref' => array('label'=>$langs->trans("Ref"), 'checked'=>1), + 'i.label' => array('label'=>$langs->trans("Label"), 'checked'=>1), 'i.fk_product_type'=>array('label'=>$langs->trans("Type"), 'checked'=>0, 'enabled'=>(!empty($conf->produit->enabled) && !empty($conf->service->enabled))), ); /* diff --git a/htdocs/langs/am_ET/products.lang b/htdocs/langs/am_ET/products.lang index 97db059594f..18af7f2f252 100644 --- a/htdocs/langs/am_ET/products.lang +++ b/htdocs/langs/am_ET/products.lang @@ -108,7 +108,7 @@ FillWithLastServiceDates=Fill with last service line dates MultiPricesAbility=Multiple price segments per product/service (each customer is in one price segment) MultiPricesNumPrices=Number of prices DefaultPriceType=Base of prices per default (with versus without tax) when adding new sale prices -AssociatedProductsAbility=Activate kits (virtual products) +AssociatedProductsAbility=Enable Kits (set of other products) AssociatedProducts=Kits AssociatedProductsNumber=Number of products composing this kit ParentProductsNumber=Number of parent packaging product diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 82338c8f98d..47f3d109662 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -208,7 +208,8 @@ JournalLabel=Journal label NumPiece=Piece number TransactionNumShort=Num. transaction AccountingCategory=Personalized groups -GroupByAccountAccounting=Group by accounting account +GroupByAccountAccounting=Group by general ledger account +GroupBySubAccountAccounting=Group by subledger account AccountingAccountGroupsDesc=You can define here some groups of accounting account. They will be used for personalized accounting reports. ByAccounts=By accounts ByPredefinedAccountGroups=By predefined groups @@ -295,6 +296,7 @@ Accounted=Accounted in ledger NotYetAccounted=Not yet accounted in ledger ShowTutorial=Show Tutorial NotReconciled=Not reconciled +WarningRecordWithoutSubledgerAreExcluded=Warning, all operations without subledger account defined are filtered and excluded from this view ## Admin BindingOptions=Binding options diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index b6784b75835..8e087ae6110 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -56,6 +56,8 @@ GUISetup=Display SetupArea=Setup UploadNewTemplate=Upload new template(s) FormToTestFileUploadForm=Form to test file upload (according to setup) +ModuleMustBeEnabled=The module/application %s must be enabled +ModuleIsEnabled=The module/application %s has been enabled IfModuleEnabled=Note: yes is effective only if module %s is enabled RemoveLock=Remove/rename file %s if it exists, to allow usage of the Update/Install tool. RestoreLock=Restore file %s, with read permission only, to disable any further use of the Update/Install tool. diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 8a18520c2fc..99bed13179f 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -358,7 +358,7 @@ VATIntraCheckableOnEUSite=Check the intra-Community VAT ID on the European Commi VATIntraManualCheck=You can also check manually on the European Commission website %s ErrorVATCheckMS_UNAVAILABLE=Check not possible. Check service is not provided by the member state (%s). NorProspectNorCustomer=Not prospect, nor customer -JuridicalStatus=Legal Entity Type +JuridicalStatus=Business entity type Workforce=Workforce Staff=Employees ProspectLevelShort=Potential diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index c32e4d01ddd..73c9964000e 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -29,6 +29,7 @@ AvailableVariables=Available substitution variables NoTranslation=No translation Translation=Translation EmptySearchString=Enter non empty search criterias +EnterADateCriteria=Enter a date criteria NoRecordFound=No record found NoRecordDeleted=No record deleted NotEnoughDataYet=Not enough data diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 6b61f8c06c1..6f8fdcad996 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -126,7 +126,6 @@ UseSpecificEditorURL = Use a specific editor URL UseSpecificFamily = Use a specific family UseSpecificAuthor = Use a specific author UseSpecificVersion = Use a specific initial version -ModuleMustBeEnabled=The module/application must be enabled first IncludeRefGeneration=The reference of object must be generated automatically IncludeRefGenerationHelp=Check this if you want to include code to manage the generation automatically of the reference IncludeDocGeneration=I want to generate some documents from the object diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 7495291cf3f..011352f1dcd 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -138,7 +138,7 @@ Right=Right CalculatedWeight=Calculated weight CalculatedVolume=Calculated volume Weight=Weight -WeightUnitton=tonne +WeightUnitton=ton WeightUnitkg=kg WeightUnitg=g WeightUnitmg=mg diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 8c30b2e02c1..f0c4a5362b8 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -108,7 +108,8 @@ FillWithLastServiceDates=Fill with last service line dates MultiPricesAbility=Multiple price segments per product/service (each customer is in one price segment) MultiPricesNumPrices=Number of prices DefaultPriceType=Base of prices per default (with versus without tax) when adding new sale prices -AssociatedProductsAbility=Activate kits (virtual products) +AssociatedProductsAbility=Enable Kits (set of other products) +VariantsAbility=Enable Variants (variations of products, for example color, size) AssociatedProducts=Kits AssociatedProductsNumber=Number of products composing this kit ParentProductsNumber=Number of parent packaging product diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index d2c1b2cb382..1b54e53d6de 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -240,3 +240,4 @@ InventoryRealQtyHelp=Set value to 0 to reset qty
Keep field empty, or remove UpdateByScaning=Update by scaning UpdateByScaningProductBarcode=Update by scan (product barcode) UpdateByScaningLot=Update by scan (lot|serial barcode) +DisableStockChangeOfSubProduct=Deactivate the stock change for all the subproducts of this Kit during this movement. \ No newline at end of file diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index babce9eba15..fba9b0d4855 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -2385,7 +2385,7 @@ if ($module == 'initmodule') print '   '; if (empty($conf->global->$const_name)) // If module is not activated { - print ''.$langs->trans("GoToApiExplorer").''; + print ''.$langs->trans("GoToApiExplorer").''; } else { print ''.$langs->trans("GoToApiExplorer").''; } diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 16c3c849ce6..6cd727d33b8 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -127,8 +127,8 @@ if ($action == 'other') $value = GETPOST('price_base_type', 'alpha'); $res = dolibarr_set_const($db, "PRODUCT_PRICE_BASE_TYPE", $value, 'chaine', 0, '', $conf->entity); - $value = GETPOST('PRODUIT_SOUSPRODUITS', 'alpha'); - $res = dolibarr_set_const($db, "PRODUIT_SOUSPRODUITS", $value, 'chaine', 0, '', $conf->entity); + /*$value = GETPOST('PRODUIT_SOUSPRODUITS', 'alpha'); + $res = dolibarr_set_const($db, "PRODUIT_SOUSPRODUITS", $value, 'chaine', 0, '', $conf->entity);*/ $value = GETPOST('activate_viewProdDescInForm', 'alpha'); $res = dolibarr_set_const($db, "PRODUIT_DESC_IN_FORM", $value, 'chaine', 0, '', $conf->entity); @@ -312,7 +312,6 @@ print ' '.$langs->trans("Status").''; print ' '.$langs->trans("ShortInfo").''; print "\n"; -$var = true; foreach ($dirproduct as $dirroot) { $dir = dol_buildpath($dirroot, 0); @@ -340,7 +339,6 @@ foreach ($dirproduct as $dirroot) if ($modCodeProduct->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; if ($modCodeProduct->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; - $var = !$var; print ''."\n"; print ''.$modCodeProduct->name.''."\n"; print ''.$modCodeProduct->info($langs).''."\n"; @@ -537,17 +535,35 @@ print ''.$langs->trans("Value").''."\n"; print ''."\n"; -/* - * Other parameters - */ +// Enable kits (subproducts) -$rowspan = 4; -if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) $rowspan++; -if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) $rowspan++; -if (!empty($conf->global->MAIN_MULTILANGS)) $rowspan++; -if (!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) $rowspan++; +print ''; +print ''.$langs->trans("AssociatedProductsAbility").''; +print ''; +print ajax_constantonoff("PRODUIT_SOUSPRODUITS", array(), $conf->entity, 0, 0, 1, 0); +//print $form->selectyesno("PRODUIT_SOUSPRODUITS", $conf->global->PRODUIT_SOUSPRODUITS, 1); +print ''; +print ''; +// Enable variants + +print ''; +print ''.$langs->trans("VariantsAbility").''; +print ''; +//print ajax_constantonoff("PRODUIT_SOUSPRODUITS", array(), $conf->entity, 0, 0, 1, 0); +//print $form->selectyesno("PRODUIT_SOUSPRODUITS", $conf->global->PRODUIT_SOUSPRODUITS, 1); +if (empty($conf->variants->enabled)) { + print ''.$langs->trans("ModuleMustBeEnabled", $langs->transnoentitiesnoconv("Module610Name")).''; +} else { + print yn(1).' ('.$langs->trans("ModuleIsEnabled", $langs->transnoentitiesnoconv("Module610Name")).')'; +} +print ''; +print ''; + + +// Rule for price + print ''; if (empty($conf->multicompany->enabled)) { @@ -575,24 +591,15 @@ if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_ print ''; } -//Default product price base type +// Default product price base type print ''; print ''.$langs->trans("DefaultPriceType").''; -print ''; +print ''; print $form->selectPriceBaseType($conf->global->PRODUCT_PRICE_BASE_TYPE, "price_base_type"); print ''; print ''; -// sousproduits activation/desactivation - -print ''; -print ''.$langs->trans("AssociatedProductsAbility").''; -print ''; -print $form->selectyesno("PRODUIT_SOUSPRODUITS", $conf->global->PRODUIT_SOUSPRODUITS, 1); -print ''; -print ''; - -// Utilisation formulaire Ajax sur choix produit +// Use Ajax form to select a product print ''; print ''.$form->textwithpicto($langs->trans("UseSearchToSelectProduct"), $langs->trans('UseSearchToSelectProductTooltip'), 1).''; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index bcf32cdce26..e1b25b9e3b7 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -280,20 +280,20 @@ class Product extends CommonObject //! Metric of products public $weight; - public $weight_units; + public $weight_units; // scale -3, 0, 3, 6 public $length; - public $length_units; + public $length_units; // scale -3, 0, 3, 6 public $width; - public $width_units; + public $width_units; // scale -3, 0, 3, 6 public $height; - public $height_units; + public $height_units; // scale -3, 0, 3, 6 public $surface; - public $surface_units; + public $surface_units; // scale -3, 0, 3, 6 public $volume; - public $volume_units; + public $volume_units; // scale -3, 0, 3, 6 public $net_measure; - public $net_measure_units; + public $net_measure_units; // scale -3, 0, 3, 6 public $accountancy_code_sell; public $accountancy_code_sell_intra; @@ -4229,9 +4229,9 @@ class Product extends CommonObject // phpcs:enable $this->res = array(); if (isset($this->sousprods) && is_array($this->sousprods)) { - foreach ($this->sousprods as $prod_name => $desc_product) - { - if (is_array($desc_product)) { $this->fetch_prod_arbo($desc_product, "", $multiply, 1, $this->id); + foreach ($this->sousprods as $prod_name => $desc_product) { + if (is_array($desc_product)) { + $this->fetch_prod_arbo($desc_product, "", $multiply, 1, $this->id); } } } @@ -4777,9 +4777,10 @@ class Product extends CommonObject * @param string $inventorycode Inventory code * @param string $origin_element Origin element type * @param int $origin_id Origin id of element + * @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (usefull only if product is a subproduct) * @return int <0 if KO, >0 if OK */ - public function correct_stock($user, $id_entrepot, $nbpiece, $movement, $label = '', $price = 0, $inventorycode = '', $origin_element = '', $origin_id = null) + public function correct_stock($user, $id_entrepot, $nbpiece, $movement, $label = '', $price = 0, $inventorycode = '', $origin_element = '', $origin_id = null, $disablestockchangeforsubproduct = 0) { // phpcs:enable if ($id_entrepot) { @@ -4792,7 +4793,7 @@ class Product extends CommonObject $movementstock = new MouvementStock($this->db); $movementstock->setOrigin($origin_element, $origin_id); // Set ->origin and ->origin->id - $result = $movementstock->_create($user, $this->id, $id_entrepot, $op[$movement], $movement, $price, $label, $inventorycode); + $result = $movementstock->_create($user, $this->id, $id_entrepot, $op[$movement], $movement, $price, $label, $inventorycode, '', '', '', '', false, 0, $disablestockchangeforsubproduct); if ($result >= 0) { $this->db->commit(); @@ -4823,9 +4824,10 @@ class Product extends CommonObject * @param string $inventorycode Inventory code * @param string $origin_element Origin element type * @param int $origin_id Origin id of element + * @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (usefull only if product is a subproduct) * @return int <0 if KO, >0 if OK */ - public function correct_stock_batch($user, $id_entrepot, $nbpiece, $movement, $label = '', $price = 0, $dlc = '', $dluo = '', $lot = '', $inventorycode = '', $origin_element = '', $origin_id = null) + public function correct_stock_batch($user, $id_entrepot, $nbpiece, $movement, $label = '', $price = 0, $dlc = '', $dluo = '', $lot = '', $inventorycode = '', $origin_element = '', $origin_id = null, $disablestockchangeforsubproduct = 0) { // phpcs:enable if ($id_entrepot) { @@ -4838,7 +4840,7 @@ class Product extends CommonObject $movementstock = new MouvementStock($this->db); $movementstock->setOrigin($origin_element, $origin_id); - $result = $movementstock->_create($user, $this->id, $id_entrepot, $op[$movement], $movement, $price, $label, $inventorycode, '', $dlc, $dluo, $lot); + $result = $movementstock->_create($user, $this->id, $id_entrepot, $op[$movement], $movement, $price, $label, $inventorycode, '', $dlc, $dluo, $lot, false, 0, $disablestockchangeforsubproduct); if ($result >= 0) { $this->db->commit(); @@ -5387,19 +5389,19 @@ class Product extends CommonObject $this->date_modification = $now; $this->weight = 4; - $this->weight_unit = 1; + $this->weight_units = 3; $this->length = 5; - $this->length_unit = 1; + $this->length_units = 1; $this->width = 6; - $this->width_unit = 0; + $this->width_units = 0; $this->height = null; - $this->height_unit = null; + $this->height_units = null; $this->surface = 30; - $this->surface_unit = 0; + $this->surface_units = 0; $this->volume = 300; - $this->volume_unit = 0; + $this->volume_units = 0; $this->barcode = -1; // Create barcode automatically } diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index 13ef4582d20..8459fa3e479 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2017 Laurent Destailleur + * Copyright (C) 2004-2020 Laurent Destailleur * Copyright (C) 2005 Eric Seigne * Copyright (C) 2005-2018 Regis Houssin * Copyright (C) 2006 Andre Cianfarani @@ -137,7 +137,7 @@ if ($action == 'search') $current_lang = $langs->getDefaultLang(); $sql = 'SELECT DISTINCT p.rowid, p.ref, p.label, p.fk_product_type as type, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,'; - $sql .= ' p.fk_product_type, p.tms as datem'; + $sql .= ' p.fk_product_type, p.tms as datem, p.tobatch'; if (!empty($conf->global->MAIN_MULTILANGS)) $sql .= ', pl.label as labelm, pl.description as descriptionm'; $sql .= ' FROM '.MAIN_DB_PREFIX.'product as p'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON p.rowid = cp.fk_product'; @@ -204,7 +204,7 @@ if ($id > 0 || !empty($ref)) dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', '', '', '', 0, '', '', 0); - if ($object->type != Product::TYPE_SERVICE || empty($conf->global->PRODUIT_MULTIPRICES)) + if ($object->type != Product::TYPE_SERVICE || !empty($conf->global->STOCK_SUPPORTS_SERVICES) || empty($conf->global->PRODUIT_MULTIPRICES)) { print '
'; print '
'; @@ -320,14 +320,11 @@ if ($id > 0 || !empty($ref)) print ''."\n"; $totalsell = 0; - if (count($prods_arbo)) - { - foreach ($prods_arbo as $value) - { + if (count($prods_arbo)) { + foreach ($prods_arbo as $value) { $productstatic->fetch($value['id']); - if ($value['level'] <= 1) - { + if ($value['level'] <= 1) { print ''; $notdefined = 0; @@ -380,7 +377,7 @@ if ($id > 0 || !empty($ref)) // Qty + IncDec if ($user->rights->produit->creer || $user->rights->service->creer) { - print ''; + print ''; print ''; } else { print ''.$nb_of_subproduct.''; @@ -566,6 +563,7 @@ if ($id > 0 || !empty($ref)) $productstatic->label = $objp->label; $productstatic->type = $objp->type; $productstatic->entity = $objp->entity; + $productstatic->status_batch = $objp->tobatch; print ''.$productstatic->getNomUrl(1, '', 24).''; $labeltoshow = $objp->label; diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index c97c56b2887..631cedd0a25 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -128,26 +128,27 @@ class MouvementStock extends CommonObject * Add a movement of stock (in one direction only). * $this->origin can be also be set to save the source object of movement. * - * @param User $user User object - * @param int $fk_product Id of product - * @param int $entrepot_id Id of warehouse - * @param int $qty Qty of movement (can be <0 or >0 depending on parameter type) - * @param int $type Direction of movement: - * 0=input (stock increase by a stock transfer), 1=output (stock decrease by a stock transfer), - * 2=output (stock decrease), 3=input (stock increase) - * Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2. - * @param int $price Unit price HT of product, used to calculate average weighted price (AWP or PMP in french). If 0, average weighted price is not changed. - * @param string $label Label of stock movement - * @param string $inventorycode Inventory code - * @param string $datem Force date of movement - * @param integer $eatby eat-by date. Will be used if lot does not exists yet and will be created. - * @param integer $sellby sell-by date. Will be used if lot does not exists yet and will be created. - * @param string $batch batch number - * @param boolean $skip_batch If set to true, stock movement is done without impacting batch record + * @param User $user User object + * @param int $fk_product Id of product + * @param int $entrepot_id Id of warehouse + * @param int $qty Qty of movement (can be <0 or >0 depending on parameter type) + * @param int $type Direction of movement: + * 0=input (stock increase by a stock transfer), 1=output (stock decrease by a stock transfer), + * 2=output (stock decrease), 3=input (stock increase) + * Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2. + * @param int $price Unit price HT of product, used to calculate average weighted price (AWP or PMP in french). If 0, average weighted price is not changed. + * @param string $label Label of stock movement + * @param string $inventorycode Inventory code + * @param string $datem Force date of movement + * @param integer $eatby eat-by date. Will be used if lot does not exists yet and will be created. + * @param integer $sellby sell-by date. Will be used if lot does not exists yet and will be created. + * @param string $batch batch number + * @param boolean $skip_batch If set to true, stock movement is done without impacting batch record * @param int $id_product_batch Id product_batch (when skip_batch is false and we already know which record of product_batch to use) - * @return int <0 if KO, 0 if fk_product is null or product id does not exists, >0 if OK + * @param int $disablestockchangeforsubproduct Disable stock change for sub-products of kit (usefull only if product is a subproduct) + * @return int <0 if KO, 0 if fk_product is null or product id does not exists, >0 if OK */ - public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false, $id_product_batch = 0) + public function _create($user, $fk_product, $entrepot_id, $qty, $type, $price = 0, $label = '', $inventorycode = '', $datem = '', $eatby = '', $sellby = '', $batch = '', $skip_batch = false, $id_product_batch = 0, $disablestockchangeforsubproduct = 0) { // phpcs:disable global $conf, $langs; @@ -571,9 +572,9 @@ class MouvementStock extends CommonObject } // Add movement for sub products (recursive call) - if (!$error && !empty($conf->global->PRODUIT_SOUSPRODUITS) && empty($conf->global->INDEPENDANT_SUBPRODUCT_STOCK)) + if (!$error && !empty($conf->global->PRODUIT_SOUSPRODUITS) && empty($conf->global->INDEPENDANT_SUBPRODUCT_STOCK) && empty($disablestockchangeforsubproduct)) { - $error = $this->_createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, 0, $label, $inventorycode); // we use 0 as price, because pmp is not changed for subproduct + $error = $this->_createSubProduct($user, $fk_product, $entrepot_id, $qty, $type, 0, $label, $inventorycode); // we use 0 as price, because AWP must not change for subproduct } if ($movestock && !$error) diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 0ea05495e5a..89df906feda 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -108,6 +108,8 @@ if (!empty($canvas)) // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('stockproductcard', 'globalcard')); +$error = 0; + /* * Actions @@ -221,17 +223,14 @@ if ($action == "correct_stock" && !$cancel) } } - if (!$error) - { + if (!$error) { $priceunit = price2num(GETPOST("unitprice")); $nbpiece = price2num(GETPOST("nbpiece", 'alphanohtml')); - if (is_numeric($nbpiece) && $nbpiece != 0 && $id) - { + if (is_numeric($nbpiece) && $nbpiece != 0 && $id) { $origin_element = ''; $origin_id = null; - if (GETPOST('projectid', 'int')) - { + if (GETPOST('projectid', 'int')) { $origin_element = 'project'; $origin_id = GETPOST('projectid', 'int'); } @@ -240,8 +239,13 @@ if ($action == "correct_stock" && !$cancel) $object = new Product($db); $result = $object->fetch($id); } - if ($object->hasbatch()) - { + + $disablestockchangeforsubproduct = 0; + if (GETPOST('disablesubproductstockchange')) { + $disablestockchangeforsubproduct = 1; + } + + if ($object->hasbatch()) { $result = $object->correct_stock_batch( $user, GETPOST("id_entrepot", 'int'), @@ -254,7 +258,8 @@ if ($action == "correct_stock" && !$cancel) $batchnumber, GETPOST('inventorycode', 'alphanohtml'), $origin_element, - $origin_id + $origin_id, + $disablestockchangeforsubproduct ); // We do not change value of stock for a correction } else { $result = $object->correct_stock( @@ -266,14 +271,13 @@ if ($action == "correct_stock" && !$cancel) $priceunit, GETPOST('inventorycode', 'alphanohtml'), $origin_element, - $origin_id + $origin_id, + $disablestockchangeforsubproduct ); // We do not change value of stock for a correction } - if ($result > 0) - { - if ($backtopage) - { + if ($result > 0) { + if ($backtopage) { header("Location: ".$backtopage); exit; } else { @@ -535,12 +539,14 @@ if ($id > 0 || $ref) dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref'); - print '
'; - - print '
'; - print ''; - if (!$variants) { + print '
'; + + print '
'; + print '
'; + + print '
'; + if ($conf->productbatch->enabled) { print ''; } - // Stock alert threshold - print ''; - // Hook formObject $parameters = array(); $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; + print '
'.$langs->trans("ManageLotSerial").''; print $object->getLibStatut(0, 2); @@ -604,16 +610,23 @@ if ($id > 0 || $ref) print '
'.$form->editfieldkey($form->textwithpicto($langs->trans("StockLimit"), $langs->trans("StockLimitDesc"), 1), 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer).''; - print $form->editfieldval("StockLimit", 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer, 'string'); - print '
'; + + print '
'; + print '
'; + + print ''; + + // Stock alert threshold + print ''; + // Desired stock print '"; } - } - print "
'.$form->editfieldkey($form->textwithpicto($langs->trans("StockLimit"), $langs->trans("StockLimitDesc"), 1), 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer).''; + print $form->editfieldval("StockLimit", 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer, 'string'); + print '
'.$form->editfieldkey($form->textwithpicto($langs->trans("DesiredStock"), $langs->trans("DesiredStockDesc"), 1), 'desiredstock', $object->desiredstock, $object, $user->rights->produit->creer); print ''; @@ -727,11 +740,15 @@ if ($id > 0 || $ref) } print "
"; - print '
'; - print '
'; + print ""; + + print '
'; + print '
'; + print '

'; + + print '
'; + } print dol_get_fiche_end(); } diff --git a/htdocs/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php index f48ac986d20..91159984a35 100644 --- a/htdocs/product/stock/stockatdate.php +++ b/htdocs/product/stock/stockatdate.php @@ -347,10 +347,14 @@ print ''; print '
'; print ''.$langs->trans('Date').' '.$form->selectDate(($date ? $date : -1), 'date'); -print '   '.$langs->trans('Product').' '; +print '   '; +print img_picto('', 'product').' '; +print $langs->trans('Product').' '; $form->select_produits($productid, 'productid', '', 0, 0, -1, 2, '', 0, array(), 0, '1', 0, 'maxwidth300'); -print '   '.$langs->trans('Warehouse').' '; +print '   '; +print img_picto('', 'stock').' '; +print $langs->trans('Warehouse').' '; print $formproduct->selectWarehouses((GETPOSTISSET('fk_warehouse') ? $fk_warehouse : 'ifone'), 'fk_warehouse', '', 1); print '
'; @@ -558,7 +562,7 @@ print $hookmanager->resPrint; if (empty($date) || ! $dateIsValid) { $colspan = 6; if ($mode == 'future') $colspan++; - print ''.$langs->trans("EmptySearchString").''; + print ''.$langs->trans("EnterADateCriteria").''; } print ''; diff --git a/htdocs/product/stock/tpl/stockcorrection.tpl.php b/htdocs/product/stock/tpl/stockcorrection.tpl.php index 0885e9ef777..4f88b448239 100644 --- a/htdocs/product/stock/tpl/stockcorrection.tpl.php +++ b/htdocs/product/stock/tpl/stockcorrection.tpl.php @@ -70,7 +70,7 @@ if ($object->element == 'product') { print ''; $ident = (GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ? GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))); if (empty($ident) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE)) $ident = $conf->global->MAIN_DEFAULT_WAREHOUSE; - print $formproduct->selectWarehouses($ident, 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100'); + print img_picto('', 'stock').$formproduct->selectWarehouses($ident, 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100'); print '   '; print ''; @@ -91,6 +92,17 @@ print ''.$langs->trans("NumberOfUnit").''; print ''; print ''; +// If product is a Kit, we ask if we must disable stock change of subproducts +if (!empty($conf->global->PRODUIT_SOUSPRODUITS) && $object->element == 'product' && $object->hasFatherOrChild(1)) { + print ''; + print ''; + print ''; + print ''; + print ' '; + print ''; + print ''; +} + // Serial / Eat-by date if (!empty($conf->productbatch->enabled) && (($object->element == 'product' && $object->hasbatch()) @@ -126,6 +138,7 @@ if (!empty($conf->projet->enabled)) { print ''.$langs->trans('Project').''; print ''; + print img_picto('', 'project'); $formproject->select_projects(-1, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); print ''; } diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php index 7e159a35b32..20445445e8e 100644 --- a/htdocs/product/stock/tpl/stocktransfer.tpl.php +++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php @@ -71,18 +71,19 @@ print ''; if ($object->element == 'product') { print ''.$langs->trans("WarehouseSource").''; print ''; - print $formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1); + print img_picto('', 'stock').$formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1); print ''; } if ($object->element == 'stock') { print ''.$langs->trans("Product").''; print ''; + print img_picto('', 'product'); $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); print ''; } print ''.$langs->trans("WarehouseTarget").''; -print $formproduct->selectWarehouses(GETPOST('id_entrepot_destination'), 'id_entrepot_destination', 'warehouseopen,warehouseinternal', 1); +print img_picto('', 'stock').$formproduct->selectWarehouses(GETPOST('id_entrepot_destination'), 'id_entrepot_destination', 'warehouseopen,warehouseinternal', 1); print ''; print ''.$langs->trans("NumberOfUnit").''; print ''; diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index ab2cddb940d..fc3d0879691 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -631,26 +631,32 @@ if (empty($reshook)) $errors[] = "ErrorFilePartiallyUploaded"; break; } - } - // Gestion du logo de la société + } } else { - if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') // TODO Sometime errors on duplicate on profid and not on code, so we must manage this case + if ($result == -3 && in_array('ErrorCustomerCodeAlreadyUsed', $object->errors)) + { + $duplicate_code_error = true; + $object->code_client = null; + } + + if ($result == -3 && in_array('ErrorSupplierCodeAlreadyUsed', $object->errors)) { $duplicate_code_error = true; $object->code_fournisseur = null; - $object->code_client = null; + } + + if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { // TODO Sometime errors on duplicate on profid and not on code, so we must manage this case + $duplicate_code_error = true; } setEventMessages($object->error, $object->errors, 'errors'); $error++; } - if ($result >= 0 && !$error) - { + if ($result >= 0 && !$error) { $db->commit(); - if (!empty($backtopage)) - { + if (!empty($backtopage)) { $backtopage = preg_replace('/--IDFORBACKTOPAGE--/', $object->id, $backtopage); // New method to autoselect project after a New on another form object creation if (preg_match('/\?/', $backtopage)) $backtopage .= '&socid='.$object->id; // Old method header("Location: ".$backtopage); @@ -838,18 +844,25 @@ if (empty($reshook)) } } + // Set third-party type + if ($action == 'set_thirdpartytype' && $user->rights->societe->creer) + { + $object->fetch($socid); + $result = $object->setThirdpartyType(GETPOST('typent_id', 'int')); + } + + // Set incoterm + if ($action == 'set_incoterms' && $user->rights->societe->creer && !empty($conf->incoterm->enabled)) + { + $object->fetch($socid); + $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); + } + // Set parent company if ($action == 'set_thirdparty' && $user->rights->societe->creer) { $object->fetch($socid); - $result = $object->set_parent(GETPOST('editparentcompany', 'int')); - } - - // Set incoterm - if ($action == 'set_incoterms' && !empty($conf->incoterm->enabled)) - { - $object->fetch($socid); - $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha')); + $result = $object->set_parent(GETPOST('parent_id', 'int')); } // Set sales representatives @@ -2455,18 +2468,24 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) } else { print ' '; } - print ''; - print ''; + print ''; - // Type + Workforce/Staff - $arr = $formcompany->typent_array(1); - $object->typent = $arr[$object->typent_code]; - print ''.$langs->trans("ThirdPartyType").''.$object->typent.''; + // Third-Party Type + print ''; + print ''; + if ($action != 'editthirdpartytype' && $user->rights->societe->creer) print ''; + print '
'.$langs->trans('ThirdPartyType').'id.'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'
'; + print ''; + $html_name = ($action == 'editthirdpartytype') ? 'typent_id' : 'none'; + $formcompany->formThirdpartyType($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->typent_id, $html_name, ''); + print ''; + + // Workforce/Staff print ''.$langs->trans("Workforce").''.$object->effectif.''; print ''; - print ''; + print '
'; print '
'; @@ -2518,14 +2537,10 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) if (!empty($conf->incoterm->enabled)) { print ''; - print '
'; - print $langs->trans('IncotermLabel'); - print ''; - if ($user->rights->societe->creer) print ''.img_edit('', 1).''; - else print ' '; - print '
'; - print ''; - print ''; + print ''; + if ($action != 'editincoterm' && $user->rights->societe->creer) print ''; + print '
'.$langs->trans('IncotermLabel').''.img_edit('', 1).'
'; + print ''; if ($action != 'editincoterm') { print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1); @@ -2553,20 +2568,13 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) if (empty($conf->global->SOCIETE_DISABLE_PARENTCOMPANY)) { print ''; - print ''; - if ($action != 'editparentcompany') print ''; + print '
'; - print $langs->trans('ParentCompany'); - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'
'; + if ($action != 'editparentcompany' && $user->rights->societe->creer) print ''; print '
'.$langs->trans('ParentCompany').'id.'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'
'; print ''; - if ($action == 'editparentcompany') - { - $form->form_thirdparty($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->parent, 'editparentcompany', 's.rowid <> '.$object->id, 1); - } else { - $form->form_thirdparty($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->parent, 'none', 's.rowid <> '.$object->id, 1); - } - print ''; - print ''; + $html_name = ($action == 'editparentcompany') ? 'parent_id' : 'none'; + $form->form_thirdparty($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->parent, $html_name, 's.rowid <> '.$object->id, 1); + print ''; } // Sales representative @@ -2587,8 +2595,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) } else { print ''.$langs->trans("ThirdpartyNotLinkedToMember").''; } - print ''; - print "\n"; + print "\n"; } // Webservices url/key diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index f18a6e1b9a8..f8796739701 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -4355,6 +4355,31 @@ class Societe extends CommonObject return $error ? -1 : 1; } + /** + * Define third-party type of current company + * + * @param int $typent_id third party type rowid in llx_c_typent + * @return int <0 if KO, >0 if OK + */ + public function setThirdpartyType($typent_id) + { + if ($this->id) + { + $sql = "UPDATE ".MAIN_DB_PREFIX."societe"; + $sql .= " SET fk_typent = ".($typent_id > 0 ? $typent_id : "null"); + $sql .= " WHERE rowid = ".$this->id; + dol_syslog(get_class($this).'::setThirdpartyType', LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $this->typent_id = $typent_id; + $this->typent_code = dol_getIdFromCode($db, $this->$typent_id, 'c_typent', 'id', 'code'); + return 1; + } else { + return -1; + } + } else return -1; + } /** * Function used to replace a thirdparty id with another one. diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index b022c76d0d8..022c5a13354 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -547,8 +547,8 @@ class SupplierProposal extends CommonObject $this->line->tva_tx = $txtva; $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0); $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0); - $this->line->localtax1_type = $localtaxes_type[0]; - $this->line->localtax2_type = $localtaxes_type[2]; + $this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; + $this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; $this->line->fk_product = $fk_product; $this->line->remise_percent = $remise_percent; $this->line->subprice = $pu_ht; @@ -593,8 +593,8 @@ class SupplierProposal extends CommonObject // Mise en option de la ligne if (empty($qty) && empty($special_code)) $this->line->special_code = 3; - if (is_array($array_option) && count($array_option) > 0) { - $this->line->array_options = $array_option; + if (is_array($array_options) && count($array_options) > 0) { + $this->line->array_options = $array_options; } $result = $this->line->insert(); @@ -736,8 +736,8 @@ class SupplierProposal extends CommonObject $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; - $this->line->localtax1_type = $localtaxes_type[0]; - $this->line->localtax2_type = $localtaxes_type[2]; + $this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; + $this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; $this->line->remise_percent = $remise_percent; $this->line->subprice = $pu; $this->line->info_bits = $info_bits; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 24751dfb9d7..1dc8f27b644 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -396,6 +396,13 @@ input.pageplusone { color: #000; } +.vmirror { + transform: scale(1, -1); +} +.hmirror { + transform: scale(-1, 1); +} + select:invalid { color: gray; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index f1084f5a537..7b4ecf08e8e 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -528,6 +528,13 @@ input.pageplusone { color: #000; } +.vmirror { + transform: scale(1, -1); +} +.hmirror { + transform: scale(-1, 1); +} + select:invalid { color: gray; } diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index 163bf320075..ce7f1074721 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -216,6 +216,8 @@ class AllTests require_once dirname(__FILE__).'/RestAPIUserTest.php'; $suite->addTestSuite('RestAPIUserTest'); + require_once dirname(__FILE__).'/RestAPIDocumentTest.php'; + $suite->addTestSuite('RestAPIDocumentTest'); // Test only with php7.2 or less //if ((float) phpversion() < 7.3) diff --git a/test/phpunit/RestAPIDocumentTest.php b/test/phpunit/RestAPIDocumentTest.php index 8dbaafab018..f45e0437ce5 100644 --- a/test/phpunit/RestAPIDocumentTest.php +++ b/test/phpunit/RestAPIDocumentTest.php @@ -152,35 +152,43 @@ class RestAPIDocumentTest extends PHPUnit\Framework\TestCase { global $conf,$user,$langs,$db; - $url = $this->api_url.'/documents/?api_key='.$this->api_key; + $url = $this->api_url.'/documents/upload?api_key='.$this->api_key; echo __METHOD__.' Request POST url='.$url."\n"; // Send to non existent directory - dol_delete_dir_recursive(DOL_DATA_ROOT.'/medias/tmpphpunit'); + dol_delete_dir_recursive(DOL_DATA_ROOT.'/medias/tmpphpunit/tmpphpunit1'); //$data = '{ "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "mysubdir1/mysubdir2", "filecontent": "content text", "fileencoding": "" }'; $data = array( 'filename'=>"mynewfile.txt", 'modulepart'=>"medias", - 'ref'=>"", - 'subdir'=>"tmpphpunit/tmpphpunit2", + 'subdir'=>"tmpphpunit/tmpphpunit1", 'filecontent'=>"content text", - 'fileencoding'=>"" + 'fileencoding'=>"", + 'overwriteifexists'=>0, + 'createdirifnotexists'=>0 ); - $result = getURLContent($url, 'POST', $data, 1, array(), array('http', 'https'), 2); + $param = ''; + foreach($data as $key => $val) { + $param .= '&'.$key.'='.urlencode($val); + } + + $result = getURLContent($url, 'POST', $param, 1, array(), array('http', 'https'), 2); echo __METHOD__.' Result for sending document: '.var_export($result, true)."\n"; echo __METHOD__.' curl_error_no: '.$result['curl_error_no']."\n"; $object = json_decode($result['content'], true); - $this->assertNotNull($object, 'Parsing of json result must no be null'); - $this->assertEquals('401', $object['error']['code']); + $this->assertNotNull($object, 'Parsing of json result must not be null'); + $this->assertEquals('401', $result['http_code'], 'Return code is not 401'); + $this->assertEquals('401', empty($object['error']['code']) ? '' : $object['error']['code'], 'Error code is not 401'); // Send to existent directory + dol_delete_dir_recursive(DOL_DATA_ROOT.'/medias/tmpphpunit/tmpphpunit2'); dol_mkdir(DOL_DATA_ROOT.'/medias/tmpphpunit/tmpphpunit2'); $data = array( @@ -189,16 +197,53 @@ class RestAPIDocumentTest extends PHPUnit\Framework\TestCase 'ref'=>"", 'subdir'=>"tmpphpunit/tmpphpunit2", 'filecontent'=>"content text", - 'fileencoding'=>"" + 'fileencoding'=>"", + 'overwriteifexists'=>0, + 'createdirifnotexists'=>0 ); - $result2 = getURLContent($url, 'POST', $data, 1, array(), array('http', 'https'), 2); + $param = ''; + foreach($data as $key => $val) { + $param .= '&'.$key.'='.urlencode($val); + } + + $result2 = getURLContent($url, 'POST', $param, 1, array(), array('http', 'https'), 2); echo __METHOD__.' Result for sending document: '.var_export($result2, true)."\n"; echo __METHOD__.' curl_error_no: '.$result2['curl_error_no']."\n"; $object2 = json_decode($result2['content'], true); - $this->assertNotNull($object2, 'Parsing of json result must no be null'); + //$this->assertNotNull($object2, 'Parsing of json result must not be null'); + $this->assertEquals('200', $result2['http_code'], 'Return code must be 200'); $this->assertEquals($result2['curl_error_no'], ''); - $this->assertEquals($result2['content'], 'true'); + $this->assertEquals($object2, 'mynewfile.txt', 'Must contains basename of file'); + + + dol_delete_dir_recursive(DOL_DATA_ROOT.'/medias/tmpphpunit/tmpphpunit3'); + + $data = array( + 'filename'=>"mynewfile.txt", + 'modulepart'=>"medias", + 'ref'=>"", + 'subdir'=>"tmpphpunit/tmpphpunit3", + 'filecontent'=>"content text", + 'fileencoding'=>"", + 'overwriteifexists'=>0, + 'createdirifnotexists'=>1 + ); + + $param = ''; + foreach($data as $key => $val) { + $param .= '&'.$key.'='.urlencode($val); + } + + $result3 = getURLContent($url, 'POST', $param, 1, array(), array('http', 'https'), 2); + echo __METHOD__.' Result for sending document: '.var_export($result3, true)."\n"; + echo __METHOD__.' curl_error_no: '.$result3['curl_error_no']."\n"; + $object3 = json_decode($result3['content'], true); + //$this->assertNotNull($object2, 'Parsing of json result must not be null'); + $this->assertEquals('200', $result3['http_code'], 'Return code must be 200'); + $this->assertEquals($result3['curl_error_no'], ''); + $this->assertEquals($object3, 'mynewfile.txt', 'Must contains basename of file'); + dol_delete_dir_recursive(DOL_DATA_ROOT.'/medias/tmpphpunit'); }