NEW Can enter price with or without tax when entering expense repor line

This commit is contained in:
Laurent Destailleur 2019-03-07 11:09:04 +01:00
parent 6206402be3
commit e67890bd22
5 changed files with 100 additions and 53 deletions

View File

@ -1912,7 +1912,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '')
print '<td><input type="text" class="flat minwidth75" value="'.price((! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')).'" name="'.$fieldlist[$field].'"></td>';
}
elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
print '<td class="maxxxx"><input type="text" class="flat minwidth75" value="'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'"></td>';
print '<td class="maxxxx"><input type="text" class="flat minwidth75 maxwidth100" value="'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'"></td>';
}
elseif ($fieldlist[$field]=='unit') {
print '<td>';

View File

@ -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 '</tr>';
// User to inform for approval
if ($object->fk_statut < 3) // informed
if ($object->fk_statut <= ExpenseReport::STATUS_VALIDATED) // informed
{
print '<tr>';
print '<td>'.$langs->trans("VALIDATOR").'</td>'; // approver
@ -1760,7 +1764,7 @@ else
}
print '</td></tr>';
}
elseif($object->fk_statut == 4)
elseif($object->fk_statut == ExpenseReport::STATUS_CANCELED)
{
print '<tr>';
print '<td>'.$langs->trans("CANCEL_USER").'</span></td>';
@ -1854,11 +1858,11 @@ else
print '<td class="titlefieldmiddle">'.$langs->trans("AmountHT").'</td>';
print '<td class="nowrap amountcard">'.price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency).'</td>';
$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 "</td>";
print '</tr>';
@ -2016,6 +2020,7 @@ else
print '<td style="text-align:center;">'.$langs->trans('Type').'</td>';
print '<td style="text-align:left;">'.$langs->trans('Description').'</td>';
print '<td style="text-align:right;">'.$langs->trans('VAT').'</td>';
print '<td style="text-align:right;">'.$langs->trans('PriceUHT').'</td>';
print '<td style="text-align:right;">'.$langs->trans('PriceUTTC').'</td>';
print '<td style="text-align:right;">'.$langs->trans('Qty').'</td>';
if ($action != 'editline')
@ -2071,6 +2076,7 @@ else
print '</td>';
print '<td style="text-align:left;">'.dol_escape_htmltag($line->comments).'</td>';
print '<td style="text-align:right;">'.vatrate($line->vatrate, true).'</td>';
print '<td style="text-align:right;">'.price($line->value_unit_ht).'</td>';
print '<td style="text-align:right;">'.price($line->value_unit).'</td>';
print '<td style="text-align:right;">'.dol_escape_htmltag($line->qty).'</td>';
@ -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 '<td style="text-align:right;" class="nowrap">';
@ -2137,12 +2143,17 @@ else
// VAT
print '<td style="text-align:right;">';
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 '</td>';
// Unit price
print '<td style="text-align:right;">';
print '<input type="text" min="0" class="maxwidth100" name="value_unit" value="'.dol_escape_htmltag($line->value_unit).'" />';
print '<input type="text" min="0" class="maxwidth100" id="value_unit_ht" name="value_unit_ht" value="'.dol_escape_htmltag($line->value_unit_ht).'" />';
print '</td>';
// Unit price with tax
print '<td style="text-align:right;">';
print '<input type="text" min="0" class="maxwidth100" id="value_unit" name="value_unit" value="'.dol_escape_htmltag($line->value_unit).'" />';
print '</td>';
// Quantity
@ -2178,6 +2189,7 @@ else
print '<td align="center">'.$langs->trans('Type').'</td>';
print '<td>'.$langs->trans('Description').'</td>';
print '<td align="right">'.$langs->trans('VAT').'</td>';
print '<td align="right">'.$langs->trans('PriceUHT').'</td>';
print '<td align="right">'.$langs->trans('PriceUTTC').'</td>';
print '<td align="right">'.$langs->trans('Qty').'</td>';
print '<td colspan="3"></td>';
@ -2225,9 +2237,14 @@ else
print $form->load_tva('vatrate', ($vatrate!=''?$vatrate:$defaultvat), $mysoc, '', 0, 0, '', false, 1);
print '</td>';
// Unit price
// Unit price net
print '<td align="right">';
print '<input type="text" class="right maxwidth50" name="value_unit" value="'.dol_escape_htmltag($value_unit).'">';
print '<input type="text" class="right maxwidth50" id="value_unit_ht" name="value_unit_ht" value="'.dol_escape_htmltag($value_unit_ht).'">';
print '</td>';
// Unit price with tax
print '<td align="right">';
print '<input type="text" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag($value_unit).'">';
print '</td>';
// Quantity
@ -2249,6 +2266,26 @@ else
print '</table>';
print '</div>';
print '<script javascript>
/* JQuery for product free or predefined select */
jQuery(document).ready(function() {
jQuery("#value_unit_ht").keyup(function(event) {
console.log(event.which); // discard event tag and arrows
if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#value_unit_ht").val() != "") {
jQuery("#value_unit").val("");
}
});
jQuery("#value_unit").keyup(function(event) {
console.log(event.which); // discard event tag and arrows
if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
jQuery("#value_unit_ht").val("");
}
});
});
</script>';
print '</form>';
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 '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
}
// 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 '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$object->id.'">'.$langs->trans('Cancel').'</a></div>';
}
// 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 '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$object->id.'">'.$langs->trans('Cancel').'</a></div>';
@ -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 '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&id='.$object->id.'">'.$langs->trans('Delete').'</a></div>';
}
elseif($user->rights->expensereport->supprimer && $object->fk_statut != 6)
elseif($user->rights->expensereport->supprimer && $object->fk_statut != ExpenseReport::STATUS_CLOSED)
{
// Delete
print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&id='.$object->id.'">'.$langs->trans('Delete').'</a></div>';

View File

@ -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

View File

@ -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;

View File

@ -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