Merge pull request #8276 from ATM-Consulting/develop_atm

NEW: supplier credit notes & discounts (absolute and relative)
This commit is contained in:
Laurent Destailleur 2018-03-08 20:06:37 +01:00 committed by GitHub
commit 1c9e7145e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 2033 additions and 735 deletions

View File

@ -882,7 +882,7 @@ if (empty($action) || $action == 'view') {
else print $accountoshow;
print '</td>';
print "<td>" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("SubledgerAccount") . "</td>";
print '<td align="right">' . ($mt < 0 ? - price(- $mt) : '') . "</td>";
print '<td align="right">'. ($mt < 0 ? price(- $mt) : '') . "</td>";
print '<td align="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
print "</tr>";
//}
@ -976,7 +976,7 @@ if (empty($action) || $action == 'view') {
print "<td>";
print '</td>';
print "<td>" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("VAT") . " NPR (counterpart)</td>";
print '<td align="right">' . ($mt < 0 ? - price(- $mt) : '') . "</td>";
print '<td align="right">' . ($mt < 0 ? price(- $mt) : '') . "</td>";
print '<td align="right">' . ($mt >= 0 ? price($mt) : '') . "</td>";
print "</tr>";
}

View File

@ -1458,17 +1458,13 @@ if ($action == 'create')
// Ligne info remises tiers
print '<tr><td>' . $langs->trans('Discounts') . '</td><td>';
if ($soc->remise_percent)
print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_percent);
else
print $langs->trans("CompanyHasNoRelativeDiscount");
$absolute_discount = $soc->getAvailableDiscounts();
print '. ';
if ($absolute_discount)
print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount, 0, $langs, 1, -1, -1, $conf->currency));
else
print $langs->trans("CompanyHasNoAbsoluteDiscount");
print '.';
$thirdparty = $soc;
$discount_type = 0;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
}
@ -1875,31 +1871,26 @@ if ($action == 'create')
print '<table class="border" width="100%">';
// Link for thirdparty discounts
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
}
print '<tr><td class="titlefield">' . $langs->trans('Discounts') . '</td><td>';
if ($soc->remise_percent)
print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_percent);
else
print $langs->trans("CompanyHasNoRelativeDiscount");
print '. ';
$absolute_discount = $soc->getAvailableDiscounts('', 'fk_facture_source IS NULL');
$absolute_creditnote = $soc->getAvailableDiscounts('', 'fk_facture_source IS NOT NULL');
$absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount);
$absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote);
$absolute_discount = price2num($absolute_discount, 'MT');
$absolute_creditnote = price2num($absolute_creditnote, 'MT');
if ($absolute_discount) {
if ($object->statut > Propal::STATUS_DRAFT) {
print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount, 0, $langs, 0, 0, -1, $conf->currency));
} else {
// Remise dispo de type non avoir
$filter = 'fk_facture_source IS NULL';
print '<br>';
$form->form_remise_dispo($_SERVER["PHP_SELF"] . '?id=' . $object->id, 0, 'remise_id', $soc->id, $absolute_discount, $filter, 0, '', 1);
}
}
if ($absolute_creditnote) {
print $langs->trans("CompanyHasCreditNote", price($absolute_creditnote, 0, $langs, 0, 0, -1, $conf->currency)) . '. ';
}
if (! $absolute_discount && ! $absolute_creditnote)
print $langs->trans("CompanyHasNoAbsoluteDiscount") . '.';
$thirdparty = $soc;
$discount_type = 0;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
// Date of proposal

View File

@ -56,7 +56,14 @@ if (GETPOST('action','aZ09') == 'setremise')
{
$object = new Societe($db);
$object->fetch($id);
$result=$object->set_remise_client(price2num(GETPOST("remise")),GETPOST("note"),$user);
$discount_type = GETPOST('discount_type', 'int');
if(! empty($discount_type)) {
$result=$object->set_remise_supplier(price2num(GETPOST("remise")),GETPOST("note"),$user);
} else {
$result=$object->set_remise_client(price2num(GETPOST("remise")),GETPOST("note"),$user);
}
if ($result > 0)
{
@ -100,7 +107,8 @@ if ($socid > 0)
$head = societe_prepare_head($object);
$isCustomer = $object->client == 1 || $object->client == 3;
$isSupplier = $object->fournisseur == 1;
print '<form method="POST" action="remise.php?id='.$object->id.'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
@ -114,11 +122,33 @@ if ($socid > 0)
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
if(! $isCustomer && ! $isSupplier) {
print '<p class="opacitymedium">'.$langs->trans('ThirdpartyIsNeitherCustomerNorClientSoCannotHaveDiscounts').'</p>';
dol_fiche_end();
print '</form>';
llxFooter();
$db->close();
exit;
}
print '<table class="border centpercent">';
// Discount
print '<tr><td class="titlefield">';
print $langs->trans("CustomerRelativeDiscount").'</td><td>'.price2num($object->remise_percent)."%</td></tr>";
if($isCustomer) {
// Customer discount
print '<tr><td class="titlefield">';
print $langs->trans("CustomerRelativeDiscount").'</td><td>'.price2num($object->remise_percent)."%</td></tr>";
}
if($isSupplier) {
// Supplier discount
print '<tr><td class="titlefield">';
print $langs->trans("SupplierRelativeDiscount").'</td><td>'.price2num($object->remise_supplier_percent)."%</td></tr>";
}
print '</table>';
print '<br>';
@ -126,8 +156,24 @@ if ($socid > 0)
print '<div class="underbanner clearboth"></div>';
if($isCustomer && ! $isSupplier) {
print '<input type="hidden" name="discount_type" value="0" />';
}
if(! $isCustomer && $isSupplier) {
print '<input type="hidden" name="discount_type" value="1" />';
}
print '<table class="border centpercent">';
if($isCustomer && $isSupplier) {
// Discount type
print '<tr><td class="titlefield fieldrequired">'.$langs->trans('DiscountType').'</td>';
print '<td><input type="radio" name="discount_type" id="discount_type_0" selected value="0"/> <label for="discount_type_0">'.$langs->trans('Customer').'</label>';
print ' <input type="radio" name="discount_type" id="discount_type_1" selected value="1"/> <label for="discount_type_1">'.$langs->trans('Supplier').'</label>';
print '</td></tr>';
}
// New value
print '<tr><td class="titlefield fieldrequired">';
print $langs->trans("NewValue").'</td><td><input type="text" size="5" name="remise" value="'.dol_escape_htmltag(GETPOST("remise")).'">%</td></tr>';
@ -155,57 +201,128 @@ if ($socid > 0)
print '<br>';
if($isCustomer) {
if($isSupplier) {
print '<div class="fichecenter">';
print '<div class="fichehalfleft">';
print load_fiche_titre($langs->trans("CustomerDiscounts"), '', '');
}
/*
* List log of all percent discounts
*/
$sql = "SELECT rc.rowid, rc.remise_client as remise_percent, rc.note, rc.datec as dc,";
$sql.= " u.login, u.rowid as user_id";
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise as rc, ".MAIN_DB_PREFIX."user as u";
$sql.= " WHERE rc.fk_soc = " . $object->id;
$sql.= " AND rc.entity = " . $conf->entity;
$sql.= " AND u.rowid = rc.fk_user_author";
$sql.= " ORDER BY rc.datec DESC";
$resql=$db->query($sql);
if ($resql)
{
print '<table class="noborder" width="100%">';
$tag = !$tag;
print '<tr class="liste_titre">';
print '<td width="160">'.$langs->trans("Date").'</td>';
print '<td width="160" align="center">'.$langs->trans("CustomerRelativeDiscountShort").'</td>';
print '<td align="left">'.$langs->trans("NoteReason").'</td>';
print '<td align="center">'.$langs->trans("User").'</td>';
print '</tr>';
$num = $db->num_rows($resql);
if ($num > 0)
{
$i = 0;
while ($i < $num)
{
$obj = $db->fetch_object($resql);
print '<tr class="oddeven">';
print '<td>'.dol_print_date($db->jdate($obj->dc),"dayhour").'</td>';
print '<td align="center">'.price2num($obj->remise_percent).'%</td>';
print '<td align="left">'.$obj->note.'</td>';
print '<td align="center"><a href="'.DOL_URL_ROOT.'/user/card.php?id='.$obj->user_id.'">'.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.'</a></td>';
print '</tr>';
$i++;
}
/*
* List log of all customer percent discounts
*/
$sql = "SELECT rc.rowid, rc.remise_client as remise_percent, rc.note, rc.datec as dc,";
$sql.= " u.login, u.rowid as user_id";
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise as rc, ".MAIN_DB_PREFIX."user as u";
$sql.= " WHERE rc.fk_soc = " . $object->id;
$sql.= " AND rc.entity = " . $conf->entity;
$sql.= " AND u.rowid = rc.fk_user_author";
$sql.= " ORDER BY rc.datec DESC";
$resql=$db->query($sql);
if ($resql)
{
print '<table class="noborder" width="100%">';
$tag = !$tag;
print '<tr class="liste_titre">';
print '<td width="160">'.$langs->trans("Date").'</td>';
print '<td width="160" align="center">'.$langs->trans("CustomerRelativeDiscountShort").'</td>';
print '<td align="left">'.$langs->trans("NoteReason").'</td>';
print '<td align="center">'.$langs->trans("User").'</td>';
print '</tr>';
$num = $db->num_rows($resql);
if ($num > 0)
{
$i = 0;
while ($i < $num)
{
$obj = $db->fetch_object($resql);
print '<tr class="oddeven">';
print '<td>'.dol_print_date($db->jdate($obj->dc),"dayhour").'</td>';
print '<td align="center">'.price2num($obj->remise_percent).'%</td>';
print '<td align="left">'.$obj->note.'</td>';
print '<td align="center"><a href="'.DOL_URL_ROOT.'/user/card.php?id='.$obj->user_id.'">'.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.'</a></td>';
print '</tr>';
$i++;
}
}
else
{
print '<tr><td colspan="8" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
$db->free($resql);
print "</table>";
}
else
{
print '<tr><td colspan="8" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
dol_print_error($db);
}
$db->free($resql);
print "</table>";
}
else
{
dol_print_error($db);
}
if($isSupplier) {
if($isCustomer) {
print '</div>'; // class="fichehalfleft"
print '<div class="fichehalfright">';
print '<div class="ficheaddleft">';
print load_fiche_titre($langs->trans("SupplierDiscounts"), '', '');
}
/*
* List log of all supplier percent discounts
*/
$sql = "SELECT rc.rowid, rc.remise_supplier as remise_percent, rc.note, rc.datec as dc,";
$sql.= " u.login, u.rowid as user_id";
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_supplier as rc, ".MAIN_DB_PREFIX."user as u";
$sql.= " WHERE rc.fk_soc = " . $object->id;
$sql.= " AND rc.entity = " . $conf->entity;
$sql.= " AND u.rowid = rc.fk_user_author";
$sql.= " ORDER BY rc.datec DESC";
$resql=$db->query($sql);
if ($resql)
{
print '<table class="noborder" width="100%">';
$tag = !$tag;
print '<tr class="liste_titre">';
print '<td width="160">'.$langs->trans("Date").'</td>';
print '<td width="160" align="center">'.$langs->trans("CustomerRelativeDiscountShort").'</td>';
print '<td align="left">'.$langs->trans("NoteReason").'</td>';
print '<td align="center">'.$langs->trans("User").'</td>';
print '</tr>';
$num = $db->num_rows($resql);
if ($num > 0)
{
$i = 0;
while ($i < $num)
{
$obj = $db->fetch_object($resql);
print '<tr class="oddeven">';
print '<td>'.dol_print_date($db->jdate($obj->dc),"dayhour").'</td>';
print '<td align="center">'.price2num($obj->remise_percent).'%</td>';
print '<td align="left">'.$obj->note.'</td>';
print '<td align="center"><a href="'.DOL_URL_ROOT.'/user/card.php?id='.$obj->user_id.'">'.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.'</a></td>';
print '</tr>';
$i++;
}
}
else
{
print '<tr><td colspan="8" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
$db->free($resql);
print "</table>";
}
else
{
dol_print_error($db);
}
if($isCustomer) {
print '</div>'; // class="ficheaddleft"
print '</div>'; // class="fichehalfright"
print '</div>'; // class="fichecenter"
}
}
}
llxFooter();

File diff suppressed because it is too large Load Diff

View File

@ -1558,17 +1558,14 @@ if ($action == 'create' && $user->rights->commande->creer)
// Ligne info remises tiers
print '<tr><td>' . $langs->trans('Discounts') . '</td><td>';
if ($soc->remise_percent)
print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_percent);
else
print $langs->trans("CompanyHasNoRelativeDiscount");
print '. ';
$absolute_discount = $soc->getAvailableDiscounts();
if ($absolute_discount)
print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->trans("Currency" . $conf->currency));
else
print $langs->trans("CompanyHasNoAbsoluteDiscount");
print '.';
$thirdparty = $soc;
$discount_type = 0;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
}
// Date
@ -2040,12 +2037,11 @@ if ($action == 'create' && $user->rights->commande->creer)
// Relative and absolute discounts
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final
// invoice
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description LIKE '(DEPOSIT)%')";
$filtercreditnote = "fk_facture_source IS NOT NULL AND description NOT LIKE '(DEPOSIT)%'";
$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
}
$addrelativediscount = '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditRelativeDiscounts") . '</a>';
@ -2053,29 +2049,17 @@ if ($action == 'create' && $user->rights->commande->creer)
$addcreditnote = '<a href="' . DOL_URL_ROOT . '/compta/facture/card.php?action=create&socid=' . $soc->id . '&type=2&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("AddCreditNote") . '</a>';
print '<tr><td class="titlefield">' . $langs->trans('Discounts') . '</td><td>';
if ($soc->remise_percent)
print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_percent);
else
print $langs->trans("CompanyHasNoRelativeDiscount");
print '. ';
$absolute_discount = $soc->getAvailableDiscounts('', 'fk_facture_source IS NULL');
$absolute_creditnote = $soc->getAvailableDiscounts('', 'fk_facture_source IS NOT NULL');
$absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount);
$absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote);
$absolute_discount = price2num($absolute_discount, 'MT');
$absolute_creditnote = price2num($absolute_creditnote, 'MT');
if ($absolute_discount) {
if ($object->statut > Commande::STATUS_DRAFT) {
print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
} else {
// Remise dispo de type remise fixe (not credit note)
print '<br>';
$form->form_remise_dispo($_SERVER["PHP_SELF"] . '?id=' . $object->id, 0, 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, 0, '', 1);
}
}
if ($absolute_creditnote) {
print $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)) . '. ';
}
if (! $absolute_discount && ! $absolute_creditnote)
print $langs->trans("CompanyHasNoAbsoluteDiscount") . '.';
$thirdparty = $soc;
$discount_type = 0;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
// Date

