From daca27b2ed8e8a2924105de16b32f7f8d894d117 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Wed, 14 Feb 2018 18:02:40 +0100 Subject: [PATCH] NEW: supplier credit notes: split display in thirdparty discount page + fixes + refactoring --- htdocs/comm/card.php | 2 +- htdocs/comm/remx.php | 372 +++++++++++++++++- htdocs/core/class/discount.class.php | 93 ++++- htdocs/core/class/html.form.class.php | 15 +- .../fourn/class/fournisseur.facture.class.php | 2 +- htdocs/fourn/facture/card.php | 21 +- .../install/mysql/migration/7.0.0-8.0.0.sql | 1 + .../tables/llx_societe_remise_except.key.sql | 1 + .../tables/llx_societe_remise_except.sql | 3 +- htdocs/societe/class/societe.class.php | 25 +- 10 files changed, 476 insertions(+), 59 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 81443f04d62..d732a10a347 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -392,7 +392,7 @@ if ($object->id > 0) print ''; print ''; print ''; - $amount_discount=$object->getAvailableDiscounts(); + $amount_discount=$object->getAvailableDiscounts(); // TODO adapt to supplier discounts if ($amount_discount < 0) dol_print_error($db,$object->error); if ($amount_discount > 0) print ''.price($amount_discount,1,$langs,1,-1,-1,$conf->currency).''; //else print $langs->trans("DiscountNone"); diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 0127b8f15be..072baa675fb 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -26,6 +26,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; $langs->load("orders"); @@ -143,6 +144,7 @@ if ($action == 'setremise' && $user->rights->societe->creer) $amount_ht=GETPOST('amount_ht'); $desc=GETPOST('desc','alpha'); $tva_tx=GETPOST('tva_tx','alpha'); + $discount_type=! empty($_POST['discount_type'])?GETPOST('discount_type','alpha'):0; if (price2num($amount_ht) > 0) { @@ -157,7 +159,7 @@ if ($action == 'setremise' && $user->rights->societe->creer) { $soc = new Societe($db); $soc->fetch($id); - $discountid=$soc->set_remise_except($amount_ht,$user,$desc,$tva_tx); + $discountid=$soc->set_remise_except($amount_ht,$user,$desc,$tva_tx,$discount_type); if ($discountid > 0) { @@ -215,6 +217,7 @@ if (GETPOST('action','aZ09') == 'confirm_remove' && GETPOST("confirm")=='yes') $form=new Form($db); $facturestatic=new Facture($db); +$facturefournstatic=new FactureFournisseur($db); llxHeader('',$langs->trans("GlobalDiscount")); @@ -244,12 +247,13 @@ if ($socid > 0) print '
'; print ''; - // Calcul avoirs en cours + // Calcul avoirs client en cours $remise_all=$remise_user=0; $sql = "SELECT SUM(rc.amount_ht) as amount, rc.fk_user"; $sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc"; $sql.= " WHERE rc.fk_soc = " . $object->id; $sql.= " AND rc.entity = " . $conf->entity; + $sql.= " AND discount_type = 0"; // Exclude supplier discounts $sql.= " AND (fk_facture_line IS NULL AND fk_facture IS NULL)"; $sql.= " GROUP BY rc.fk_user"; $resql=$db->query($sql); @@ -264,14 +268,47 @@ if ($socid > 0) dol_print_error($db); } - print ''; + print ''; // TODO adapt text print ''; if (! empty($user->fk_soc)) // No need to show this for external users { - print ''; + print ''; // TODO adapt text print ''; } + + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + // Calcul avoirs fournisseur en cours + $remise_all=$remise_user=0; + $sql = "SELECT SUM(rc.amount_ht) as amount, rc.fk_user"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql.= " WHERE rc.fk_soc = " . $object->id; + $sql.= " AND rc.entity = " . $conf->entity; + $sql.= " AND discount_type = 1"; // Exclude customer discounts + $sql.= " AND (fk_invoice_supplier_line IS NULL AND fk_invoice_supplier IS NULL)"; + $sql.= " GROUP BY rc.fk_user"; + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + $remise_all+=$obj->amount; + if ($obj->fk_user == $user->id) $remise_user+=$obj->amount; + } + else + { + dol_print_error($db); + } + + print ''; // TODO adapt text + print ''; + + if (! empty($user->fk_soc)) // No need to show this for external users + { + print ''; // TODO adapt text + print ''; + } + } + print '
'.$langs->trans("CustomerAbsoluteDiscountAllUsers").'
'.$langs->trans("CustomerAbsoluteDiscountAllUsers").''.$remise_all.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
'.$langs->trans("CustomerAbsoluteDiscountMy").'
'.$langs->trans("CustomerAbsoluteDiscountMy").''.$remise_user.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
'.$langs->trans("CustomerAbsoluteDiscountAllUsers").''.$remise_all.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
'.$langs->trans("CustomerAbsoluteDiscountMy").''.$remise_user.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
'; print ''; @@ -284,6 +321,11 @@ if ($socid > 0) print '
'; print ''; + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print ''; + print ''; + } print ''; print ''; @@ -321,9 +363,18 @@ if ($socid > 0) print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.GETPOST('remid'), $langs->trans('RemoveDiscount'), $langs->trans('ConfirmRemoveDiscount'), 'confirm_remove', '', 0, 1); } + /* - * Liste remises fixes restant en cours (= liees a aucune facture ni ligne de facture) + * Liste remises fixes client restant en cours (= liees a aucune facture ni ligne de facture) */ + + print load_fiche_titre($langs->trans("DiscountStillRemaining")); + + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print '
'; + print '
'; + } + $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; $sql.= " rc.datec as dc, rc.description,"; $sql.= " rc.fk_facture_source,"; @@ -334,13 +385,16 @@ if ($socid > 0) $sql.= " WHERE rc.fk_soc = " . $object->id; $sql.= " AND rc.entity = " . $conf->entity; $sql.= " AND u.rowid = rc.fk_user"; + $sql.= " AND rc.discount_type = 0"; // Eliminate supplier discounts $sql.= " AND (rc.fk_facture_line IS NULL AND rc.fk_facture IS NULL)"; $sql.= " ORDER BY rc.datec DESC"; $resql=$db->query($sql); if ($resql) { - print load_fiche_titre($langs->trans("DiscountStillRemaining")); + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print load_fiche_titre($langs->trans("CustomerDiscounts"), '', ''); // TODO translate + } print '
'.$langs->trans('DiscountType').' '; + print '
'.$langs->trans("AmountHT").''; print ' '.$langs->trans("Currency".$conf->currency).'
'; print ''; print ''; // Need 120+ for format with AM/PM @@ -449,11 +503,157 @@ if ($socid > 0) dol_print_error($db); } + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print ''; // class="fichehalfleft" + print '
'; + print '
'; + + /* + * Liste remises fixes fournisseur restant en cours (= liees a aucune facture ni ligne de facture) + */ + $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; + $sql.= " rc.datec as dc, rc.description,"; + $sql.= " rc.fk_invoice_supplier_source,"; + $sql.= " u.login, u.rowid as user_id,"; + $sql.= " fa.ref, fa.type as type"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u, ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as fa ON rc.fk_invoice_supplier_source = fa.rowid"; + $sql.= " WHERE rc.fk_soc = " . $object->id; + $sql.= " AND rc.entity = " . $conf->entity; + $sql.= " AND u.rowid = rc.fk_user"; + $sql.= " AND rc.discount_type = 1"; // Eliminate customer discounts + $sql.= " AND (rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line IS NULL)"; + $sql.= " ORDER BY rc.datec DESC"; + + $resql=$db->query($sql); + if ($resql) + { + print load_fiche_titre($langs->trans("SupplierDiscounts"), '', ''); // TODO translate + print '
'.$langs->trans("Date").'
'; + print ''; + print ''; // Need 120+ for format with AM/PM + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $showconfirminfo=array(); + + $i = 0; + $num = $db->num_rows($resql); + if ($num > 0) + { + while ($i < $num) + { + $obj = $db->fetch_object($resql); + + print ''; + print ''; + if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(EXCESS PAID\)/',$obj->description)) + { + print ''; + } + else + { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + if ($user->rights->societe->creer || $user->rights->facture->creer) + { + print ''; + } + else print ''; + print ''; + + if ($_GET["action"]=='split' && GETPOST('remid') == $obj->rowid) + { + $showconfirminfo['rowid']=$obj->rowid; + $showconfirminfo['amount_ttc']=$obj->amount_ttc; + } + $i++; + } + } + else + { + print ''; + } + $db->free($resql); + print "
'.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("ConsumedBy").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").''.$langs->trans("AmountTTC").''.$langs->trans("DiscountOfferedBy").' 
'.dol_print_date($db->jdate($obj->dc),'dayhour').''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(EXCESS PAID\)/',$langs->trans("ExcessPaid"),$obj->description).' '.$facturefournstatic->getNomURl(1); // TODO translate ExcessPaid + print ''; + print $obj->description; + print ''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; + print ''; + print 'rowid.($backtopage?'&backtopage='.urlencode($backtopage):'').'">'.img_split($langs->trans("SplitDiscount")).''; + print '   '; + print 'rowid.($backtopage?'&backtopage='.urlencode($backtopage):'').'">'.img_delete($langs->trans("RemoveDiscount")).''; + print ' 
'.$langs->trans("None").'
"; + + if (count($showconfirminfo)) + { + $amount1=price2num($showconfirminfo['amount_ttc']/2,'MT'); + $amount2=($showconfirminfo['amount_ttc']-$amount1); + $formquestion=array( + 'text' => $langs->trans('TypeAmountOfEachNewDiscount'), + array('type' => 'text', 'name' => 'amount_ttc_1', 'label' => $langs->trans("AmountTTC").' 1', 'value' => $amount1, 'size' => '5'), + array('type' => 'text', 'name' => 'amount_ttc_2', 'label' => $langs->trans("AmountTTC").' 2', 'value' => $amount2, 'size' => '5') + ); + $langs->load("dict"); + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.$showconfirminfo['rowid'].($backtopage?'&backtopage='.urlencode($backtopage):''), $langs->trans('SplitDiscount'), $langs->trans('ConfirmSplitDiscount',price($showconfirminfo['amount_ttc']),$langs->transnoentities("Currency".$conf->currency)), 'confirm_split', $formquestion, 0, 0); + } + } + else + { + dol_print_error($db); + } + + print ''; // class="ficheaddleft" + print ''; // class="fichehalfright" + print ''; // class="fichecenter" + } + print '
'; /* * List discount consumed (=liees a une ligne de facture ou facture) */ + + print load_fiche_titre($langs->trans("DiscountAlreadyCounted")); + + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print '
'; + print '
'; + } // Remises liees a lignes de factures $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; @@ -471,6 +671,7 @@ if ($socid > 0) $sql.= " AND rc.fk_facture_line = fc.rowid"; $sql.= " AND fc.fk_facture = f.rowid"; $sql.= " AND rc.fk_user = u.rowid"; + $sql.= " AND rc.discount_type = 0"; // Eliminate supplier discounts $sql.= " ORDER BY dc DESC"; //$sql.= " UNION "; // Remises liees a factures @@ -487,7 +688,7 @@ if ($socid > 0) $sql2.= " WHERE rc.fk_soc =". $object->id; $sql2.= " AND rc.fk_facture = f.rowid"; $sql2.= " AND rc.fk_user = u.rowid"; - + $sql2.= " AND rc.discount_type = 0"; // Eliminate supplier discounts $sql2.= " ORDER BY dc DESC"; $resql=$db->query($sql); @@ -495,7 +696,9 @@ if ($socid > 0) if ($resql) $resql2=$db->query($sql2); if ($resql2) { - print load_fiche_titre($langs->trans("DiscountAlreadyCounted")); + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print load_fiche_titre($langs->trans("CustomerDiscounts"), '', ''); // TODO translate + } print ''; print ''; print ''; // Need 120+ for format with AM/PM @@ -598,6 +801,159 @@ if ($socid > 0) dol_print_error($db); } + if($conf->global->MAIN_FEATURES_LEVEL > 0) { + print ''; // class="fichehalfleft" + print '
'; + print '
'; + + // Remises liees a lignes de factures + $sql = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; + $sql.= " rc.datec as dc, rc.description, rc.fk_invoice_supplier_line, rc.fk_invoice_supplier,"; + $sql.= " rc.fk_invoice_supplier_source,"; + $sql.= " u.login, u.rowid as user_id,"; + $sql.= " f.rowid, f.ref as facnumber,"; + $sql.= " fa.ref, fa.type as type"; + $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; + $sql.= " , ".MAIN_DB_PREFIX."user as u"; + $sql.= " , ".MAIN_DB_PREFIX."facture_fourn_det as fc"; + $sql.= " , ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as fa ON rc.fk_invoice_supplier_source = fa.rowid"; + $sql.= " WHERE rc.fk_soc =". $object->id; + $sql.= " AND rc.fk_invoice_supplier_line = fc.rowid"; + $sql.= " AND fc.fk_facture_fourn = f.rowid"; + $sql.= " AND rc.fk_user = u.rowid"; + $sql.= " AND rc.discount_type = 1"; // Eliminate customer discounts + $sql.= " ORDER BY dc DESC"; + //$sql.= " UNION "; + // Remises liees a factures + $sql2 = "SELECT rc.rowid, rc.amount_ht, rc.amount_tva, rc.amount_ttc, rc.tva_tx,"; + $sql2.= " rc.datec as dc, rc.description, rc.fk_invoice_supplier_line, rc.fk_invoice_supplier,"; + $sql2.= " rc.fk_invoice_supplier_source,"; + $sql2.= " u.login, u.rowid as user_id,"; + $sql2.= " f.rowid, f.ref as facnumber,"; + $sql2.= " fa.ref, fa.type as type"; + $sql2.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; + $sql2.= " , ".MAIN_DB_PREFIX."user as u"; + $sql2.= " , ".MAIN_DB_PREFIX."societe_remise_except as rc"; + $sql2.= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn as fa ON rc.fk_invoice_supplier_source = fa.rowid"; + $sql2.= " WHERE rc.fk_soc =". $object->id; + $sql2.= " AND rc.fk_invoice_supplier = f.rowid"; + $sql2.= " AND rc.fk_user = u.rowid"; + $sql2.= " AND rc.discount_type = 1"; // Eliminate customer discounts + $sql2.= " ORDER BY dc DESC"; + + $resql=$db->query($sql); + $resql2=null; + if ($resql) $resql2=$db->query($sql2); + if ($resql2) + { + print load_fiche_titre($langs->trans("SupplierDiscounts"), '', ''); // TODO translate + print '
'.$langs->trans("Date").'
'; + print ''; + print ''; // Need 120+ for format with AM/PM + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $tab_sqlobj=array(); + $tab_sqlobjOrder=array(); + $num = $db->num_rows($resql); + if ($num > 0) + { + for ($i = 0;$i < $num; $i++) + { + $sqlobj = $db->fetch_object($resql); + $tab_sqlobj[] = $sqlobj; + $tab_sqlobjOrder[]=$db->jdate($sqlobj->dc); + } + } + $db->free($resql); + + $num = $db->num_rows($resql2); + for ($i = 0;$i < $num;$i++) + { + $sqlobj = $db->fetch_object($resql2); + $tab_sqlobj[] = $sqlobj; + $tab_sqlobjOrder[]= $db->jdate($sqlobj->dc); + } + $db->free($resql2); + array_multisort($tab_sqlobjOrder,SORT_DESC,$tab_sqlobj); + + $num = count($tab_sqlobj); + if ($num > 0) + { + $i = 0 ; + while ($i < $num ) + { + $obj = array_shift($tab_sqlobj); + print ''; + print ''; + if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(DEPOSIT\)/',$obj->description)) + { + print ''; + } + elseif (preg_match('/\(EXCESS PAID\)/',$obj->description)) + { + print ''; + } + else + { + print ''; + } + print ''; // TODO adapt to supplier invoice of use getNomUrl + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + $i++; + } + } + else + { + print ''; + } + + print "
'.$langs->trans("Date").''.$langs->trans("ReasonDiscount").''.$langs->trans("ConsumedBy").''.$langs->trans("AmountHT").''.$langs->trans("VATRate").''.$langs->trans("AmountTTC").''.$langs->trans("Author").' 
'.dol_print_date($db->jdate($obj->dc),'dayhour').''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(CREDIT_NOTE\)/',$langs->trans("CreditNote"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(DEPOSIT\)/',$langs->trans("InvoiceDeposit"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + $facturefournstatic->id=$obj->fk_invoice_supplier_source; + $facturefournstatic->ref=$obj->ref; + $facturefournstatic->type=$obj->type; + print preg_replace('/\(EXCESS PAID\)/',$langs->trans("Invoice"),$obj->description).' '.$facturefournstatic->getNomURl(1); + print ''; + print $obj->description; + print ''.img_object($langs->trans("ShowBill"),'bill').' '.$obj->facnumber.''.price($obj->amount_ht).''.price2num($obj->tva_tx,'MU').'%'.price($obj->amount_ttc).''; + print ''.img_object($langs->trans("ShowUser"),'user').' '.$obj->login.''; // TODO getNomUrl ? + print ' 
'.$langs->trans("None").'
"; + } + else + { + dol_print_error($db); + } + + print '
'; // class="ficheaddleft" + print '
'; // class="fichehalfright" + print ''; // class="fichecenter" + } } llxFooter(); diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index c8aa11996b6..b62e35c183e 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -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; // @@ -76,7 +77,7 @@ class DiscountAbsolute 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,"; @@ -101,6 +102,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; @@ -166,11 +168,11 @@ 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, 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_invoice_supplier_source ? "'".$this->db->escape($this->fk_invoice_supplier_source)."'":"null"); @@ -202,7 +204,7 @@ class DiscountAbsolute global $conf, $langs; // Check if we can remove the discount - if ($this->fk_facture_source) // TODO check + if ($this->fk_facture_source) { $sql="SELECT COUNT(rowid) as nb"; $sql.=" FROM ".MAIN_DB_PREFIX."societe_remise_except"; @@ -228,15 +230,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); @@ -263,6 +296,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(); @@ -286,10 +339,9 @@ class DiscountAbsolute * * @param int $rowidline Invoice line id (To use discount into invoice lines) * @param int $rowidinvoice Invoice id (To use discount as a credit note to reduc payment of invoice) - * @param string $mode 'supplier' to link to supplier invoice, 'customer' instead * @return int <0 if KO, >0 if OK */ - function link_to_invoice($rowidline,$rowidinvoice,$mode='customer') + function link_to_invoice($rowidline,$rowidinvoice) { // Check parameters if (! $rowidline && ! $rowidinvoice) @@ -304,7 +356,7 @@ class DiscountAbsolute } $sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except"; - if($mode == 'supplier') { + if(! empty($this->discount_type)) { if ($rowidline) $sql.=" SET fk_invoice_supplier_line = ".$rowidline; if ($rowidinvoice) $sql.=" SET fk_invoice_supplier = ".$rowidinvoice; } else { @@ -317,7 +369,7 @@ class DiscountAbsolute $resql = $this->db->query($sql); if ($resql) { - if($mode == 'supplier') { + if(! empty($this->discount_type)) { $this->fk_invoice_supplier_line=$rowidline; $this->fk_invoice_supplier=$rowidinvoice; } else { @@ -338,13 +390,12 @@ class DiscountAbsolute * Link the discount to a particular invoice line or a particular invoice. * Do not call this if discount is linked to a reconcialiated invoice * - * @param string $mode 'supplier' to unlink a supplier invoice, 'customer' instead * @return int <0 if KO, >0 if OK */ - function unlink_invoice($mode = 'customer') + function unlink_invoice() { $sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except"; - if($mode = 'supplier') { + 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"; @@ -368,14 +419,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; @@ -383,8 +434,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_source IS NULL AND rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL)"; // Available - else $sql.= " AND (rc.fk_invoice_supplier_source IS NULL AND rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line 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.')'; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 8a1cc6ac33c..e6ab69dff95 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4220,10 +4220,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 string $mode 'supplier' to list available discounts for suppliers, 'customer' instead + * @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, $mode='customer') + function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0, $discount_type=0) { global $conf,$langs; if ($htmlname != "none") @@ -4232,7 +4232,7 @@ class Form print ''; print ''; print '
'; - if($mode == 'supplier') { + if(! empty($discount_type)) { if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { if (! $filter || $filter=="fk_invoice_supplier IS NOT 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 @@ -4260,11 +4260,10 @@ class Form if (empty($hidelist)) { print '
'; - if($mode == 'supplier') { - $newfilter = 'fk_facture_source IS NULL AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Exclude customer discounts + $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 = 'fk_invoice_supplier_source IS NULL AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Exclude supplier discounts $newfilter.= ' AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Customer discounts available } if ($filter) $newfilter.=' AND ('.$filter.')'; @@ -4272,9 +4271,9 @@ class Form if ($nbqualifiedlines > 0) { print '   '; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index b23c9af5fce..198954572d1 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2672,7 +2672,7 @@ class SupplierInvoiceLine extends CommonObjectLine $this->error = $this->db->lasterror(); } } - + // TODO free discount linked to line as in customer invoice if (! $error) { $this->db->commit(); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index a397d40d147..e3c68177b41 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -133,7 +133,7 @@ if (empty($reshook)) $object->fetch_thirdparty(); $result = $object->add_object_linked('order_supplier', GETPOST('linkedOrder')); } - + var_dump($conf->global->MAIN_VERSION_LAST_UPGRADE, $conf->global->MAIN_VERSION_LAST_INSTALL); // Action clone object if ($action == 'confirm_clone' && $confirm == 'yes') { @@ -272,7 +272,7 @@ if (empty($reshook)) { $discount = new DiscountAbsolute($db); $result = $discount->fetch(GETPOST("discountid")); - $discount->unlink_invoice('supplier'); + $discount->unlink_invoice(); } elseif ($action == 'confirm_paid' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer) @@ -419,7 +419,7 @@ if (empty($reshook)) if (! $error) { - $result = $discount->link_to_invoice(0, $id, 'supplier'); + $result = $discount->link_to_invoice(0, $id); if ($result < 0) { setEventMessages($discount->error, $discount->errors, 'errors'); } @@ -486,6 +486,7 @@ if (empty($reshook)) 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; @@ -1679,7 +1680,7 @@ if ($action == 'create') if ($societe->id > 0) { - $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 'supplier'); + $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1); print $societe->getNomUrl(1); print ''; } @@ -2143,12 +2144,12 @@ else $filterabsolutediscount = "fk_invoice_supplier IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice $filtercreditnote = "fk_invoice_supplier IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice } else { - $filterabsolutediscount = "fk_invoice_supplier IS NOT NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')"; + $filterabsolutediscount = "fk_invoice_supplier IS NOT NULL AND (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')"; $filtercreditnote = "fk_invoice_supplier IS NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')"; } - $absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 'supplier'); - $absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 'supplier'); + $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'); @@ -2442,7 +2443,7 @@ else } else { // Discount available of type fixed amount (not credit note) print '
'; - $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, GETPOST('discountid'), 'remise_id', $societe->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' (' . $addabsolutediscount . ')', 0, 'supplier'); + $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, GETPOST('discountid'), 'remise_id', $societe->id, $absolute_discount, $filterabsolutediscount, $resteapayer, ' (' . $addabsolutediscount . ')', 0, 1); } } else { if ($absolute_creditnote > 0) // If not, link will be added later @@ -2468,9 +2469,9 @@ else } 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 '
'; - // $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, $resteapayer, '', 0, 'supplier'); + // $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, $resteapayer, '', 0, 1); $more=' ('.$addcreditnote. (($addcreditnote && $viewabsolutediscount) ? ' - ' : '') . $viewabsolutediscount . ')'; - $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, 0, $more, 0, 'supplier'); // We allow credit note even if amount is higher + $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $societe->id, $absolute_creditnote, $filtercreditnote, 0, $more, 0, 1); // We allow credit note even if amount is higher } } if (! $absolute_discount && ! $absolute_creditnote) { diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql index 9bfe0bd2915..bfc2c79a679 100644 --- a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -35,3 +35,4 @@ ALTER TABLE llx_projet ADD COLUMN bill_time integer DEFAULT 0; ALTER TABLE llx_societe ADD COLUMN order_min_amount double(24,8) DEFAULT NULL AFTER outstanding_limit; ALTER TABLE llx_societe ADD COLUMN supplier_order_min_amount double(24,8) DEFAULT NULL AFTER order_min_amount; +ALTER TABLE llx_societe_remise_except ADD COLUMN discount_type integer DEFAULT 0 NOT NULL AFTER fk_soc; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql index 148a8777915..525af592041 100644 --- a/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql +++ b/htdocs/install/mysql/tables/llx_societe_remise_except.key.sql @@ -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); diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.sql index 3a19a026ca9..151e33d7f1e 100644 --- a/htdocs/install/mysql/tables/llx_societe_remise_except.sql +++ b/htdocs/install/mysql/tables/llx_societe_remise_except.sql @@ -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, diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 4adfae72258..2e980ba7ff8 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1661,13 +1661,14 @@ class Societe extends CommonObject /** * 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; @@ -1693,11 +1694,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) { @@ -1715,18 +1718,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 string $mode 'supplier' to get available discounts for suppliers, 'customer' instead + * @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,$mode='customer') + 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,$mode); + $result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue,$discount_type); if ($result >= 0) { return $result;