diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 11134f70194..541262b2bf5 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -1912,7 +1912,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) { - print ''; + print ''; } elseif ($fieldlist[$field]=='unit') { print ''; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 2ce6ca0f70a..3c7253f9065 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -133,6 +133,7 @@ if (empty($reshook)) $date=''; $comments=''; $vatrate=''; + $value_unit_ht=''; $value_unit=''; $qty=1; $fk_c_type_fees=-1; @@ -1095,10 +1096,16 @@ if (empty($reshook)) // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary. if (empty($vatrate)) $vatrate = "0.000"; - $vatrate = price2num($vatrate); + $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $vatrate)); + $value_unit_ht=price2num(GETPOST('value_unit_ht', 'alpha'), 'MU'); $value_unit=price2num(GETPOST('value_unit', 'alpha'), 'MU'); - $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int'); + if (empty($value_unit)) + { + $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU'); + } + + $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int'); $qty = GETPOST('qty', 'int'); if (empty($qty)) $qty=1; @@ -1110,23 +1117,13 @@ if (empty($reshook)) $action=''; } - if ($vatrate < 0 || $vatrate == '') + if ((int) $tmpvat < 0 || $tmpvat == '') { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("VAT")), null, 'errors'); $action=''; } - /* Projects are never required. To force them, check module forceproject - if ($conf->projet->enabled) - { - if (empty($object_ligne->fk_projet) || $object_ligne->fk_projet==-1) - { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Project")), null, 'errors'); - } - }*/ - // Si aucune date n'est rentrée if (empty($date) || $date=="--") { @@ -1134,7 +1131,7 @@ if (empty($reshook)) setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); } // Si aucun prix n'est rentré - if ($value_unit==0) + if ($value_unit == 0) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PriceUTTC")), null, 'errors'); @@ -1171,6 +1168,7 @@ if (empty($reshook)) } unset($qty); + unset($value_unit_ht); unset($value_unit); unset($vatrate); unset($comments); @@ -1240,12 +1238,18 @@ if (empty($reshook)) $projet_id = $fk_projet; $comments = GETPOST('comments', 'none'); $qty = GETPOST('qty', 'int'); - $value_unit = price2num(GETPOST('value_unit', 'alpha'), 'MU'); $vatrate = GETPOST('vatrate', 'alpha'); - // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary. - if (empty($vatrate)) $vatrate = "0.000"; - $vatrate = price2num($vatrate); + // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary. + if (empty($vatrate)) $vatrate = "0.000"; + $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $vatrate)); + + $value_unit_ht=price2num(GETPOST('value_unit_ht', 'alpha'), 'MU'); + $value_unit=price2num(GETPOST('value_unit', 'alpha'), 'MU'); + if (empty($value_unit)) + { + $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU'); + } if (! GETPOST('fk_c_type_fees', 'int') > 0) { @@ -1253,7 +1257,7 @@ if (empty($reshook)) setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors'); $action=''; } - if ((int) $vatrate < 0 || $vatrate == '') + if ((int) $tmpvat < 0 || $tmpvat == '') { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Vat")), null, 'errors'); @@ -1742,7 +1746,7 @@ else print ''; // User to inform for approval - if ($object->fk_statut < 3) // informed + if ($object->fk_statut <= ExpenseReport::STATUS_VALIDATED) // informed { print ''; print ''.$langs->trans("VALIDATOR").''; // approver @@ -1760,7 +1764,7 @@ else } print ''; } - elseif($object->fk_statut == 4) + elseif($object->fk_statut == ExpenseReport::STATUS_CANCELED) { print ''; print ''.$langs->trans("CANCEL_USER").''; @@ -1854,11 +1858,11 @@ else print ''.$langs->trans("AmountHT").''; print ''.price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency).''; $rowspan = 5; - if ($object->fk_statut < 3) $rowspan++; - elseif($object->fk_statut == 4) $rowspan+=2; + if ($object->fk_statut <= ExpenseReport::STATUS_VALIDATED) $rowspan++; + elseif($object->fk_statut == ExpenseReport::STATUS_CANCELED) $rowspan+=2; else $rowspan+=2; - if ($object->fk_statut==99 || !empty($object->detail_refuse)) $rowspan+=2; - if($object->fk_statut==6) $rowspan+=2; + if ($object->fk_statut == ExpenseReport::STATUS_REFUSED || !empty($object->detail_refuse)) $rowspan+=2; + if ($object->fk_statut == ExpenseReport::STATUS_CLOSED) $rowspan+=2; print ""; print ''; @@ -2016,6 +2020,7 @@ else print ''.$langs->trans('Type').''; print ''.$langs->trans('Description').''; print ''.$langs->trans('VAT').''; + print ''.$langs->trans('PriceUHT').''; print ''.$langs->trans('PriceUTTC').''; print ''.$langs->trans('Qty').''; if ($action != 'editline') @@ -2071,6 +2076,7 @@ else print ''; print ''.dol_escape_htmltag($line->comments).''; print ''.vatrate($line->vatrate, true).''; + print ''.price($line->value_unit_ht).''; print ''.price($line->value_unit).''; print ''.dol_escape_htmltag($line->qty).''; @@ -2081,7 +2087,7 @@ else } // Ajout des boutons de modification/suppression - if (($object->fk_statut < 2 || $object->fk_statut == 99) && $user->rights->expensereport->creer) + if (($object->fk_statut < ExpenseReport::STATUS_VALIDATED || $object->fk_statut == ExpenseReport::STATUS_REFUSED) && $user->rights->expensereport->creer) { print ''; @@ -2137,12 +2143,17 @@ else // VAT print ''; - print $form->load_tva('vatrate', (isset($_POST["vatrate"])?$_POST["vatrate"]:$line->vatrate), $mysoc, ''); + print $form->load_tva('vatrate', (isset($_POST["vatrate"])?$_POST["vatrate"]:$line->vatrate), $mysoc, '', 0, 0, '', false, 1); print ''; // Unit price print ''; - print ''; + print ''; + print ''; + + // Unit price with tax + print ''; + print ''; print ''; // Quantity @@ -2178,6 +2189,7 @@ else print ''.$langs->trans('Type').''; print ''.$langs->trans('Description').''; print ''.$langs->trans('VAT').''; + print ''.$langs->trans('PriceUHT').''; print ''.$langs->trans('PriceUTTC').''; print ''.$langs->trans('Qty').''; print ''; @@ -2225,9 +2237,14 @@ else print $form->load_tva('vatrate', ($vatrate!=''?$vatrate:$defaultvat), $mysoc, '', 0, 0, '', false, 1); print ''; - // Unit price + // Unit price net print ''; - print ''; + print ''; + print ''; + + // Unit price with tax + print ''; + print ''; print ''; // Quantity @@ -2249,6 +2266,26 @@ else print ''; print ''; + print ''; + print ''; dol_fiche_end(); @@ -2286,7 +2323,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_author == user courant * Afficher : "Enregistrer" / "Modifier" / "Supprimer" */ - if ($user->rights->expensereport->creer && $object->fk_statut==0) + if ($user->rights->expensereport->creer && $object->fk_statut == ExpenseReport::STATUS_DRAFT) { if (in_array($object->fk_user_author, $user->getAllChildIds(1)) || !empty($user->rights->expensereport->writeall_advance)) { @@ -2306,7 +2343,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_author == user courant * Afficher : "Enregistrer" / "Modifier" / "Supprimer" */ - if($user->rights->expensereport->creer && $object->fk_statut==99) + if($user->rights->expensereport->creer && $object->fk_statut == ExpenseReport::STATUS_REFUSED) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) { @@ -2320,7 +2357,7 @@ if ($action != 'create' && $action != 'edit') } } - if ($user->rights->expensereport->to_paid && $object->fk_statut==5) + if ($user->rights->expensereport->to_paid && $object->fk_statut == ExpenseReport::STATUS_APPROVED) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) { @@ -2334,7 +2371,7 @@ if ($action != 'create' && $action != 'edit') * ET fk_user_validator == user courant * Afficher : "Valider" / "Refuser" / "Supprimer" */ - if ($object->fk_statut == 2) + if ($object->fk_statut == ExpenseReport::STATUS_VALIDATED) { if (in_array($object->fk_user_author, $user->getAllChildIds(1))) { @@ -2343,7 +2380,7 @@ if ($action != 'create' && $action != 'edit') } } - if ($user->rights->expensereport->approve && $object->fk_statut == 2) + if ($user->rights->expensereport->approve && $object->fk_statut == ExpenseReport::STATUS_VALIDATED) { //if($object->fk_user_validator==$user->id) //{ @@ -2364,13 +2401,13 @@ if ($action != 'create' && $action != 'edit') // If status is Appoved // -------------------- - if ($user->rights->expensereport->approve && $object->fk_statut == 5) + if ($user->rights->expensereport->approve && $object->fk_statut == ExpenseReport::STATUS_APPROVED) { print '
id.'">'.$langs->trans('Deny').'
'; } // If bank module is used - if ($user->rights->expensereport->to_paid && ! empty($conf->banque->enabled) && $object->fk_statut == 5) + if ($user->rights->expensereport->to_paid && ! empty($conf->banque->enabled) && $object->fk_statut == ExpenseReport::STATUS_APPROVED) { // Pay if ($remaintopay == 0) @@ -2384,7 +2421,7 @@ if ($action != 'create' && $action != 'edit') } // If bank module is not used - if (($user->rights->expensereport->to_paid || empty($conf->banque->enabled)) && $object->fk_statut == 5) + if (($user->rights->expensereport->to_paid || empty($conf->banque->enabled)) && $object->fk_statut == ExpenseReport::STATUS_APPROVED) { //if ((round($remaintopay) == 0 || empty($conf->banque->enabled)) && $object->paid == 0) if ($object->paid == 0) @@ -2393,14 +2430,14 @@ if ($action != 'create' && $action != 'edit') } } - if ($user->rights->expensereport->creer && ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) && $object->fk_statut == 5) + if ($user->rights->expensereport->creer && ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) && $object->fk_statut == ExpenseReport::STATUS_APPROVED) { // Cancel print '
id.'">'.$langs->trans('Cancel').'
'; } // TODO Replace this. It should be SetUnpaid and should go back to status unpaid not canceled. - if (($user->rights->expensereport->approve || $user->rights->expensereport->to_paid) && $object->fk_statut == 6) + if (($user->rights->expensereport->approve || $user->rights->expensereport->to_paid) && $object->fk_statut == ExpenseReport::STATUS_CLOSED) { // Cancel print '
id.'">'.$langs->trans('Cancel').'
'; @@ -2412,12 +2449,12 @@ if ($action != 'create' && $action != 'edit') } /* If draft, validated, cancel, and user can create, he can always delete its card before it is approved */ - if ($user->rights->expensereport->creer && $user->id == $object->fk_user_author && $object->fk_statut <= 4) + if ($user->rights->expensereport->creer && $user->id == $object->fk_user_author && $object->fk_statut < ExpenseReport::STATUS_APPROVED) { // Delete print '
id.'">'.$langs->trans('Delete').'
'; } - elseif($user->rights->expensereport->supprimer && $object->fk_statut != 6) + elseif($user->rights->expensereport->supprimer && $object->fk_statut != ExpenseReport::STATUS_CLOSED) { // Delete print '
id.'">'.$langs->trans('Delete').'
'; diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index bbada0e22f7..dc0ffefe4ff 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -115,6 +115,11 @@ class ExpenseReport extends CommonObject */ const STATUS_VALIDATED = 2; + /** + * Classified canceled + */ + const STATUS_CANCELED = 4; + /** * Classified approved */ @@ -1442,12 +1447,12 @@ class ExpenseReport extends CommonObject // phpcs:enable $error = 0; $this->date_cancel = $this->db->idate(gmmktime()); - if ($this->fk_statut != 4) + if ($this->fk_statut != ExpenseReport::STATUS_CANCELED) { $this->db->begin(); $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET fk_statut = 4, fk_user_cancel = ".$fuser->id; + $sql.= " SET fk_statut = ".ExpenseReport::STATUS_CANCELED.", fk_user_cancel = ".$fuser->id; $sql.= ", date_cancel='".$this->db->idate($this->date_cancel)."'"; $sql.= " ,detail_cancel='".$this->db->escape($detail)."'"; $sql.= ' WHERE rowid = '.$this->id; @@ -1676,10 +1681,10 @@ class ExpenseReport extends CommonObject /** * addline * - * @param real $qty Qty + * @param float $qty Qty * @param double $up Value init * @param int $fk_c_type_fees Type payment - * @param double $vatrate Vat rate + * @param string $vatrate Vat rate (Can be '10' or '10 (ABC)') * @param string $date Date * @param string $comments Description * @param int $fk_project Project id @@ -1703,8 +1708,8 @@ class ExpenseReport extends CommonObject if (empty($fk_project)) $fk_project = 0; $qty = price2num($qty); - if (!preg_match('/\((.*)\)/', $vatrate)) { - $vatrate = price2num($vatrate); // $txtva can have format '5.0(XXX)' or '5' + if (! preg_match('/\s*\((.*)\)/', $vatrate)) { + $vatrate = price2num($vatrate); // $txtva can have format '5.0 (XXX)' or '5' } $up = price2num($up); @@ -1715,7 +1720,7 @@ class ExpenseReport extends CommonObject $localtaxes_type=getLocalTaxesFromRate($vatrate, 0, $mysoc, $this->thirdparty); $vat_src_code = ''; - if (preg_match('/\((.*)\)/', $vatrate, $reg)) + if (preg_match('/\s*\((.*)\)/', $vatrate, $reg)) { $vat_src_code = $reg[1]; $vatrate = preg_replace('/\s*\(.*\)/', '', $vatrate); // Remove code into vatrate. @@ -1727,6 +1732,7 @@ class ExpenseReport extends CommonObject $tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller, $localtaxes_type); $this->line->value_unit = $up; + $this->line->vat_src_code = $vat_src_code; $this->line->vatrate = price2num($vatrate); $this->line->total_ttc = $tmp[2]; $this->line->total_ht = $tmp[0]; @@ -1928,9 +1934,9 @@ class ExpenseReport extends CommonObject * @param int $rowid Line to edit * @param int $type_fees_id Type payment * @param int $projet_id Project id - * @param double $vatrate Vat rate. Can be '8.5* (8.5NPROM...)' + * @param double $vatrate Vat rate. Can be '8.5' or '8.5* (8.5NPROM...)' * @param string $comments Description - * @param real $qty Qty + * @param float $qty Qty * @param double $value_unit Value init * @param int $date Date * @param int $expensereport_id Expense report id diff --git a/htdocs/install/mysql/migration/9.0.0-10.0.0.sql b/htdocs/install/mysql/migration/9.0.0-10.0.0.sql index 7dd893b8dab..72330e09b92 100644 --- a/htdocs/install/mysql/migration/9.0.0-10.0.0.sql +++ b/htdocs/install/mysql/migration/9.0.0-10.0.0.sql @@ -237,3 +237,6 @@ ALTER TABLE llx_facturedet_rec ADD COLUMN fk_product_fournisseur_price integer D ALTER TABLE llx_facturedet_rec ADD COLUMN fk_user_author integer; ALTER TABLE llx_facturedet_rec ADD COLUMN fk_user_modif integer; +ALTER TABLE llx_expensereport_det MODIFY COLUMN value_unit double(24,8) NOT NULL; +ALTER TABLE llx_expensereport_det ADD COLUMN subprice double(24,8) NOT NULL after qty; + diff --git a/htdocs/install/mysql/tables/llx_expensereport_det.sql b/htdocs/install/mysql/tables/llx_expensereport_det.sql index fc0bd6e697f..1000e10955f 100644 --- a/htdocs/install/mysql/tables/llx_expensereport_det.sql +++ b/htdocs/install/mysql/tables/llx_expensereport_det.sql @@ -27,7 +27,8 @@ CREATE TABLE llx_expensereport_det comments text NOT NULL, product_type integer DEFAULT -1, qty real NOT NULL, - value_unit real NOT NULL, + subprice double(24,8), -- P.U. HT (example 100) + value_unit double(24,8) NOT NULL, -- P.U. TTC (example 120) remise_percent real, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. tva_tx double(6,3), -- Vat rate