View File

@ -2699,19 +2699,12 @@ if ($action == 'create')
{
// Discounts for third party
print '<tr><td>' . $langs->trans('Discounts') . '</td><td colspan="2">';
if ($soc->remise_percent)
print $langs->trans("CompanyHasRelativeDiscount", '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">' . $soc->remise_percent . '</a>');
else
print $langs->trans("CompanyHasNoRelativeDiscount");
print ' <a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">(' . $langs->trans("EditRelativeDiscount") . ')</a>';
print '. ';
print '<br>';
if ($absolute_discount)
print $langs->trans("CompanyHasAbsoluteDiscount", '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">' . price($absolute_discount) . '</a>', $langs->trans("Currency" . $conf->currency));
else
print $langs->trans("CompanyHasNoAbsoluteDiscount");
print ' <a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">(' . $langs->trans("EditGlobalDiscounts") . ')</a>';
print '.';
$thirdparty = $soc;
$discount_type = 0;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
}
@ -3000,7 +2993,7 @@ else if ($id > 0 || ! empty($ref))
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%'))";
$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
}
@ -3363,84 +3356,14 @@ else if ($id > 0 || ! empty($ref))
print '</td></tr>';
// Relative and absolute discounts
$addrelativediscount = '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditRelativeDiscounts") . '</a>';
$addabsolutediscount = '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("EditGlobalDiscounts") . '</a>';
$addcreditnote = '<a href="' . DOL_URL_ROOT . '/compta/facture/card.php?action=create&socid=' . $soc->id . '&type=2&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("AddCreditNote") . '</a>';
$viewabsolutediscount = '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"]) . '?facid=' . $object->id . '">' . $langs->trans("ViewAvailableGlobalDiscounts") . '</a>';
print '<!-- Discounts --><tr><td>' . $langs->trans('Discounts');
print '</td><td>';
if ($soc->remise_percent)
print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_percent);
else
print $langs->trans("CompanyHasNoRelativeDiscount");
// print ' ('.$addrelativediscount.')';
// Is there is commercial discount or down payment available ?
if ($absolute_discount > 0) {
print '. ';
if ($object->statut > 0 || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) {
if ($object->statut == 0) {
print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
print '. ';
} else {
if ($object->statut < 1 || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) {
$text = $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
print '<br>' . $text . '.<br>';
} else {
$text = $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency));
$text2 = $langs->trans("AbsoluteDiscountUse");
print $form->textwithpicto($text, $text2);
}
}
} else {
// Discount available of type fixed amount (not credit note)
print '<br>';
$form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, GETPOST('discountid'), 'remise_id', $soc->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' (' . $addabsolutediscount . ')');
}
} else {
if ($absolute_creditnote > 0) // If not, link will be added later
{
if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT)
print ' (' . $addabsolutediscount . ')<br>';
else
print '. ';
} else
print '. ';
}
// Is there credit notes availables ?
if ($absolute_creditnote > 0)
{
// If validated, we show link "add credit note to payment"
if ($object->statut != Facture::STATUS_VALIDATED || $object->type == Facture::TYPE_CREDIT_NOTE) {
if ($object->statut == 0 && $object->type != Facture::TYPE_DEPOSIT) {
$text = $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency));
print $form->textwithpicto($text, $langs->trans("CreditNoteDepositUse"));
} else {
print $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)) . '.';
}
} else { // We can add a credit note on a down payment or standard invoice or situation invoice
// There is credit notes discounts available
if (! $absolute_discount) print '<br>';
// $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer);
$more=' ('.$addcreditnote. (($addcreditnote && $viewabsolutediscount) ? ' - ' : '') . $viewabsolutediscount . ')';
$form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0, $more); // We allow credit note even if amount is higher
}
}
if (! $absolute_discount && ! $absolute_creditnote) {
print $langs->trans("CompanyHasNoAbsoluteDiscount");
if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT)
print ' (' . $addabsolutediscount . ')<br>';
else
print '. ';
}
// if ($object->statut == 0 && $object->type != 2 && $object->type != 3)
// {
// if (! $absolute_discount && ! $absolute_creditnote) print '<br>';
// print ' &nbsp; - &nbsp; ';
// print $addabsolutediscount;
// print ' &nbsp; - &nbsp; '.$addcreditnote; // We disbale link to credit note
// }
print '</td><td>';
$thirdparty = $soc;
$discount_type = 0;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?facid=' . $object->id);
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
// Date invoice

View File

@ -140,8 +140,16 @@ if ($object->id > 0)
if ($object->paye) $resteapayer=0;
$resteapayeraffiche=$resteapayer;
$absolute_discount=$object->thirdparty->getAvailableDiscounts('','fk_facture_source IS NULL');
$absolute_creditnote=$object->thirdparty->getAvailableDiscounts('','fk_facture_source IS NOT NULL');
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
}
$absolute_discount=$object->thirdparty->getAvailableDiscounts('',$filterabsolutediscount);
$absolute_creditnote=$object->thirdparty->getAvailableDiscounts('',$filtercreditnote);
$absolute_discount=price2num($absolute_discount,'MT');
$absolute_creditnote=price2num($absolute_creditnote,'MT');
@ -253,61 +261,13 @@ if ($object->id > 0)
// Discounts
print '<tr><td>'.$langs->trans('Discounts').'</td><td colspan="3">';
if ($object->thirdparty->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$object->thirdparty->remise_percent);
else print $langs->trans("CompanyHasNoRelativeDiscount");
print '. ';
if ($absolute_discount > 0)
{
if ($object->statut > Facture::STATUS_DRAFT || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT)
{
if ($object->statut == Facture::STATUS_DRAFT)
{
print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency)).'. ';
}
else
{
if ($object->statut < Facture::STATUS_VALIDATED || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT)
{
$text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
print '<br>'.$text.'.<br>';
}
else
{
$text=$langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
$text2=$langs->trans("AbsoluteDiscountUse");
print $form->textwithpicto($text,$text2);
}
}
}
else
{
// Remise dispo de type non avoir
$filter='fk_facture_source IS NULL';
print '<br>';
$form->form_remise_dispo($_SERVER["PHP_SELF"].'?id='.$object->id,0,'remise_id',$object->thirdparty->id,$absolute_discount,$filter,$resteapayer,'',1);
}
}
if ($absolute_creditnote > 0)
{
// If validated, we show link "add credit note to payment"
if ($object->statut != Facture::STATUS_VALIDATED || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_CREDIT_NOTE)
{
if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_DEPOSIT)
{
$text=$langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency));
print $form->textwithpicto($text,$langs->trans("CreditNoteDepositUse"));
}
else print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'.';
}
else
{
// Remise dispo de type avoir
$filter='fk_facture_source IS NOT NULL';
if (! $absolute_discount) print '<br>';
$form->form_remise_dispo($_SERVER["PHP_SELF"].'?id='.$object->id,0,'remise_id_for_payment',$object->thirdparty->id,$absolute_creditnote,$filter,$resteapayer,'',1);
}
}
if (! $absolute_discount && ! $absolute_creditnote) print $langs->trans("CompanyHasNoAbsoluteDiscount").'.';
$thirdparty = $object->thirdparty;
$discount_type = 0;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?facid=' . $object->id);
$cannotApplyDiscount = 1;
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
// Date invoice

View File

