From e3142fff39325431eb3379596d2c840e9a9dd963 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Apr 2018 11:38:31 +0200 Subject: [PATCH] NEW Add method to register distributed payments on invoices --- .../facture/class/api_invoices.class.php | 219 +++++++++++++++--- 1 file changed, 181 insertions(+), 38 deletions(-) diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index a8c29a76754..35f7e966104 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -569,7 +569,7 @@ class Invoices extends DolibarrApi * @param int $fk_socpeople Id of thirdparty contact (if source = 'external') or id of user (if souce = 'internal') to link * @param string $type_contact Type of contact (code). Must a code found into table llx_c_type_contact. For example: BILLING * @param string $source external=Contact extern (llx_socpeople), internal=Contact intern (llx_user) - * @param int $notrigger Disable all triggers + * @param int $notrigger Disable all triggers * * @url POST {id}/contacts * @@ -952,14 +952,13 @@ class Invoices extends DolibarrApi return $result; } - /** - * Add payment line to a specific invoice + + /** + * Add payment line to a specific invoice with the remain to pay as amount. * - * The model schema is defined by the PaymentData class. - * - * @param array $ids {@from body} Id of invoice {@type int} - * @param string $datepaye {@from body} Payment date {@type timestamp} - * @param int $paiementid {@from body} Payment mode Id {@min 1} + * @param int $id Id of invoice + * @param string $datepaye {@from body} Payment date {@type timestamp} + * @param int $paiementid {@from body} Payment mode Id {@min 1} * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} * @param int $accountid {@from body} Account Id {@min 1} * @param string $num_paiement {@from body} Payment number (optional) @@ -967,44 +966,186 @@ class Invoices extends DolibarrApi * @param string $chqemetteur {@from body} Payment issuer (mandatory if paiementcode = 'CHQ') * @param string $chqbank {@from body} Issuer bank name (optional) * - * @url POST /payments + * @url POST {id}/payments * * @return int Payment ID * @throws 400 * @throws 401 * @throws 404 */ - function addPayment($ids, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement='', $comment='', $chqemetteur='', $chqbank='') { + function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement='', $comment='', $chqemetteur='', $chqbank='') { + global $conf; + + require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; + + if(! DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(403); + } + if(empty($id)) { + throw new RestException(400, 'Invoice ID is mandatory'); + } + + if( ! DolibarrApi::_checkAccessToResource('facture',$id)) { + throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if (! empty($conf->banque->enabled)) { + if(empty($accountid)) { + throw new RestException(400, 'Account ID is mandatory'); + } + } + + if(empty($paiementid)) { + throw new RestException(400, 'Paiement ID or Paiement Code is mandatory'); + } + + + $result = $this->invoice->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Invoice not found'); + } + + // Calculate amount to pay + $totalpaye = $this->invoice->getSommePaiement(); + $totalcreditnotes = $this->invoice->getSumCreditNotesUsed(); + $totaldeposits = $this->invoice->getSumDepositsUsed(); + $resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + + $this->db->begin(); + + $amounts = array(); + $multicurrency_amounts = array(); + + // Clean parameters amount if payment is for a credit note + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { + $resteapayer = price2num($resteapayer,'MT'); + $amounts[$id] = -$resteapayer; + // Multicurrency + $newvalue = price2num($this->invoice->multicurrency_total_ttc,'MT'); + $multicurrency_amounts[$id] = -$newvalue; + } else { + $resteapayer = price2num($resteapayer,'MT'); + $amounts[$id] = $resteapayer; + // Multicurrency + $newvalue = price2num($this->invoice->multicurrency_total_ttc,'MT'); + $multicurrency_amounts[$id] = $newvalue; + } + + + // Creation of payment line + $paiement = new Paiement($this->db); + $paiement->datepaye = $datepaye; + $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id + $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching + $paiement->paiementid = $paiementid; + $paiement->paiementcode = dol_getIdFromCode($this->db,$paiementid,'c_paiement','id','code',1); + $paiement->num_paiement = $num_paiement; + $paiement->note = $comment; + + $paiement_id = $paiement->create(DolibarrApiAccess::$user, ($closepaidinvoices=='yes'?1:0)); // This include closing invoices + if ($paiement_id < 0) + { + $this->db->rollback(); + throw new RestException(400, 'Payment error : '.$paiement->error); + } + + if (! empty($conf->banque->enabled)) { + $label='(CustomerInvoicePayment)'; + + if($paiement->paiementcode == 'CHQ' && empty($chqemetteur)) { + throw new RestException(400, 'Emetteur is mandatory when payment code is '.$paiement->paiementcode); + } + if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) $label='(CustomerInvoicePaymentBack)'; // Refund of a credit note + $result=$paiement->addPaymentToBank(DolibarrApiAccess::$user,'payment',$label,$accountid,$chqemetteur,$chqbank); + if ($result < 0) + { + $this->db->rollback(); + throw new RestException(400, 'Add payment to bank error : '.$paiement->error); + } + } + + $this->db->commit(); + + return $paiement_id; + } + + /** + * Add a payment to pay partially or completely one or several invoices. + * Warning: Take care that all invoices are owned by the same customer. + * + * @param array $arrayofamounts {@from body} Array with id of invoices with amount to pay for each invoice. Example {"1": "99.99", "2": "10"} + * @param string $datepaye {@from body} Payment date {@type timestamp} + * @param int $paiementid {@from body} Payment mode Id {@min 1} + * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} + * @param int $accountid {@from body} Account Id {@min 1} + * @param string $num_paiement {@from body} Payment number (optional) + * @param string $comment {@from body} Note (optional) + * @param string $chqemetteur {@from body} Payment issuer (mandatory if paiementcode = 'CHQ') + * @param string $chqbank {@from body} Issuer bank name (optional) + * + * @url POST /paymentsdistributed + * + * @return int Payment ID + * @throws 400 + * @throws 401 + * @throws 403 + * @throws 404 + */ + function addPaymentDistributed($arrayofamounts, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement='', $comment='', $chqemetteur='', $chqbank='') + { global $conf; + require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; + if(! DolibarrApiAccess::$user->rights->facture->creer) { - throw new RestException(401); + throw new RestException(403); } - foreach($ids as $id) { - if(empty($id)) { - throw new RestException(400, 'Invoice ID is mandatory'); - } - if( ! DolibarrApi::_checkAccessToResource('facture',$id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - $request_data = (object) $payment_data; - if (! empty($conf->banque->enabled)) { - if(empty($accountid)) { - throw new RestException(400, 'Account ID is mandatory'); - } - } - if(empty($paiementid)) { - throw new RestException(400, 'Paiement ID or Paiement Code is mandatory'); - } - $result = $this->invoice->fetch($id); - if( ! $result ) { - throw new RestException(404, 'Invoice not found'); - } - // Calculate amount to pay - $totalpaye = $this->invoice->getSommePaiement(); - $totalcreditnotes = $this->invoice->getSumCreditNotesUsed(); - $totaldeposits = $this->invoice->getSumDepositsUsed(); - $resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + foreach($arrayofamounts as $id => $amount) { + if(empty($id)) { + throw new RestException(400, 'Invoice ID is mandatory. Fill the invoice id and amount into arrayofamounts parameter. For example: {"1": "99.99", "2": "10"}'); + } + if( ! DolibarrApi::_checkAccessToResource('facture',$id)) { + throw new RestException(403, 'Access not allowed on invoice ID '.$id.' for login '.DolibarrApiAccess::$user->login); + } + } + + if (! empty($conf->banque->enabled)) { + if(empty($accountid)) { + throw new RestException(400, 'Account ID is mandatory'); + } + } + if(empty($paiementid)) { + throw new RestException(400, 'Paiement ID or Paiement Code is mandatory'); + } + + $this->db->begin(); + + $amounts = array(); + $multicurrency_amounts = array(); + + // Loop on each invoice to pay + foreach($arrayofamounts as $id => $amount) + { + $result = $this->invoice->fetch($id); + if( ! $result ) { + $this->db->rollback(); + throw new RestException(404, 'Invoice ID '.$id.' not found'); + } + + // Calculate amount to pay + $totalpaye = $this->invoice->getSommePaiement(); + $totalcreditnotes = $this->invoice->getSumCreditNotesUsed(); + $totaldeposits = $this->invoice->getSumDepositsUsed(); + $resteapayer = price2num($this->invoice->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + if ($amount != 'remain') + { + if ($amount > $resteapayer) + { + $this->db->rollback(); + throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$resteapayer.')'); + } + $resteapayer = $amount; + } // Clean parameters amount if payment is for a credit note if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) { $resteapayer = price2num($resteapayer,'MT'); @@ -1019,8 +1160,8 @@ class Invoices extends DolibarrApi $newvalue = price2num($this->invoice->multicurrency_total_ttc,'MT'); $multicurrency_amounts[$id] = $newvalue; } - } - $this->db->begin(); + } + // Creation of payment line $paiement = new Paiement($this->db); $paiement->datepaye = $datepaye; @@ -1049,7 +1190,9 @@ class Invoices extends DolibarrApi throw new RestException(400, 'Add payment to bank error : '.$paiement->error); } } + $this->db->commit(); + return $paiement_id; }