2
0
forked from Wavyzz/dolibarr

New: Gestion des factures de remplacement et debut de gestion des avoirs

This commit is contained in:
Laurent Destailleur
2006-08-26 22:45:32 +00:00
parent 9eaf26e6f8
commit 07949ce4c5
6 changed files with 730 additions and 403 deletions

View File

@@ -45,7 +45,7 @@ if ($conf->commande->enabled) require_once(DOL_DOCUMENT_ROOT.'/commande/commande
$user->getrights('facture');
$user->getrights('banque');
if (!$user->rights->facture->lire)
if (! $user->rights->facture->lire)
accessforbidden();
$langs->load('bills');
@@ -53,9 +53,9 @@ $langs->load('companies');
$langs->load('products');
$langs->load('main');
$sall=isset($_GET['sall'])?$_GET['sall']:$_POST['sall'];
if (isset($_GET['msg'])) { $msg=urldecode($_GET['msg']); }
if ($_GET['socidp']) { $socidp=$_GET['socidp']; }
$sall=isset($_GET['sall'])?trim($_GET['sall']):trim($_POST['sall']);
$msg=isset($_GET['msg'])?urldecode($_GET['msg']):'';
$socidp=isset($_GET['socidp'])?$_GET['socidp']:$_POST['socidp'];
// S<>curit<69> acc<63>s client
if ($user->societe_id > 0)
@@ -273,10 +273,12 @@ if ($_POST['action'] == 'add')
$facture = new Facture($db, $_POST['socid']);
$facture->type = $_POST['type'];
if ($facture->type == 1) $facture->fk_facture_source = $_POST['replacement_ref'];
$facture->number = $_POST['facnumber'];
$facture->date = $datefacture;
$facture->note_public = $_POST['note_public'];
$facture->note = $_POST['note'];
$facture->note_public = trim($_POST['note_public']);
$facture->note = trim($_POST['note']);
$facture->ref_client = $_POST['ref_client'];
$facture->modelpdf = $_POST['model'];
@@ -604,17 +606,24 @@ if ($_POST['action'] == 'updateligne' && $user->rights->facture->creer && $_POST
exit;
}
if ($_GET['action'] == 'deleteline' && $user->rights->facture->creer && !$conf->global->PRODUIT_CONFIRM_DELETE_LINE)
if ($_GET['action'] == 'deleteline' && $user->rights->facture->creer && ! $conf->global->PRODUIT_CONFIRM_DELETE_LINE)
{
$fac = new Facture($db,'',$_GET['facid']);
$fac->fetch($_GET['facid']);
$result = $fac->deleteline($_GET['rowid']);
if ($result > 0)
{
if ($_REQUEST['lang_id'])
{
$outputlangs = new Translate(DOL_DOCUMENT_ROOT ."/langs");
$outputlangs->setDefaultLang($_REQUEST['lang_id']);
}
facture_pdf_create($db, $fac->id, '', $fac->modelpdf, $outputlangs);
// facture_pdf_create($db, $fac->id, '', $fac->modelpdf, $outputlangs);
}
else
{
print $fac->error;
}
}
if ($_POST['action'] == 'confirm_delete' && $_POST['confirm'] == 'yes')
@@ -623,10 +632,16 @@ if ($_POST['action'] == 'confirm_delete' && $_POST['confirm'] == 'yes')
{
$fac = new Facture($db);
$result = $fac->delete($_GET['facid']);
$_GET['facid'] = 0 ;
if ($result > 0)
{
Header('Location: '.$_SERVER["PHP_SELF"]);
exit;
}
else
{
$mesg='<div class="error">'.$fac->error.'</div>';
}
}
}
if ($_POST['action'] == 'confirm_canceled' && $_POST['confirm'] == 'yes')
@@ -888,6 +903,8 @@ $html = new Form($db);
**********************************************************************/
if ($_GET['action'] == 'create')
{
$facturestatic=new Facture($db);
print_titre($langs->trans('NewBill'));
if ($msg) print $msg;
@@ -958,14 +975,46 @@ if ($_GET['action'] == 'create')
// Ref
print '<tr><td>'.$langs->trans('Ref').'</td><td colspan="2">'.$langs->trans('Draft').'</td></tr>';
// Reference client
$refclient = $ref_client ? $ref_client : '';
print '<tr><td>'.$langs->trans('RefCustomer').'</td><td>';
print '<input type="text" name="ref_client" value="'.$refclient.'"></td>';
print '</tr>';
// Type de facture
print '<tr><td valign="top">'.$langs->trans('Type').'</td><td colspan="2">';
print '<table class="nobordernopadding"><tr>';
print '<td width="16px">';
print '<input type="radio" name="type" value="0"'.($_POST['type']==0?' checked=true':'').'>';
print '</td><td>';
$desc=$html->textwithhelp($langs->trans("InvoiceStandardAsk"),$langs->transnoentities("InvoiceStandardDesc"),1);
print $desc;
print '</td></tr>';
print '<tr><td>';
print '<input type="radio" name="type" value="1"'.($_POST['type']==1?' checked=true':'').'>';
print '</td><td>';
$facids=$facturestatic->list_replacable_invoices($soc->id);
$options="";
foreach ($facids as $key => $value)
{
$options.='<option value="'.$key.'">'.$value.'</option>';
}
$text=$langs->trans("InvoiceReplacementAsk").' ';
$text.='<select name="replacement_ref">';
$text.='<option value="-1">&nbsp;</option>';
$text.=$options;
$text.='</select>';
$desc=$html->textwithhelp($text,$langs->transnoentities("InvoiceReplacementDesc"),1);
print $desc;
print '</td></tr>';
print '<tr><td>';
print '<input type="radio" name="type" value="2"'.($_POST['type']==2?' checked=true':'').' disabled>';
print '</td><td>';
$desc=$html->textwithhelp($langs->trans("InvoiceAvoirAsk").' ('.$langs->trans("FeatureNotYetAvailable").')',$langs->transnoentities("InvoiceAvoirDesc"),1);
print $desc;
print '</td></tr>';
print '</table>';
print '</td></tr>';
// Societe
print '<tr><td>'.$langs->trans('Company').'</td><td colspan="2">'.$soc->getNomUrl(1).'</td>';
print '<tr><td>'.$langs->trans('Company').'</td><td colspan="2">';
print $soc->getNomUrl(1);
print '<input type="hidden" name="socidp" value="'.$soc->id.'">';
print '</td>';
print '</tr>';
// Ligne info remises tiers
@@ -1044,15 +1093,29 @@ if ($_GET['action'] == 'create')
print '</td></tr>';
}
// Modele PDF
print '<tr><td>'.$langs->trans('Model').'</td>';
print '<td>';
// pdf
include_once(DOL_DOCUMENT_ROOT.'/includes/modules/facture/modules_facture.php');
$model=new ModelePDFFactures();
$liste=$model->liste_modeles($db);
$html->select_array('model',$liste,$conf->global->FACTURE_ADDON_PDF);
print "</td></tr>";
/*
\todo
L'info "Reference commande client" est une carac de la commande et non de la facture.
Elle devrait donc etre stock<63>e sur l'objet commande li<6C> <20> la facture et non sur la facture.
Pour ceux qui veulent l'utiliser au niveau de la facture, positionner la
constante FAC_USE_CUSTOMER_ORDER_REF <20> 1.
*/
if ($conf->global->FAC_USE_CUSTOMER_ORDER_REF)
{
print '<tr><td>'.$langs->trans('RefCustomerOrder').'</td><td>';
print '<input type="text" name="ref_client" value="'.$ref_client.'">';
print '</td></tr>';
}
// Note publique
print '<tr>';
print '<td class="border" valign="top">'.$langs->trans('NotePublic').'</td>';
@@ -1094,19 +1157,6 @@ if ($_GET['action'] == 'create')
print '</textarea></td></tr>';
}
/*
\todo
L'info "Reference commande client" est une carac de la commande et non de la facture.
Elle devrait donc etre stock<63>e sur l'objet commande li<6C> <20> la facture et non sur la facture.
Pour ceux qui utilisent ainsi, positionner la constante FAC_USE_CUSTOMER_ORDER_REF <20> 1.
*/
if ($conf->global->FAC_USE_CUSTOMER_ORDER_REF)
{
print '<tr><td>'.$langs->trans('RefCustomerOrder').'</td><td>';
print '<input type="text" name="ref_client" value="'.$ref_client.'">';
print '</td></tr>';
}
if ($_GET['propalid'] > 0)
{
print '<input type="hidden" name="amount" value="'.$propal->price.'">'."\n";
@@ -1155,6 +1205,8 @@ if ($_GET['action'] == 'create')
print '<tr><td>'.$langs->trans('TotalTTC').'</td><td colspan="2">'.price($contrat->total_ttc)."</td></tr>";
}
else
{
if ($conf->global->PRODUCT_SHOW_WHEN_CREATE)
{
print '<tr><td colspan="3">';
@@ -1198,6 +1250,7 @@ if ($_GET['action'] == 'create')
print '</table>';
print '</td></tr>';
}
}
/*
* Factures r<>currentes
@@ -1483,28 +1536,23 @@ else
// Reference
print '<tr><td width="20%">'.$langs->trans('Ref').'</td><td colspan="5">'.$fac->ref.'</td></tr>';
// Ref client
print '<tr><td>';
print '<table class="nobordernopadding" width="100%"><tr><td nowrap="nowrap">';
print $langs->trans('RefCustomer').'</td><td align="left">';
print '</td>';
if ($_GET['action'] != 'RefCustomerOrder' && $fac->brouillon) print '<td align="right"><a href="'.$_SERVER['PHP_SELF'].'?action=RefCustomerOrder&amp;facid='.$fac->id.'">'.img_edit($langs->trans('Edit')).'</a></td>';
print '</tr></table>';
print '</td><td colspan="5">';
if ($user->rights->facture->creer && $_GET['action'] == 'RefCustomerOrder')
// Type
print '<tr><td width="20%">'.$langs->trans('Type').'</td><td colspan="5">';
print $fac->getLibType();
if ($fac->type == 1)
{
print '<form action="facture.php?facid='.$id.'" method="post">';
print '<input type="hidden" name="action" value="set_ref_client">';
print '<input type="text" class="flat" size="20" name="ref_client" value="'.$fac->ref_client.'">';
print ' <input type="submit" class="button" value="'.$langs->trans('Modify').'">';
print '</form>';
$facreplaced=new Facture($db);
$facreplaced->fetch($fac->fk_facture_source);
print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')';
}
else
$facidnext=$fac->getIdNextInvoice();
if ($facidnext > 0)
{
print $fac->ref_client;
$facthatreplace=new Facture($db);
$facthatreplace->fetch($facidnext);
print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')';
}
print '</td>';
print '</tr>';
print '</td></tr>';
// Soci<63>t<EFBFBD>
print '<tr><td>'.$langs->trans('Company').'</td>';
@@ -1706,8 +1754,8 @@ else
// Projet
if ($conf->projet->enabled)
{
print '<tr>';
$langs->load('projects');
print '<tr>';
print '<td>';
print '<table class="nobordernopadding" width="100%"><tr><td>';
@@ -2203,7 +2251,7 @@ else
else
{
// G<>n<EFBFBD>rer
if ($fac->statut == 1 && $user->rights->facture->creer)
if ($fac->statut >= 1 && $user->rights->facture->creer)
{
if ($fac->paye == 0)
{
@@ -2216,12 +2264,6 @@ else
}
}
// On v<>rifie si la facture est supprimable. Si oui, on propose bouton supprimer
if ($fac->statut == 0 && $fac->is_erasable() && $user->rights->facture->supprimer && $_GET['action'] != 'delete')
{
print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?facid='.$fac->id.'&amp;action=delete">'.$langs->trans('Delete').'</a>';
}
// Envoyer
if ($fac->statut == 1 && $user->rights->facture->envoyer)
{
@@ -2264,6 +2306,12 @@ else
}
}
// Supprimer
if ($fac->is_erasable() && $user->rights->facture->supprimer && $_GET['action'] != 'delete')
{
print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?facid='.$fac->id.'&amp;action=delete">'.$langs->trans('Delete').'</a>';
}
print '</div>';
}
@@ -2276,7 +2324,7 @@ else
$filename=sanitize_string($fac->ref);
$filedir=$conf->facture->dir_output . '/' . sanitize_string($fac->ref);
$urlsource=$_SERVER['PHP_SELF'].'?facid='.$fac->id;
$genallowed=($fac->statut == 1 && $user->rights->facture->creer);
$genallowed=($fac->statut >= 1 && $user->rights->facture->creer);
$delallowed=$user->rights->facture->supprimer;
$var=true;
@@ -2568,24 +2616,21 @@ else
* Mode Liste *
* *
***************************************************************************/
$page = $_GET['page'];
$page =$_GET['page'];
$sortorder=$_GET['sortorder'];
$sortfield=$_GET['sortfield'];
$month=$_GET['month'];
$year=$_GET['year'];
$facturestatic=new Facture($db);
if ($page == -1) $page = 0 ;
if ($user->rights->facture->lire)
{
$month =$_GET['month'];
$year =$_GET['year'];
$limit = $conf->liste_limit;
$offset = $limit * $page ;
if (! $sortorder) $sortorder='DESC';
if (! $sortfield) $sortfield='f.datef';
$facturestatic=new Facture($db);
if ($page == -1) $page = 0 ;
$sql = 'SELECT s.nom, s.idp,';
$sql.= ' f.rowid as facid, f.facnumber, f.increment, f.total, f.total_ttc,';
$sql.= $db->pdate('f.datef').' as df, '.$db->pdate('f.date_lim_reglement').' as datelimite, ';
@@ -2604,24 +2649,24 @@ else
foreach ($filtrearr as $fil)
{
$filt = split(':', $fil);
$sql .= ' AND ' . $filt[0] . ' = ' . $filt[1];
$sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]);
}
}
if ($_GET['search_ref'])
{
$sql .= ' AND f.facnumber like \'%'.addslashes($_GET['search_ref']).'%\'';
$sql .= ' AND f.facnumber like \'%'.addslashes(trim($_GET['search_ref'])).'%\'';
}
if ($_GET['search_societe'])
{
$sql .= ' AND s.nom like \'%'.addslashes($_GET['search_societe']).'%\'';
$sql .= ' AND s.nom like \'%'.addslashes(trim($_GET['search_societe'])).'%\'';
}
if ($_GET['search_montant_ht'])
{
$sql .= ' AND f.total = \''.addslashes($_GET['search_montant_ht']).'\'';
$sql .= ' AND f.total = \''.addslashes(trim($_GET['search_montant_ht'])).'\'';
}
if ($_GET['search_montant_ttc'])
{
$sql .= ' AND f.total_ttc = \''.addslashes($_GET['search_montant_ttc']).'\'';
$sql .= ' AND f.total_ttc = \''.addslashes(trim($_GET['search_montant_ttc'])).'\'';
}
if ($year > 0)
{
@@ -2629,7 +2674,7 @@ else
}
if ($_POST['sf_ref'])
{
$sql .= ' AND f.facnumber like \'%'.addslashes($_POST['sf_ref']) . '%\'';
$sql .= ' AND f.facnumber like \'%'.addslashes(trim($_POST['sf_ref'])) . '%\'';
}
if ($sall)
{
@@ -2759,7 +2804,6 @@ else
dolibarr_print_error($db);
}
}
}
}
$db->close();

