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 '';
}
// 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 '';
}
// 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 '';
@@ -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 '';
}
- elseif($user->rights->expensereport->supprimer && $object->fk_statut != 6)
+ elseif($user->rights->expensereport->supprimer && $object->fk_statut != ExpenseReport::STATUS_CLOSED)
{
// Delete
print '';
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