diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 226e9ef6389..25a29270976 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -875,7 +875,7 @@ if (empty($reshook)) { } } } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('vatforalllines', 'alpha') !== '' && $usercancreate) { - // Define vat_rate + // Define a vat_rate for all lines $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0); $vat_rate = str_replace('*', '', $vat_rate); $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc); @@ -884,7 +884,7 @@ if (empty($reshook)) { $result = $object->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); } } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('remiseforalllines', 'alpha') !== '' && $usercancreate) { - // Define vat_rate + // Define a discount for all lines $remise_percent = (GETPOST('remiseforalllines') ? GETPOST('remiseforalllines') : 0); $remise_percent = str_replace('*', '', $remise_percent); foreach ($object->lines as $line) { @@ -894,22 +894,36 @@ if (empty($reshook)) { // Set if we used free entry or predefined product $predef = ''; $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); - $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); - $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); - $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); - $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); - $prod_entry_mode = GETPOST('prod_entry_mode'); + $price_ht = ''; + $price_ht_devise = ''; + $price_ttc = ''; + $price_ttc_devise = ''; + + if (GETPOST('price_ht') !== '') { + $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ht') !== '') { + $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); + } + if (GETPOST('price_ttc') !== '') { + $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ttc') !== '') { + $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); + } + + $prod_entry_mode = GETPOST('prod_entry_mode', 'aZ09'); if ($prod_entry_mode == 'free') { $idprod = 0; - $tva_tx = (GETPOST('tva_tx') ? price2num(preg_replace('/\s*\(.*\)/', '', GETPOST('tva_tx'))) : 0); + $tva_tx = (GETPOST('tva_tx', 'alpha') ? price2num(preg_replace('/\s*\(.*\)/', '', GETPOST('tva_tx', 'alpha'))) : 0); } else { $idprod = GETPOST('idprod', 'int'); $tva_tx = ''; } $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2); - $remise_percent = price2num(GETPOST('remise_percent'.$predef), '', 2); + $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0); if (empty($remise_percent)) { $remise_percent = 0; } @@ -930,7 +944,7 @@ if (empty($reshook)) { $error++; } - if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && $price_ht === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for proposal. + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && $price_ht === '' && $price_ht_devise === '' && $price_ttc === '' && $price_ttc_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for proposal. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error++; } @@ -1077,13 +1091,15 @@ if (empty($reshook)) { $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx)); $tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx)); - // if price ht is forced (ie: calculated by margin rate and cost price). TODO Why this ? + // Set unit price to use if (!empty($price_ht) || $price_ht === '0') { $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU'); + } elseif (!empty($price_ttc) || $price_ttc === '0') { + $pu_ttc = price2num($price_ttc, 'MU'); + $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); } elseif ($tmpvat != $tmpprodvat) { - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + // Is this still used ? if ($price_base_type != 'HT') { $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); } else { @@ -1170,16 +1186,22 @@ if (empty($reshook)) { $fk_unit = $prod->fk_unit; } else { $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $pu_ttc = price2num($price_ttc, 'MU'); $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); + if (empty($tva_tx)) { + $tva_npr = 0; + } $tva_tx = str_replace('*', '', $tva_tx); $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); $desc = $product_desc; $type = GETPOST('type'); - $fk_unit = GETPOST('units', 'alpha'); $pu_ht_devise = price2num($price_ht_devise, 'MU'); $pu_ttc_devise = price2num($price_ttc_devise, 'MU'); + + if ($pu_ttc && !$pu_ht) { + $price_base_type = 'TTC'; + } } // Margin @@ -1298,7 +1320,7 @@ if (empty($reshook)) { $buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we muste keep this value $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2); - //$pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2); + $pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2); $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); @@ -1382,7 +1404,14 @@ if (empty($reshook)) { $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); - $result = $object->updateline(GETPOST('lineid', 'int'), $pu_ht, $qty, $remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, GETPOST("units"), $pu_ht_devise); + $pu = $pu_ht; + $price_base_type = 'HT'; + if (empty($pu) && ! empty($pu_ttc)) { + $pu = $pu_ttc; + $price_base_type = 'TTC'; + } + + $result = $object->updateline(GETPOST('lineid', 'int'), $pu, $qty, $remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $description, $price_base_type, $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, GETPOST("units"), $pu_ht_devise); if ($result >= 0) { $db->commit(); @@ -2696,7 +2725,7 @@ if ($action == 'create') { * Lines */ - // Show object lines + // Get object lines $result = $object->getLinesArray(); // Add products/services form @@ -2704,7 +2733,7 @@ if ($action == 'create') { global $inputalsopricewithtax; $inputalsopricewithtax = 1; - print '
+ print ' diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 9831c6d7772..aa7753946a7 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -932,9 +932,6 @@ class Propal extends CommonObject $this->line->date_start = $date_start; $this->line->date_end = $date_end; - // TODO deprecated - $this->line->price = $price; - if (is_array($array_options) && count($array_options) > 0) { // We replace values in this->line->array_options only for entries defined into $array_options foreach ($array_options as $key => $value) { diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index b6e859689ec..b7ef455f515 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -646,22 +646,35 @@ if (empty($reshook)) { // Set if we used free entry or predefined product $predef = ''; $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); - $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); - $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); - $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); - $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); - $prod_entry_mode = GETPOST('prod_entry_mode'); + $price_ht = ''; + $price_ht_devise = ''; + $price_ttc = ''; + $price_ttc_devise = ''; + + if (GETPOST('price_ht') !== '') { + $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ht') !== '') { + $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); + } + if (GETPOST('price_ttc') !== '') { + $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ttc') !== '') { + $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); + } + + $prod_entry_mode = GETPOST('prod_entry_mode', 'aZ09'); if ($prod_entry_mode == 'free') { $idprod = 0; - $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + $tva_tx = (GETPOST('tva_tx', 'alpha') ? price2num(preg_replace('/\s*\(.*\)/', '', GETPOST('tva_tx', 'alpha'))) : 0); } else { $idprod = GETPOST('idprod', 'int'); $tva_tx = ''; } - $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS'); - + $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2); $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0); if (empty($remise_percent)) { $remise_percent = 0; @@ -686,7 +699,7 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } - if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && $price_ht == '' && $price_ht_devise == '') { // Unit price can be 0 but not ''. Also price can be negative for order. + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && $price_ht === '' && $price_ht_devise === '' && $price_ttc === '' && $price_ttc_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for order. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); $error++; } @@ -835,13 +848,15 @@ if (empty($reshook)) { $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx)); $tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx)); - // if price ht is forced (ie: calculated by margin rate and cost price). TODO Why this ? + // Set unit price to use if (!empty($price_ht) || $price_ht === '0') { $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU'); + } elseif (!empty($price_ttc) || $price_ttc === '0') { + $pu_ttc = price2num($price_ttc, 'MU'); + $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); } elseif ($tmpvat != $tmpprodvat) { - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + // Is this still used ? if ($price_base_type != 'HT') { $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); } else { @@ -928,14 +943,22 @@ if (empty($reshook)) { $fk_unit = $prod->fk_unit; } else { $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $pu_ttc = price2num($price_ttc, 'MU'); $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); $tva_tx = str_replace('*', '', $tva_tx); + if (empty($tva_tx)) { + $tva_npr = 0; + } $label = (GETPOST('product_label') ? GETPOST('product_label') : ''); $desc = $product_desc; $type = GETPOST('type'); $fk_unit = GETPOST('units', 'alpha'); $pu_ht_devise = price2num($price_ht_devise, 'MU'); + $pu_ttc_devise = price2num($price_ttc_devise, 'MU'); + + if ($pu_ttc && !$pu_ht) { + $price_base_type = 'TTC'; + } } // Margin @@ -946,13 +969,13 @@ if (empty($reshook)) { $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty); $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty); - $desc = dol_htmlcleanlastbr($desc); - $info_bits = 0; if ($tva_npr) { $info_bits |= 0x01; } + $desc = dol_htmlcleanlastbr($desc); + if ($usermustrespectpricemin) { if ($pu_ht && $price_min && ((price2num($pu_ht) * (1 - $remise_percent / 100)) < price2num($price_min))) { $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)); @@ -1035,12 +1058,14 @@ if (empty($reshook)) { $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml')); $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx', 'alpha') : 0); $vat_rate = str_replace('*', '', $vat_rate); + $pu_ht = price2num(GETPOST('price_ht'), '', 2); $pu_ttc = price2num(GETPOST('price_ttc'), '', 2); - $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2); - //$pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2); - $qty = price2num(GETPOST('qty'), 'MS'); + $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2); + $pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2); + + $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); // Define info_bits $info_bits = 0; @@ -1135,7 +1160,15 @@ if (empty($reshook)) { } } } - $result = $object->updateline(GETPOST('lineid', 'int'), $description, $pu_ht, $qty, $remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOST('units'), $pu_ht_devise); + + $price_base_type = 'HT'; + $pu = $pu_ht; + if (empty($pu) && ! empty($pu_ttc)) { + $pu = $pu_ttc; + $price_base_type = 'TTC'; + } + + $result = $object->updateline(GETPOST('lineid', 'int'), $description, $pu, $qty, $remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $price_base_type, $info_bits, $date_start, $date_end, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOST('units'), $pu_ht_devise); if ($result >= 0) { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { @@ -2678,9 +2711,16 @@ if ($action == 'create' && $usercancreate) { /* * Lines */ + + // Get object lines $result = $object->getLinesArray(); - print ' + // Add products/services form + //$forceall = 1; + global $inputalsopricewithtax; + $inputalsopricewithtax = 1; + + print ' diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 6ad9c545dee..c5d1bf2d8bf 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2008,22 +2008,39 @@ if (empty($reshook)) { // Set if we used free entry or predefined product $predef = ''; $product_desc =(GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); - $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); - $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); - $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); - $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); - $prod_entry_mode = GETPOST('prod_entry_mode', 'alpha'); + $price_ht = ''; + $price_ht_devise = ''; + $price_ttc = ''; + $price_ttc_devise = ''; + + if (GETPOST('price_ht') !== '') { + $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ht') !== '') { + $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); + } + if (GETPOST('price_ttc') !== '') { + $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ttc') !== '') { + $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); + } + + $prod_entry_mode = GETPOST('prod_entry_mode', 'aZ09'); if ($prod_entry_mode == 'free') { $idprod = 0; - $tva_tx = (GETPOST('tva_tx', 'alpha') ? GETPOST('tva_tx', 'alpha') : 0); + $tva_tx = (GETPOST('tva_tx', 'alpha') ? price2num(preg_replace('/\s*\(.*\)/', '', GETPOST('tva_tx', 'alpha'))) : 0); } else { $idprod = GETPOST('idprod', 'int'); $tva_tx = ''; } - $qty = price2num(GETPOST('qty'.$predef), 'MS', 2); - $remise_percent = price2num(GETPOST('remise_percent'.$predef), '', 2); + $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2); + $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0); + if (empty($remise_percent)) { + $remise_percent = 0; + } // Extrafields $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line); @@ -2050,8 +2067,8 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } - if (($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && (($price_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $price_ht == '') && $price_ht_devise == '') && $object->type != Facture::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not '' - if ($price_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) { + if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && (($price_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $price_ht == '') && (($price_ht_devise < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $price_ht_devise == '') && $price_ttc === '' && $price_ttc_devise === '' && $object->type != Facture::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not '' + if (($price_ht < 0 || $price_ttc < 0) && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) { $langs->load("errors"); if ($object->type == $object::TYPE_DEPOSIT) { // Using negative lines on deposit lead to headach and blocking problems when you want to consume them. @@ -2131,19 +2148,22 @@ if (empty($reshook)) { $price_min = $datapriceofproduct['price_min']; $price_min_ttc = $datapriceofproduct['price_min_ttc']; $price_base_type = $datapriceofproduct['price_base_type']; + $tva_tx = $datapriceofproduct['tva_tx']; $tva_npr = $datapriceofproduct['tva_npr']; $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx)); $tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx)); - // if price ht was forced (ie: from gui when calculated by margin rate and cost price). TODO Why this ? + // Set unit price to use if (!empty($price_ht) || $price_ht === '0') { $pu_ht = price2num($price_ht, 'MU'); $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU'); + } elseif (!empty($price_ttc) || $price_ttc === '0') { + $pu_ttc = price2num($price_ttc, 'MU'); + $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); } elseif ($tmpvat != $tmpprodvat) { - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + // Is this still used ? if ($price_base_type != 'HT') { $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); } else { @@ -2231,7 +2251,7 @@ if (empty($reshook)) { $fk_unit = $prod->fk_unit; } else { $pu_ht = price2num($price_ht, 'MU'); - $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); + $pu_ttc = price2num($price_ttc, 'MU'); $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); $tva_tx = str_replace('*', '', $tva_tx); if (empty($tva_tx)) { @@ -2243,6 +2263,10 @@ if (empty($reshook)) { $fk_unit = GETPOST('units', 'alpha'); $pu_ht_devise = price2num($price_ht_devise, 'MU'); $pu_ttc_devise = price2num($price_ttc_devise, 'MU'); + + if ($pu_ttc && !$pu_ht) { + $price_base_type = 'TTC'; + } } // Margin @@ -2381,12 +2405,14 @@ if (empty($reshook)) { $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml') ? GETPOST('product_desc', 'restricthtml') : GETPOST('desc', 'restricthtml')); $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); $vat_rate = str_replace('*', '', $vat_rate); + $pu_ht = price2num(GETPOST('price_ht'), '', 2); $pu_ttc = price2num(GETPOST('price_ttc'), '', 2); - $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2); - //$pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2); - $qty = GETPOST('qty'); + $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2); + $pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2); + + $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); // Define info_bits $info_bits = 0; @@ -2495,8 +2521,8 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors'); $error++; } - if ((empty($productid) && (($pu_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $pu_ht == '') && $pu_ht_devise == '') && $object->type != Facture::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not '' - if ($pu_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) { + if (empty($productid) && (($pu_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $pu_ht == '') && (($pu_ht_devise < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $pu_ht_devise == '') && $pu_ttc === '' && $pu_ttc_devise === '' && $object->type != Facture::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not '' + if (($pu_ht < 0 || $pu_ttc < 0) && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) { $langs->load("errors"); if ($object->type == $object::TYPE_DEPOSIT) { // Using negative lines on deposit lead to headach and blocking problems when you want to consume them. @@ -2524,10 +2550,17 @@ if (empty($reshook)) { } } + $price_base_type = 'HT'; + $pu = $pu_ht; + if (empty($pu) && ! empty($pu_ttc)) { + $pu = $pu_ttc; + $price_base_type = 'TTC'; + } + $result = $object->updateline( GETPOST('lineid', 'int'), $description, - $pu_ht, + $pu, $qty, $remise_percent, $date_start, @@ -2535,7 +2568,7 @@ if (empty($reshook)) { $vat_rate, $localtax1_rate, $localtax2_rate, - 'HT', + $price_base_type, $info_bits, $type, GETPOST('fk_parent_line', 'int'), @@ -5318,10 +5351,15 @@ if ($action == 'create') { include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php'; } - // Lines + // Get object lines $result = $object->getLinesArray(); - // Show global modifiers + // Add products/services form + //$forceall = 1; + global $inputalsopricewithtax; + $inputalsopricewithtax = 1; + + // Show global modifiers for situation invoices if (!empty($conf->global->INVOICE_USE_SITUATION)) { if ($object->situation_cycle_ref && $object->statut == 0) { print ''."\n"; @@ -5363,7 +5401,7 @@ if ($action == 'create') { } } - print ' + print ' diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 9b25e710d85..439f312bef6 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -396,11 +396,28 @@ if (empty($reshook)) { // Set if we used free entry or predefined product $predef = ''; $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : ''); - $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); - $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); + + $price_ht = ''; + $price_ht_devise = ''; + $price_ttc = ''; + $price_ttc_devise = ''; + + if (GETPOST('price_ht') !== '') { + $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ht') !== '') { + $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); + } + if (GETPOST('price_ttc') !== '') { + $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ttc') !== '') { + $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); + } + if (GETPOST('prod_entry_mode', 'alpha') == 'free') { $idprod = 0; - $tva_tx = (GETPOST('tva_tx', 'alpha') ? GETPOST('tva_tx', 'alpha') : 0); + $tva_tx = (GETPOST('tva_tx', 'alpha') ? price2num(preg_replace('/\s*\(.*\)/', '', GETPOST('tva_tx', 'alpha'))) : 0); } else { $idprod = GETPOST('idprod', 'int'); $tva_tx = ''; @@ -408,6 +425,9 @@ if (empty($reshook)) { $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS'); $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef), 2) : 0); + if (empty($remise_percent)) { + $remise_percent = 0; + } if ($qty == '') { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors'); @@ -460,6 +480,7 @@ if (empty($reshook)) { $pu_ht = $prod->price; $pu_ttc = $prod->price_ttc; $price_min = $prod->price_min; + $price_min_ttc = $prod->price_min_ttc; $price_base_type = $prod->price_base_type; // On defini prix unitaire @@ -467,8 +488,10 @@ if (empty($reshook)) { $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; + $price_min_ttc = $prod->multiprices_min_ttc[$object->thirdparty->price_level]; $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + // If price per customer require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php'; $prodcustprice = new Productcustomerprice($db); @@ -478,10 +501,12 @@ if (empty($reshook)) { $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); if ($result) { if (count($prodcustprice->lines) > 0) { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $tva_tx = $prodcustprice->lines [0]->tva_tx; + $pu_ht = price($prodcustprice->lines[0]->price); + $pu_ttc = price($prodcustprice->lines[0]->price_ttc); + $price_min = price($prodcustprice->lines[0]->price_min); + $price_min_ttc = price($prodcustprice->lines[0]->price_min_ttc); + $price_base_type = $prodcustprice->lines[0]->price_base_type; + $tva_tx = $prodcustprice->lines[0]->tva_tx; if ($prodcustprice->lines[0]->default_vat_code && !preg_match('/\(.*\)/', $tva_tx)) { $tva_tx .= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; } @@ -496,9 +521,15 @@ if (empty($reshook)) { $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx)); $tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx)); - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - if ($tmpvat != $tmpprodvat) { + // Set unit price to use + if (!empty($price_ht) || $price_ht === '0') { + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU'); + } elseif (!empty($price_ttc) || $price_ttc === '0') { + $pu_ttc = price2num($price_ttc, 'MU'); + $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); + } elseif ($tmpvat != $tmpprodvat) { + // Is this still used ? if ($price_base_type != 'HT') { $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU'); } else { @@ -521,12 +552,22 @@ if (empty($reshook)) { $fk_unit = $prod->fk_unit; } else { - $pu_ht = GETPOST('price_ht'); - $price_base_type = 'HT'; - $tva_tx = GETPOST('tva_tx') ?str_replace('*', '', GETPOST('tva_tx')) : 0; // tva_tx field may be disabled, so we use vat rate 0 - $tva_npr = preg_match('/\*/', GETPOST('tva_tx')) ? 1 : 0; + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num($price_ttc, 'MU'); + $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0); + if (empty($tva_tx)) { + $tva_npr = 0; + } + $tva_tx = str_replace('*', '', $tva_tx); $desc = $product_desc; $fk_unit = GETPOST('units', 'alpha'); + $pu_ht_devise = price2num($price_ht_devise, 'MU'); + $pu_ttc_devise = price2num($price_ttc_devise, 'MU'); + + $price_base_type = 'HT'; + if ($pu_ttc && !$pu_ht) { + $price_base_type = 'TTC'; + } } $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr); @@ -1427,6 +1468,11 @@ if ($action == 'create') { * Lines of contracts */ + // Add products/services form + //$forceall = 1; + global $inputalsopricewithtax; + $inputalsopricewithtax = 1; + $productstatic = new Product($db); $usemargins = 0; diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 9a330c7aba5..a60c3fdd8f5 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -1334,4 +1334,74 @@ class Utils return $result; } } + + /** + * Clean unfinished cronjob in processing when pid is no longer present in the system + * CAN BE A CRON TASK + * + * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) + * @throws Exception + */ + public function cleanUnfinishedCronjob() + { + global $db, $user; + dol_syslog("Utils::cleanUnfinishedCronjob Starting cleaning"); + + // Import Cronjob class if not present + dol_include_once('/cron/class/cronjob.class.php'); + + // Get this job object + $this_job = new Cronjob($db); + $this_job->fetch(-1, 'Utils', 'cleanUnfinishedCronjob'); + if (empty($this_job->id) || !empty($this_job->error)) { + dol_syslog("Utils::cleanUnfinishedCronjob Unable to fetch himself: ".$this_job->error, LOG_ERR); + return -1; + } + + // Set this job processing to 0 to avoid being locked by his processing state + $this_job->processing = 0; + if ($this_job->update($user) < 0) { + dol_syslog("Utils::cleanUnfinishedCronjob Unable to update himself: ".implode(', ', $this_job->errors), LOG_ERR); + return -1; + } + + $cron_job = new Cronjob($db); + $cron_job->fetchAll('DESC', 't.rowid', 100, 0, 1, '', 1); // Fetch jobs that are currently running + + // Iterate over all jobs in processing (this can't be this job since his state is set to 0 before) + foreach ($cron_job->lines as $job_line) { + // Avoid job with no PID + if (empty($job_line->pid)) { + dol_syslog("Utils::cleanUnfinishedCronjob Cronjob ".$job_line->id." don't have a PID", LOG_DEBUG); + continue; + } + + $job = new Cronjob($db); + $job->fetch($job_line->id); + if (empty($job->id) || !empty($job->error)) { + dol_syslog("Utils::cleanUnfinishedCronjob Cronjob ".$job_line->id." can't be fetch: ".$job->error, LOG_ERR); + continue; + } + + // Calling posix_kill with the 0 kill signal will return true if the process is running, false otherwise. + if (! posix_kill($job->pid, 0)) { + // Clean processing and pid values + $job->processing = 0; + $job->pid = null; + + // Set last result as an error and add the reason on the last output + $job->lastresult = -1; + $job->lastoutput = 'Job killed by job cleanUnfinishedCronjob'; + + if ($job->update($user) < 0) { + dol_syslog("Utils::cleanUnfinishedCronjob Cronjob ".$job_line->id." can't be updated: ".implode(', ', $job->errors), LOG_ERR); + continue; + } + dol_syslog("Utils::cleanUnfinishedCronjob Cronjob ".$job_line->id." cleaned"); + } + } + + dol_syslog("Utils::cleanUnfinishedCronjob Cleaning completed"); + return 0; + } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index e76106e44c6..71161d77c64 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -432,8 +432,8 @@ function GETPOSTISSET($paramname) * Can be used before GETPOST to know if the $check param of GETPOST need to check an array or a string * * @param string $paramname Name or parameter to test - * @param int $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get) - * @return bool True if we have just submit a POST or GET request with the parameter provided (even if param is empty) + * @param int $method Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get) + * @return bool True if we have just submit a POST or GET request with the parameter provided (even if param is empty) */ function GETPOSTISARRAY($paramname, $method = 0) { diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index 290eea449f5..00d73dd7d14 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -101,6 +101,7 @@ class modCron extends DolibarrModules 0=>array('entity'=>0, 'label'=>'PurgeDeleteTemporaryFilesShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'purgeFiles', 'parameters'=>'tempfilesold+logfiles', 'comment'=>'PurgeDeleteTemporaryFiles', 'frequency'=>2, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>50, 'status'=>1, 'test'=>true), 1=>array('entity'=>0, 'label'=>'MakeLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'dumpDatabase', 'parameters'=>'none,auto,1,auto,10', 'comment'=>'MakeLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7, 'priority'=>90, 'status'=>0, 'test'=>'in_array($conf->db->type, array(\'mysql\', \'mysqli\'))'), 2=>array('entity'=>0, 'label'=>'MakeSendLocalDatabaseDumpShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'sendDumpDatabase', 'parameters'=>',,,,,sql', 'comment'=>'MakeSendLocalDatabaseDump', 'frequency'=>1, 'unitfrequency'=>604800, 'priority'=>91, 'status'=>0, 'test'=>'!empty($conf->global->MAIN_ALLOW_BACKUP_BY_EMAIL) && in_array($conf->db->type, array(\'mysql\', \'mysqli\'))'), + 3=>array('entity'=>0, 'label'=>'CleanUnfinishedCronjobShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'cleanUnfinishedCronjob', 'parameters'=>'', 'comment'=>'CleanUnfinishedCronjob', 'frequency'=>5, 'unitfrequency'=>60, 'priority'=>10, 'status'=>0, 'test'=>'getDolGlobalInt("MAIN_FEATURES_LEVEL") >= 2'), // 1=>array('entity'=>0, 'label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24) ); diff --git a/htdocs/core/modules/modRecruitment.class.php b/htdocs/core/modules/modRecruitment.class.php index 1d2d614b9ea..ed67430bce5 100644 --- a/htdocs/core/modules/modRecruitment.class.php +++ b/htdocs/core/modules/modRecruitment.class.php @@ -261,7 +261,7 @@ class modRecruitment extends DolibarrModules 'prefix' => img_picto('', $this->picto, 'class="paddingright pictofixedwidth"'), 'mainmenu'=>'hrm', 'leftmenu'=>'recruitmentjobposition', - 'url'=>'/recruitment/recruitmentindex.php', + 'url'=>'/recruitment/index.php', 'langs'=>'recruitment', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>1000 + $r, 'enabled'=>'$conf->recruitment->enabled', // Define condition to show or hide menu entry. Use '$conf->recruitment->enabled' if entry must be visible if module is enabled. diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index c0e64a513ab..5fbb227bc69 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -146,6 +146,11 @@ if ($action == 'presend') { $formmail->fromname = (!empty($conf->global->ORDER_SUPPLIER_EMAIL_SENDER_NAME) ? $conf->global->ORDER_SUPPLIER_EMAIL_SENDER_NAME : ''); $formmail->fromtype = 'special'; } + if ($object->element === 'recruitmentcandidature' ) { + $formmail->frommail = (!empty($conf->global->RECRUITMENT_EMAIL_SENDER) ? $conf->global->RECRUITMENT_EMAIL_SENDER : $recruitermail); + $formmail->fromname = (!empty($conf->global->RECRUITMENT_EMAIL_SENDER_NAME) ? $conf->global->RECRUITMENT_EMAIL_SENDER_NAME : (!empty($recruitername) ? $recruitername : '')); + $formmail->fromtype = 'special'; + } $formmail->trackid = empty($trackid) ? '' : $trackid; $formmail->inreplyto = empty($inreplyto) ? '' : $inreplyto; diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 21e82d306a8..761be27b512 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2010-2020 Laurent Destailleur + * Copyright (C) 2010-2022 Laurent Destailleur * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2012 Cédric Salvador * Copyright (C) 2012-2014 Raphaël Doursenaud @@ -325,8 +325,8 @@ $coldisplay++; - ">
- "> + ">
+ "> diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 714622e8014..9bc8400188f 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1140,7 +1140,7 @@ class Cronjob extends CommonObject $this->lastoutput = ''; $this->lastresult = ''; $this->processing = 1; // To know job was started - $this->pid = dol_getmypid(); + $this->pid = function_exists('getmypid') ? getmypid() : null; // Avoid dol_getmypid to get null if the function is not available $this->nbrun = $this->nbrun + 1; $result = $this->update($user); // This include begin/commit if ($result < 0) { diff --git a/htdocs/delivery/card.php b/htdocs/delivery/card.php index 0b216df80a1..108f81751b3 100644 --- a/htdocs/delivery/card.php +++ b/htdocs/delivery/card.php @@ -49,7 +49,7 @@ if (!empty($conf->project->enabled)) { } // Load translation files required by the page -$langs->loadLangs(array("sendings", "bills", 'deliveries', 'orders')); +$langs->loadLangs(array('bills', 'deliveries', 'orders', 'sendings')); if (!empty($conf->incoterm->enabled)) { $langs->load('incoterm'); @@ -89,10 +89,10 @@ $error = 0; */ $parameters = array(); -$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks // Delete Link $permissiondellink = $user->rights->expedition->delivery->supprimer; // Used by the include of actions_dellink.inc.php -include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once +include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once if ($action == 'add') { $db->begin(); @@ -101,7 +101,7 @@ if ($action == 'add') { $object->note = GETPOST("note", 'restricthtml'); $object->note_private = GETPOST("note", 'restricthtml'); $object->commande_id = GETPOST("commande_id", 'int'); - $object->fk_incoterms = GETPOST('incoterm_id', 'int'); + $object->fk_incoterms = GETPOST('incoterm_id', 'int'); if (!$conf->expedition_bon->enabled && !empty($conf->stock->enabled)) { $expedition->entrepot_id = GETPOST('entrepot_id', 'int'); diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 7c43286ed9f..a87c90a6dd9 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1582,7 +1582,9 @@ class EmailCollector extends CommonObject $plainmsg = $imapemail->getTextBody(); } if ($imapemail->hasAttachments()) { - $attachments = $imapemail->getAttachments(); + $attachments = $imapemail->getAttachments()->all(); + } else { + $attachments = []; } } else { $this->getmsg($connection, $imapemail); @@ -2440,6 +2442,20 @@ class EmailCollector extends CommonObject $errorforactions++; $this->error = 'Failed to create project: '.$langs->trans($projecttocreate->error); $this->errors = $projecttocreate->errors; + } else { + if ($attachments) { + $destdir = $conf->project->dir_output.'/'.$projecttocreate->ref; + if (!dol_is_dir($destdir)) { + dol_mkdir($destdir); + } + if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) { + foreach ($attachments as $attachment) { + $attachment->save($destdir.'/'); + } + } else { + $this->getmsg($connection, $imapemail, $destdir); + } + } } } } @@ -2550,13 +2566,16 @@ class EmailCollector extends CommonObject $this->errors = $tickettocreate->errors; } else { if ($attachments) { + $destdir = $conf->ticket->dir_output.'/'.$tickettocreate->ref; + if (!dol_is_dir($destdir)) { + dol_mkdir($destdir); + } if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) { - $destdir = $conf->ticket->dir_output.'/'.$tickettocreate->ref; - if (!dol_is_dir($destdir)) { - return -1; - dol_mkdir($destdir); - $this->getmsg($connection, $imapemail, $destdir); + foreach ($attachments as $attachment) { + $attachment->save($destdir.'/'); } + } else { + $this->getmsg($connection, $imapemail, $destdir); } } } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 8d03dbb387c..354c92eb534 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -120,7 +120,7 @@ $search_project_ref = GETPOST('search_project_ref', 'alpha'); $search_btn = GETPOST('button_search', 'alpha'); $search_remove_btn = GETPOST('button_removefilter', 'alpha'); -if (is_array(GETPOST('search_status', 'none'))) { // 'none' because we want to know type before sanitizing +if (GETPOSTISARRAY('search_status')) { $search_status = join(',', GETPOST('search_status', 'array:intcomma')); } else { $search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma')); diff --git a/htdocs/includes/webklex/php-imap/deleted.txt b/htdocs/includes/webklex/php-imap/deleted.txt index 9993acc6994..7eba7283d76 100644 --- a/htdocs/includes/webklex/php-imap/deleted.txt +++ b/htdocs/includes/webklex/php-imap/deleted.txt @@ -13,4 +13,5 @@ ./vendor/phpdocumentor ./vendor/nesbot/carbon/src/Carbon/Lang ./vendor/doctrine +./vendor/bin ./tests diff --git a/htdocs/includes/webklex/php-imap/vendor/composer/autoload_static.php b/htdocs/includes/webklex/php-imap/vendor/composer/autoload_static.php index db56e4812b6..0120578feb6 100644 --- a/htdocs/includes/webklex/php-imap/vendor/composer/autoload_static.php +++ b/htdocs/includes/webklex/php-imap/vendor/composer/autoload_static.php @@ -16,24 +16,24 @@ class ComposerStaticInit4da13270269c89a28e472e1f7324e6d1 ); public static $prefixLengthsPsr4 = array ( - 'v' => + 'v' => array ( 'voku\\' => 5, ), - 'p' => + 'p' => array ( 'phpDocumentor\\Reflection\\' => 25, ), - 'W' => + 'W' => array ( 'Webmozart\\Assert\\' => 17, 'Webklex\\PHPIMAP\\' => 16, ), - 'T' => + 'T' => array ( - 'Tests\\' => 6, + // 'Tests\\' => 6, ), - 'S' => + 'S' => array ( 'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, @@ -43,115 +43,115 @@ class ComposerStaticInit4da13270269c89a28e472e1f7324e6d1 'Symfony\\Component\\Translation\\' => 30, 'Symfony\\Component\\HttpFoundation\\' => 33, ), - 'P' => + 'P' => array ( 'Psr\\SimpleCache\\' => 16, 'Psr\\Container\\' => 14, 'Prophecy\\' => 9, ), - 'I' => + 'I' => array ( 'Illuminate\\Support\\' => 19, 'Illuminate\\Pagination\\' => 22, 'Illuminate\\Contracts\\' => 21, ), - 'D' => + 'D' => array ( 'Doctrine\\Instantiator\\' => 22, 'Doctrine\\Inflector\\' => 19, ), - 'C' => + 'C' => array ( 'Carbon\\' => 7, ), ); public static $prefixDirsPsr4 = array ( - 'voku\\' => + 'voku\\' => array ( 0 => __DIR__ . '/..' . '/voku/portable-ascii/src/voku', ), - 'phpDocumentor\\Reflection\\' => + 'phpDocumentor\\Reflection\\' => array ( 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', 1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', 2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', ), - 'Webmozart\\Assert\\' => + 'Webmozart\\Assert\\' => array ( 0 => __DIR__ . '/..' . '/webmozart/assert/src', ), - 'Webklex\\PHPIMAP\\' => + 'Webklex\\PHPIMAP\\' => array ( 0 => __DIR__ . '/../..' . '/src', ), - 'Tests\\' => + 'Tests\\' => array ( 0 => __DIR__ . '/../..' . '/tests', ), - 'Symfony\\Polyfill\\Php80\\' => + 'Symfony\\Polyfill\\Php80\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', ), - 'Symfony\\Polyfill\\Mbstring\\' => + 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), - 'Symfony\\Polyfill\\Ctype\\' => + 'Symfony\\Polyfill\\Ctype\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', ), - 'Symfony\\Contracts\\Translation\\' => + 'Symfony\\Contracts\\Translation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/translation-contracts', ), - 'Symfony\\Component\\Yaml\\' => + 'Symfony\\Component\\Yaml\\' => array ( 0 => __DIR__ . '/..' . '/symfony/yaml', ), - 'Symfony\\Component\\Translation\\' => + 'Symfony\\Component\\Translation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/translation', ), - 'Symfony\\Component\\HttpFoundation\\' => + 'Symfony\\Component\\HttpFoundation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/http-foundation', ), - 'Psr\\SimpleCache\\' => + 'Psr\\SimpleCache\\' => array ( 0 => __DIR__ . '/..' . '/psr/simple-cache/src', ), - 'Psr\\Container\\' => + 'Psr\\Container\\' => array ( 0 => __DIR__ . '/..' . '/psr/container/src', ), - 'Prophecy\\' => + 'Prophecy\\' => array ( 0 => __DIR__ . '/..' . '/phpspec/prophecy/src/Prophecy', ), - 'Illuminate\\Support\\' => + 'Illuminate\\Support\\' => array ( 0 => __DIR__ . '/..' . '/illuminate/macroable', 1 => __DIR__ . '/..' . '/illuminate/collections', 2 => __DIR__ . '/..' . '/illuminate/support', ), - 'Illuminate\\Pagination\\' => + 'Illuminate\\Pagination\\' => array ( 0 => __DIR__ . '/..' . '/illuminate/pagination', ), - 'Illuminate\\Contracts\\' => + 'Illuminate\\Contracts\\' => array ( 0 => __DIR__ . '/..' . '/illuminate/contracts', ), - 'Doctrine\\Instantiator\\' => + 'Doctrine\\Instantiator\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', ), - 'Doctrine\\Inflector\\' => + 'Doctrine\\Inflector\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector', ), - 'Carbon\\' => + 'Carbon\\' => array ( 0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon', ), diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang index 9705f8823b0..d5f784248be 100644 --- a/htdocs/langs/en_US/cron.lang +++ b/htdocs/langs/en_US/cron.lang @@ -84,6 +84,8 @@ MakeLocalDatabaseDumpShort=Local database backup MakeLocalDatabaseDump=Create a local database dump. Parameters are: compression ('gz' or 'bz' or 'none'), backup type ('mysql', 'pgsql', 'auto'), 1, 'auto' or filename to build, number of backup files to keep MakeSendLocalDatabaseDumpShort=Send local database backup MakeSendLocalDatabaseDump=Send local database backup by email. Parameters are: to, from, subject, message, filename (Name of file sent), filter ('sql' for backup of database only) +CleanUnfinishedCronjobShort=Clean unfinished cronjob +CleanUnfinishedCronjob=Clean cronjob stuck in processing when the process is no longer running WarningCronDelayed=Attention, for performance purpose, whatever is next date of execution of enabled jobs, your jobs may be delayed to a maximum of %s hours, before being run. DATAPOLICYJob=Data cleaner and anonymizer JobXMustBeEnabled=Job %s must be enabled diff --git a/htdocs/langs/en_US/recruitment.lang b/htdocs/langs/en_US/recruitment.lang index 888f6fe5225..1f80ecf1082 100644 --- a/htdocs/langs/en_US/recruitment.lang +++ b/htdocs/langs/en_US/recruitment.lang @@ -57,8 +57,9 @@ EmailRecruiter=Email recruiter ToUseAGenericEmail=To use a generic email. If not defined, the email of the responsible of recruitment will be used NewCandidature=New application ListOfCandidatures=List of applications -RequestedRemuneration=Requested remuneration -ProposedRemuneration=Proposed remuneration +Remuneration=Salary +RequestedRemuneration=Requested salary +ProposedRemuneration=Proposed salary ContractProposed=Contract proposed ContractSigned=Contract signed ContractRefused=Contract refused diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php index c42d6d10ff1..060f51ebefe 100644 --- a/htdocs/recruitment/class/recruitmentcandidature.class.php +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -50,7 +50,7 @@ class RecruitmentCandidature extends CommonObject * @var int Does this object support multicompany module ? * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table */ - public $ismultientitymanaged = 0; + public $ismultientitymanaged = 1; /** * @var int Does object support extrafields ? 0=No, 1=Yes diff --git a/htdocs/recruitment/recruitmentindex.php b/htdocs/recruitment/index.php similarity index 99% rename from htdocs/recruitment/recruitmentindex.php rename to htdocs/recruitment/index.php index f028f2f8243..d8c037a22a9 100644 --- a/htdocs/recruitment/recruitmentindex.php +++ b/htdocs/recruitment/index.php @@ -19,7 +19,7 @@ */ /** - * \file recruitment/recruitmentindex.php + * \file recruitment/index.php * \ingroup recruitment * \brief Home page of recruitment top menu */ diff --git a/htdocs/recruitment/lib/recruitment_recruitmentcandidature.lib.php b/htdocs/recruitment/lib/recruitment_recruitmentcandidature.lib.php index 759e627bf59..c4ad141bca6 100644 --- a/htdocs/recruitment/lib/recruitment_recruitmentcandidature.lib.php +++ b/htdocs/recruitment/lib/recruitment_recruitmentcandidature.lib.php @@ -41,12 +41,12 @@ function recruitmentCandidaturePrepareHead($object) $head[$h][2] = 'card'; $h++; - if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - $head[$h][0] = dol_buildpath("/recruitment/recruitmentrating_card.php", 1).'?id='.$object->id; - $head[$h][1] = $langs->trans("Rating"); - $head[$h][2] = 'rating'; - $h++; - } + // if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { + // $head[$h][0] = dol_buildpath("/recruitment/recruitmentrating_card.php", 1).'?id='.$object->id; + // $head[$h][1] = $langs->trans("Rating"); + // $head[$h][2] = 'rating'; + // $h++; + // } if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { $nbNote = 0; diff --git a/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php b/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php index 28e6128452d..4e9b8d33e36 100644 --- a/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php +++ b/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php @@ -42,7 +42,7 @@ function recruitmentjobpositionPrepareHead($object) $h++; $head[$h][0] = dol_buildpath("/recruitment/recruitmentcandidature_list.php", 1).'?id='.$object->id; - $head[$h][1] = $langs->trans("Candidatures"); + $head[$h][1] = $langs->trans("RecruitmentCandidatures"); $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."recruitment_recruitmentcandidature WHERE fk_recruitmentjobposition = ".((int) $object->id); $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/recruitment/recruitmentcandidature_agenda.php b/htdocs/recruitment/recruitmentcandidature_agenda.php index bfe70deb075..067a472e1f8 100644 --- a/htdocs/recruitment/recruitmentcandidature_agenda.php +++ b/htdocs/recruitment/recruitmentcandidature_agenda.php @@ -124,7 +124,7 @@ if (empty($reshook)) { $form = new Form($db); if ($object->id > 0) { - $title = $langs->trans("Agenda"); + $title = $object->ref." - ".$langs->trans('Agenda'); //if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title; $help_url = 'Module_Agenda_En'; llxHeader('', $title, $help_url); diff --git a/htdocs/recruitment/recruitmentcandidature_card.php b/htdocs/recruitment/recruitmentcandidature_card.php index b1903edb71f..0a5bd616fd5 100644 --- a/htdocs/recruitment/recruitmentcandidature_card.php +++ b/htdocs/recruitment/recruitmentcandidature_card.php @@ -257,10 +257,15 @@ $form = new Form($db); $formfile = new FormFile($db); $formproject = new FormProjets($db); -$title = $langs->trans("RecruitmentCandidature"); -$help_url = ''; -llxHeader('', $title, $help_url); +if ($action == 'create') { + $title = $langs->trans('NewCandidature'); + $help_url = ''; +} else { + $title = $object->ref." - ".$langs->trans('Card'); + $help_url = ''; +} +llxHeader('', $title, $help_url); // Part to create if ($action == 'create') { @@ -651,6 +656,16 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $trackid = 'recruitmentcandidature'.$object->id; $inreplyto = $object->email_msgid; + $job = new RecruitmentJobPosition($db); + $job->fetch($object->fk_recruitmentjobposition); + + require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + $recruiter = new User($db); + $recruiter->fetch($job->fk_user_recruiter); + + $recruitername = $recruiter->getFullName(''); + $recruitermail = (!empty($job->email_recruiter) ? $job->email_recruiter : $recruiter->email); + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } diff --git a/htdocs/recruitment/recruitmentcandidature_document.php b/htdocs/recruitment/recruitmentcandidature_document.php index cd3da93b9e0..95ce0210303 100644 --- a/htdocs/recruitment/recruitmentcandidature_document.php +++ b/htdocs/recruitment/recruitmentcandidature_document.php @@ -97,9 +97,8 @@ include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; $form = new Form($db); -$title = $langs->trans("RecruitmentJobPosition").' - '.$langs->trans("Files"); +$title = $object->ref." - ".$langs->trans('Files'); $help_url = ''; -//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; llxHeader('', $title, $help_url); if ($object->id) { diff --git a/htdocs/recruitment/recruitmentcandidature_list.php b/htdocs/recruitment/recruitmentcandidature_list.php index d64d2e70037..1e3423dfd6c 100644 --- a/htdocs/recruitment/recruitmentcandidature_list.php +++ b/htdocs/recruitment/recruitmentcandidature_list.php @@ -556,7 +556,7 @@ $newcardbutton = ''; $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); $newcardbutton .= dolGetButtonTitleSeparator(); -$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.((int) $id)), '', $permissiontoadd); +$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?action=create&fk_recruitmentjobposition='.$id, '', $permissiontoadd); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/recruitment/recruitmentcandidature_note.php b/htdocs/recruitment/recruitmentcandidature_note.php index c6fedf6fcea..a9a14376b94 100644 --- a/htdocs/recruitment/recruitmentcandidature_note.php +++ b/htdocs/recruitment/recruitmentcandidature_note.php @@ -80,9 +80,9 @@ if (empty($reshook)) { $form = new Form($db); -//$help_url='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; +$title = $object->ref." - ".$langs->trans('Notes'); $help_url = ''; -llxHeader('', $langs->trans('RecruitmentCandidature'), $help_url); +llxHeader('', $title, $help_url); if ($id > 0 || !empty($ref)) { $object->fetch_thirdparty(); diff --git a/htdocs/recruitment/recruitmentjobposition_agenda.php b/htdocs/recruitment/recruitmentjobposition_agenda.php index 07cecb0070e..df6ff2ed6ad 100644 --- a/htdocs/recruitment/recruitmentjobposition_agenda.php +++ b/htdocs/recruitment/recruitmentjobposition_agenda.php @@ -124,7 +124,7 @@ if (empty($reshook)) { $form = new Form($db); if ($object->id > 0) { - $title = $langs->trans("Agenda"); + $title = $object->ref." - ".$langs->trans('Agenda'); //if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title; $help_url = ''; llxHeader('', $title, $help_url); diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index 996868a791e..cf41a06f954 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -177,7 +177,7 @@ $form = new Form($db); $formfile = new FormFile($db); $formproject = new FormProjets($db); -$title = $langs->trans("PositionToBeFilled"); +$title = $object->ref." - ".$langs->trans('Card'); $help_url = ''; llxHeader('', $title, $help_url); diff --git a/htdocs/recruitment/recruitmentjobposition_document.php b/htdocs/recruitment/recruitmentjobposition_document.php index d05ed9ab5d6..ca9907976be 100644 --- a/htdocs/recruitment/recruitmentjobposition_document.php +++ b/htdocs/recruitment/recruitmentjobposition_document.php @@ -97,7 +97,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; $form = new Form($db); -$title = $langs->trans("RecruitmentJobPosition").' - '.$langs->trans("Files"); +$title = $object->ref." - ".$langs->trans('Files'); $help_url = ''; //$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; llxHeader('', $title, $help_url); diff --git a/htdocs/recruitment/recruitmentjobposition_note.php b/htdocs/recruitment/recruitmentjobposition_note.php index c5d8cc29533..bbcced5326a 100644 --- a/htdocs/recruitment/recruitmentjobposition_note.php +++ b/htdocs/recruitment/recruitmentjobposition_note.php @@ -85,9 +85,9 @@ if (empty($reshook)) { $form = new Form($db); -//$help_url='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; +$title = $object->ref." - ".$langs->trans('Notes'); $help_url = ''; -llxHeader('', $langs->trans('RecruitmentJobPosition'), $help_url); +llxHeader('', $title, $help_url); if ($id > 0 || !empty($ref)) { $object->fetch_thirdparty(); diff --git a/htdocs/resource/agenda.php b/htdocs/resource/agenda.php index cb13ce78e7d..27edf4457e5 100644 --- a/htdocs/resource/agenda.php +++ b/htdocs/resource/agenda.php @@ -35,12 +35,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php'; require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; // Load translation files required by the page -$langs->load("companies"); +$langs->load('companies'); // Get parameters -$id = GETPOST('id', 'int'); +$id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); -$action = GETPOST('action', 'aZ09'); +$action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); @@ -52,6 +52,7 @@ if (GETPOST('actioncode', 'array')) { } else { $actioncode = GETPOST("actioncode", "alpha", 3) ?GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); } + $search_agenda_label = GETPOST('search_agenda_label'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; @@ -72,7 +73,7 @@ if (!$sortorder) { } // Initialize technical objects -//$object=new MyObject($db); + $extrafields = new ExtraFields($db); $hookmanager->initHooks(array('agendaresource')); @@ -94,7 +95,7 @@ if (!$user->rights->resource->read) { */ $parameters = array('id'=>$id); -$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +$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'); } @@ -126,7 +127,6 @@ if ($object->id > 0) { require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - $langs->load("companies"); $picto = 'resource'; $title = $langs->trans("Agenda"); diff --git a/htdocs/resource/contact.php b/htdocs/resource/contact.php index aca47d49743..cf291cce28c 100644 --- a/htdocs/resource/contact.php +++ b/htdocs/resource/contact.php @@ -1,10 +1,13 @@ * Copyright (C) 2007-2009 Laurent Destailleur * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2016 Gilles Poirier - * + */ + +/** * 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 @@ -22,7 +25,7 @@ /** * \file htdocs/resource/contact.php * \ingroup resource - * \brief Onglet de gestion des contacts des resources + * \brief Contacts management tab for resources */ require '../main.inc.php'; @@ -32,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; // Load translation files required by the page -$langs->loadLangs(array('resource', 'sendings', 'companies')); +$langs->loadLangs(array('companies', 'resource', 'sendings')); $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); @@ -41,7 +44,7 @@ $action = GETPOST('action', 'aZ09'); $object = new DolResource($db); // Load object -include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Security check if ($user->socid) { @@ -55,10 +58,12 @@ if (!$user->rights->resource->read) { } + /* - * Add a new contact + * Actions */ +// Add a new contact if ($action == 'addcontact' && $user->rights->resource->write) { if ($result > 0 && $id > 0) { $contactid = (GETPOST('userid', 'int') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int')); @@ -106,7 +111,7 @@ $userstatic = new User($db); llxHeader('', $langs->trans("Resource")); -// Mode vue et edition +// View and edit mode if ($id > 0 || !empty($ref)) { $soc = new Societe($db); diff --git a/htdocs/workstation/workstation_agenda.php b/htdocs/workstation/workstation_agenda.php index ff30d062f38..c09bef044c6 100644 --- a/htdocs/workstation/workstation_agenda.php +++ b/htdocs/workstation/workstation_agenda.php @@ -1,4 +1,5 @@ * Copyright (C) 2020 Gauthier VERDOL * @@ -17,7 +18,7 @@ */ /** - * \file workstation_agenda.php + * \file htdocs/workstation/workstation_agenda.php * \ingroup workstation * \brief Tab of events on Workstation */ @@ -32,12 +33,12 @@ require_once DOL_DOCUMENT_ROOT.'/workstation/lib/workstation_workstation.lib.php // Load translation files required by the page -$langs->loadLangs(array("workstation", "other")); +$langs->loadLangs(array('workstation', 'other')); // Get parameters -$id = GETPOST('id', 'int'); +$id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); -$action = GETPOST('action', 'aZ09'); +$action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); @@ -49,6 +50,7 @@ if (GETPOST('actioncode', 'array')) { } else { $actioncode = GETPOST("actioncode", "alpha", 3) ?GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); } + $search_agenda_label = GETPOST('search_agenda_label'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; @@ -73,6 +75,7 @@ $object = new Workstation($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('workstationagenda', 'globalcard')); // Note that conf->hooks_modules contains array + // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); diff --git a/htdocs/workstation/workstation_card.php b/htdocs/workstation/workstation_card.php index 9e859dcc2d0..31530a50f9b 100644 --- a/htdocs/workstation/workstation_card.php +++ b/htdocs/workstation/workstation_card.php @@ -1,4 +1,5 @@ * * This program is free software; you can redistribute it and/or modify @@ -16,7 +17,7 @@ */ /** - * \file workstation_card.php + * \file htdocs/workstation/workstation_card.php * \ingroup workstation * \brief Page to create/edit/view workstation */ @@ -24,32 +25,33 @@ // Load Dolibarr environment require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; -require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php'; require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; -require_once DOL_DOCUMENT_ROOT.'/workstation/lib/workstation_workstation.lib.php'; require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstationusergroup.class.php'; +require_once DOL_DOCUMENT_ROOT.'/workstation/lib/workstation_workstation.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("workstation", "other")); +$langs->loadLangs(array('workstation', 'other')); // Get parameters -$id = GETPOST('id', 'int'); -$ref = GETPOST('ref', 'alpha'); -$action = GETPOST('action', 'aZ09'); -$confirm = GETPOST('confirm', 'alpha'); -$cancel = GETPOST('cancel', 'aZ09'); -$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'workstationcard'; // To manage different context of search -$backtopage = GETPOST('backtopage', 'alpha'); +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'workstationcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); -$groups = GETPOST('groups', 'array:int'); +$groups = GETPOST('groups', 'array:int'); $resources = GETPOST('resources', 'array:int'); //$lineid = GETPOST('lineid', 'int'); // Initialize technical objects $object = new Workstation($db); + //$extrafields = new ExtraFields($db); $diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('workstationcard', 'globalcard')); // Note that conf->hooks_modules contains array @@ -142,7 +144,6 @@ if (empty($reshook)) { - /* * View * diff --git a/htdocs/workstation/workstation_document.php b/htdocs/workstation/workstation_document.php index 92cf4dfde15..2ccf1936615 100644 --- a/htdocs/workstation/workstation_document.php +++ b/htdocs/workstation/workstation_document.php @@ -1,4 +1,5 @@ * Copyright (C) 2020 Gauthier VERDOL * @@ -17,22 +18,22 @@ */ /** - * \file workstation_document.php + * \file htdocs/workstation/workstation_document.php * \ingroup workstation * \brief Tab for documents linked to Workstation */ // Load Dolibarr environment require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; require_once DOL_DOCUMENT_ROOT.'/workstation/lib/workstation_workstation.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("workstation", "companies", "other", "mails")); +$langs->loadLangs(array('companies', 'mails', 'other', 'workstation')); $action = GETPOST('action', 'aZ09'); @@ -64,6 +65,7 @@ $object = new Workstation($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('workstationdocument', 'globalcard')); // Note that conf->hooks_modules contains array + // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); diff --git a/htdocs/workstation/workstation_list.php b/htdocs/workstation/workstation_list.php index 540f6bc9c6b..d4ea81e769f 100644 --- a/htdocs/workstation/workstation_list.php +++ b/htdocs/workstation/workstation_list.php @@ -1,4 +1,5 @@ * Copyright (C) 2020 Gauthier VERDOL * @@ -17,7 +18,7 @@ */ /** - * \file workstation_list.php + * \file htdocs/workstation/workstation_list.php * \ingroup workstation * \brief List page for workstation */ @@ -25,24 +26,24 @@ // Load Dolibarr environment require '../main.inc.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'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php'; require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; // Load translation files required by the page -$langs->loadLangs(array("workstation", "other")); +$langs->loadLangs(array('workstation', 'other')); -$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... -$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) -$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? -$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation -$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button -$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list -$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'workstationlist'; // To manage different context of search -$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page -$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') -$mode = GETPOST('mode', 'aZ'); +$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... +$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) +$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? +$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation +$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button +$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'workstationlist'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$mode = GETPOST('mode', 'aZ'); $id = GETPOST('id', 'int'); @@ -63,7 +64,7 @@ $pagenext = $page + 1; $object = new Workstation($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; -$hookmanager->initHooks(array('workstationlist')); // Note that conf->hooks_modules contains array +$hookmanager->initHooks(array('workstationlist')); // Note that conf->hooks_modules contains array // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); diff --git a/htdocs/workstation/workstation_note.php b/htdocs/workstation/workstation_note.php index dc230dd38ff..d5eb05737f0 100644 --- a/htdocs/workstation/workstation_note.php +++ b/htdocs/workstation/workstation_note.php @@ -1,4 +1,5 @@ * Copyright (C) 2020 Gauthier VERDOL * @@ -17,7 +18,7 @@ */ /** - * \file workstation_note.php + * \file htdocs/workstation/workstation_note.php * \ingroup workstation * \brief Tab for notes on Workstation */ @@ -29,12 +30,12 @@ require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php'; require_once DOL_DOCUMENT_ROOT.'/workstation/lib/workstation_workstation.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("workstation", "companies")); +$langs->loadLangs(array('workstation', 'companies')); // Get parameters -$id = GETPOST('id', 'int'); +$id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); -$action = GETPOST('action', 'aZ09'); +$action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); @@ -42,18 +43,19 @@ $backtopage = GETPOST('backtopage', 'alpha'); $object = new Workstation($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->workstation->dir_output.'/temp/massgeneration/'.$user->id; -$hookmanager->initHooks(array('workstationnote', 'globalcard')); // Note that conf->hooks_modules contains array +$hookmanager->initHooks(array('workstationnote', 'globalcard')); // Note that conf->hooks_modules contains array + // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); // Load object -include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals if ($id > 0 || !empty($ref)) { $upload_dir = $conf->workstation->multidir_output[$object->entity]."/".$object->id; } -$permissionnote = $user->rights->workstation->workstation->write; // Used by the include of actions_setnotes.inc.php -$permissiontoadd = $user->rights->workstation->workstation->write; // Used by the include of actions_addupdatedelete.inc.php +$permissionnote = $user->rights->workstation->workstation->write; // Used by the include of actions_setnotes.inc.php +$permissiontoadd = $user->rights->workstation->workstation->write; // Used by the include of actions_addupdatedelete.inc.php // Security check $isdraft = 0; @@ -63,7 +65,8 @@ restrictedArea($user, $object->element, $object->id, $object->table_element, 'wo /* * Actions */ -$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } diff --git a/htdocs/zapier/admin/setup.php b/htdocs/zapier/admin/setup.php index 0d3cf64c54f..90e2b8b8283 100644 --- a/htdocs/zapier/admin/setup.php +++ b/htdocs/zapier/admin/setup.php @@ -26,11 +26,11 @@ require '../../main.inc.php'; // Libraries -require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/zapier/lib/zapier.lib.php'; // Translations -$langs->loadLangs(array("admin", "zapier")); +$langs->loadLangs(array('admin', 'zapier')); // Access control if (!$user->admin) { @@ -63,7 +63,7 @@ if ((float) DOL_VERSION >= 6) { * View */ -$page_name = "ZapierForDolibarrSetup"; +$page_name = 'ZapierForDolibarrSetup'; $help_url = 'EN:Module_Zapier'; llxHeader('', $langs->trans($page_name), $help_url); diff --git a/htdocs/zapier/class/api_zapier.class.php b/htdocs/zapier/class/api_zapier.class.php index 5bcab883238..cfb46fb70b9 100644 --- a/htdocs/zapier/class/api_zapier.class.php +++ b/htdocs/zapier/class/api_zapier.class.php @@ -1,4 +1,5 @@ * Copyright (C) 2019-2020 Frédéric France * @@ -16,16 +17,17 @@ * along with this program. If not, see . */ -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/zapier/class/hook.class.php'; - /** * \file htdocs/zapier/class/api_zapier.class.php * \ingroup zapier * \brief File for API management of hook. */ +use Luracast\Restler\RestException; + +require_once DOL_DOCUMENT_ROOT.'/zapier/class/hook.class.php'; + + /** * API class for zapier hook * diff --git a/htdocs/zapier/lib/zapier_hook.lib.php b/htdocs/zapier/lib/zapier_hook.lib.php deleted file mode 100644 index 3d4228325e2..00000000000 --- a/htdocs/zapier/lib/zapier_hook.lib.php +++ /dev/null @@ -1,90 +0,0 @@ -. - */ - -/** - * \file htdocs/modulebuilder/template/lib/mymodule_myobject.lib.php - * \ingroup mymodule - * \brief Library files with common functions for MyObject - */ - -/** - * Prepare array of tabs for MyObject - * - * @param MyObject $object MyObject - * @return array Array of tabs - */ -function myobjectPrepareHead($object) -{ - global $db, $langs, $conf; - - $langs->load("mymodule@mymodule"); - - $h = 0; - $head = array(); - - $head[$h][0] = dol_buildpath("/mymodule/myobject_card.php", 1).'?id='.$object->id; - $head[$h][1] = $langs->trans("Card"); - $head[$h][2] = 'card'; - $h++; - - if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { - $nbNote = 0; - if (!empty($object->note_private)) { - $nbNote++; - } - if (!empty($object->note_public)) { - $nbNote++; - } - $head[$h][0] = dol_buildpath('/mymodule/myobject_note.php', 1).'?id='.$object->id; - $head[$h][1] = $langs->trans('Notes'); - if ($nbNote > 0) { - $head[$h][1] .= ''.$nbNote.''; - } - $head[$h][2] = 'note'; - $h++; - } - - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; - $upload_dir = $conf->mymodule->dir_output."/myobject/".dol_sanitizeFileName($object->ref); - $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); - $nbLinks = Link::count($db, $object->element, $object->id); - $head[$h][0] = dol_buildpath("/mymodule/myobject_document.php", 1).'?id='.$object->id; - $head[$h][1] = $langs->trans('Documents'); - if (($nbFiles + $nbLinks) > 0) { - $head[$h][1] .= ''.($nbFiles + $nbLinks).''; - } - $head[$h][2] = 'document'; - $h++; - - $head[$h][0] = dol_buildpath("/mymodule/myobject_agenda.php", 1).'?id='.$object->id; - $head[$h][1] = $langs->trans("Events"); - $head[$h][2] = 'agenda'; - $h++; - - // Show more tabs from modules - // Entries must be declared in modules descriptor with line - //$this->tabs = array( - // 'entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__' - //); // to add new tab - //$this->tabs = array( - // 'entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__' - //); // to remove a tab - complete_head_from_modules($conf, $langs, $object, $head, $h, 'myobject@mymodule'); - - return $head; -} diff --git a/test/phpunit/CodingPhpTest.php b/test/phpunit/CodingPhpTest.php index 6388d3985e7..dd0e6827ec1 100644 --- a/test/phpunit/CodingPhpTest.php +++ b/test/phpunit/CodingPhpTest.php @@ -464,7 +464,9 @@ class CodingPhpTest extends PHPUnit\Framework\TestCase //var_dump($val); if (!in_array($val[1], array( "'replacestring'", "'htmlheader'", "'WEBSITE_HTML_HEADER'", "'WEBSITE_CSS_INLINE'", "'WEBSITE_JS_INLINE'", "'WEBSITE_MANIFEST_JSON'", "'PAGE_CONTENT'", "'WEBSITE_README'", - "'search_status'", '"mysqldump"', '"postgresqldump"', "'db_pass_root'", "'db_pass'", '"pass"', '"pass1"', '"pass2"', '"password"', "'password'", '"MAIN_MAIL_SMTPS_PW"'))) { + '"mysqldump"', '"postgresqldump"', + "'db_pass_root'", "'db_pass'", '"pass"', '"pass1"', '"pass2"', '"password"', "'password'", + '"MAIN_MAIL_SMTPS_PW"', '"MAIN_MAIL_SMTPS_PW_EMAILING"', '"MAIN_MAIL_SMTPS_PW_TICKET"'))) { $ok=false; break; }