New: task #10969 : Add checkbox to close automatically invoice to "payed"

This commit is contained in:
Laurent Destailleur 2011-03-19 13:59:04 +00:00
parent bcefd7006b
commit 1a3c45faea
7 changed files with 141 additions and 94 deletions

View File

@ -5,6 +5,7 @@ $Id$
***** ChangeLog for 3.1 compared to 3.0 *****
For users:
- New: task #10969 : Add checkbox to close automatically invoice to "payed"
- New: Can edit note of payment.
- New: Login is not mandatory in member module.
- New: Reduce a step into supplier order workflow to save time (if user

View File

@ -419,10 +419,10 @@ class Facture extends CommonObject
/**
* \brief Create a new invoice in database from current invoice
* \param user Object user that ask creation
* \param invertdetail Reverse sign of amounts for lines
* \return int <0 si ko, >0 si ok
* Create a new invoice in database from current invoice
* @param user Object user that ask creation
* @param invertdetail Reverse sign of amounts for lines
* @return int <0 if KO, >0 if OK
*/
function createFromCurrent($user,$invertdetail=0)
{
@ -476,10 +476,10 @@ class Facture extends CommonObject
/**
* \brief Load an object from its id and create a new one in database
* \param fromid Id of object to clone
* \param invertdetail Reverse sign of amounts for lines
* \return int New id of clone
* Load an object from its id and create a new one in database
* @param fromid Id of object to clone
* @param invertdetail Reverse sign of amounts for lines
* @return int New id of clone
*/
function createFromClone($fromid,$invertdetail=0)
{
@ -741,8 +741,8 @@ class Facture extends CommonObject
/**
* \brief Recupere les lignes de factures dans this->lines
* \return int 1 if OK, < 0 if KO
* Recupere les lignes de factures dans this->lines
* @return int 1 if OK, < 0 if KO
*/
function fetch_lines()
{
@ -1203,11 +1203,11 @@ class Facture extends CommonObject
}
/**
* \brief Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED
* \param user Objet utilisateur qui modifie
* \param close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas ecompte par exemple)
* \param close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas ecompte par exemple)
* \return int <0 si ok, >0 si ok
* Tag la facture comme paye completement (close_code non renseigne) ou partiellement (close_code renseigne) + appel trigger BILL_PAYED
* @param user Objet utilisateur qui modifie
* @param close_code Code renseigne si on classe a payee completement alors que paiement incomplet (cas escompte par exemple)
* @param close_note Commentaire renseigne si on classe a payee alors que paiement incomplet (cas escompte par exemple)
* @return int <0 si ok, >0 si ok
*/
function set_paid($user,$close_code='',$close_note='')
{
@ -1686,7 +1686,7 @@ class Facture extends CommonObject
if (empty($txtva)) $txtva=0;
if (empty($txlocaltax1)) $txlocaltax1=0;
if (empty($txlocaltax2)) $txlocaltax2=0;
$remise_percent=price2num($remise_percent);
$qty=price2num($qty);
$pu_ht=price2num($pu_ht);
@ -2227,7 +2227,7 @@ class Facture extends CommonObject
* \param paye Etat paye
* \param statut Id statut
* \param mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
* \param alreadypaid Montant deja paye
* \param alreadypaid Montant deja paye
* \param type Type facture
* \return string Libelle du statut
*/

View File

@ -143,49 +143,59 @@ if ($_POST['action'] == 'confirm_paiement' && $_POST['confirm'] == 'yes')
$datepaye = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
$db->begin();
// Creation of payment line
$paiement = new Paiement($db);
$paiement->datepaye = $datepaye;
$paiement->amounts = $amounts; // Array with all payments dispatching
$paiement->paiementid = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement');
$paiement->num_paiement = $_POST['num_paiement'];
$paiement->note = $_POST['comment'];
if (! $error)
{
$db->begin();
// Creation de la ligne paiement
$paiement = new Paiement($db);
$paiement->datepaye = $datepaye;
$paiement->amounts = $amounts; // Tableau de montant
$paiement->paiementid = dol_getIdFromCode($db,$_POST['paiementcode'],'c_paiement');
$paiement->num_paiement = $_POST['num_paiement'];
$paiement->note = $_POST['comment'];
if (! $error)
$paiement_id = $paiement->create($user,(GETPOST('closepaidinvoices')=='on'?1:0));
if ($paiement_id < 0)
{
$paiement_id = $paiement->create($user);
if ($paiement_id < 0)
{
$errmsg=$paiement->error;
$error++;
}
$errmsg=$paiement->error;
$error++;
}
}
if (! $error)
{
$result=$paiement->addPaymentToBank($user,'payment','(CustomerInvoicePayment)',$_POST['accountid'],$_POST['chqemetteur'],$_POST['chqbank']);
if ($result < 0)
if (! $error)
{
$result=$paiement->addPaymentToBank($user,'payment','(CustomerInvoicePayment)',$_POST['accountid'],$_POST['chqemetteur'],$_POST['chqbank']);
if ($result < 0)
{
$errmsg=$paiement->error;
$error++;
}
}
if (! $error)
{
$db->commit();
// If payment dispatching on more than one invoice, we keep on summary page, otherwise go on invoice card
$invoiceid=0;
foreach ($paiement->amounts as $key => $amount)
{
$facid = $key;
if (is_numeric($amount) && $amount <> 0)
{
$errmsg=$paiement->error;
$error++;
if ($invoiceid != 0) $invoiceid=-1; // There is more than one invoice payed by this payment
else $invoiceid=$facid;
}
}
if (! $error)
{
$db->commit();
$loc = DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$paiement_id;
Header('Location: '.$loc);
exit;
}
else
{
$db->rollback();
}
}
if ($invoiceid > 0) $loc = DOL_URL_ROOT.'/compta/facture.php?facid='.$invoiceid;
else $loc = DOL_URL_ROOT.'/compta/paiement/fiche.php?id='.$paiement_id;
Header('Location: '.$loc);
exit;
}
else
{
$db->rollback();
}
}
@ -197,7 +207,6 @@ if ($_POST['action'] == 'confirm_paiement' && $_POST['confirm'] == 'yes')
llxHeader();
$html=new Form($db);
$facturestatic=new Facture($db);
if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_POST['action'] == 'add_paiement')
@ -256,7 +265,7 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
print '});';
print '</script>'."\n";
}
print '<form name="add_paiement" action="paiement.php" method="post">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="add_paiement">';
@ -264,9 +273,10 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
print '<input type="hidden" name="socid" value="'.$facture->socid.'">';
print '<input type="hidden" name="type" value="'.$facture->type.'">';
print '<input type="hidden" name="thirdpartylabel" id="thirdpartylabel" value="'.dol_escape_htmltag($facture->client->name).'">';
print '<table class="border" width="100%">';
// Third party
print '<tr><td><span class="fieldrequired">'.$langs->trans('Company').'</span></td><td colspan="2">'.$facture->client->getNomUrl(4)."</td></tr>\n";
// Date payment
@ -278,7 +288,7 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
print '<td>'.$langs->trans('Comments').'</td></tr>';
print '<tr><td><span class="fieldrequired">'.$langs->trans('PaymentMode').'</span></td><td>';
$html->select_types_paiements(empty($_POST['paiementcode'])?'':$_POST['paiementcode'],'paiementcode','',2);
$html->select_types_paiements(GETPOST('paiementcode'),'paiementcode','',2);
print "</td>\n";
print '<td rowspan="5" valign="top">';
@ -290,7 +300,7 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
if ($facture->type != 2) print '<td><span class="fieldrequired">'.$langs->trans('AccountToCredit').'</span></td>';
if ($facture->type == 2) print '<td><span class="fieldrequired">'.$langs->trans('AccountToDebit').'</span></td>';
print '<td>';
$html->select_comptes(empty($_POST['accountid'])?'':$_POST['accountid'],'accountid',0,'',2);
$html->select_comptes(GETPOST('accountid'),'accountid',0,'',2);
print '</td>';
}
else
@ -302,17 +312,18 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
print '<tr><td>'.$langs->trans('Numero');
print ' <em>('.$langs->trans("ChequeOrTransferNumber").')</em>';
print '</td>';
print '<td><input name="num_paiement" type="text" value="'.(empty($_POST['num_paiement'])?'':$_POST['num_paiement']).'"></td></tr>';
print '<td><input name="num_paiement" type="text" value="'.GETPOST('num_paiement').'"></td></tr>';
print '<tr><td class="fieldrequireddyn">'.$langs->trans('CheckTransmitter');
// Check transmitter
print '<tr><td class="'.(GETPOST('paiementcode')=='CHQ'?'fieldrequired ':'').'fieldrequireddyn">'.$langs->trans('CheckTransmitter');
print ' <em>('.$langs->trans("ChequeMaker").')</em>';
print '</td>';
print '<td><input id="fieldchqemetteur" name="chqemetteur" size="30" type="text" value="'.(empty($_POST['chqemetteur'])?'':$_POST['chqemetteur']).'"></td></tr>';
print '<td><input id="fieldchqemetteur" name="chqemetteur" size="30" type="text" value="'.GETPOST('chqemetteur').'"></td></tr>';
print '<tr><td>'.$langs->trans('Bank');
print ' <em>('.$langs->trans("ChequeBank").')</em>';
print '</td>';
print '<td><input name="chqbank" size="30" type="text" value="'.(empty($_POST['chqbank'])?'':$_POST['chqbank']).'"></td></tr>';
print '<td><input name="chqbank" size="30" type="text" value="'.GETPOST('chqbank').'"></td></tr>';
print '</table>';
@ -366,17 +377,18 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
$objp = $db->fetch_object($resql);
$var=!$var;
$facturestatic->ref=$objp->facnumber;
$facturestatic->id=$objp->facid;
$facturestatic->type=$objp->type;
$creditnotes=$facturestatic->getSumCreditNotesUsed();
$deposits=$facturestatic->getSumDepositsUsed();
$invoice=new Facture($db);
$invoice->fetch($objp->facid);
$paiement = $invoice->getSommePaiement();
$creditnotes=$invoice->getSumCreditNotesUsed();
$deposits=$invoice->getSumDepositsUsed();
$alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
$remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
print '<tr '.$bc[$var].'>';
print '<td>';
print $facturestatic->getNomUrl(1,'');
print $invoice->getNomUrl(1,'');
print "</td>\n";
// Date
@ -386,14 +398,13 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
print '<td align="right">'.price($objp->total_ttc).'</td>';
// Recu
$paiement = $facturestatic->getSommePaiement();
print '<td align="right">'.price($paiement);
if ($creditnotes) print '+'.price($creditnotes);
if ($deposits) print '+'.price($deposits);
print '</td>';
// Remain to pay
print '<td align="right">'.price(price2num($objp->total_ttc - $paiement - $creditnotes - $deposits,'MT')).'</td>';
print '<td align="right">'.price($remaintopay).'</td>';
// Amount
print '<td align="right">';
@ -411,7 +422,7 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
// Warning
print '<td align="center" width="16">';
if ($amounts[$facturestatic->id] && $amounts[$facturestatic->id] > $amountsresttopay[$facturestatic->id])
if ($amounts[$invoice->id] && $amounts[$invoice->id] > $amountsresttopay[$invoice->id])
{
print ' '.img_warning($langs->trans("PaymentHigherThanReminderToPay"));
}
@ -457,7 +468,8 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
if ($_POST["action"] != 'add_paiement')
{
// print '<tr><td colspan="3" align="center">';
print '<br><center><input type="submit" class="button" value="'.$langs->trans('Save').'"></center>';
print '<center><br><input type="checkbox" checked="checked" name="closepaidinvoices"> '.$langs->trans("ClosePaidInvoicesAutomatically");
print '<br><input type="submit" class="button" value="'.$langs->trans('Save').'"></center>';
// print '</td></tr>';
}
@ -476,6 +488,11 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
print '<br>';
$text=$langs->trans('ConfirmCustomerPayment',$totalpaiement,$langs->trans("Currency".$conf->monnaie));
if (GETPOST('closepaidinvoices'))
{
$text.='<br>'.$langs->trans("AllCompletelyPayedInvoiceWillBeClosed");
print '<input type="hidden" name="closepaidinvoices" value="'.GETPOST('closepaidinvoices').'">';
}
$html->form_confirm($_SERVER['PHP_SELF'].'?facid='.$facture->id.'&socid='.$facture->socid.'&type='.$facture->type,$langs->trans('ReceivedCustomersPayments'),$text,'confirm_paiement',$formquestion,$preselectedchoice);
}
@ -485,9 +502,9 @@ if ($_GET['action'] == 'create' || $_POST['action'] == 'confirm_paiement' || $_P
/**
* \brief Affichage de la liste des paiements
* Show list of payments
*/
if (! $_GET['action'] && ! $_POST['action'])
if (! GETPOST('action'))
{
if ($page == -1) $page = 0 ;
$limit = $conf->liste_limit;

View File

@ -123,10 +123,11 @@ class Paiement extends CommonObject
/**
* Create payment of invoices into database.
* Use this->amounts to have list of invoices for the payment
* @param user object user
* @return int id of created payment, < 0 if error
* @param user object user
* @param closepaidinvoices 1=Also close payed invoices to paid, 0=Do nothing more
* @return int id of created payment, < 0 if error
*/
function create($user)
function create($user,$closepaidinvoices=0)
{
global $langs,$conf;
@ -159,7 +160,7 @@ class Paiement extends CommonObject
{
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'paiement');
// Insere liens montants / factures
// Insert links amount / invoices
foreach ($this->amounts as $key => $amount)
{
$facid = $key;
@ -171,7 +172,26 @@ class Paiement extends CommonObject
dol_syslog(get_class($this).'::Create Amount line '.$key.' insert paiement_facture sql='.$sql);
$resql=$this->db->query($sql);
if (! $resql)
if ($resql)
{
if ($closepaidinvoices)
{
$invoice=new Facture($this->db);
$invoice->fetch($facid);
$paiement = $invoice->getSommePaiement();
$creditnotes=$invoice->getSumCreditNotesUsed();
$deposits=$invoice->getSumDepositsUsed();
$alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
$remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
if ($remaintopay == 0)
{
$result=$invoice->set_paid($user,'','');
}
else dol_syslog("Remain to pay for invoice ".$facid." not null. We do nothing.");
}
}
else
{
$this->error=$this->db->lasterror();
dol_syslog(get_class($this).'::Create insert paiement_facture error='.$this->error, LOG_ERR);

View File

@ -252,28 +252,32 @@ if ($resql)
print '<td>'.$langs->trans('Bill').'</td>';
print '<td>'.$langs->trans('Company').'</td>';
print '<td align="right">'.$langs->trans('ExpectedToPay').'</td>';
print '<td align="center">'.$langs->trans('Status').'</td>';
print '<td align="right">'.$langs->trans('PayedByThisPayment').'</td>';
print '<td align="right">'.$langs->trans('PayedByThisPayment').'</td>';
print '<td align="right">'.$langs->trans('RemainderToPay').'</td>';
print '<td align="right">'.$langs->trans('Status').'</td>';
print "</tr>\n";
if ($num > 0)
{
$var=True;
$facturestatic=new Facture($db);
while ($i < $num)
{
$objp = $db->fetch_object($resql);
$var=!$var;
print '<tr '.$bc[$var].'>';
// Invoice
$invoice=new Facture($db);
$invoice->fetch($objp->facid);
$paiement = $invoice->getSommePaiement();
$creditnotes=$invoice->getSumCreditNotesUsed();
$deposits=$invoice->getSumDepositsUsed();
$alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
$remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
// Invoice
print '<td>';
$facturestatic->id=$objp->facid;
$facturestatic->ref=$objp->facnumber;
$facturestatic->type=$objp->type;
print $facturestatic->getNomUrl(1);
print $invoice->getNomUrl(1);
print "</td>\n";
// Third party
@ -286,11 +290,14 @@ if ($resql)
// Expected to pay
print '<td align="right">'.price($objp->total_ttc).'</td>';
// Statut
print '<td align="center">'.$facturestatic->LibStatut($objp->paye,$objp->fk_statut,2,1).'</td>';
// Amount payed
print '<td align="right">'.price($objp->amount).'</td>';
// Amount payed
print '<td align="right">'.price($objp->amount).'</td>';
// Remain to pay
print '<td align="right">'.price($remaintopay).'</td>';
// Status
print '<td align="right">'.$invoice->getLibStatut(5, $alreadypayed).'</td>';
print "</tr>\n";
if ($objp->paye == 1) // If at least one invoice is paid, disable delete

View File

@ -367,6 +367,7 @@ CantRemovePaymentWithOneInvoicePaid=Can't remove payment since there is at least
ExpectedToPay=Expected payment
PayedByThisPayment=Payed by this payment
ClosePaidInvoicesAutomatically=Classify "Payed" all invoices entierely payed.
AllCompletelyPayedInvoiceWillBeClosed=All invoice with no remain to pay will be automatically closed to status "Payed".
##### Types de contacts #####
TypeContact_facture_internal_SALESREPFOLL=Representative following-up customer invoice
TypeContact_facture_external_BILLING=Customer invoice contact

View File

@ -366,7 +366,8 @@ DisabledBecausePayments=Non disponible car il existe des paiements
CantRemovePaymentWithOneInvoicePaid=Suppression impossible quand il existe au moins une facture classée payée.
ExpectedToPay=Paiement attendu
PayedByThisPayment=Règlé par ce paiement
ClosePaidInvoicesAutomatically=Classer automatiquement à "Payé" les factures entièrement payés.
ClosePaidInvoicesAutomatically=Classer automatiquement à "Payé" les factures entièrement payées.
AllCompletelyPayedInvoiceWillBeClosed=Toutes les factures avec un reste à payer nul seront automatiquement fermées au statut "Payé".
##### Types de contacts #####
TypeContact_facture_internal_SALESREPFOLL=Responsable suivi facture client
TypeContact_facture_external_BILLING=Contact client facturation