@ -180,12 +180,6 @@ abstract class CommonInvoice extends CommonObject
*/
function getSumCreditNotesUsed($multicurrency=0)
{
if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier')
{
// TODO
return 0;
}
require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discountstatic=new DiscountAbsolute($this->db);

View File

@ -3984,6 +3984,12 @@ abstract class CommonObject
$discount->fetch($line->fk_remise_except);
$this->tpl['description'] = $langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0));
}
elseif ($line->desc == '(EXCESS PAID)')
{
$discount=new DiscountAbsolute($this->db);
$discount->fetch($line->fk_remise_except);
$this->tpl['description'] = $langs->transnoentities("DiscountFromExcessPaid",$discount->getNomUrl(0));
}
else
{
$this->tpl['description'] = dol_trunc($line->desc,60);

View File

@ -34,6 +34,7 @@ class DiscountAbsolute
public $id; // Id discount
public $fk_soc;
public $discount_type; // 0 => customer discount, 1 => supplier discount
public $amount_ht; //
public $amount_tva; //
public $amount_ttc; //
@ -45,6 +46,7 @@ class DiscountAbsolute
public $fk_facture; // Id invoice when a discount line is used into an invoice (for credit note)
public $fk_facture_source; // Id facture avoir a l'origine de la remise
public $ref_facture_source; // Ref facture avoir a l'origine de la remise
public $ref_invoice_supplier_source;
/**
* Constructor
@ -60,33 +62,36 @@ class DiscountAbsolute
/**
* Load object from database into memory
*
* @param int $rowid id discount to load
* @param int $fk_facture_source fk_facture_source
* @return int <0 if KO, =0 if not found, >0 if OK
* @param int $rowid id discount to load
* @param int $fk_facture_source fk_facture_source
* @param int $fk_invoice_supplier_source fk_invoice_supplier_source
* @return int <0 if KO, =0 if not found, >0 if OK
*/
function fetch($rowid, $fk_facture_source=0)
function fetch($rowid, $fk_facture_source=0, $fk_invoice_supplier_source=0)
{
global $conf;
// Check parameters
if (! $rowid && ! $fk_facture_source)
if (! $rowid && ! $fk_facture_source && ! $fk_invoice_supplier_source)
{
$this->error='ErrorBadParameters';
return -1;
}
$sql = "SELECT sr.rowid, sr.fk_soc,";
$sql = "SELECT sr.rowid, sr.fk_soc, sr.discount_type,";
$sql.= " sr.fk_user,";
$sql.= " sr.amount_ht, sr.amount_tva, sr.amount_ttc, sr.tva_tx,";
$sql.= " sr.multicurrency_amount_ht, sr.multicurrency_amount_tva, sr.multicurrency_amount_ttc,";
$sql.= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.description,";
$sql.= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.fk_invoice_supplier_line, sr.fk_invoice_supplier, sr.fk_invoice_supplier_source, sr.description,";
$sql.= " sr.datec,";
$sql.= " f.facnumber as ref_facture_source";
$sql.= " f.facnumber as ref_facture_source, fsup.facnumber as ref_invoice_supplier_source";
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as sr";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON sr.fk_facture_source = f.rowid";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as fsup ON sr.fk_invoice_supplier_source = fsup.rowid";
$sql.= " WHERE sr.entity = " . $conf->entity;
if ($rowid) $sql.= " AND sr.rowid=".$rowid;
if ($fk_facture_source) $sql.= " AND sr.fk_facture_source=".$fk_facture_source;
if ($fk_invoice_supplier_source) $sql.= " AND sr.fk_invoice_supplier_source=".$fk_invoice_supplier_source;
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
$resql = $this->db->query($sql);
@ -98,6 +103,7 @@ class DiscountAbsolute
$this->id = $obj->rowid;
$this->fk_soc = $obj->fk_soc;
$this->discount_type = $obj->discount_type;
$this->amount_ht = $obj->amount_ht;
$this->amount_tva = $obj->amount_tva;
@ -113,6 +119,10 @@ class DiscountAbsolute
$this->fk_facture = $obj->fk_facture;
$this->fk_facture_source = $obj->fk_facture_source; // Id avoir source
$this->ref_facture_source = $obj->ref_facture_source; // Ref avoir source
$this->fk_invoice_supplier_line = $obj->fk_invoice_supplier_line;
$this->fk_invoice_supplier = $obj->fk_invoice_supplier;
$this->fk_invoice_supplier_source = $obj->fk_invoice_supplier_source; // Id avoir source
$this->ref_invoice_supplier_source = $obj->ref_invoice_supplier_source; // Ref avoir source
$this->description = $obj->description;
$this->datec = $this->db->jdate($obj->datec);
@ -159,13 +169,14 @@ class DiscountAbsolute
// Insert request
$sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_except";
$sql.= " (entity, datec, fk_soc, fk_user, description,";
$sql.= " (entity, datec, fk_soc, discount_type, fk_user, description,";
$sql.= " amount_ht, amount_tva, amount_ttc, tva_tx,";
$sql.= " fk_facture_source";
$sql.= " fk_facture_source, fk_invoice_supplier_source";
$sql.= ")";
$sql.= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec!=''?$this->datec:dol_now())."', ".$this->fk_soc.", ".$user->id.", '".$this->db->escape($this->description)."',";
$sql.= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec!=''?$this->datec:dol_now())."', ".$this->fk_soc.", ".(empty($this->discount_type)?0:intval($this->discount_type)).", ".$user->id.", '".$this->db->escape($this->description)."',";
$sql.= " ".$this->amount_ht.", ".$this->amount_tva.", ".$this->amount_ttc.", ".$this->tva_tx.",";
$sql.= " ".($this->fk_facture_source ? "'".$this->db->escape($this->fk_facture_source)."'":"null");
$sql.= " ".($this->fk_facture_source ? "'".$this->db->escape($this->fk_facture_source)."'":"null").",";
$sql.= " ".($this->fk_invoice_supplier_source ? "'".$this->db->escape($this->fk_invoice_supplier_source)."'":"null");
$sql.= ")";
dol_syslog(get_class($this)."::create", LOG_DEBUG);
@ -220,15 +231,46 @@ class DiscountAbsolute
return -1;
}
}
// Check if we can remove the discount
if ($this->fk_invoice_supplier_source)
{
$sql="SELECT COUNT(rowid) as nb";
$sql.=" FROM ".MAIN_DB_PREFIX."societe_remise_except";
$sql.=" WHERE (fk_invoice_supplier_line IS NOT NULL"; // Not used as absolute simple discount
$sql.=" OR fk_invoice_supplier IS NOT NULL)"; // Not used as credit note and not used as deposit
$sql.=" AND fk_invoice_supplier_source = ".$this->fk_invoice_supplier_source;
//$sql.=" AND rowid != ".$this->id;
dol_syslog(get_class($this)."::delete Check if we can remove discount", LOG_DEBUG);
$resql=$this->db->query($sql);
if ($resql)
{
$obj = $this->db->fetch_object($resql);
if ($obj->nb > 0)
{
$this->error='ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved';
return -2;
}
}
else
{
dol_print_error($this->db);
return -1;
}
}
$this->db->begin();
// Delete but only if not used
$sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_remise_except ";
if ($this->fk_facture_source) $sql.= " WHERE fk_facture_source = ".$this->fk_facture_source; // Delete all lines of same serie
elseif ($this->fk_invoice_supplier_source) $sql.= " WHERE fk_invoice_supplier_source = ".$this->fk_invoice_supplier_source; // Delete all lines of same serie
else $sql.= " WHERE rowid = ".$this->id; // Delete only line
$sql.= " AND (fk_facture_line IS NULL"; // Not used as absolute simple discount
$sql.= " AND fk_facture IS NULL)"; // Not used as credit note and not used as deposit
$sql.= " AND (fk_invoice_supplier_line IS NULL"; // Not used as absolute simple discount
$sql.= " AND fk_invoice_supplier IS NULL)"; // Not used as credit note and not used as deposit
dol_syslog(get_class($this)."::delete Delete discount", LOG_DEBUG);
$result=$this->db->query($sql);
@ -255,6 +297,26 @@ class DiscountAbsolute
return -1;
}
}
elseif($this->fk_invoice_supplier_source) {
$sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn";
$sql.=" set paye=0, fk_statut=1";
$sql.=" WHERE (type = 2 or type = 3) AND rowid=".$this->fk_invoice_supplier_source;
dol_syslog(get_class($this)."::delete Update credit note or deposit invoice statut", LOG_DEBUG);
$result=$this->db->query($sql);
if ($result)
{
$this->db->commit();
return 1;
}
else
{
$this->error=$this->db->lasterror();
$this->db->rollback();
return -1;
}
}
else
{
$this->db->commit();
@ -295,16 +357,26 @@ class DiscountAbsolute
}
$sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except";
if ($rowidline) $sql.=" SET fk_facture_line = ".$rowidline;
if ($rowidinvoice) $sql.=" SET fk_facture = ".$rowidinvoice;
if(! empty($this->discount_type)) {
if ($rowidline) $sql.=" SET fk_invoice_supplier_line = ".$rowidline;
if ($rowidinvoice) $sql.=" SET fk_invoice_supplier = ".$rowidinvoice;
} else {
if ($rowidline) $sql.=" SET fk_facture_line = ".$rowidline;
if ($rowidinvoice) $sql.=" SET fk_facture = ".$rowidinvoice;
}
$sql.=" WHERE rowid = ".$this->id;
dol_syslog(get_class($this)."::link_to_invoice", LOG_DEBUG);
$resql = $this->db->query($sql);
if ($resql)
{
$this->fk_facture_line=$rowidline;
$this->fk_facture=$rowidinvoice;
if(! empty($this->discount_type)) {
$this->fk_invoice_supplier_line=$rowidline;
$this->fk_invoice_supplier=$rowidinvoice;
} else {
$this->fk_facture_line=$rowidline;
$this->fk_facture=$rowidinvoice;
}
return 1;
}
else
@ -324,7 +396,11 @@ class DiscountAbsolute
function unlink_invoice()
{
$sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except";
$sql.=" SET fk_facture_line = NULL, fk_facture = NULL";
if(! empty($this->discount_type)) {
$sql.=" SET fk_invoice_supplier_line = NULL, fk_invoice_supplier = NULL";
} else {
$sql.=" SET fk_facture_line = NULL, fk_facture = NULL";
}
$sql.=" WHERE rowid = ".$this->id;
dol_syslog(get_class($this)."::unlink_invoice", LOG_DEBUG);
@ -344,14 +420,14 @@ class DiscountAbsolute
/**
* Return amount (with tax) of discounts currently available for a company, user or other criteria
*
* @param Societe $company Object third party for filter
* @param User $user Filtre sur un user auteur des remises
* @param string $filter Filtre autre
* @param int $maxvalue Filter on max value for discount
* @param string $mode 'customer' = discounts the customer has, 'supplier' = discount i have at this supplier
* @param Societe $company Object third party for filter
* @param User $user Filtre sur un user auteur des remises
* @param string $filter Filtre autre
* @param int $maxvalue Filter on max value for discount
* @param int $discount_type 0 => customer discount, 1 => supplier discount
* @return int <0 if KO, amount otherwise
*/
function getAvailableDiscounts($company='', $user='',$filter='', $maxvalue=0, $mode='customer')
function getAvailableDiscounts($company='', $user='',$filter='', $maxvalue=0, $discount_type=0)
{
global $conf;
@ -359,8 +435,12 @@ class DiscountAbsolute
//$sql = "SELECT rc.amount_ttc as amount";
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc";
$sql.= " WHERE rc.entity = " . $conf->entity;
if ($mode != 'supplier') $sql.= " AND (rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL)"; // Available
else $sql.= " AND (rc.fk_suppler_invoice IS NULL AND rc.fk_supplier_invoice IS NULL)"; // Available
$sql.= " AND rc.discount_type=".intval($discount_type);
if (! empty($discount_type)) {
$sql.= " AND (rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line IS NULL)"; // Available from supplier
} else {
$sql.= " AND (rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL)"; // Available to customer
}
if (is_object($company)) $sql.= " AND rc.fk_soc = ".$company->id;
if (is_object($user)) $sql.= " AND rc.fk_user = ".$user->id;
if ($filter) $sql.=' AND ('.$filter.')';
@ -452,7 +532,7 @@ class DiscountAbsolute
$sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount';
$sql.= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture_fourn as f';
$sql.= ' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = '.$invoice->id;
$sql.= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess received
$sql.= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess paid
}
else
{
@ -489,10 +569,12 @@ class DiscountAbsolute
$result='';
if ($option == 'invoice') {
$facid=! empty($this->discount_type)?$this->fk_invoice_supplier_source:$this->fk_facture_source;
$link=! empty($this->discount_type)?'/fourn/facture/card.php':'/compta/facture/card.php';
$label=$langs->trans("ShowDiscount").': '.$this->ref_facture_source;
$link = '<a href="'.DOL_URL_ROOT.'/compta/facture/card.php?facid='.$this->fk_facture_source.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
$link = '<a href="'.DOL_URL_ROOT.$link.'?facid='.$facid.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
$linkend='</a>';
$ref=$this->ref_facture_source;
$ref=! empty($this->discount_type)?$this->ref_invoice_supplier_source:$this->ref_facture_source;
$picto='bill';
}
if ($option == 'discount') {

View File

@ -1236,6 +1236,7 @@ class Form
if (preg_match('/\(CREDIT_NOTE\)/', $desc)) $desc=preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $desc);
if (preg_match('/\(DEPOSIT\)/', $desc)) $desc=preg_replace('/\(DEPOSIT\)/', $langs->trans("Deposit"), $desc);
if (preg_match('/\(EXCESS RECEIVED\)/', $desc)) $desc=preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $desc);
if (preg_match('/\(EXCESS PAID\)/', $desc)) $desc=preg_replace('/\(EXCESS PAID\)/', $langs->trans("ExcessPaid"), $desc);
$selectstring='';
if ($selected > 0 && $selected == $obj->rowid) $selectstring=' selected';
@ -2481,6 +2482,10 @@ class Form
$opt = '<option value="'.$outkey.'"';
if ($selected && $selected == $objp->idprodfournprice) $opt.= ' selected';
if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt.=' disabled';
if (!empty($objp->idprodfournprice) && $objp->idprodfournprice > 0)
{
$opt.= ' pbq="'.$objp->idprodfournprice.'" data-pbq="'.$objp->idprodfournprice.'" data-pbqqty="'.$objp->quantity.'" data-pbqpercent="'.$objp->remise_percent.'"';
}
$opt.= '>';
$objRef = $objp->ref;
@ -4220,9 +4225,10 @@ class Form
* @param int $maxvalue Max value for lines that can be selected
* @param string $more More string to add
* @param int $hidelist 1=Hide list
* @param int $discount_type 0 => customer discount, 1 => supplier discount
* @return void
*/
function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0)
function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0, $discount_type=0)
{
global $conf,$langs;
if ($htmlname != "none")
@ -4231,28 +4237,51 @@ class Form
print '<input type="hidden" name="action" value="setabsolutediscount">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<div class="inline-block">';
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
{
if (! $filter || $filter=="fk_facture_source IS NULL") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency)); // If we want deposit to be substracted to payments only and not to total of final invoice
else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
}
else
{
if (! $filter || $filter=="fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%'))") print $langs->trans("CompanyHasAbsoluteDiscount",price($amount,0,$langs,0,0,-1,$conf->currency));
else print $langs->trans("CompanyHasCreditNote",price($amount,0,$langs,0,0,-1,$conf->currency));
if(! empty($discount_type)) {
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
{
if (! $filter || $filter=="fk_invoice_supplier_source IS NULL") $translationKey = 'HasAbsoluteDiscountFromSupplier'; // If we want deposit to be substracted to payments only and not to total of final invoice
else $translationKey = 'HasCreditNoteFromSupplier';
}
else
{
if (! $filter || $filter=="fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')") $translationKey = 'HasAbsoluteDiscountFromSupplier';
else $translationKey = 'HasCreditNoteFromSupplier';
}
} else {
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
{
if (! $filter || $filter=="fk_facture_source IS NULL") $translationKey = 'CompanyHasAbsoluteDiscount'; // If we want deposit to be substracted to payments only and not to total of final invoice
else $translationKey = 'CompanyHasCreditNote';
}
else
{
if (! $filter || $filter=="fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')") $translationKey = 'CompanyHasAbsoluteDiscount';
else $translationKey = 'CompanyHasCreditNote';
}
}
print $langs->trans($translationKey,price($amount,0,$langs,0,0,-1,$conf->currency));
if (empty($hidelist)) print ': ';
print '</div>';
if (empty($hidelist))
{
print '<div class="inline-block" style="padding-right: 10px">';
$newfilter='fk_facture IS NULL AND fk_facture_line IS NULL'; // Remises disponibles
$newfilter = 'discount_type='.intval($discount_type);
if(! empty($discount_type)) {
$newfilter.= ' AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Supplier discounts available
} else {
$newfilter.= ' AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Customer discounts available
}
if ($filter) $newfilter.=' AND ('.$filter.')';
$nbqualifiedlines=$this->select_remises($selected,$htmlname,$newfilter,$socid,$maxvalue);
if ($nbqualifiedlines > 0)
{
print ' &nbsp; <input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("UseLine")).'"';
if ($filter && $filter != "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND description LIKE '(DEPOSIT)%')") print ' title="'.$langs->trans("UseCreditNoteInInvoicePayment").'"';
if(! empty($discount_type) && $filter && $filter != "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')")
print ' title="'.$langs->trans("UseCreditNoteInInvoicePayment").'"';
if(empty($discount_type) && $filter && $filter != "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')")
print ' title="'.$langs->trans("UseCreditNoteInInvoicePayment").'"';
print '>';
}
print '</div>';

View File

@ -73,13 +73,15 @@ function doc_getlinedesc($line,$outputlangs,$hideref=0,$hidedesc=0,$issupplierli
{
$discount=new DiscountAbsolute($db);
$discount->fetch($line->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromCreditNote",$discount->ref_facture_source);
$sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromCreditNote",$sourceref);
}
elseif ($desc == '(DEPOSIT)' && $line->fk_remise_except)
{
$discount=new DiscountAbsolute($db);
$discount->fetch($line->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$discount->ref_facture_source);
$sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$sourceref);
// Add date of deposit
if (! empty($conf->global->INVOICE_ADD_DEPOSIT_DATE)) $libelleproduitservice.=' ('.dol_print_date($discount->datec,'day','',$outputlangs).')';
}
@ -89,6 +91,12 @@ function doc_getlinedesc($line,$outputlangs,$hideref=0,$hidedesc=0,$issupplierli
$discount->fetch($line->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived",$discount->ref_facture_source);
}
elseif ($desc == '(EXCESS PAID)' && $line->fk_remise_except)
{
$discount=new DiscountAbsolute($db);
$discount->fetch($line->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid",$discount->ref_invoice_supplier_source);
}
else
{
if ($idprod)

View File

@ -1236,13 +1236,15 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl
{
$discount=new DiscountAbsolute($db);
$discount->fetch($object->lines[$i]->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromCreditNote",$discount->ref_facture_source);
$sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromCreditNote",$sourceref);
}
elseif ($desc == '(DEPOSIT)' && $object->lines[$i]->fk_remise_except)
{
$discount=new DiscountAbsolute($db);
$discount->fetch($object->lines[$i]->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$discount->ref_facture_source);
$sourceref=!empty($discount->discount_type)?$discount->ref_invoive_supplier_source:$discount->ref_facture_source;
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromDeposit",$sourceref);
// Add date of deposit
if (! empty($conf->global->INVOICE_ADD_DEPOSIT_DATE)) echo ' ('.dol_print_date($discount->datec,'day','',$outputlangs).')';
}
@ -1252,6 +1254,12 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl
$discount->fetch($object->lines[$i]->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessReceived",$discount->ref_facture_source);
}
elseif ($desc == '(EXCESS PAID)' && $object->lines[$i]->fk_remise_except)
{
$discount=new DiscountAbsolute($db);
$discount->fetch($object->lines[$i]->fk_remise_except);
$libelleproduitservice=$outputlangs->transnoentitiesnoconv("DiscountFromExcessPaid",$discount->ref_invoice_supplier_source);
}
else
{
if ($idprod)

View File

@ -0,0 +1,104 @@
<?php
/* Copyright (C) 2018 ATM Consulting <support@atm-consulting.fr>
*
* 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
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Needs the following variables defined:
* $object Proposal, order, invoice (including supplier versions)
* $thirdparty Thirdparty of object
* $absolute_discount Amount of fixed discounts available
* $absolute_creditnote Amount of credit notes available
* $discount_type 0 => Customer discounts, 1 => Supplier discounts
* $cannotApplyDiscount Set it to prevent form to apply discount
* $backtopage URL to come back to from discount modification pages
*/
$classname = get_class($object);
$isInvoice = in_array($object->element, array('facture', 'invoice', 'facture_fourn', 'invoice_supplier'));
$isNewObject = empty($object->id) && empty($object->rowid);
// Relative and absolute discounts
$addrelativediscount = '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $thirdparty->id . '&backtopage=' . $backtopage . '">' . $langs->trans("EditRelativeDiscount") . '</a>';
$addabsolutediscount = '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $thirdparty->id . '&backtopage=' . $backtopage . '">' . $langs->trans("EditGlobalDiscounts") . '</a>';
$viewabsolutediscount = '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $thirdparty->id . '&backtopage=' . $backtopage . '">' . $langs->trans("ViewAvailableGlobalDiscounts") . '</a>';
$fixedDiscount = $thirdparty->remise_percent;
if(! empty($discount_type)) {
$fixedDiscount = $thirdparty->remise_supplier_percent;
}
$translationKey = ! empty($discount_type) ? 'HasRelativeDiscountFromSupplier' : 'CompanyHasRelativeDiscount';
if ($fixedDiscount > 0)
print $langs->trans($translationKey, $fixedDiscount).'.';
else
print $langs->trans($translationKey).'.';
if($isNewObject) print ' ('.$addrelativediscount.')';
// Is there is commercial discount or down payment available ?
if ($absolute_discount > 0) {
if ($cannotApplyDiscount || ! $isInvoice || $isNewObject || $object->statut > $classname::STATUS_DRAFT || $object->type == $classname::TYPE_CREDIT_NOTE || $object->type == $classname::TYPE_DEPOSIT) {
$translationKey = ! empty($discount_type) ? 'HasAbsoluteDiscountFromSupplier' : 'CompanyHasAbsoluteDiscount';
$text = $langs->trans($translationKey, price($absolute_discount), $langs->transnoentities("Currency" . $conf->currency)).'.';
if ($isInvoice && ! $isNewObject && $object->statut > $classname::STATUS_DRAFT && $object->type != $classname::TYPE_CREDIT_NOTE && $object->type != $classname::TYPE_DEPOSIT) {
$text = $form->textwithpicto($text, $langs->trans('AbsoluteDiscountUse'));
}
if ($isNewObject) {
$text.= ' ('.$addabsolutediscount.')';
}
print '<br>'.$text;
} else {
// Discount available of type fixed amount (not credit note)
$more = '(' . $addabsolutediscount . ')';
$form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, GETPOST('discountid'), 'remise_id', $thirdparty->id, $absolute_discount, $filterabsolutediscount, $resteapayer, $more, 0, $discount_type);
}
}
// Is there credit notes availables ?
if ($absolute_creditnote > 0) {
// If validated, we show link "add credit note to payment"
if ($cannotApplyDiscount || ! $isInvoice || $isNewObject || $object->statut != $classname::STATUS_VALIDATED || $object->type == $classname::TYPE_CREDIT_NOTE) {
$translationKey = ! empty($discount_type) ? 'HasCreditNoteFromSupplier' : 'CompanyHasCreditNote';
$text = $langs->trans($translationKey, price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)) . '.';
if ($isInvoice && ! $isNewObject && $object->statut == $classname::STATUS_DRAFT && $object->type != $classname::TYPE_DEPOSIT) {
$text = $form->textwithpicto($text, $langs->trans('CreditNoteDepositUse'));
}
if ($absolute_discount <= 0 || $isNewObject) {
$text.= '('.$addabsolutediscount.')';
}
print '<br>'.$text;
} else { // We can add a credit note on a down payment or standard invoice or situation invoice
// There is credit notes discounts available
$more = $isInvoice && ! $isNewObject ? ' (' . $viewabsolutediscount . ')' : '';
$form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $thirdparty->id, $absolute_creditnote, $filtercreditnote, 0, $more, 0, $discount_type); // We allow credit note even if amount is higher
}
}
if($absolute_discount <= 0 && $absolute_creditnote <= 0) {
$translationKey = ! empty($discount_type) ? 'HasNoAbsoluteDiscountFromSupplier' : 'CompanyHasNoAbsoluteDiscount';
print '<br>'.$langs->trans($translationKey).'.';
if ($isInvoice && $object->statut == $classname::STATUS_DRAFT && $object->type != $classname::TYPE_CREDIT_NOTE && $object->type != $classname::TYPE_DEPOSIT) {
print ' (' . $addabsolutediscount . ')';
}
}

View File

@ -322,8 +322,12 @@ else {
print $form->selectUnits($line->fk_unit, "units");
print '</td>';
}
$remise_percent = $buyer->remise_percent;
if($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier') {
$remise_percent = $seller->remise_supplier_percent;
}
?>
<td class="nobottom nowrap linecoldiscount" align="right"><input type="text" size="1" name="remise_percent" id="remise_percent" class="flat right" value="<?php echo (isset($_POST["remise_percent"])?GETPOST("remise_percent",'alpha',2):$buyer->remise_percent); ?>"><span class="hideonsmartphone">%</span></td>
<td class="nobottom nowrap linecoldiscount" align="right"><input type="text" size="1" name="remise_percent" id="remise_percent" class="flat right" value="<?php echo (isset($_POST["remise_percent"])?GETPOST("remise_percent",'alpha',2):$remise_percent); ?>"><span class="hideonsmartphone">%</span></td>
<?php
if ($this->situation_cycle_ref) {
$coldisplay++;
@ -725,10 +729,11 @@ jQuery(document).ready(function() {
?>
/* To process customer price per quantity */
var pbq = $('option:selected', this).attr('data-pbq');
var pbqqty = $('option:selected', this).attr('data-pbqqty');
var pbqpercent = $('option:selected', this).attr('data-pbqpercent');
if (jQuery('#idprod').val() > 0 && typeof pbq !== "undefined")
var pbq = parseInt($('option:selected', this).attr('data-pbq'));
var pbqqty = parseFloat($('option:selected', this).attr('data-pbqqty'));
var pbqpercent = parseFloat($('option:selected', this).attr('data-pbqpercent'));
if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && typeof pbq !== "undefined")
{
console.log("We choose a price by quanty price_by_qty id = "+pbq+" price_by_qty qty = "+pbqqty+" price_by_qty percent = "+pbqpercent);
jQuery("#pbq").val(pbq);
@ -782,7 +787,6 @@ function setforfree() {
jQuery("#tva_tx").show();
jQuery("#buying_price").val('').show();
jQuery("#fournprice_predef").hide();
jQuery("#title_fourn_ref").show();
jQuery("#title_vat").show();
jQuery("#title_up_ht").show();
jQuery("#title_up_ht_currency").show();
@ -806,7 +810,6 @@ function setforpredef() {
jQuery("#fourn_ref").hide();
jQuery("#tva_tx").hide();
jQuery("#buying_price").show();
jQuery("#title_fourn_ref").hide();
jQuery("#title_vat").hide();
jQuery("#title_up_ht").hide();
jQuery("#title_up_ht_currency").hide();

View File

@ -73,6 +73,7 @@ if (empty($outputalsopricetotalwithtax)) $outputalsopricetotalwithtax=0;
print img_object($langs->trans("ShowReduc"),'reduc').' ';
if ($line->description == '(DEPOSIT)') $txt=$langs->trans("Deposit");
elseif ($line->description == '(EXCESS RECEIVED)') $txt=$langs->trans("ExcessReceived");
elseif ($line->description == '(EXCESS PAID)') $txt=$langs->trans("ExcessPaid");
//else $txt=$langs->trans("Discount");
print $txt;
?>
@ -101,6 +102,12 @@ if (empty($outputalsopricetotalwithtax)) $outputalsopricetotalwithtax=0;
$discount->fetch($line->fk_remise_except);
echo ($txt?' - ':'').$langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0));
}
elseif ($line->description == '(EXCESS PAID)' && $objp->fk_remise_except > 0)
{
$discount=new DiscountAbsolute($this->db);
$discount->fetch($line->fk_remise_except);
echo ($txt?' - ':'').$langs->transnoentities("DiscountFromExcessPaid",$discount->getNomUrl(0));
}
else
{
echo ($txt?' - ':'').dol_htmlentitiesbr($line->description);

View File

@ -331,33 +331,26 @@ if ($id > 0 || ! empty($ref))
print '<table class="border" width="100%">';
// Discounts for third party
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
}
print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td colspan="3">';
if ($soc->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_percent);
else print $langs->trans("CompanyHasNoRelativeDiscount");
print '. ';
$absolute_discount=$soc->getAvailableDiscounts('','fk_facture_source IS NULL');
$absolute_creditnote=$soc->getAvailableDiscounts('','fk_facture_source IS NOT NULL');
$absolute_discount=$soc->getAvailableDiscounts('',$filterabsolutediscount);
$absolute_creditnote=$soc->getAvailableDiscounts('',$filtercreditnote);
$absolute_discount=price2num($absolute_discount,'MT');
$absolute_creditnote=price2num($absolute_creditnote,'MT');
if ($absolute_discount)
{
if ($object->statut > Commande::STATUS_DRAFT)
{
print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->transnoentities("Currency".$conf->currency));
}
else
{
// Remise dispo de type non avoir
$filter='fk_facture_source IS NULL';
print '<br>';
$form->form_remise_dispo($_SERVER["PHP_SELF"].'?id='.$object->id,0,'remise_id',$soc->id,$absolute_discount,$filter, 0, '', 1);
}
}
if ($absolute_creditnote)
{
print $langs->trans("CompanyHasCreditNote",price($absolute_creditnote),$langs->transnoentities("Currency".$conf->currency)).'. ';
}
if (! $absolute_discount && ! $absolute_creditnote) print $langs->trans("CompanyHasNoAbsoluteDiscount").'.';
$thirdparty = $soc;
$discount_type = 0;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
$cannotApplyDiscount = 1;
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
// Date

View File

@ -258,6 +258,39 @@ if ($object->id > 0)
print "</td>";
print '</tr>';
// Relative discounts (Discounts-Drawbacks-Rebates)
print '<tr><td class="nowrap">';
print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
print $langs->trans("CustomerRelativeDiscountShort");
print '<td><td align="right">';
if ($user->rights->societe->creer && !$user->societe_id > 0)
{
print '<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$object->id.'">'.img_edit($langs->trans("Modify")).'</a>';
}
print '</td></tr></table>';
print '</td><td>'.($object->remise_supplier_percent?'<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$object->id.'">'.$object->remise_supplier_percent.'%</a>':'').'</td>';
print '</tr>';
// Absolute discounts (Discounts-Drawbacks-Rebates)
print '<tr><td class="nowrap">';
print '<table width="100%" class="nobordernopadding">';
print '<tr><td class="nowrap">';
print $langs->trans("CustomerAbsoluteDiscountShort");
print '<td><td align="right">';
if ($user->rights->societe->creer && !$user->societe_id > 0)
{
print '<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$object->id).'">'.img_edit($langs->trans("Modify")).'</a>';
}
print '</td></tr></table>';
print '</td>';
print '<td>';
$amount_discount=$object->getAvailableDiscounts('', '', 0, 1);
if ($amount_discount < 0) dol_print_error($db,$object->error);
if ($amount_discount > 0) print '<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?socid='.$object->id).'">'.price($amount_discount,1,$langs,1,-1,-1,$conf->currency).'</a>';
//else print $langs->trans("DiscountNone");
print '</td>';
print '</tr>';
print '<tr class="nowrap">';
print '<td>';
print $form->editfieldkey("OrderMinAmount",'supplier_order_min_amount',$object->supplier_order_min_amount,$object,$user->rights->societe->creer);

View File

@ -894,6 +894,107 @@ class FactureFournisseur extends CommonInvoice
}
}
/**
* Add a discount line into an invoice (as an invoice line) using an existing absolute discount (Consume the discount)
*
* @param int $idremise Id of absolute discount
* @return int >0 if OK, <0 if KO
*/
function insert_discount($idremise)
{
global $langs;
include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$this->db->begin();
$remise=new DiscountAbsolute($this->db);
$result=$remise->fetch($idremise);
if ($result > 0)
{
if ($remise->fk_invoice_supplier) // Protection against multiple submission
{
$this->error=$langs->trans("ErrorDiscountAlreadyUsed");
$this->db->rollback();
return -5;
}
$facligne=new SupplierInvoiceLine($this->db);
$facligne->fk_facture_fourn=$this->id;
$facligne->fk_remise_except=$remise->id;
$facligne->desc=$remise->description; // Description ligne
$facligne->vat_src_code=$remise->vat_src_code;
$facligne->tva_tx=$remise->tva_tx;
$facligne->subprice = -$remise->amount_ht;
$facligne->fk_product=0; // Id produit predefini
$facligne->product_type=0;
$facligne->qty=1;
$facligne->remise_percent=0;
$facligne->rang=-1;
$facligne->info_bits=2;
// Get buy/cost price of invoice that is source of discount
if ($remise->fk_invoice_supplier_source > 0)
{
$srcinvoice=new FactureFournisseur($this->db);
$srcinvoice->fetch($remise->fk_invoice_supplier_source);
$totalcostpriceofinvoice=0;
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; // TODO Move this into commonobject
$formmargin=new FormMargin($this->db);
$arraytmp=$formmargin->getMarginInfosArray($srcinvoice, false);
$facligne->pa_ht = $arraytmp['pa_total'];
}
$facligne->total_ht = -$remise->amount_ht;
$facligne->total_tva = -$remise->amount_tva;
$facligne->total_ttc = -$remise->amount_ttc;
$facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
$facligne->multicurrency_total_ht = -$remise->multicurrency_total_ht;
$facligne->multicurrency_total_tva = -$remise->multicurrency_total_tva;
$facligne->multicurrency_total_ttc = -$remise->multicurrency_total_ttc;
$lineid=$facligne->insert();
if ($lineid > 0)
{
$result=$this->update_price(1);
if ($result > 0)
{
// Create link between discount and invoice line
$result=$remise->link_to_invoice($lineid,0,'supplier');
if ($result < 0)
{
$this->error=$remise->error;
$this->db->rollback();
return -4;
}
$this->db->commit();
return 1;
}
else
{
$this->error=$facligne->error;
$this->db->rollback();
return -1;
}
}
else
{
$this->error=$facligne->error;
$this->db->rollback();
return -2;
}
}
else
{
$this->db->rollback();
return -3;
}
}
/**
* Delete invoice from database
@ -927,6 +1028,33 @@ class FactureFournisseur extends CommonInvoice
// Fin appel triggers
}
if (! $error) {
// If invoice was converted into a discount not yet consumed, we remove discount
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'societe_remise_except';
$sql .= ' WHERE fk_invoice_supplier_source = ' . $rowid;
$sql .= ' AND fk_invoice_supplier_line IS NULL';
$resql = $this->db->query($sql);
// If invoice has consumned discounts
$this->fetch_lines();
$list_rowid_det = array ();
foreach ($this->lines as $key => $invoiceline) {
$list_rowid_det[] = $invoiceline->rowid;
}
// Consumned discounts are freed
if (count($list_rowid_det)) {
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except';
$sql .= ' SET fk_invoice_supplier = NULL, fk_invoice_supplier_line = NULL';
$sql .= ' WHERE fk_invoice_supplier_line IN (' . join(',', $list_rowid_det) . ')';
dol_syslog(get_class($this) . "::delete", LOG_DEBUG);
if (! $this->db->query($sql)) {
$error ++;
}
}
}
if (! $error)
{
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';';
@ -1668,6 +1796,22 @@ class FactureFournisseur extends CommonInvoice
$rowid = $this->id;
}
$this->db->begin();
// Libere remise liee a ligne de facture
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe_remise_except';
$sql .= ' SET fk_invoice_supplier_line = NULL';
$sql .= ' WHERE fk_invoice_supplier_line = ' . $rowid;
dol_syslog(get_class($this) . "::deleteline", LOG_DEBUG);
$result = $this->db->query($sql);
if (! $result)
{
$this->error = $this->db->error();
$this->db->rollback();
return - 2;
}
$line = new SupplierInvoiceLine($this->db);
if ($line->fetch($rowid) < 1) {
@ -1677,12 +1821,24 @@ class FactureFournisseur extends CommonInvoice
$res = $line->delete($notrigger);
if ($res < 1) {
$this->errors[] = $line->error;
$this->errors[] = $line->error;
$this->db->rollback();
return - 3;
} else {
$res = $this->update_price();
}
$res = $this->update_price();
return $res;
if ($res > 0)
{
$this->db->commit();
return 1;
}
else
{
$this->db->rollback();
$this->error = $this->db->lasterror();
return - 4;
}
}
}

View File

@ -1401,7 +1401,7 @@ if ($action=='create')
$availability_id = (!empty($objectsrc->availability_id)?$objectsrc->availability_id:(!empty($soc->availability_id)?$soc->availability_id:0));
$shipping_method_id = (! empty($objectsrc->shipping_method_id)?$objectsrc->shipping_method_id:(! empty($soc->shipping_method_id)?$soc->shipping_method_id:0));
$demand_reason_id = (!empty($objectsrc->demand_reason_id)?$objectsrc->demand_reason_id:(!empty($soc->demand_reason_id)?$soc->demand_reason_id:0));
$remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_percent)?$soc->remise_percent:0));
$remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_supplier_percent)?$soc->remise_supplier_percent:0));
$remise_absolue = (!empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(!empty($soc->remise_absolue)?$soc->remise_absolue:0));
$dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:'';
@ -1439,7 +1439,7 @@ if ($action=='create')
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="add">';
print '<input type="hidden" name="socid" value="' . $soc->id . '">' . "\n";
print '<input type="hidden" name="remise_percent" value="' . $soc->remise_percent . '">';
print '<input type="hidden" name="remise_percent" value="' . $soc->remise_supplier_percent . '">';
print '<input type="hidden" name="origin" value="' . $origin . '">';
print '<input type="hidden" name="originid" value="' . $originid . '">';
if (!empty($currency_tx)) print '<input type="hidden" name="originmulticurrency_tx" value="' . $currency_tx . '">';
@ -1480,6 +1480,21 @@ if ($action=='create')
}
print '</td>';
if ($societe->id > 0)
{
// Discounts for third party
print '<tr><td>' . $langs->trans('Discounts') . '</td><td>';
$absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1);
$thirdparty = $societe;
$discount_type = 1;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
}
// Ref supplier
print '<tr><td>'.$langs->trans('RefSupplier').'</td><td><input name="refsupplier" type="text"></td>';
print '</tr>';
@ -1860,6 +1875,29 @@ elseif (! empty($object->id))
print '<td>'.$author->getNomUrl(1, '', 0, 0, 0).'</td>';
print '</tr>';
// Relative and absolute discounts
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
$filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
}
$absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 1);
$absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 1);
$absolute_discount = price2num($absolute_discount, 'MT');
$absolute_creditnote = price2num($absolute_creditnote, 'MT');
print '<tr><td class="titlefield">' . $langs->trans('Discounts') . '</td><td>';
$thirdparty = $societe;
$discount_type = 1;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
// Conditions de reglement par defaut
$langs->load('bills');
print '<tr><td class="nowrap">';

View File

@ -36,6 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
@ -265,6 +266,14 @@ if (empty($reshook))
$action='';
}
}
// Delete link of credit note to invoice
else if ($action == 'unlinkdiscount' && $user->rights->fournisseur->facture->creer)
{
$discount = new DiscountAbsolute($db);
$result = $discount->fetch(GETPOST("discountid"));
$discount->unlink_invoice();
}
elseif ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer)
{
@ -317,12 +326,12 @@ if (empty($reshook))
}
// Multicurrency Code
else if ($action == 'setmulticurrencycode' && $user->rights->facture->creer) {
else if ($action == 'setmulticurrencycode' && $user->rights->fournisseur->facture->creer) {
$result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
}
// Multicurrency rate
else if ($action == 'setmulticurrencyrate' && $user->rights->facture->creer) {
else if ($action == 'setmulticurrencyrate' && $user->rights->fournisseur->facture->creer) {
$result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx', 'alpha')));
}
@ -376,6 +385,187 @@ if (empty($reshook))
$result=$object->update($user);
if ($result < 0) dol_print_error($db,$object->error);
}
elseif ($action == "setabsolutediscount" && $user->rights->fournisseur->facture->creer)
{
// POST[remise_id] or POST[remise_id_for_payment]
// We use the credit to reduce amount of invoice
if (! empty($_POST["remise_id"])) {
$ret = $object->fetch($id);
if ($ret > 0) {
$result = $object->insert_discount($_POST["remise_id"]);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
} else {
dol_print_error($db, $object->error);
}
}
// We use the credit to reduce remain to pay
if (! empty($_POST["remise_id_for_payment"]))
{
require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
$discount = new DiscountAbsolute($db);
$discount->fetch($_POST["remise_id_for_payment"]);
//var_dump($object->getRemainToPay(0));
//var_dump($discount->amount_ttc);exit;
if ($discount->amount_ttc > $object->getRemainToPay(0))
{
// TODO Split the discount in 2 automatically
$error++;
setEventMessages($langs->trans("ErrorDiscountLargerThanRemainToPaySplitItBefore"), null, 'errors');
}
if (! $error)
{
$result = $discount->link_to_invoice(0, $id);
if ($result < 0) {
setEventMessages($discount->error, $discount->errors, 'errors');
}
}
}
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
{
$outputlangs = $langs;
$newlang = '';
if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
if (! empty($newlang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($newlang);
}
$ret = $object->fetch($id); // Reload to get new records
$result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
}
}
// Convertir en reduc
else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer)
{
$object->fetch($id);
$object->fetch_thirdparty();
//$object->fetch_lines(); // Already done into fetch
// Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
$discountcheck=new DiscountAbsolute($db);
$result=$discountcheck->fetch(0,0,$object->id);
$canconvert=0;
if ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc)
if (($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc)
if ($canconvert)
{
$db->begin();
$amount_ht = $amount_tva = $amount_ttc = array();
// Loop on each vat rate
$i = 0;
foreach ($object->lines as $line)
{
if ($line->product_type < 9 && $line->total_ht != 0) // Remove lines with product_type greater than or equal to 9
{ // no need to create discount if amount is null
$amount_ht[$line->tva_tx] += $line->total_ht;
$amount_tva[$line->tva_tx] += $line->total_tva;
$amount_ttc[$line->tva_tx] += $line->total_ttc;
$i ++;
}
}
// Insert one discount by VAT rate category
$discount = new DiscountAbsolute($db);
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE)
$discount->description = '(CREDIT_NOTE)';
elseif ($object->type == FactureFournisseur::TYPE_DEPOSIT)
$discount->description = '(DEPOSIT)';
elseif ($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_SITUATION)
$discount->description = '(EXCESS PAID)';
else {
setEventMessages($langs->trans('CantConvertToReducAnInvoiceOfThisType'), null, 'errors');
}
$discount->discount_type = 1; // Supplier discount
$discount->fk_soc = $object->socid;
$discount->fk_invoice_supplier_source = $object->id;
$error = 0;
if ($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_SITUATION)
{
// If we're on a standard invoice, we have to get excess paid to create a discount in TTC without VAT
$sql = 'SELECT SUM(pf.amount) as total_paiements';
$sql.= ' FROM '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf, '.MAIN_DB_PREFIX.'paiementfourn as p';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN (' . getEntity('c_paiement') . ')';
$sql.= ' WHERE pf.fk_facturefourn = '.$object->id;
$sql.= ' AND pf.fk_paiementfourn = p.rowid';
$sql.= ' AND p.entity IN (' . getEntity('facture').')';
$sql.= ' ORDER BY p.datep, p.tms';
$resql = $db->query($sql);
if (! $resql) dol_print_error($db);
$res = $db->fetch_object($resql);
$total_paiements = $res->total_paiements;
$discount->amount_ht = $discount->amount_ttc = $total_paiements - $object->total_ttc;
$discount->amount_tva = 0;
$discount->tva_tx = 0;
$result = $discount->create($user);
if ($result < 0)
{
$error++;
}
}
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT)
{
foreach ($amount_ht as $tva_tx => $xxx)
{
$discount->amount_ht = abs($amount_ht[$tva_tx]);
$discount->amount_tva = abs($amount_tva[$tva_tx]);
$discount->amount_ttc = abs($amount_ttc[$tva_tx]);
$discount->tva_tx = abs($tva_tx);
$result = $discount->create($user);
if ($result < 0)
{
$error++;
break;
}
}
}
if (empty($error))
{
if($object->type != FactureFournisseur::TYPE_DEPOSIT) {
// Classe facture
$result = $object->set_paid($user);
if ($result >= 0)
{
$db->commit();
}
else
{
setEventMessages($object->error, $object->errors, 'errors');
$db->rollback();
}
} else {
$db->commit();
}
}
else
{
setEventMessages($discount->error, $discount->errors, 'errors');
$db->rollback();
}
}
}
// Delete payment
elseif ($action == 'confirm_delete_paiement' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer)
@ -464,6 +654,7 @@ if (empty($reshook))
// Credit note invoice
if ($_POST['type'] == FactureFournisseur::TYPE_CREDIT_NOTE)
{
$sourceinvoice = GETPOST('fac_avoir','int');
if (! ($sourceinvoice > 0) && empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE))
{
@ -519,6 +710,10 @@ if (empty($reshook))
$id = $object->create($user);
if($id <= 0) {
$error++;
}
if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0)
{
$facture_source = new FactureFournisseur($db); // fetch origin object
@ -677,7 +872,7 @@ if (empty($reshook))
}
$num=count($lines);
for ($i = 0; $i < $num; $i++)
for ($i = 0; $i < $num; $i++) // TODO handle subprice < 0
{
$desc=($lines[$i]->desc?$lines[$i]->desc:$lines[$i]->libelle);
$product_type=($lines[$i]->product_type?$lines[$i]->product_type:0);
@ -1434,7 +1629,7 @@ if ($action == 'create')
$cond_reglement_id = (!empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(!empty($soc->cond_reglement_supplier_id)?$soc->cond_reglement_supplier_id:1));
$mode_reglement_id = (!empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(!empty($soc->mode_reglement_supplier_id)?$soc->mode_reglement_supplier_id:0));
$fk_account = (! empty($objectsrc->fk_account)?$objectsrc->fk_account:(! empty($soc->fk_account)?$soc->fk_account:0));
$remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_percent)?$soc->remise_percent:0));
$remise_percent = (!empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(!empty($soc->remise_supplier_percent)?$soc->remise_supplier_percent:0));
$remise_absolue = (!empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(!empty($soc->remise_absolue)?$soc->remise_absolue:0));
$dateinvoice = empty($conf->global->MAIN_AUTOFILL_DATE)?-1:'';
@ -1489,6 +1684,7 @@ if ($action == 'create')
if ($societe->id > 0)
{
$absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1);
print $societe->getNomUrl(1);
print '<input type="hidden" name="socid" value="'.$societe->id.'">';
}
@ -1654,90 +1850,80 @@ if ($action == 'create')
if (empty($origin))
{
if ($conf->global->MAIN_FEATURES_LEVEL > 0) // Need to fix reports of standard accounting module to manage supplier credit note
if ($societe->id > 0)
{
if ($societe->id > 0)
{
// Credit note
if (empty($conf->global->INVOICE_DISABLE_CREDIT_NOTE))
{
print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
$tmp='<input type="radio" id="radio_creditnote" name="type" value="2"' . (GETPOST('type') == 2 ? ' checked' : '');
if (! $optionsav) $tmp.=' disabled';
$tmp.= '> ';
// Show credit note options only if we checked credit note
print '<script type="text/javascript" language="javascript">
jQuery(document).ready(function() {
if (! jQuery("#radio_creditnote").is(":checked"))
{
jQuery("#credit_note_options").hide();
}
jQuery("#radio_creditnote").click(function() {
jQuery("#credit_note_options").show();
});
jQuery("#radio_standard, #radio_replacement, #radio_deposit").click(function() {
jQuery("#credit_note_options").hide();
});
});
</script>';
$text = $tmp.$langs->transnoentities("InvoiceAvoirAsk") . ' ';
// $text.='<input type="text" value="">';
$text .= '<select class="flat valignmiddle" name="fac_avoir" id="fac_avoir"';
if (! $optionsav)
$text .= ' disabled';
$text .= '>';
if ($optionsav) {
$text .= '<option value="-1"></option>';
$text .= $optionsav;
} else {
$text .= '<option value="-1">' . $langs->trans("NoInvoiceToCorrect") . '</option>';
}
$text .= '</select>';
$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
print $desc;
print '<div id="credit_note_options" class="clearboth">';
print '&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithPaymentRestAmount\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithLines','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
print '<br>&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithLines\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithPaymentRestAmount','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
print '</div>';
print '</div></div>';
}
}
else
// Credit note
if (empty($conf->global->INVOICE_DISABLE_CREDIT_NOTE))
{
print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
$tmp='<input type="radio" name="type" id="radio_creditnote" value="0" disabled> ';
$text = $tmp.$langs->trans("InvoiceAvoir") . ' ';
$text.= '('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").') ';
$tmp='<input type="radio" id="radio_creditnote" name="type" value="2"' . (GETPOST('type') == 2 ? ' checked' : '');
if (! $optionsav) $tmp.=' disabled';
$tmp.= '> ';
// Show credit note options only if we checked credit note
print '<script type="text/javascript" language="javascript">
jQuery(document).ready(function() {
if (! jQuery("#radio_creditnote").is(":checked"))
{
jQuery("#credit_note_options").hide();
}
jQuery("#radio_creditnote").click(function() {
jQuery("#credit_note_options").show();
});
jQuery("#radio_standard, #radio_replacement, #radio_deposit").click(function() {
jQuery("#credit_note_options").hide();
});
});
</script>';
$text = $tmp.$langs->transnoentities("InvoiceAvoirAsk") . ' ';
// $text.='<input type="text" value="">';
$text .= '<select class="flat valignmiddle" name="fac_avoir" id="fac_avoir"';
if (! $optionsav)
$text .= ' disabled';
$text .= '>';
if ($optionsav) {
$text .= '<option value="-1"></option>';
$text .= $optionsav;
} else {
$text .= '<option value="-1">' . $langs->trans("NoInvoiceToCorrect") . '</option>';
}
$text .= '</select>';
$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
print $desc;
print '</div></div>' . "\n";
print '<div id="credit_note_options" class="clearboth">';
print '&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithPaymentRestAmount\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithLines','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
print '<br>&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithLines\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithPaymentRestAmount','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
print '</div>';
print '</div></div>';
}
}
else
{
print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
$tmp='<input type="radio" name="type" id="radio_creditnote" value="0" disabled> ';
$text = $tmp.$langs->trans("InvoiceAvoir") . ' ';
$text.= '('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").') ';
$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
print $desc;
print '</div></div>' . "\n";
}
}
print '</div>';
print '</td></tr>';
if ($socid > 0)
if ($societe->id > 0)
{
// Discounts for third party
print '<tr><td>' . $langs->trans('Discounts') . '</td><td>';
if ($soc->remise_percent)
print $langs->trans("CompanyHasRelativeDiscount", '<a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">' . $soc->remise_percent . '</a>');
else
print $langs->trans("CompanyHasNoRelativeDiscount");
print ' <a href="' . DOL_URL_ROOT . '/comm/remise.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">(' . $langs->trans("EditRelativeDiscount") . ')</a>';
print '. ';
print '<br>';
if ($absolute_discount)
print $langs->trans("CompanyHasAbsoluteDiscount", '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">' . price($absolute_discount) . '</a>', $langs->trans("Currency" . $conf->currency));
else
print $langs->trans("CompanyHasNoAbsoluteDiscount");
print ' <a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $soc->id . '&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?socid=' . $soc->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid')) . '">(' . $langs->trans("EditGlobalDiscounts") . ')</a>';
print '.';
$thirdparty = $societe;
$discount_type = 1;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $societe->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
}
@ -1948,6 +2134,18 @@ else
}
$resteapayeraffiche = $resteapayer;
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { // Never use this
$filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
$filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
}
$absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 1);
$absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 1);
$absolute_discount = price2num($absolute_discount, 'MT');
$absolute_creditnote = price2num($absolute_creditnote, 'MT');
/*
* View card
@ -1957,6 +2155,17 @@ else
dol_fiche_head($head, 'card', $titre, -1, 'bill');
$formconfirm = '';
// Confirmation de la conversion de l'avoir en reduc
if ($action == 'converttoreduc') {
if($object->type == FactureFournisseur::TYPE_STANDARD) $type_fac = 'ExcessPaid';
elseif($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) $type_fac = 'CreditNote';
elseif($object->type == FactureFournisseur::TYPE_DEPOSIT) $type_fac = 'Deposit';
$text = $langs->trans('ConfirmConvertToReducSupplier', strtolower($langs->transnoentities($type_fac)));
$formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
}
// Clone confirmation
if ($action == 'clone')
{
@ -2192,8 +2401,27 @@ else
$facthatreplace->fetch($facidnext);
print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')';
}
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
$discount = new DiscountAbsolute($db);
$result = $discount->fetch(0, 0, $object->id);
if ($result > 0){
print '. '.$langs->trans("CreditNoteConvertedIntoDiscount", $object->getLibType(), $discount->getNomUrl(1, 'discount')).'<br>';
}
}
print '</td></tr>';
// Relative and absolute discounts
print '<!-- Discounts --><tr><td>' . $langs->trans('Discounts');
print '</td><td>';
$thirdparty = $societe;
$discount_type = 1;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?facid=' . $object->id);
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
// Label
print '<tr>';
print '<td>'.$form->editfieldkey("Label",'label',$object->label,$object,($user->rights->fournisseur->facture->creer)).'</td>';
@ -2543,18 +2771,20 @@ else
print $langs->trans('AlreadyPaid');
print ' :</td><td align="right"'.(($totalpaye > 0)?' class="amountalreadypaid"':'').'>' . price($totalpaye) . '</td><td>&nbsp;</td></tr>';
$resteapayer = $object->total_ttc - $totalpaye;
//$resteapayer = $object->total_ttc - $totalpaye;
$resteapayeraffiche = $resteapayer;
$cssforamountpaymentcomplete = 'amountpaymentcomplete';
// Loop on each credit note or deposit amount applied
$creditnoteamount = 0;
$depositamount = 0;
/*
$sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
$sql .= " re.description, re.fk_facture_source";
$sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except_supplier as re";
$sql .= " WHERE fk_facture = " . $object->id;
$sql .= " re.description, re.fk_invoice_supplier_source";
$sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except as re";
$sql .= " WHERE fk_invoice_supplier = " . $object->id;
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
@ -2562,7 +2792,7 @@ else
$invoice = new FactureFournisseur($db);
while ($i < $num) {
$obj = $db->fetch_object($resql);
$invoice->fetch($obj->fk_facture_source);
$invoice->fetch($obj->fk_invoice_supplier_source);
print '<tr><td colspan="' . $nbcols . '" align="right">';
if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE)
print $langs->trans("CreditNote") . ' ';
@ -2583,7 +2813,6 @@ else
} else {
dol_print_error($db);
}
*/
// Paye partiellement 'escompte'
if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'discount_vat') {
@ -2629,9 +2858,9 @@ else
if ($resteapayeraffiche >= 0)
print $langs->trans('RemainderToPay');
else
print $langs->trans('ExcessReceived');
print $langs->trans('ExcessPaid');
print ' :</td>';
print '<td align="right"'.($resteapayeraffiche?' class="amountremaintopay"':$cssforamountpaymentcomplete).'>' . price($resteapayeraffiche) . '</td>';
print '<td align="right" class="'.($resteapayeraffiche?'amountremaintopay':$cssforamountpaymentcomplete).'">' . price($resteapayeraffiche) . '</td>';
print '<td class="nowrap">&nbsp;</td></tr>';
}
else // Credit note
@ -2653,7 +2882,7 @@ else
else
print $langs->trans('ExcessPaydBack');
print ' :</td>';
print '<td align="right"'.($resteapayeraffiche?' class="amountremaintopay"':(' class="'.$cssforamountpaymentcomplete.'"')).'>' . price($sign * $resteapayeraffiche) . '</td>';
print '<td align="right" class="'.($resteapayeraffiche?'amountremaintopay':$cssforamountpaymentcomplete).'">' . price($sign * $resteapayeraffiche) . '</td>';
print '<td class="nowrap">&nbsp;</td></tr>';
// Sold credit note
@ -2796,7 +3025,7 @@ else
}
// Reverse back money or convert to reduction
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) {
// For credit note only
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0)
{
@ -2810,6 +3039,11 @@ else
}
}
// For standard invoice with excess paid
if ($object->type == FactureFournisseur::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) < 0 && $user->rights->fournisseur->facture->creer && empty($discount->id))
{
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertExcessPaidToReduc').'</a></div>';
}
// For credit note
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->fournisseur->facture->creer && $object->getSommePaiement() == 0) {
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&amp;action=converttoreduc">' . $langs->trans('ConvertToReduc') . '</a></div>';

View File

@ -76,6 +76,7 @@ $search_amount_all_tax = GETPOST("search_amount_all_tax","alpha");
$search_product_category=GETPOST('search_product_category','int');
$search_ref=GETPOST('sf_ref')?GETPOST('sf_ref','alpha'):GETPOST('search_ref','alpha');
$search_refsupplier=GETPOST('search_refsupplier','alpha');
$search_type=GETPOST('search_type','int');
$search_project=GETPOST('search_project','alpha');
$search_societe=GETPOST('search_societe','alpha');
$search_montant_ht=GETPOST('search_montant_ht','alpha');
@ -148,6 +149,7 @@ $checkedtypetiers=0;
$arrayfields=array(
'f.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
'f.ref_supplier'=>array('label'=>$langs->trans("RefSupplier"), 'checked'=>1),
'f.type'=>array('label'=>$langs->trans("Type"), 'checked'=>0),
'f.label'=>array('label'=>$langs->trans("Label"), 'checked'=>0),
'f.datef'=>array('label'=>$langs->trans("DateInvoice"), 'checked'=>1),
'f.date_lim_reglement'=>array('label'=>$langs->trans("DateDue"), 'checked'=>1),
@ -203,6 +205,7 @@ if (empty($reshook))
$search_product_category='';
$search_ref="";
$search_refsupplier="";
$search_type="";
$search_label="";
$search_project='';
$search_societe="";
@ -261,7 +264,7 @@ llxHeader('',$langs->trans("SuppliersInvoices"),'EN:Suppliers_Invoices|FR:Factur
$sql = "SELECT";
if ($search_all || $search_product_category > 0) $sql = 'SELECT DISTINCT';
$sql.= " f.rowid as facid, f.ref, f.ref_supplier, f.datef, f.date_lim_reglement as datelimite, f.fk_mode_reglement,";
$sql.= " f.rowid as facid, f.ref, f.ref_supplier, f.type, f.datef, f.date_lim_reglement as datelimite, f.fk_mode_reglement,";
$sql.= " f.total_ht, f.total_ttc, f.total_tva as total_vat, f.paye as paye, f.fk_statut as fk_statut, f.libelle as label, f.datec as date_creation, f.tms as date_update,";
$sql.= " f.localtax1 as total_localtax1, f.localtax2 as total_localtax2,";
$sql.= " s.rowid as socid, s.nom as name, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur,";
@ -307,6 +310,15 @@ if ($search_ref)
}
if ($search_ref) $sql .= natural_search('f.ref', $search_ref);
if ($search_refsupplier) $sql .= natural_search('f.ref_supplier', $search_refsupplier);
if ($search_type != '' && $search_type >= 0)
{
if ($search_type == '0') $sql.=" AND f.type = 0"; // standard
if ($search_type == '1') $sql.=" AND f.type = 1"; // replacement
if ($search_type == '2') $sql.=" AND f.type = 2"; // credit note
if ($search_type == '3') $sql.=" AND f.type = 3"; // deposit
//if ($search_type == '4') $sql.=" AND f.type = 4"; // proforma
//if ($search_type == '5') $sql.=" AND f.type = 5"; // situation
}
if ($search_project) $sql .= natural_search('p.ref', $search_project);
if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
if ($search_town) $sql.= natural_search('s.town', $search_town);
@ -377,7 +389,7 @@ $sql.=$hookmanager->resPrint;
if (! $search_all)
{
$sql.= " GROUP BY f.rowid, f.ref, f.ref_supplier, f.datef, f.date_lim_reglement, f.fk_mode_reglement,";
$sql.= " GROUP BY f.rowid, f.ref, f.ref_supplier, f.type, f.datef, f.date_lim_reglement, f.fk_mode_reglement,";
$sql.= " f.total_ht, f.total_ttc, f.total_tva, f.paye, f.fk_statut, f.libelle, f.datec, f.tms,";
$sql.= " f.localtax1, f.localtax2,";
$sql.= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,';
@ -434,6 +446,7 @@ if ($resql)
if ($year_lim) $param.='&year_lim=' .urlencode($year_lim);
if ($search_ref) $param.='&search_ref='.urlencode($search_ref);
if ($search_refsupplier) $param.='&search_refsupplier='.urlencode($search_refsupplier);
if ($search_type != '') $param.='&search_type='.urlencode($search_type);
if ($search_label) $param.='&search_label='.urlencode($search_label);
if ($search_company) $param.='&search_company='.urlencode($search_company);
if ($search_montant_ht != '') $param.='&search_montant_ht='.urlencode($search_montant_ht);
@ -590,6 +603,26 @@ if ($resql)
print '<input class="flat" size="6" type="text" name="search_refsupplier" value="'.$search_refsupplier.'">';
print '</td>';
}
// Type
if (! empty($arrayfields['f.type']['checked']))
{
print '<td class="liste_titre maxwidthonsmartphone">';
$listtype=array(
FactureFournisseur::TYPE_STANDARD=>$langs->trans("InvoiceStandard"),
FactureFournisseur::TYPE_REPLACEMENT=>$langs->trans("InvoiceReplacement"),
FactureFournisseur::TYPE_CREDIT_NOTE=>$langs->trans("InvoiceAvoir"),
FactureFournisseur::TYPE_DEPOSIT=>$langs->trans("InvoiceDeposit"),
);
/*
if (! empty($conf->global->INVOICE_USE_SITUATION))
{
$listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation");
}
*/
//$listtype[Facture::TYPE_PROFORMA]=$langs->trans("InvoiceProForma"); // A proformat invoice is not an invoice but must be an order.
print $form->selectarray('search_type', $listtype, $search_type, 1, 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth100');
print '</td>';
}
// Label
if (! empty($arrayfields['f.label']['checked']))
{
@ -741,6 +774,7 @@ if ($resql)
print '<tr class="liste_titre">';
if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'],$_SERVER['PHP_SELF'],'f.ref,f.rowid','',$param,'',$sortfield,$sortorder);
if (! empty($arrayfields['f.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['f.ref_supplier']['label'],$_SERVER["PHP_SELF"],'f.ref_supplier','',$param,'',$sortfield,$sortorder);
if (! empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'],$_SERVER["PHP_SELF"],'f.type','',$param,'',$sortfield,$sortorder);
if (! empty($arrayfields['f.label']['checked'])) print_liste_field_titre($arrayfields['f.label']['label'],$_SERVER['PHP_SELF'],"f.libelle,f.rowid",'',$param,'',$sortfield,$sortorder);
if (! empty($arrayfields['f.datef']['checked'])) print_liste_field_titre($arrayfields['f.datef']['label'],$_SERVER['PHP_SELF'],'f.datef,f.rowid','',$param,'align="center"',$sortfield,$sortorder);
if (! empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'],$_SERVER['PHP_SELF'],"f.date_lim_reglement",'',$param,'align="center"',$sortfield,$sortorder);
@ -767,7 +801,7 @@ if ($resql)
print $hookmanager->resPrint;
if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye","",$param,'align="right"',$sortfield,$sortorder);
if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"fk_statut,paye,type","",$param,'align="right"',$sortfield,$sortorder);
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ');
print "</tr>\n";
@ -843,6 +877,15 @@ if ($resql)
print '</td>';
if (! $i) $totalarray['nbfield']++;
}
// Type
if (! empty($arrayfields['f.type']['checked']))
{
print '<td class="nowrap">';
print $facturestatic->getLibType();
print "</td>";
if (! $i) $totalarray['nbfield']++;
}
// Label
if (! empty($arrayfields['f.label']['checked']))

View File

@ -57,6 +57,21 @@ create table llx_c_type_container
ALTER TABLE llx_c_type_container ADD UNIQUE INDEX uk_c_type_container_id (code, entity);
ALTER TABLE llx_societe_remise_except ADD COLUMN discount_type integer DEFAULT 0 NOT NULL AFTER fk_soc;
ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_discount_type (discount_type);
ALTER TABLE llx_societe ADD COLUMN remise_supplier real DEFAULT 0 AFTER remise_client;
CREATE TABLE llx_societe_remise_supplier
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1 NOT NULL, -- multi company id
fk_soc integer NOT NULL,
tms timestamp,
datec datetime, -- creation date
fk_user_author integer, -- creation user
remise_supplier double(6,3) DEFAULT 0 NOT NULL, -- discount
note text
)ENGINE=innodb;
insert into llx_c_type_container (code,label,module,active) values ('page', 'Page', 'system', 1);
insert into llx_c_type_container (code,label,module,active) values ('banner', 'Banner', 'system', 1);
insert into llx_c_type_container (code,label,module,active) values ('blogpost', 'BlogPost', 'system', 1);

View File

@ -78,6 +78,7 @@ create table llx_societe
customer_rate real DEFAULT 0, -- taux fiabilite client (0 a 1)
supplier_rate real DEFAULT 0, -- taux fiabilite fournisseur (0 a 1)
remise_client real DEFAULT 0, -- remise systematique pour le client
remise_supplier real DEFAULT 0, -- remise systematique auprès du fournisseur
mode_reglement tinyint, -- mode de reglement
cond_reglement tinyint, -- condition de reglement
mode_reglement_supplier tinyint, -- mode de reglement fournisseur

View File

@ -26,6 +26,7 @@ ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_soc
ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture_line (fk_facture_line);
ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture (fk_facture);
ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_fk_facture_source (fk_facture_source);
ALTER TABLE llx_societe_remise_except ADD INDEX idx_societe_remise_except_discount_type (discount_type);
ALTER TABLE llx_societe_remise_except ADD CONSTRAINT fk_societe_remise_fk_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid);

View File

@ -23,7 +23,8 @@ create table llx_societe_remise_except
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1 NOT NULL, -- multi company id
fk_soc integer NOT NULL, -- client
fk_soc integer NOT NULL, -- customer or supplier
discount_type integer DEFAULT 0 NOT NULL, -- 0 => customer, 1 => supplier
datec datetime,
amount_ht double(24,8) NOT NULL,
amount_tva double(24,8) DEFAULT 0 NOT NULL,

View File

@ -0,0 +1,34 @@
-- ========================================================================
-- Copyright (C) 2000-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
-- Copyright (C) 2011-2016 Regis Houssin <regis.houssin@capnetworks.com>
--
-- 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
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--
-- Historique evolution de la remise relative des tiers
-- ========================================================================
create table llx_societe_remise_supplier
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1 NOT NULL, -- multi company id
fk_soc integer NOT NULL,
tms timestamp,
datec datetime, -- creation date
fk_user_author integer, -- creation user
remise_supplier double(6,3) DEFAULT 0 NOT NULL, -- discount
note text
)ENGINE=innodb;

View File

@ -67,6 +67,7 @@ PaidBack=Paid back
DeletePayment=Delete payment
ConfirmDeletePayment=Are you sure you want to delete this payment?
ConfirmConvertToReduc=Do you want to convert this %s into an absolute discount ?<br>The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this customer.
ConfirmConvertToReducSupplier=Do you want to convert this %s into an absolute discount ?<br>The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this supplier.
SupplierPayments=Suppliers payments
ReceivedPayments=Received payments
ReceivedCustomersPayments=Payments received from customers
@ -91,7 +92,7 @@ PaymentAmount=Payment amount
ValidatePayment=Validate payment
PaymentHigherThanReminderToPay=Payment higher than reminder to pay
HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm and think about creating a credit note of the excess received for each overpaid invoices.
HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm.
HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm and think about creating a credit note of the excess paid for each overpaid invoice.
ClassifyPaid=Classify 'Paid'
ClassifyPaidPartially=Classify 'Paid partially'
ClassifyCanceled=Classify 'Abandoned'
@ -110,6 +111,7 @@ DoPayment=Enter payment
DoPaymentBack=Enter refund
ConvertToReduc=Convert into future discount
ConvertExcessReceivedToReduc=Convert excess received into future discount
ConvertExcessPaidToReduc=Convert excess paid into future discount
EnterPaymentReceivedFromCustomer=Enter payment received from customer
EnterPaymentDueToCustomer=Make payment due to customer
DisabledBecauseRemainderToPayIsZero=Disabled because remaining unpaid is zero
@ -220,6 +222,7 @@ RemainderToPayBack=Remaining amount to refund
Rest=Pending
AmountExpected=Amount claimed
ExcessReceived=Excess received
ExcessPaid=Excess paid
EscompteOffered=Discount offered (payment before term)
EscompteOfferedShort=Discount
SendBillRef=Submission of invoice %s
@ -284,15 +287,19 @@ Deposits=Down payments
DiscountFromCreditNote=Discount from credit note %s
DiscountFromDeposit=Down payments from invoice %s
DiscountFromExcessReceived=Payments from excess received of invoice %s
DiscountFromExcessPaid=Payments from excess paid of invoice %s
AbsoluteDiscountUse=This kind of credit can be used on invoice before its validation
CreditNoteDepositUse=Invoice must be validated to use this kind of credits
NewGlobalDiscount=New absolute discount
NewRelativeDiscount=New relative discount
DiscountType=Discount type
NoteReason=Note/Reason
ReasonDiscount=Reason
DiscountOfferedBy=Granted by
DiscountStillRemaining=Discounts available
DiscountAlreadyCounted=Discounts already consumed
CustomerDiscounts=Customer discounts
SupplierDiscounts=Supplier discounts
BillAddress=Bill address
HelpEscompte=This discount is a discount granted to customer because its payment was made before term.
HelpAbandonBadCustomer=This amount has been abandoned (customer said to be a bad customer) and is considered as an exceptional loose.

View File

@ -79,6 +79,7 @@ VATIsUsed=Sales tax is used
VATIsNotUsed=Sales tax is not used
CopyAddressFromSoc=Fill address with third party address
ThirdpartyNotCustomerNotSupplierSoNoRef=Thirdparty neither customer nor supplier, no available refering objects
ThirdpartyIsNeitherCustomerNorClientSoCannotHaveDiscounts=Thirdparty neither customer nor supplier, discounts are not available
PaymentBankAccount=Payment bank account
OverAllProposals=Proposals
OverAllOrders=Orders
@ -268,12 +269,20 @@ CustomerRelativeDiscountShort=Relative discount
CustomerAbsoluteDiscountShort=Absolute discount
CompanyHasRelativeDiscount=This customer has a default discount of <b>%s%%</b>
CompanyHasNoRelativeDiscount=This customer has no relative discount by default
HasRelativeDiscountFromSupplier=You have a default discount of <b>%s%%</b> from this supplier
HasNoRelativeDiscountFromSupplier=You have no default relative discount from this supplier
CompanyHasAbsoluteDiscount=This customer has discount available (credits notes or down payments) for <b>%s</b> %s
CompanyHasDownPaymentOrCommercialDiscount=This customer has discount available (commercial, down payments) for <b>%s</b> %s
CompanyHasCreditNote=This customer still has credit notes for <b>%s</b> %s
HasNoAbsoluteDiscountFromSupplier=You have no discount credit available from this supplier
HasAbsoluteDiscountFromSupplier=You have discounts available (credits notes or down payments) for <b>%s</b> %s from this supplier
HasDownPaymentOrCommercialDiscountFromSupplier=You have discounts available (commercial, down payments) for <b>%s</b> %s from this supplier
HasCreditNoteFromSupplier=You have credit notes for <b>%s</b> %s from this supplier
CompanyHasNoAbsoluteDiscount=This customer has no discount credit available
CustomerAbsoluteDiscountAllUsers=Absolute discounts (granted by all users)
CustomerAbsoluteDiscountMy=Absolute discounts (granted by yourself)
CustomerAbsoluteDiscountAllUsers=Absolute customer discounts (granted by all users)
CustomerAbsoluteDiscountMy=Absolute customer discounts (granted by yourself)
SupplierAbsoluteDiscountAllUsers=Absolute supplier discounts (granted by all users)
SupplierAbsoluteDiscountMy=Absolute supplier discounts (granted by yourself)
DiscountNone=None
Supplier=Supplier
AddContact=Create contact

View File

@ -149,7 +149,7 @@ if (empty($reshook))
$listofproperties=array(
'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode',
'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
'model_pdf', 'fk_projet'

View File

@ -83,8 +83,14 @@ class Thirdparties extends DolibarrApi
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
$filterabsolutediscount = "fk_facture_source IS NULL OR (fk_facture_source IS NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%'))";
$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
}
$absolute_discount = $this->company->getAvailableDiscounts('', $filterabsolutediscount);
$absolute_creditnote = $this->company->getAvailableDiscounts('', $filtercreditnote);
$this->company->absolute_discount = price2num($absolute_discount, 'MT');
@ -308,7 +314,7 @@ class Thirdparties extends DolibarrApi
$listofproperties=array(
'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode',
'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
'model_pdf', 'fk_projet'

View File

@ -234,6 +234,7 @@ class Societe extends CommonObject
var $forme_juridique;
var $remise_percent;
var $remise_supplier_percent;
var $mode_reglement_supplier_id;
var $cond_reglement_supplier_id;
var $fk_prospectlevel;
@ -1144,7 +1145,7 @@ class Societe extends CommonObject
$sql .= ', s.fk_forme_juridique as forme_juridique_code';
$sql .= ', s.webservices_url, s.webservices_key';
$sql .= ', s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur, s.parent, s.barcode';
$sql .= ', s.fk_departement, s.fk_pays as country_id, s.fk_stcomm, s.remise_client, s.mode_reglement, s.cond_reglement, s.fk_account, s.tva_assuj';
$sql .= ', s.fk_departement, s.fk_pays as country_id, s.fk_stcomm, s.remise_client, s.remise_supplier, s.mode_reglement, s.cond_reglement, s.fk_account, s.tva_assuj';
$sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo';
$sql .= ', s.fk_shipping_method';
$sql .= ', s.outstanding_limit, s.import_key, s.canvas, s.fk_incoterms, s.location_incoterms';
@ -1277,6 +1278,7 @@ class Societe extends CommonObject
$this->prefix_comm = $obj->prefix_comm;
$this->remise_percent = $obj->remise_client;
$this->remise_supplier_percent = $obj->remise_supplier;
$this->mode_reglement_id = $obj->mode_reglement;
$this->cond_reglement_id = $obj->cond_reglement;
$this->mode_reglement_supplier_id = $obj->mode_reglement_supplier;
@ -1660,17 +1662,79 @@ class Societe extends CommonObject
return 1;
}
}
/**
* Definit la societe comme un client
*
* @param float $remise Valeur en % de la remise
* @param string $note Note/Motif de modification de la remise
* @param User $user Utilisateur qui definie la remise
* @return int <0 if KO, >0 if OK
*/
function set_remise_supplier($remise, $note, User $user)
{
global $conf, $langs;
// Nettoyage parametres
$note=trim($note);
if (! $note)
{
$this->error=$langs->trans("ErrorFieldRequired",$langs->trans("NoteReason"));
return -2;
}
dol_syslog(get_class($this)."::set_remise_supplier ".$remise.", ".$note.", ".$user->id);
if ($this->id)
{
$this->db->begin();
$now=dol_now();
// Positionne remise courante
$sql = "UPDATE ".MAIN_DB_PREFIX."societe ";
$sql.= " SET remise_supplier = '".$this->db->escape($remise)."'";
$sql.= " WHERE rowid = " . $this->id;
$resql=$this->db->query($sql);
if (! $resql)
{
$this->db->rollback();
$this->error=$this->db->error();
return -1;
}
// Ecrit trace dans historique des remises
$sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_supplier";
$sql.= " (entity, datec, fk_soc, remise_supplier, note, fk_user_author)";
$sql.= " VALUES (".$conf->entity.", '".$this->db->idate($now)."', ".$this->id.", '".$this->db->escape($remise)."',";
$sql.= " '".$this->db->escape($note)."',";
$sql.= " ".$user->id;
$sql.= ")";
$resql=$this->db->query($sql);
if (! $resql)
{
$this->db->rollback();
$this->error=$this->db->lasterror();
return -1;
}
$this->db->commit();
return 1;
}
}
/**
* Add a discount for third party
*
* @param float $remise Amount of discount
* @param User $user User adding discount
* @param string $desc Reason of discount
* @param float $tva_tx VAT rate
* @param float $remise Amount of discount
* @param User $user User adding discount
* @param string $desc Reason of discount
* @param float $tva_tx VAT rate
* @param int $discount_type 0 => customer discount, 1 => supplier discount
* @return int <0 if KO, id of discount record if OK
*/
function set_remise_except($remise, User $user, $desc, $tva_tx=0)
function set_remise_except($remise, User $user, $desc, $tva_tx=0, $discount_type=0)
{
global $langs;
@ -1696,11 +1760,13 @@ class Societe extends CommonObject
$discount = new DiscountAbsolute($this->db);
$discount->fk_soc=$this->id;
$discount->discount_type=$discount_type;
$discount->amount_ht=price2num($remise,'MT');
$discount->amount_tva=price2num($remise*$tva_tx/100,'MT');
$discount->amount_ttc=price2num($discount->amount_ht+$discount->amount_tva,'MT');
$discount->tva_tx=price2num($tva_tx,'MT');
$discount->description=$desc;
$result=$discount->create($user);
if ($result > 0)
{
@ -1718,17 +1784,18 @@ class Societe extends CommonObject
/**
* Renvoie montant TTC des reductions/avoirs en cours disponibles de la societe
*
* @param User $user Filtre sur un user auteur des remises
* @param string $filter Filtre autre
* @param integer $maxvalue Filter on max value for discount
* @param User $user Filtre sur un user auteur des remises
* @param string $filter Filtre autre
* @param integer $maxvalue Filter on max value for discount
* @param int $discount_type 0 => customer discount, 1 => supplier discount
* @return int <0 if KO, Credit note amount otherwise
*/
function getAvailableDiscounts($user='',$filter='',$maxvalue=0)
function getAvailableDiscounts($user='',$filter='',$maxvalue=0,$discount_type=0)
{
require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discountstatic=new DiscountAbsolute($this->db);
$result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue);
$result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue,$discount_type);
if ($result >= 0)
{
return $result;

View File

@ -491,6 +491,7 @@ if ($sql_select)
print img_object($langs->trans("ShowReduc"),'reduc').' ';
if ($objp->description == '(DEPOSIT)') $txt=$langs->trans("Deposit");
elseif ($objp->description == '(EXCESS RECEIVED)') $txt=$langs->trans("ExcessReceived");
elseif ($objp->description == '(EXCESS PAID)') $txt=$langs->trans("ExcessPaid");
//else $txt=$langs->trans("Discount");
print $txt;
?>
@ -510,6 +511,12 @@ if ($sql_select)
$discount->fetch($objp->fk_remise_except);
echo ($txt?' - ':'').$langs->transnoentities("DiscountFromExcessReceived",$discount->getNomUrl(0));
}
elseif ($objp->description == '(EXCESS PAID)' && $objp->fk_remise_except > 0)
{
$discount=new DiscountAbsolute($db);
$discount->fetch($objp->fk_remise_except);
echo ($txt?' - ':'').$langs->transnoentities("DiscountFromExcessPaid",$discount->getNomUrl(0));
}
elseif ($objp->description == '(DEPOSIT)' && $objp->fk_remise_except > 0)
{
$discount=new DiscountAbsolute($db);

View File

@ -1000,7 +1000,7 @@ if ($action == 'create')
$cond_reglement_id = (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:1));
$mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0));
$remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0));
$remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_supplier_percent)?$soc->remise_supplier_percent:0));
$remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0));
// Replicate extrafields
@ -1053,6 +1053,21 @@ if ($action == 'create')
}
print '</tr>' . "\n";
if ($soc->id > 0)
{
// Discounts for third party
print '<tr><td>' . $langs->trans('Discounts') . '</td><td>';
$absolute_discount = $soc->getAvailableDiscounts('', '', 0, 1);
$thirdparty = $soc;
$discount_type = 1;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
}
// Terms of payment
print '<tr><td class="nowrap">' . $langs->trans('PaymentConditionsShort') . '</td><td colspan="2">';
$form->select_conditions_paiements(GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1);
@ -1392,6 +1407,29 @@ if ($action == 'create')
print '<table class="border" width="100%">';
// Relative and absolute discounts
if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
$filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
} else {
$filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
$filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
}
print '<tr><td class="titlefield">' . $langs->trans('Discounts') . '</td><td>';
$absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount, 0, 1);
$absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote, 0, 1);
$absolute_discount = price2num($absolute_discount, 'MT');
$absolute_creditnote = price2num($absolute_creditnote, 'MT');
$thirdparty = $soc;
$discount_type = 1;
$backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
print '</td></tr>';
// Payment term
print '<tr><td class="titlefield">';
print '<table class="nobordernopadding" width="100%"><tr><td>';