View File

@@ -50,7 +50,7 @@ class DiscountAbsolute
/**
* \brief Charge objet remiset depuis la base
* \brief Charge objet remise depuis la base
* \param rowid id du projet <20> charger
* \return int <0 si ko, =0 si non trouv<75>, >0 si ok
*/
@@ -91,5 +91,31 @@ class DiscountAbsolute
return -1;
}
}
/**
* \brief Link the discount to a particular invoice
* \param rowid Invoice id
* \return int <0 ko, >0 ok
*/
function link_to_invoice($rowid)
{
dolibarr_syslog("Discount.class::link_to_invoice link discount ".$this->id." to invoice rowid=".$rowid);
$sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except";
$sql.=" SET fk_facture = ".$rowid;
$sql.=" WHERE rowid = ".$this->id;
$resql = $this->db->query($sql);
if ($resql)
{
return 1;
}
else
{
$this->error=$this->db->error();
dolibarr_syslog("Discount.class::link_to_invoice ".$this->error." sql=".$sql);
return -1;
}
}
}
?>

View File

@@ -63,7 +63,8 @@ class Facture extends CommonObject
var $note_public;
var $statut;
var $paye; // 1 si facture pay<61>e COMPLETEMENT, 0 sinon
var $close_code; // Si mis a paye sans paiement complet, code qui justifie
var $fk_facture_source; // id facture source si facture de remplacement ou avoir
var $close_code; // abandon, replaced, avoir, discount_vat
var $close_note; // Commentaire si mis a paye sans paiement complet
var $propalid;
var $projetid;
@@ -109,20 +110,20 @@ class Facture extends CommonObject
/**
* \brief Cr<43>ation de la facture en base
* \param user object utilisateur qui cr<63>e
* \param user Object utilisateur qui cr<63>e
* \return int <0 si ko, >0 si ok
*/
function create($user)
{
global $langs,$conf,$mysoc;
// Nettoyage param<61>tres
if (! $this->type) $this->type = 0 ;
$this->ref_client=trim($this->ref_client);
$this->note=trim($this->note);
$this->note_public=trim($this->note_public);
$this->ref_client=trim($this->ref_client);
if (! $this->remise) $this->remise = 0 ;
if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
// On positionne en mode brouillon la facture
$this->brouillon = 1;
dolibarr_syslog("Facture::create");
@@ -132,6 +133,45 @@ class Facture extends CommonObject
$this->db->begin();
// Verification param<61>tres
if ($this->type == 1) // si remplacement
{
// Controle que facture source connue
if ($this->fk_facture_source <= 0)
{
$this->error=$langs->trans("ErrorFieldRequired",$langs->trans("InvoiceReplacement"));
$this->db->rollback();
return -10;
}
// Charge la facture source a remplacer
$facreplaced=new Facture($this->db);
$result=$facreplaced->fetch($this->fk_facture_source);
if ($result <= 0)
{
$this->error=$langs->trans("ErrorBadInvoice");
$this->db->rollback();
return -11;
}
// Controle que facture source non deja remplacee
$idreplacement=$facreplaced->getIdNextInvoice();
if ($idreplacement != 0)
{
$this->error=$langs->trans("ErrorInvoiceAlreadyReplaced",$facreplaced->ref);
$this->db->rollback();
return -12;
}
$result=$facreplaced->set_canceled($user,'replaced','');
if ($result < 0)
{
$this->error=$facreplaced->error." sql=".$sql;
$this->db->rollback();
return -13;
}
}
// Facture r<>currente
if ($this->fac_rec > 0)
{
@@ -162,19 +202,20 @@ class Facture extends CommonObject
$totalht = ($amount - $remise);
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'facture (';
$sql.= ' facnumber, fk_soc, datec, amount, remise_absolue, remise_percent,';
$sql.= ' facnumber, type, fk_soc, datec, amount, remise_absolue, remise_percent,';
$sql.= ' datef,';
$sql.= ' note,';
$sql.= ' note_public,';
$sql.= ' ref_client,';
$sql.= ' fk_user_author, fk_projet,';
$sql.= ' fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf) ';
$sql.= " VALUES (";
$sql.= "'$number','$socid', now(), '$totalht', '".$this->remise_absolue."'";
$sql.= ' fk_facture_source, fk_user_author, fk_projet,';
$sql.= ' fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf)';
$sql.= ' VALUES (';
$sql.= "'$number', '".$this->type."', '$socid', now(), '$totalht', '".$this->remise_absolue."'";
$sql.= ",'".$this->remise_percent."', ".$this->db->idate($this->date);
$sql.= ",".($this->note?"'".addslashes($this->note)."'":"null");
$sql.= ",".($this->note_public?"'".addslashes($this->note_public)."'":"null");
$sql.= ",".($this->ref_client?"'".addslashes($this->ref_client)."'":"null");
$sql.= ",".($this->fk_facture_source?"'".addslashes($this->fk_facture_source)."'":"null");
$sql.= ",".$user->id;
$sql.= ",".($this->projetid?$this->projetid:"null");
$sql.= ','.$this->cond_reglement_id;
@@ -189,6 +230,7 @@ class Facture extends CommonObject
$sql = 'UPDATE '.MAIN_DB_PREFIX."facture SET facnumber='(PROV".$this->id.")' WHERE rowid=".$this->id;
$resql=$this->db->query($sql);
// Mise a jour lien avec propal ou commande
if ($resql && $this->id && $this->propalid)
{
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'fa_pr (fk_facture, fk_propal) VALUES ('.$this->id.','.$this->propalid.')';
@@ -301,6 +343,27 @@ class Facture extends CommonObject
}
/**
* \brief Renvoie nom clicable (avec eventuellement le picto)
* \param withpicto Inclut le picto dans le lien
* \param option Sur quoi pointe le lien
* \return string Chaine avec URL
*/
function getNomUrl($withpicto=0,$option='')
{
global $langs;
$result='';
$lien = '<a href="'.DOL_URL_ROOT.'/compta/facture.php?facid='.$this->id.'">';
$lienfin='</a>';
if ($withpicto) $result.=($lien.img_object($langs->trans("ShowInvoice"),'bill').$lienfin.' ');
$result.=$lien.$this->ref.$lienfin;
return $result;
}
/**
* \brief Recup<75>re l'objet facture et ses lignes de factures
* \param rowid id de la facture a r<>cup<75>rer
@@ -311,20 +374,21 @@ class Facture extends CommonObject
{
//dolibarr_syslog("Facture::Fetch rowid : $rowid, societe_id : $societe_id");
$sql = 'SELECT f.fk_soc,f.facnumber,f.amount,f.tva,f.total,f.total_ttc,f.remise_percent,f.remise_absolue,f.remise';
$sql .= ','.$this->db->pdate('f.datef').' as df, f.fk_projet';
$sql .= ','.$this->db->pdate('f.date_lim_reglement').' as dlr';
$sql .= ', f.note, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.model_pdf';
$sql .= ', f.fk_mode_reglement, f.ref_client, p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
$sql .= ', f.fk_cond_reglement, c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_facture';
$sql .= ', cf.fk_commande';
$sql .= ' FROM '.MAIN_DB_PREFIX.'cond_reglement as c, '.MAIN_DB_PREFIX.'facture as f';
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'co_fa as cf ON cf.fk_facture = f.rowid';
$sql .= ' WHERE f.rowid='.$rowid.' AND c.rowid = f.fk_cond_reglement';
$sql = 'SELECT f.facnumber,f.ref_client,f.type,f.fk_soc,f.amount,f.tva,f.total,f.total_ttc,f.remise_percent,f.remise_absolue,f.remise';
$sql.= ','.$this->db->pdate('f.datef').' as df, f.fk_projet';
$sql.= ','.$this->db->pdate('f.date_lim_reglement').' as dlr';
$sql.= ', f.note, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.model_pdf';
$sql.= ', f.fk_mode_reglement, p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
$sql.= ', f.fk_cond_reglement, c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_facture';
$sql.= ', f.fk_facture_source';
$sql.= ', cf.fk_commande';
$sql.= ' FROM '.MAIN_DB_PREFIX.'cond_reglement as c, '.MAIN_DB_PREFIX.'facture as f';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'co_fa as cf ON cf.fk_facture = f.rowid';
$sql.= ' WHERE f.rowid='.$rowid.' AND c.rowid = f.fk_cond_reglement';
if ($societe_id > 0)
{
$sql .= ' AND f.fk_soc = '.$societe_id;
$sql.= ' AND f.fk_soc = '.$societe_id;
}
$result = $this->db->query($sql);
@@ -336,10 +400,11 @@ class Facture extends CommonObject
//print strftime('%Y%m%d%H%M%S',$obj->df).' '.$obj->df.' '.dolibarr_print_date($obj->df);
$this->id = $rowid;
$this->datep = $obj->dp;
$this->date = $obj->df;
$this->ref = $obj->facnumber;
$this->ref_client = $obj->ref_client;
$this->type = $obj->type;
$this->datep = $obj->dp;
$this->date = $obj->df;
$this->amount = $obj->amount;
$this->remise_percent = $obj->remise_percent;
$this->remise_absolue = $obj->remise_absolue;
@@ -361,6 +426,7 @@ class Facture extends CommonObject
$this->cond_reglement = $obj->cond_reglement_libelle;
$this->cond_reglement_facture = $obj->cond_reglement_libelle_facture;
$this->projetid = $obj->fk_projet;
$this->fk_facture_source = $obj->fk_facture_source;
$this->note = $obj->note;
$this->note_public = $obj->note_public;
$this->user_author = $obj->fk_user_author;
@@ -368,7 +434,6 @@ class Facture extends CommonObject
$this->commande_id = $obj->fk_commande;
$this->lignes = array();
if ($this->commande_id)
{
$sql = "SELECT ref";
@@ -465,7 +530,7 @@ class Facture extends CommonObject
/**
* \brief Ajout d'une ligne remise fixe dans la facture, en base
* \brief Ajout en base d'une ligne remise fixe en ligne de facture
* \param idremise Id de la remise fixe
* \return int >0 si ok, <0 si ko
*/
@@ -480,9 +545,15 @@ class Facture extends CommonObject
$remise=new DiscountAbsolute($this->db);
$result=$remise->fetch($idremise);
if ($result > 0)
{
if ($remise->fk_facture)
{
$this->error=$langs->trans("ErrorDiscountAlreadyUsed");
$this->db->rollback();
return -5;
}
$facligne=new FactureLigne($this->db);
$facligne->fk_facture=$this->id;
$facligne->fk_remise_except=$remise->id;
@@ -502,17 +573,27 @@ class Facture extends CommonObject
$facligne->total_tva = $tabprice[1];
$facligne->total_ttc = $tabprice[2];
$result=$facligne->insert();
if ($result > 0)
$lineid=$facligne->insert();
if ($lineid > 0)
{
$result=$this->update_price($this->id);
if ($result > 0)
{
// Cr<43>e lien entre remise et ligne de facture
$result=$remise->link_to_invoice($lineid);
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;
}
@@ -527,7 +608,7 @@ class Facture extends CommonObject
else
{
$this->db->rollback();
return -2;
return -3;
}
}
@@ -575,34 +656,36 @@ class Facture extends CommonObject
/**
* \brief Supprime la facture
* \param rowid id de la facture <20> supprimer
* \param rowid Id de la facture <20> supprimer
* \return int <0 si ko, >0 si ok
*/
function delete($rowid)
{
global $user,$langs,$conf;
$this->db->begin();
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum WHERE fk_facture = '.$rowid;
dolibarr_syslog("Facture.class::delete rowid=".$rowid);
if ( $this->db->query( $sql) )
$this->db->begin();
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_tva_sum WHERE fk_facture = '.$rowid;
if ($this->db->query($sql))
{
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'fa_pr WHERE fk_facture = '.$rowid;
if ($this->db->query( $sql) )
if ($this->db->query($sql))
{
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'co_fa WHERE fk_facture = '.$rowid;
if ($this->db->query( $sql) )
{
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid;
if ($this->db->query( $sql) )
if ($this->db->query($sql))
{
// On d<>saffecte de la facture les remises li<6C>es
$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
$sql.= ' SET fk_facture = NULL WHERE fk_facture = '.$rowid;
if ($this->db->query( $sql) )
if ($this->db->query($sql))
{
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid.' AND fk_statut = 0';
$resql=$this->db->query($sql) ;
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid;
if ($this->db->query($sql))
{
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid;
$resql=$this->db->query($sql);
if ($resql)
{
// Appel des triggers
@@ -616,36 +699,48 @@ class Facture extends CommonObject
}
else
{
$this->error=$this->db->error()." sql=".$sql;
dolibarr_syslog("Facture.class::delete ".$this->error);
$this->db->rollback();
return -6;
}
}
else
{
$this->db->rollback();
return -5;
}
}
else
{
$this->error=$this->db->error()." sql=".$sql;
dolibarr_syslog("Facture.class::delete ".$this->error);
$this->db->rollback();
return -4;
}
}
else
{
$this->error=$this->db->error()." sql=".$sql;
dolibarr_syslog("Facture.class::delete ".$this->error);
$this->db->rollback();
return -5;
}
}
else
{
$this->error=$this->db->error()." sql=".$sql;
dolibarr_syslog("Facture.class::delete ".$this->error);
$this->db->rollback();
return -3;
}
}
else
{
$this->error=$this->db->error()." sql=".$sql;
dolibarr_syslog("Facture.class::delete ".$this->error);
$this->db->rollback();
return -2;
}
}
else
{
$this->error=$this->db->error()." sql=".$sql;
dolibarr_syslog("Facture.class::delete ".$this->error);
$this->db->rollback();
return -1;
}
@@ -796,13 +891,22 @@ class Facture extends CommonObject
global $conf,$langs;
dolibarr_syslog("Facture.class.php::set_canceled rowid=".$this->id);
$this->db->begin();
$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET';
$sql.= ' fk_statut=3';
if ($close_code) $sql.= ", close_code='".addslashes($close_code)."'";
if ($close_note) $sql.= ", close_note='".addslashes($close_note)."'";
$sql.= ' WHERE rowid = '.$this->id;
$resql = $this->db->query($sql);
$resql = $this->db->query($sql);
if ($resql)
{
// On d<>saffecte de la facture les remises li<6C>es
$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
$sql.= ' SET fk_facture = NULL WHERE fk_facture = '.$this->id;
$resql=$this->db->query($sql);
if ($resql)
{
$this->use_webcal=($conf->global->PHPWEBCALENDAR_BILLSTATUS=='always'?1:0);
@@ -812,9 +916,23 @@ class Facture extends CommonObject
$interface=new Interfaces($this->db);
$result=$interface->run_triggers('BILL_CANCEL',$this,$user,$langs,$conf);
// Fin appel triggers
}
$this->db->commit();
return 1;
}
else
{
$this->error=$this->db->error()." sql=".$sql;
$this->db->rollback();
return -1;
}
}
else
{
$this->error=$this->db->error()." sql=".$sql;
$this->db->rollback();
return -2;
}
}
/**
@@ -1283,15 +1401,44 @@ class Facture extends CommonObject
/**
* \brief Supprime une ligne facture de la base
* \param rowid id de la ligne de facture a supprimer
* \param rowid Id de la ligne de facture a supprimer
*/
function deleteline($rowid)
{
dolibarr_syslog("Facture.class::deleteline rowid=".$rowid." ".$this->brouillon);
if ($this->brouillon)
{
$this->db->begin();
// Libere remise liee a ligne de facture
$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
$sql.= ' SET fk_facture = NULL where fk_facture = '.$rowid;
$result = $this->db->query($sql);
if ($result < 0)
{
$this->error=$this->db->error();
dolibarr_syslog("Facture.class::deleteline Error ".$this->error);
$this->db->rollback();
return -1;
}
// Efface ligne de facture
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE rowid = '.$rowid;
$result = $this->db->query( $sql);
$this->update_price($this->id);
$result = $this->db->query($sql);
if ($result < 0)
{
$this->error=$this->db->error();
dolibarr_syslog("Facture.class::deleteline Error ".$this->error);
$this->db->rollback();
return -1;
}
$result=$this->update_price($this->id);
$this->db->commit();
return 1;
}
}
@@ -1522,6 +1669,50 @@ class Facture extends CommonObject
}
}
/**
* \brief Renvoie l'id de la facture qui la remplace
* \return int <0 si ko, 0 si aucune facture ne remplace, id facture sinon
*/
function getIdNextInvoice()
{
$sql = 'SELECT rowid';
$sql.= ' FROM '.MAIN_DB_PREFIX.'facture';
$sql.= ' WHERE fk_facture_source = '.$this->id;
$resql=$this->db->query($sql);
if ($resql)
{
$obj = $this->db->fetch_object($resql);
if ($obj)
{
// Si il y en a
return $obj->rowid;
}
else
{
// Si aucune facture ne remplace
return 0;
}
}
else
{
return -1;
}
}
/**
* \brief Retourne le libell<6C> du type de facture
* \return string Libelle
*/
function getLibType()
{
global $langs;
if ($this->type == 0) return $langs->trans("InvoiceStandard");
if ($this->type == 1) return $langs->trans("InvoiceReplacement");
if ($this->type == 2) return $langs->trans("InvoiceAvoir");
return $langs->trans("Unknown");
}
/**
* \brief Retourne le libell<6C> du statut d'une facture (brouillon, valid<69>e, abandonn<6E>e, pay<61>e)
* \param mode 0=libell<6C> long, 1=libell<6C> court, 2=Picto + Libell<6C> court, 3=Picto, 4=Picto + Libell<6C> long
@@ -1886,7 +2077,7 @@ class Facture extends CommonObject
$facref = substr($this->ref, 1, 4);
// Si facture non brouillon et non provisoire
if ($facref != 'PROV' && $conf->compta->enabled && $conf->global->FACTURE_ENABLE_EDITDELETE)
if ($facref != 'PROV' && ! $conf->comptaexpert->enabled && $conf->global->FACTURE_ENABLE_EDITDELETE)
{
// On ne peut supprimer que la derni<6E>re facture valid<69>e
// pour ne pas avoir de trou dans la num<75>rotation
@@ -1916,6 +2107,42 @@ class Facture extends CommonObject
}
/**
* \brief Renvoi liste des factures remplacables
* Statut validee + aucun paiement + non paye
* \param socid Id societe
* \return array Tableau des factures ($id => $ref)
*/
function list_replacable_invoices($socid=0)
{
global $conf;
$return = array();
$sql = "SELECT f.rowid, f.facnumber";
$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture";
$sql.= " WHERE f.fk_statut = 1 AND f.paye = 0 AND pf.fk_paiement IS NULL";
if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
$sql.= " ORDER BY f.facnumber";
dolibarr_syslog("Facture.class::list_replacable_invoices sq=$sql");
$resql=$this->db->query($sql);
if ($resql)
{
while ($obj=$this->db->fetch_object($resql))
{
$return[$obj->rowid]=$obj->facnumber;
}
return $return;
}
else
{
return -1;
}
}
/**
* \brief Cr<43><72> une demande de pr<70>l<EFBFBD>vement
* \param user Utilisateur cr<63>ant la demande
@@ -2429,8 +2656,10 @@ class FactureLigne
$resql=$this->db->query($sql);
if ($resql)
{
$this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'facturedet');
$this->db->commit();
return 1;
return $this->rowid;
}
else
{

View File

@@ -8,6 +8,17 @@ BillsCustomersUnpayedForCompany=Unpayed customers' invoices for %s
BillsSuppliersUnpayed=Unpayed suppliers' invoices
BillsUnpayed=Unpayed
BillsStatistics=Invoices statistics
InvoiceStandard=Standard invoice
InvoiceStandardAsk=Standard invoice
InvoiceStandardDesc=This kind of invoice is the common invoice.
InvoiceReplacement=Replacement invoice. Must replace invoice with reference
InvoiceReplacementAsk=Replacement invoice for following invoice
InvoiceReplacementDesc=<b>Replacement invoice</b> is used to cancel and replace completely an invoice with no paiement already recevided.<br>Reference of canceled invoice is required.
InvoiceAvoir=Avoir invoice
InvoiceAvoirAsk=Avoir invoice
InvoiceAvoirDesc=La <b>facture d'avoir</b> est une facture n<>gative destin<69>e <20> compenser une facture comportant un montant sup<75>rieur <20> ce qui a <20>t<EFBFBD> ou sera r<>ellement pay<61> (toutes causes possibles).
ReplaceInvoice=Replace invoice %s
ReplacedByInvoice=Replaced by invoice %s
CardBill=Invoice card
Invoice=Invoice
Invoices=Invoices
@@ -68,6 +79,8 @@ ErrorVATIntraNotConfigured=Intracommunautary VAT number not yet defined
ErrorNoPaiementModeConfigured=No paiment mode yet defined
ErrorCreateBankAccount=Creat a bank account then go to Setup panel of Invoice module to define paiement modes
ErrorBillNotFound=Invoice %s does not exists
ErrorInvoiceAlreadyReplaced=Error, invoice %s has already been replaced
ErrorDiscountAlreadyUsed=Error, discount already used
BillFrom=From
BillTo=Bill to
ActionsOnBill=Actions on invoice
@@ -99,6 +112,7 @@ ValidateBill=Validate invoice
NumberOfBills=Nb of invoices
NumberOfBillsByMonth=Nb of invoices by month
ShowBill=Show invoice
ShowInvoice=Show invoice
ShowPayment=Show payment
File=File
AlreadyPayed=Already payed

View File

@@ -8,6 +8,17 @@ BillsCustomersUnpayedForCompany=Factures clients impay
BillsSuppliersUnpayed=Factures fournisseurs impay<61>es
BillsUnpayed=Impay<61>es
BillsStatistics=Statistiques factures
InvoiceStandard=Facture standard
InvoiceStandardAsk=Facture standard
InvoiceStandardDesc=Ce type de facture est la facture traditionnelle. On l'appelle aussi <b>facture de doit</b>.
InvoiceReplacement=Facture de remplacement
InvoiceReplacementAsk=Facture de remplacement de la facture suivante
InvoiceReplacementDesc=La <b>facture de remplacement</b> sert <20> annuler et remplacer une facture existante sur laquelle aucun paiement n'a encore eu lieu.<br>La r<>f<EFBFBD>rence de la facture qui doit <20>tre annul<75>e est obligatoire.
InvoiceAvoir=Facture avoir
InvoiceAvoirAsk=Facture avoir
InvoiceAvoirDesc=La <b>facture d'avoir</b> est une facture n<>gative destin<69>e <20> compenser une facture comportant un montant sup<75>rieur <20> ce qui a <20>t<EFBFBD> ou sera r<>ellement pay<61> (toutes causes possibles).
ReplaceInvoice=Remplace la facture %s
ReplacedByInvoice=Remplac<61>e par la facture %s
CardBill=Fiche facture
Invoice=Facture
Invoices=Factures
@@ -68,6 +79,8 @@ ErrorVATIntraNotConfigured=Num
ErrorNoPaiementModeConfigured=Aucun mode de r<>glement d<>fini
ErrorCreateBankAccount=Cr<43>er un compte bancaire puis aller dans la configuration du module facture pour d<>finir les modes de r<>glement
ErrorBillNotFound=Facture %s inexistante
ErrorInvoiceAlreadyReplaced=Erreur, la facture %s a d<>j<EFBFBD> <20>t<EFBFBD> remplac<61>e
ErrorDiscountAlreadyUsed=Erreur, la remise a d<>j<EFBFBD> <20>t<EFBFBD> attribu<62>e
BillFrom=<3D>metteur
BillTo=Adress<73> <20>
ActionsOnBill=Actions sur la facture
@@ -99,6 +112,7 @@ ValidateBill=Valider facture
NumberOfBills=Nb de factures
NumberOfBillsByMonth=Nb de factures par mois
ShowBill=Afficher facture
ShowInvoice=Afficher facture
ShowPayment=Afficher paiement
File=Fichier
AlreadyPayed=D<>j<EFBFBD> r<>gl<67>

View File

@@ -762,8 +762,8 @@ function img_help($usehelpcursor=1,$usealttitle=1)
$s ='<img ';
if ($usehelpcursor) $s.='style="cursor: help;" ';
$s.='src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/info.png" border="0"';
if ($usealttitle) $s.=' alt="'.$langs->trans("Info").'" title="'.$langs->trans("Info");
$s.='">';
if ($usealttitle) $s.=' alt="'.$langs->trans("Info").'" title="'.$langs->trans("Info").'"';
$s.='>';
return $s;
}