Total Complexity | 198 |
Total Lines | 1419 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like Paiement often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Paiement, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
48 | class Paiement extends CommonObject |
||
49 | { |
||
50 | /** |
||
51 | * @var string ID to identify managed object |
||
52 | */ |
||
53 | public $element = 'payment'; |
||
54 | |||
55 | /** |
||
56 | * @var string Name of table without prefix where object is stored |
||
57 | */ |
||
58 | public $table_element = 'paiement'; |
||
59 | |||
60 | /** |
||
61 | * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png |
||
62 | */ |
||
63 | public $picto = 'payment'; |
||
64 | |||
65 | /** |
||
66 | * @var int Invoice ID |
||
67 | */ |
||
68 | public $facid; |
||
69 | |||
70 | /** |
||
71 | * @var int Company ID |
||
72 | */ |
||
73 | public $socid; |
||
74 | |||
75 | /** |
||
76 | * @var int|string |
||
77 | */ |
||
78 | public $datepaye; |
||
79 | |||
80 | /** |
||
81 | * @var int|string same than $datepaye |
||
82 | */ |
||
83 | public $date; |
||
84 | |||
85 | /** |
||
86 | * @deprecated |
||
87 | * @see $amount, $amounts |
||
88 | */ |
||
89 | public $total; |
||
90 | |||
91 | /** |
||
92 | * @deprecated |
||
93 | * @see $amount, $amounts |
||
94 | */ |
||
95 | public $montant; |
||
96 | |||
97 | /** |
||
98 | * @var float Total amount of payment (in the main currency) |
||
99 | */ |
||
100 | public $amount; |
||
101 | |||
102 | /** |
||
103 | * @var float Total amount of payment (in the currency of the bank account) |
||
104 | */ |
||
105 | public $multicurrency_amount; |
||
106 | |||
107 | /** |
||
108 | * @var float[] array: invoice ID => amount for that invoice (in the main currency) |
||
109 | */ |
||
110 | public $amounts = array(); |
||
111 | |||
112 | /** |
||
113 | * @var float[] array: invoice ID => amount for that invoice (in the invoice's currency) |
||
114 | */ |
||
115 | public $multicurrency_amounts = array(); |
||
116 | |||
117 | /** |
||
118 | * @var float[] Multicurrency rate (array: invoice ID => currency rate ("taux" in French) for that invoice) |
||
119 | */ |
||
120 | public $multicurrency_tx = array(); |
||
121 | |||
122 | /** |
||
123 | * @var string[] Multicurrency code (array: invoice ID => currency code for that invoice) |
||
124 | */ |
||
125 | public $multicurrency_code = array(); |
||
126 | |||
127 | /** |
||
128 | * @var float Excess received in TakePOS cash payment |
||
129 | */ |
||
130 | public $pos_change = 0.0; |
||
131 | |||
132 | public $author; |
||
133 | |||
134 | /** |
||
135 | * @var int ID of mode of payment. Is saved into fields fk_paiement on llx_paiement = id of llx_c_paiement. Can get value from code using ... |
||
136 | */ |
||
137 | public $paiementid; |
||
138 | |||
139 | /** |
||
140 | * @var string Code of mode of payment. |
||
141 | */ |
||
142 | public $paiementcode; |
||
143 | |||
144 | /** |
||
145 | * @var string Type of payment label |
||
146 | */ |
||
147 | public $type_label; |
||
148 | |||
149 | /** |
||
150 | * @var string Type of payment code (seems duplicate with $paiementcode); |
||
151 | */ |
||
152 | public $type_code; |
||
153 | |||
154 | /** |
||
155 | * @var string |
||
156 | * @deprecated |
||
157 | * @see $num_payment |
||
158 | */ |
||
159 | public $num_paiement; |
||
160 | |||
161 | /** |
||
162 | * @var string Payment reference |
||
163 | * (Cheque or bank transfer reference. Can be "ABC123") |
||
164 | */ |
||
165 | public $num_payment; |
||
166 | |||
167 | /** |
||
168 | * @var string Id of external payment mode |
||
169 | */ |
||
170 | public $ext_payment_id; |
||
171 | |||
172 | /** |
||
173 | * @var string Id of prelevement |
||
174 | */ |
||
175 | public $id_prelevement; |
||
176 | |||
177 | /** |
||
178 | * @var string num_prelevement |
||
179 | */ |
||
180 | public $num_prelevement; |
||
181 | |||
182 | /** |
||
183 | * @var string Name of external payment mode |
||
184 | */ |
||
185 | public $ext_payment_site; |
||
186 | |||
187 | /** |
||
188 | * @var int bank account id of payment |
||
189 | * @deprecated |
||
190 | * @see $fk_account |
||
191 | */ |
||
192 | public $bank_account; |
||
193 | |||
194 | /** |
||
195 | * @var int bank account id of payment |
||
196 | */ |
||
197 | public $fk_account; |
||
198 | |||
199 | /** |
||
200 | * @var int id of payment line in bank account |
||
201 | */ |
||
202 | public $bank_line; |
||
203 | |||
204 | // fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...) |
||
205 | // fk_paiement dans llx_paiement_facture est le rowid du paiement |
||
206 | /** |
||
207 | * @var int payment id |
||
208 | */ |
||
209 | public $fk_paiement; // Type of payment |
||
210 | |||
211 | /** |
||
212 | * @var string payment external reference |
||
213 | */ |
||
214 | public $ref_ext; |
||
215 | |||
216 | |||
217 | /** |
||
218 | * Constructor |
||
219 | * |
||
220 | * @param DoliDB $db Database handler |
||
|
|||
221 | */ |
||
222 | public function __construct($db) |
||
223 | { |
||
224 | $this->db = $db; |
||
225 | } |
||
226 | |||
227 | /** |
||
228 | * Load payment from database |
||
229 | * |
||
230 | * @param int $id Id of payment to get |
||
231 | * @param string $ref Ref of payment to get (currently ref = id but this may change in future) |
||
232 | * @param int $fk_bank Id of bank line associated to payment |
||
233 | * @return int Return integer <0 if KO, 0 if not found, >0 if OK |
||
234 | */ |
||
235 | public function fetch($id, $ref = '', $fk_bank = 0) |
||
236 | { |
||
237 | $sql = 'SELECT p.rowid, p.ref, p.ref_ext, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank, p.multicurrency_amount,'; |
||
238 | $sql .= ' c.code as type_code, c.libelle as type_label,'; |
||
239 | $sql .= ' p.num_paiement as num_payment, p.note,'; |
||
240 | $sql .= ' b.fk_account'; |
||
241 | $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement as p LEFT JOIN ' . MAIN_DB_PREFIX . 'c_paiement as c ON p.fk_paiement = c.id'; |
||
242 | $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank as b ON p.fk_bank = b.rowid'; |
||
243 | $sql .= ' WHERE p.entity IN (' . getEntity('invoice') . ')'; |
||
244 | if ($id > 0) { |
||
245 | $sql .= ' AND p.rowid = ' . ((int) $id); |
||
246 | } elseif ($ref) { |
||
247 | $sql .= " AND p.ref = '" . $this->db->escape($ref) . "'"; |
||
248 | } elseif ($fk_bank) { |
||
249 | $sql .= ' AND p.fk_bank = ' . ((int) $fk_bank); |
||
250 | } |
||
251 | |||
252 | $resql = $this->db->query($sql); |
||
253 | if ($resql) { |
||
254 | if ($this->db->num_rows($resql)) { |
||
255 | $obj = $this->db->fetch_object($resql); |
||
256 | |||
257 | $this->id = $obj->rowid; |
||
258 | $this->ref = $obj->ref ? $obj->ref : $obj->rowid; |
||
259 | $this->ref_ext = $obj->ref_ext; |
||
260 | $this->date = $this->db->jdate($obj->dp); |
||
261 | $this->datepaye = $this->db->jdate($obj->dp); |
||
262 | $this->num_payment = $obj->num_payment; |
||
263 | $this->montant = $obj->amount; // deprecated |
||
264 | $this->amount = $obj->amount; |
||
265 | $this->multicurrency_amount = $obj->multicurrency_amount; |
||
266 | $this->note = $obj->note; |
||
267 | $this->note_private = $obj->note; |
||
268 | $this->type_label = $obj->type_label; |
||
269 | $this->type_code = $obj->type_code; |
||
270 | $this->statut = $obj->statut; |
||
271 | $this->ext_payment_id = $obj->ext_payment_id; |
||
272 | $this->ext_payment_site = $obj->ext_payment_site; |
||
273 | |||
274 | $this->bank_account = $obj->fk_account; // deprecated |
||
275 | $this->fk_account = $obj->fk_account; |
||
276 | $this->bank_line = $obj->fk_bank; |
||
277 | |||
278 | $this->db->free($resql); |
||
279 | return 1; |
||
280 | } else { |
||
281 | $this->db->free($resql); |
||
282 | return 0; |
||
283 | } |
||
284 | } else { |
||
285 | dol_print_error($this->db); |
||
286 | return -1; |
||
287 | } |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * Create payment of invoices into database. |
||
292 | * Use this->amounts to have list of invoices for the payment. |
||
293 | * For payment of a customer invoice, amounts are positive, for payment of credit note, amounts are negative |
||
294 | * |
||
295 | * @param User $user Object user |
||
296 | * @param int $closepaidinvoices 1=Also close paid invoices to paid, 0=Do nothing more |
||
297 | * @param Societe $thirdparty Thirdparty |
||
298 | * @return int id of created payment, < 0 if error |
||
299 | */ |
||
300 | public function create($user, $closepaidinvoices = 0, $thirdparty = null) |
||
301 | { |
||
302 | global $conf, $langs; |
||
303 | |||
304 | $error = 0; |
||
305 | $way = $this->getWay(); // 'dolibarr' to use amount, 'customer' to use foreign multicurrency amount |
||
306 | |||
307 | $now = dol_now(); |
||
308 | |||
309 | // Clean parameters |
||
310 | $totalamount = 0; |
||
311 | $totalamount_converted = 0; |
||
312 | $atleastonepaymentnotnull = 0; |
||
313 | |||
314 | if ($way == 'dolibarr') { // Payments were entered into the column of main currency |
||
315 | $amounts = &$this->amounts; |
||
316 | $amounts_to_update = &$this->multicurrency_amounts; |
||
317 | } else { // Payments were entered into the column of foreign currency |
||
318 | $amounts = &$this->multicurrency_amounts; |
||
319 | $amounts_to_update = &$this->amounts; |
||
320 | } |
||
321 | |||
322 | $currencyofpayment = ''; |
||
323 | $currencytxofpayment = ''; |
||
324 | |||
325 | foreach ($amounts as $key => $value) { // How payment is dispatched |
||
326 | if (empty($value)) { |
||
327 | continue; |
||
328 | } |
||
329 | // $key is id of invoice, $value is amount, $way is a 'dolibarr' if amount is in main currency, 'customer' if in foreign currency |
||
330 | $value_converted = MultiCurrency::getAmountConversionFromInvoiceRate($key, $value, $way); |
||
331 | // Add controls of input validity |
||
332 | if ($value_converted === false) { |
||
333 | // We failed to find the conversion for one invoice |
||
334 | $this->error = $langs->trans('FailedToFoundTheConversionRateForInvoice'); |
||
335 | return -1; |
||
336 | } |
||
337 | if (empty($currencyofpayment)) { |
||
338 | $currencyofpayment = isset($this->multicurrency_code[$key]) ? $this->multicurrency_code[$key] : ""; |
||
339 | } elseif ($currencyofpayment != $this->multicurrency_code[$key]) { |
||
340 | // If we have invoices with different currencies in the payment, we stop here |
||
341 | $this->error = 'ErrorYouTryToPayInvoicesWithDifferentCurrenciesInSamePayment'; |
||
342 | return -1; |
||
343 | } |
||
344 | if (empty($currencytxofpayment)) { |
||
345 | $currencytxofpayment = isset($this->multicurrency_tx[$key]) ? $this->multicurrency_tx[$key] : ""; |
||
346 | } |
||
347 | |||
348 | $totalamount_converted += $value_converted; |
||
349 | $amounts_to_update[$key] = price2num($value_converted, 'MT'); |
||
350 | |||
351 | $newvalue = price2num($value, 'MT'); |
||
352 | $amounts[$key] = $newvalue; |
||
353 | $totalamount += $newvalue; |
||
354 | if (!empty($newvalue)) { |
||
355 | $atleastonepaymentnotnull++; |
||
356 | } |
||
357 | } |
||
358 | |||
359 | if (empty($currencyofpayment)) { // Should not happen. For the case the multicurrency_code was not saved into invoices |
||
360 | $currencyofpayment = $conf->currency; |
||
361 | } |
||
362 | |||
363 | if (!empty($currencyofpayment)) { |
||
364 | // We must check that the currency of invoices is the same than the currency of the bank |
||
365 | $bankaccount = new Account($this->db); |
||
366 | $bankaccount->fetch($this->fk_account); |
||
367 | $bankcurrencycode = empty($bankaccount->currency_code) ? $conf->currency : $bankaccount->currency_code; |
||
368 | if ($currencyofpayment != $bankcurrencycode && $currencyofpayment != $conf->currency && $bankcurrencycode != $conf->currency) { |
||
369 | $langs->load("errors"); |
||
370 | $this->error = $langs->trans('ErrorYouTryToPayInvoicesInACurrencyFromBankWithAnotherCurrency', $currencyofpayment, $bankcurrencycode); |
||
371 | return -1; |
||
372 | } |
||
373 | } |
||
374 | |||
375 | |||
376 | $totalamount = (float) price2num($totalamount); |
||
377 | $totalamount_converted = (float) price2num($totalamount_converted); |
||
378 | |||
379 | // Check parameters |
||
380 | if (empty($totalamount) && empty($atleastonepaymentnotnull)) { // We accept negative amounts for withdraw reject but not empty arrays |
||
381 | $this->errors[] = 'TotalAmountEmpty'; |
||
382 | $this->error = $langs->trans('TotalAmountEmpty'); |
||
383 | return -1; |
||
384 | } |
||
385 | |||
386 | dol_syslog(get_class($this) . "::create insert paiement (closepaidinvoices = " . $closepaidinvoices . ")", LOG_DEBUG); |
||
387 | |||
388 | $this->db->begin(); |
||
389 | |||
390 | $this->ref = $this->getNextNumRef(is_object($thirdparty) ? $thirdparty : ''); |
||
391 | |||
392 | if (empty($this->ref_ext)) { |
||
393 | $this->ref_ext = ''; |
||
394 | } |
||
395 | |||
396 | if ($way == 'dolibarr') { |
||
397 | $total = $totalamount; |
||
398 | $mtotal = $totalamount_converted; |
||
399 | } else { |
||
400 | $total = $totalamount_converted; |
||
401 | $mtotal = $totalamount; |
||
402 | } |
||
403 | |||
404 | $num_payment = $this->num_payment; |
||
405 | $note = ($this->note_private ? $this->note_private : $this->note); |
||
406 | |||
407 | $sql = "INSERT INTO " . MAIN_DB_PREFIX . "paiement (entity, ref, ref_ext, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat, pos_change)"; |
||
408 | $sql .= " VALUES (" . ((int) $conf->entity) . ", '" . $this->db->escape($this->ref) . "', '" . $this->db->escape($this->ref_ext) . "', '" . $this->db->idate($now) . "', '" . $this->db->idate($this->datepaye) . "', " . ((float) $total) . ", " . ((float) $mtotal) . ", " . ((int) $this->paiementid) . ", "; |
||
409 | $sql .= "'" . $this->db->escape($num_payment) . "', '" . $this->db->escape($note) . "', " . ($this->ext_payment_id ? "'" . $this->db->escape($this->ext_payment_id) . "'" : "null") . ", " . ($this->ext_payment_site ? "'" . $this->db->escape($this->ext_payment_site) . "'" : "null") . ", " . ((int) $user->id) . ", " . ((float) $this->pos_change) . ")"; |
||
410 | |||
411 | $resql = $this->db->query($sql); |
||
412 | if ($resql) { |
||
413 | $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . 'paiement'); |
||
414 | |||
415 | // Insert links amount / invoices |
||
416 | foreach ($this->amounts as $key => $amount) { |
||
417 | $facid = $key; |
||
418 | if (is_numeric($amount) && $amount != 0) { |
||
419 | $amount = price2num($amount); |
||
420 | $sql = "INSERT INTO " . MAIN_DB_PREFIX . "paiement_facture (fk_facture, fk_paiement, amount, multicurrency_amount, multicurrency_code, multicurrency_tx)"; |
||
421 | $sql .= " VALUES (" . ((int) $facid) . ", " . ((int) $this->id) . ", " . ((float) $amount) . ", " . ((float) $this->multicurrency_amounts[$key]) . ", " . ($currencyofpayment ? "'" . $this->db->escape($currencyofpayment) . "'" : 'NULL') . ", " . (!empty($this->multicurrency_tx) ? (float) $currencytxofpayment : 1) . ")"; |
||
422 | |||
423 | dol_syslog(get_class($this) . '::create Amount line ' . $key . ' insert paiement_facture', LOG_DEBUG); |
||
424 | $resql = $this->db->query($sql); |
||
425 | if ($resql) { |
||
426 | $invoice = new Facture($this->db); |
||
427 | $invoice->fetch($facid); |
||
428 | |||
429 | // If we want to closed paid invoices |
||
430 | if ($closepaidinvoices) { |
||
431 | $paiement = $invoice->getSommePaiement(); |
||
432 | $creditnotes = $invoice->getSumCreditNotesUsed(); |
||
433 | $deposits = $invoice->getSumDepositsUsed(); |
||
434 | $alreadypayed = price2num($paiement + $creditnotes + $deposits, 'MT'); |
||
435 | $remaintopay = price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT'); |
||
436 | |||
437 | //var_dump($invoice->total_ttc.' - '.$paiement.' -'.$creditnotes.' - '.$deposits.' - '.$remaintopay);exit; |
||
438 | |||
439 | //Invoice types that are eligible for changing status to paid |
||
440 | $affected_types = array( |
||
441 | Facture::TYPE_STANDARD, |
||
442 | Facture::TYPE_REPLACEMENT, |
||
443 | Facture::TYPE_CREDIT_NOTE, |
||
444 | Facture::TYPE_DEPOSIT, |
||
445 | Facture::TYPE_SITUATION |
||
446 | ); |
||
447 | |||
448 | if (!in_array($invoice->type, $affected_types)) { |
||
449 | dol_syslog("Invoice " . $facid . " is not a standard, nor replacement invoice, nor credit note, nor deposit invoice, nor situation invoice. We do nothing more."); |
||
450 | } elseif ($remaintopay) { |
||
451 | // hook to have an option to automatically close a closable invoice with less payment than the total amount (e.g. agreed cash discount terms) |
||
452 | global $hookmanager; |
||
453 | $hookmanager->initHooks(array('paymentdao')); |
||
454 | $parameters = array('facid' => $facid, 'invoice' => $invoice, 'remaintopay' => $remaintopay); |
||
455 | $action = 'CLOSEPAIDINVOICE'; |
||
456 | $reshook = $hookmanager->executeHooks('createPayment', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks |
||
457 | if ($reshook < 0) { |
||
458 | $this->errors[] = $hookmanager->error; |
||
459 | $this->error = $hookmanager->error; |
||
460 | $error++; |
||
461 | } elseif ($reshook == 0) { |
||
462 | dol_syslog("Remain to pay for invoice " . $facid . " not null. We do nothing more."); |
||
463 | } |
||
464 | // } else if ($mustwait) dol_syslog("There is ".$mustwait." differed payment to process, we do nothing more."); |
||
465 | } else { |
||
466 | // If invoice is a down payment, we also convert down payment to discount |
||
467 | if ($invoice->type == Facture::TYPE_DEPOSIT) { |
||
468 | $amount_ht = $amount_tva = $amount_ttc = array(); |
||
469 | $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array(); |
||
470 | |||
471 | // Insert one discount by VAT rate category |
||
472 | $discount = new DiscountAbsolute($this->db); |
||
473 | $discount->fetch('', $invoice->id); |
||
474 | if (empty($discount->id)) { // If the invoice was not yet converted into a discount (this may have been done manually before we come here) |
||
475 | $discount->description = '(DEPOSIT)'; |
||
476 | $discount->fk_soc = $invoice->socid; |
||
477 | $discount->socid = $invoice->socid; |
||
478 | $discount->fk_facture_source = $invoice->id; |
||
479 | |||
480 | // Loop on each vat rate |
||
481 | $i = 0; |
||
482 | foreach ($invoice->lines as $line) { |
||
483 | if ($line->total_ht != 0) { // no need to create discount if amount is null |
||
484 | $amount_ht[$line->tva_tx] += $line->total_ht; |
||
485 | $amount_tva[$line->tva_tx] += $line->total_tva; |
||
486 | $amount_ttc[$line->tva_tx] += $line->total_ttc; |
||
487 | $multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht; |
||
488 | $multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva; |
||
489 | $multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc; |
||
490 | $i++; |
||
491 | } |
||
492 | } |
||
493 | |||
494 | foreach ($amount_ht as $tva_tx => $xxx) { |
||
495 | $discount->amount_ht = abs($amount_ht[$tva_tx]); |
||
496 | $discount->amount_tva = abs($amount_tva[$tva_tx]); |
||
497 | $discount->amount_ttc = abs($amount_ttc[$tva_tx]); |
||
498 | $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]); |
||
499 | $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]); |
||
500 | $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]); |
||
501 | $discount->tva_tx = abs($tva_tx); |
||
502 | |||
503 | $result = $discount->create($user); |
||
504 | if ($result < 0) { |
||
505 | $error++; |
||
506 | break; |
||
507 | } |
||
508 | } |
||
509 | } |
||
510 | |||
511 | if ($error) { |
||
512 | $this->error = $discount->error; |
||
513 | $this->errors = $discount->errors; |
||
514 | $error++; |
||
515 | } |
||
516 | } |
||
517 | |||
518 | // Set invoice to paid |
||
519 | if (!$error) { |
||
520 | $result = $invoice->setPaid($user, '', ''); |
||
521 | if ($result < 0) { |
||
522 | $this->error = $invoice->error; |
||
523 | $this->errors = $invoice->errors; |
||
524 | $error++; |
||
525 | } |
||
526 | } |
||
527 | } |
||
528 | } |
||
529 | |||
530 | // Regenerate documents of invoices |
||
531 | if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) { |
||
532 | dol_syslog(get_class($this) . '::create Regenerate the document after inserting payment for thirdparty default_lang=' . (is_object($invoice->thirdparty) ? $invoice->thirdparty->default_lang : 'null'), LOG_DEBUG); |
||
533 | |||
534 | $newlang = ''; |
||
535 | $outputlangs = $langs; |
||
536 | if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) { |
||
537 | $invoice->fetch_thirdparty(); |
||
538 | $newlang = $invoice->thirdparty->default_lang; |
||
539 | } |
||
540 | if (!empty($newlang)) { |
||
541 | $outputlangs = new Translate("", $conf); |
||
542 | $outputlangs->setDefaultLang($newlang); |
||
543 | } |
||
544 | |||
545 | $hidedetails = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0; |
||
546 | $hidedesc = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0; |
||
547 | $hideref = getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0; |
||
548 | |||
549 | $ret = $invoice->fetch($facid); // Reload to get new records |
||
550 | |||
551 | $result = $invoice->generateDocument($invoice->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); |
||
552 | |||
553 | dol_syslog(get_class($this) . '::create Regenerate end result=' . $result, LOG_DEBUG); |
||
554 | |||
555 | if ($result < 0) { |
||
556 | $this->error = $invoice->error; |
||
557 | $this->errors = $invoice->errors; |
||
558 | $error++; |
||
559 | } |
||
560 | } |
||
561 | } else { |
||
562 | $this->error = $this->db->lasterror(); |
||
563 | $error++; |
||
564 | } |
||
565 | } else { |
||
566 | dol_syslog(get_class($this) . '::Create Amount line ' . $key . ' not a number. We discard it.'); |
||
567 | } |
||
568 | } |
||
569 | |||
570 | dol_syslog(get_class($this) . '::create Now we call the triggers if no error (error = ' . $error . ')', LOG_DEBUG); |
||
571 | |||
572 | if (!$error) { // All payments into $this->amounts were recorded without errors |
||
573 | // Appel des triggers |
||
574 | $result = $this->call_trigger('PAYMENT_CUSTOMER_CREATE', $user); |
||
575 | if ($result < 0) { |
||
576 | $error++; |
||
577 | } |
||
578 | // Fin appel triggers |
||
579 | } |
||
580 | } else { |
||
581 | $this->error = $this->db->lasterror(); |
||
582 | $error++; |
||
583 | } |
||
584 | |||
585 | if (!$error) { |
||
586 | $this->amount = $total; |
||
587 | $this->total = $total; // deprecated |
||
588 | $this->multicurrency_amount = $mtotal; |
||
589 | $this->db->commit(); |
||
590 | return $this->id; |
||
591 | } else { |
||
592 | $this->db->rollback(); |
||
593 | return -1; |
||
594 | } |
||
595 | } |
||
596 | |||
597 | |||
598 | /** |
||
599 | * Delete a payment and generated links into account |
||
600 | * - Si le paiement porte sur un ecriture compte qui est rapprochee, on refuse |
||
601 | * - Si le paiement porte sur au moins une facture a "payee", on refuse |
||
602 | * |
||
603 | * @param User $user User making the deletion |
||
604 | * @param int $notrigger No trigger |
||
605 | * @return int Return integer <0 if KO, >0 if OK |
||
606 | */ |
||
607 | public function delete($user, $notrigger = 0) |
||
608 | { |
||
609 | $error = 0; |
||
610 | |||
611 | $bank_line_id = $this->bank_line; |
||
612 | |||
613 | $this->db->begin(); |
||
614 | |||
615 | // Verifier si paiement porte pas sur une facture classee |
||
616 | // Si c'est le cas, on refuse la suppression |
||
617 | $billsarray = $this->getBillsArray('f.fk_statut > 1'); |
||
618 | if (is_array($billsarray)) { |
||
619 | if (count($billsarray)) { |
||
620 | $this->error = "ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible"; |
||
621 | $this->db->rollback(); |
||
622 | return -1; |
||
623 | } |
||
624 | } else { |
||
625 | $this->db->rollback(); |
||
626 | return -2; |
||
627 | } |
||
628 | |||
629 | // Delete bank urls. If payment is on a conciliated line, return error. |
||
630 | if ($bank_line_id > 0) { |
||
631 | $accline = new AccountLine($this->db); |
||
632 | |||
633 | $result = $accline->fetch($bank_line_id); |
||
634 | if ($result == 0) { |
||
635 | $accline->id = $accline->rowid = $bank_line_id; // If not found, we set artificially rowid to allow delete of llx_bank_url |
||
636 | } |
||
637 | |||
638 | // Delete bank account url lines linked to payment |
||
639 | $result = $accline->delete_urls($user); |
||
640 | if ($result < 0) { |
||
641 | $this->error = $accline->error; |
||
642 | $this->db->rollback(); |
||
643 | return -3; |
||
644 | } |
||
645 | |||
646 | // Delete bank account lines linked to payment |
||
647 | $result = $accline->delete($user); |
||
648 | if ($result < 0) { |
||
649 | $this->error = $accline->error; |
||
650 | $this->db->rollback(); |
||
651 | return -4; |
||
652 | } |
||
653 | } |
||
654 | |||
655 | if (!$notrigger) { |
||
656 | // Call triggers |
||
657 | $result = $this->call_trigger('PAYMENT_CUSTOMER_DELETE', $user); |
||
658 | if ($result < 0) { |
||
659 | $this->db->rollback(); |
||
660 | return -1; |
||
661 | } |
||
662 | // End call triggers |
||
663 | } |
||
664 | |||
665 | // Delete payment (into paiement_facture and paiement) |
||
666 | $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'paiement_facture'; |
||
667 | $sql .= ' WHERE fk_paiement = ' . ((int) $this->id); |
||
668 | dol_syslog($sql); |
||
669 | $result = $this->db->query($sql); |
||
670 | if ($result) { |
||
671 | $sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'paiement'; |
||
672 | $sql .= " WHERE rowid = " . ((int) $this->id); |
||
673 | dol_syslog($sql); |
||
674 | $result = $this->db->query($sql); |
||
675 | if (!$result) { |
||
676 | $this->error = $this->db->lasterror(); |
||
677 | $this->db->rollback(); |
||
678 | return -3; |
||
679 | } |
||
680 | |||
681 | $this->db->commit(); |
||
682 | return 1; |
||
683 | } else { |
||
684 | $this->error = $this->db->error; |
||
685 | $this->db->rollback(); |
||
686 | return -5; |
||
687 | } |
||
688 | } |
||
689 | |||
690 | |||
691 | /** |
||
692 | * Add a record into bank for payment + links between this bank record and sources of payment. |
||
693 | * All payment properties (this->amount, this->amounts, ...) must have been set first like after a call to create(). |
||
694 | * |
||
695 | * @param User $user Object of user making payment |
||
696 | * @param string $mode 'payment', 'payment_supplier' |
||
697 | * @param string $label Label to use in bank record |
||
698 | * @param int $accountid Id of bank account to do link with |
||
699 | * @param string $emetteur_nom Name of transmitter |
||
700 | * @param string $emetteur_banque Name of bank |
||
701 | * @param int $notrigger No trigger |
||
702 | * @param string $accountancycode When we record a free bank entry, we must provide accounting account if accountancy module is on. |
||
703 | * @param string $addbankurl 'direct-debit' or 'credit-transfer': Add another entry into bank_url. |
||
704 | * @return int Return integer <0 if KO, bank_line_id if OK |
||
705 | */ |
||
706 | public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0, $accountancycode = '', $addbankurl = '') |
||
707 | { |
||
708 | global $conf, $user; |
||
709 | |||
710 | $error = 0; |
||
711 | $bank_line_id = 0; |
||
712 | |||
713 | if (isModEnabled("bank")) { |
||
714 | if ($accountid <= 0) { |
||
715 | $this->error = 'Bad value for parameter accountid=' . $accountid; |
||
716 | dol_syslog(get_class($this) . '::addPaymentToBank ' . $this->error, LOG_ERR); |
||
717 | return -1; |
||
718 | } |
||
719 | |||
720 | $this->fk_account = $accountid; |
||
721 | |||
722 | dol_syslog("addPaymentToBank " . $user->id . ", " . $mode . ", " . $label . ", " . $this->fk_account . ", " . $emetteur_nom . ", " . $emetteur_banque); |
||
723 | |||
724 | $acc = new Account($this->db); |
||
725 | $result = $acc->fetch($this->fk_account); |
||
726 | if ($result < 0) { |
||
727 | $this->error = $acc->error; |
||
728 | $this->errors = $acc->errors; |
||
729 | $error++; |
||
730 | return -1; |
||
731 | } |
||
732 | |||
733 | $this->db->begin(); |
||
734 | |||
735 | $totalamount = $this->amount; |
||
736 | $totalamount_main_currency = null; |
||
737 | if (empty($totalamount)) { |
||
738 | $totalamount = $this->total; // For backward compatibility |
||
739 | } |
||
740 | |||
741 | // if dolibarr currency != bank currency then we received an amount in customer currency (currently I don't manage the case : my currency is USD, the customer currency is EUR and he paid me in GBP. Seems no sense for me) |
||
742 | if (isModEnabled('multicurrency') && $conf->currency != $acc->currency_code) { |
||
743 | $totalamount = $this->multicurrency_amount; // We will insert into llx_bank.amount in foreign currency |
||
744 | $totalamount_main_currency = $this->amount; // We will also save the amount in main currency into column llx_bank.amount_main_currency |
||
745 | } |
||
746 | |||
747 | if ($mode == 'payment_supplier') { |
||
748 | $totalamount = -$totalamount; |
||
749 | if (isset($totalamount_main_currency)) { |
||
750 | $totalamount_main_currency = -$totalamount_main_currency; |
||
751 | } |
||
752 | } |
||
753 | |||
754 | // Insert payment into llx_bank |
||
755 | $bank_line_id = $acc->addline( |
||
756 | $this->datepaye, |
||
757 | $this->paiementcode ? $this->paiementcode : $this->paiementid, // Payment mode code ('CB', 'CHQ' or 'VIR' for example). Use payment id if not defined for backward compatibility. |
||
758 | $label, |
||
759 | $totalamount, // Sign must be positive when we receive money (customer payment), negative when you give money (supplier invoice or credit note) |
||
760 | $this->num_payment, |
||
761 | '', |
||
762 | $user, |
||
763 | $emetteur_nom, |
||
764 | $emetteur_banque, |
||
765 | $accountancycode, |
||
766 | null, |
||
767 | '', |
||
768 | $totalamount_main_currency |
||
769 | ); |
||
770 | |||
771 | // Mise a jour fk_bank dans llx_paiement |
||
772 | // On connait ainsi le paiement qui a genere l'ecriture bancaire |
||
773 | if ($bank_line_id > 0) { |
||
774 | $result = $this->update_fk_bank($bank_line_id); |
||
775 | if ($result <= 0) { |
||
776 | $error++; |
||
777 | dol_print_error($this->db); |
||
778 | } |
||
779 | |||
780 | // Add link 'payment', 'payment_supplier' in bank_url between payment and bank transaction |
||
781 | if (!$error) { |
||
782 | $url = ''; |
||
783 | if ($mode == 'payment') { |
||
784 | $url = constant('BASE_URL') . '/compta/paiement/card.php?id='; |
||
785 | } |
||
786 | if ($mode == 'payment_supplier') { |
||
787 | $url = constant('BASE_URL') . '/fourn/paiement/card.php?id='; |
||
788 | } |
||
789 | if ($url) { |
||
790 | $result = $acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode); |
||
791 | if ($result <= 0) { |
||
792 | $error++; |
||
793 | dol_print_error($this->db); |
||
794 | } |
||
795 | } |
||
796 | } |
||
797 | |||
798 | // Add link 'company' in bank_url between invoice and bank transaction (for each invoice concerned by payment) |
||
799 | if (!$error) { |
||
800 | $linkaddedforthirdparty = array(); |
||
801 | foreach ($this->amounts as $key => $value) { // We should have invoices always for same third party but we loop in case of. |
||
802 | if ($mode == 'payment') { |
||
803 | $fac = new Facture($this->db); |
||
804 | $fac->fetch($key); |
||
805 | $fac->fetch_thirdparty(); |
||
806 | if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) { // Not yet done for this thirdparty |
||
807 | $result = $acc->add_url_line( |
||
808 | $bank_line_id, |
||
809 | $fac->thirdparty->id, |
||
810 | constant('BASE_URL') . '/comm/card.php?socid=', |
||
811 | $fac->thirdparty->name, |
||
812 | 'company' |
||
813 | ); |
||
814 | if ($result <= 0) { |
||
815 | dol_syslog(get_class($this) . '::addPaymentToBank ' . $this->db->lasterror()); |
||
816 | } |
||
817 | $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty |
||
818 | } |
||
819 | } |
||
820 | if ($mode == 'payment_supplier') { |
||
821 | $fac = new FactureFournisseur($this->db); |
||
822 | $fac->fetch($key); |
||
823 | $fac->fetch_thirdparty(); |
||
824 | if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) { // Not yet done for this thirdparty |
||
825 | $result = $acc->add_url_line( |
||
826 | $bank_line_id, |
||
827 | $fac->thirdparty->id, |
||
828 | constant('BASE_URL') . '/fourn/card.php?socid=', |
||
829 | $fac->thirdparty->name, |
||
830 | 'company' |
||
831 | ); |
||
832 | if ($result <= 0) { |
||
833 | dol_syslog(get_class($this) . '::addPaymentToBank ' . $this->db->lasterror()); |
||
834 | } |
||
835 | $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty |
||
836 | } |
||
837 | } |
||
838 | } |
||
839 | } |
||
840 | |||
841 | // Add a link to the Direct Debit ('direct-debit') or Credit transfer ('credit-transfer') file in bank_url |
||
842 | if (!$error && $addbankurl && in_array($addbankurl, array('direct-debit', 'credit-transfer'))) { |
||
843 | $result = $acc->add_url_line( |
||
844 | $bank_line_id, |
||
845 | $this->id_prelevement, |
||
846 | constant('BASE_URL') . '/compta/prelevement/card.php?id=', |
||
847 | $this->num_payment, |
||
848 | $addbankurl |
||
849 | ); |
||
850 | } |
||
851 | |||
852 | // Add link to the Direct Debit if invoice refused ('InvoiceRefused') in bank_url |
||
853 | if (!$error && $label == '(InvoiceRefused)') { |
||
854 | $result = $acc->add_url_line( |
||
855 | $bank_line_id, |
||
856 | $this->id_prelevement, |
||
857 | constant('BASE_URL') . '/compta/prelevement/card.php?id=', |
||
858 | $this->num_prelevement, |
||
859 | 'withdraw' |
||
860 | ); |
||
861 | } |
||
862 | |||
863 | if (!$error && !$notrigger) { |
||
864 | // Appel des triggers |
||
865 | $result = $this->call_trigger('PAYMENT_ADD_TO_BANK', $user); |
||
866 | if ($result < 0) { |
||
867 | $error++; |
||
868 | } |
||
869 | // Fin appel triggers |
||
870 | } |
||
871 | } else { |
||
872 | $this->error = $acc->error; |
||
873 | $this->errors = $acc->errors; |
||
874 | $error++; |
||
875 | } |
||
876 | |||
877 | if (!$error) { |
||
878 | $this->db->commit(); |
||
879 | } else { |
||
880 | $this->db->rollback(); |
||
881 | } |
||
882 | } |
||
883 | |||
884 | if (!$error) { |
||
885 | return $bank_line_id; |
||
886 | } else { |
||
887 | return -1; |
||
888 | } |
||
889 | } |
||
890 | |||
891 | |||
892 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
893 | /** |
||
894 | * Mise a jour du lien entre le paiement et la ligne generee dans llx_bank |
||
895 | * |
||
896 | * @param int $id_bank Id compte bancaire |
||
897 | * @return int Return integer <0 if KO, >0 if OK |
||
898 | */ |
||
899 | public function update_fk_bank($id_bank) |
||
900 | { |
||
901 | // phpcs:enable |
||
902 | $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' set fk_bank = ' . ((int) $id_bank); |
||
903 | $sql .= " WHERE rowid = " . ((int) $this->id); |
||
904 | |||
905 | dol_syslog(get_class($this) . '::update_fk_bank', LOG_DEBUG); |
||
906 | $result = $this->db->query($sql); |
||
907 | if ($result) { |
||
908 | return 1; |
||
909 | } else { |
||
910 | $this->error = $this->db->lasterror(); |
||
911 | dol_syslog(get_class($this) . '::update_fk_bank ' . $this->error); |
||
912 | return -1; |
||
913 | } |
||
914 | } |
||
915 | |||
916 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
917 | /** |
||
918 | * Updates the payment date |
||
919 | * |
||
920 | * @param int $date New date |
||
921 | * @return int Return integer <0 if KO, 0 if OK |
||
922 | */ |
||
923 | public function update_date($date) |
||
924 | { |
||
925 | // phpcs:enable |
||
926 | $error = 0; |
||
927 | |||
928 | if (!empty($date) && $this->statut != 1) { |
||
929 | $this->db->begin(); |
||
930 | |||
931 | dol_syslog(get_class($this) . "::update_date with date = " . $date, LOG_DEBUG); |
||
932 | |||
933 | $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element; |
||
934 | $sql .= " SET datep = '" . $this->db->idate($date) . "'"; |
||
935 | $sql .= " WHERE rowid = " . ((int) $this->id); |
||
936 | |||
937 | $result = $this->db->query($sql); |
||
938 | if (!$result) { |
||
939 | $error++; |
||
940 | $this->error = 'Error -1 ' . $this->db->error(); |
||
941 | } |
||
942 | |||
943 | $type = $this->element; |
||
944 | |||
945 | $sql = "UPDATE " . MAIN_DB_PREFIX . 'bank'; |
||
946 | $sql .= " SET dateo = '" . $this->db->idate($date) . "', datev = '" . $this->db->idate($date) . "'"; |
||
947 | $sql .= " WHERE rowid IN (SELECT fk_bank FROM " . MAIN_DB_PREFIX . "bank_url WHERE type = '" . $this->db->escape($type) . "' AND url_id = " . ((int) $this->id) . ")"; |
||
948 | $sql .= " AND rappro = 0"; |
||
949 | |||
950 | $result = $this->db->query($sql); |
||
951 | if (!$result) { |
||
952 | $error++; |
||
953 | $this->error = 'Error -1 ' . $this->db->error(); |
||
954 | } |
||
955 | |||
956 | if (!$error) { |
||
957 | } |
||
958 | |||
959 | if (!$error) { |
||
960 | $this->datepaye = $date; |
||
961 | $this->date = $date; |
||
962 | |||
963 | $this->db->commit(); |
||
964 | return 0; |
||
965 | } else { |
||
966 | $this->db->rollback(); |
||
967 | return -2; |
||
968 | } |
||
969 | } |
||
970 | return -1; //no date given or already validated |
||
971 | } |
||
972 | |||
973 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
974 | /** |
||
975 | * Updates the payment number |
||
976 | * |
||
977 | * @param string $num_payment New num |
||
978 | * @return int Return integer <0 if KO, 0 if OK |
||
979 | */ |
||
980 | public function update_num($num_payment) |
||
981 | { |
||
982 | // phpcs:enable |
||
983 | if (!empty($num_payment) && $this->statut != 1) { |
||
984 | $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element; |
||
985 | $sql .= " SET num_paiement = '" . $this->db->escape($num_payment) . "'"; |
||
986 | $sql .= " WHERE rowid = " . ((int) $this->id); |
||
987 | |||
988 | dol_syslog(get_class($this) . "::update_num", LOG_DEBUG); |
||
989 | $result = $this->db->query($sql); |
||
990 | if ($result) { |
||
991 | $this->num_payment = $this->db->escape($num_payment); |
||
992 | return 0; |
||
993 | } else { |
||
994 | $this->error = 'Error -1 ' . $this->db->error(); |
||
995 | return -2; |
||
996 | } |
||
997 | } |
||
998 | return -1; //no num given or already validated |
||
999 | } |
||
1000 | |||
1001 | /** |
||
1002 | * Validate payment |
||
1003 | * |
||
1004 | * @param User|null $user User making validation |
||
1005 | * @return int Return integer <0 if KO, >0 if OK |
||
1006 | * @deprecated |
||
1007 | */ |
||
1008 | public function valide(User $user = null) |
||
1009 | { |
||
1010 | return $this->validate($user); |
||
1011 | } |
||
1012 | |||
1013 | /** |
||
1014 | * Validate payment |
||
1015 | * |
||
1016 | * @param User|null $user User making validation |
||
1017 | * @return int Return integer <0 if KO, >0 if OK |
||
1018 | */ |
||
1019 | public function validate(User $user = null) |
||
1020 | { |
||
1021 | $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET statut = 1 WHERE rowid = ' . ((int) $this->id); |
||
1022 | |||
1023 | dol_syslog(get_class($this) . '::valide', LOG_DEBUG); |
||
1024 | $result = $this->db->query($sql); |
||
1025 | if ($result) { |
||
1026 | return 1; |
||
1027 | } else { |
||
1028 | $this->error = $this->db->lasterror(); |
||
1029 | dol_syslog(get_class($this) . '::valide ' . $this->error); |
||
1030 | return -1; |
||
1031 | } |
||
1032 | } |
||
1033 | |||
1034 | /** |
||
1035 | * Reject payment |
||
1036 | * |
||
1037 | * @param User|null $user User making reject |
||
1038 | * @return int Return integer <0 if KO, >0 if OK |
||
1039 | */ |
||
1040 | public function reject(User $user = null) |
||
1041 | { |
||
1042 | $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET statut = 2 WHERE rowid = ' . ((int) $this->id); |
||
1043 | |||
1044 | dol_syslog(get_class($this) . '::reject', LOG_DEBUG); |
||
1045 | $result = $this->db->query($sql); |
||
1046 | if ($result) { |
||
1047 | return 1; |
||
1048 | } else { |
||
1049 | $this->error = $this->db->lasterror(); |
||
1050 | dol_syslog(get_class($this) . '::reject ' . $this->error); |
||
1051 | return -1; |
||
1052 | } |
||
1053 | } |
||
1054 | |||
1055 | /** |
||
1056 | * Information sur l'objet |
||
1057 | * |
||
1058 | * @param int $id id du paiement don't il faut afficher les infos |
||
1059 | * @return void |
||
1060 | */ |
||
1061 | public function info($id) |
||
1062 | { |
||
1063 | $sql = 'SELECT p.rowid, p.datec, p.fk_user_creat, p.fk_user_modif, p.tms'; |
||
1064 | $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement as p'; |
||
1065 | $sql .= ' WHERE p.rowid = ' . ((int) $id); |
||
1066 | |||
1067 | dol_syslog(get_class($this) . '::info', LOG_DEBUG); |
||
1068 | $result = $this->db->query($sql); |
||
1069 | |||
1070 | if ($result) { |
||
1071 | if ($this->db->num_rows($result)) { |
||
1072 | $obj = $this->db->fetch_object($result); |
||
1073 | |||
1074 | $this->id = $obj->rowid; |
||
1075 | |||
1076 | $this->user_creation_id = $obj->fk_user_creat; |
||
1077 | $this->user_modification_id = $obj->fk_user_modif; |
||
1078 | $this->date_creation = $this->db->jdate($obj->datec); |
||
1079 | $this->date_modification = $this->db->jdate($obj->tms); |
||
1080 | } |
||
1081 | $this->db->free($result); |
||
1082 | } else { |
||
1083 | dol_print_error($this->db); |
||
1084 | } |
||
1085 | } |
||
1086 | |||
1087 | /** |
||
1088 | * Return list of invoices the payment is related to. |
||
1089 | * |
||
1090 | * @param string $filter Filter |
||
1091 | * @return int|array Return integer <0 if KO or array of invoice id |
||
1092 | * @see getAmountsArray() |
||
1093 | */ |
||
1094 | public function getBillsArray($filter = '') |
||
1095 | { |
||
1096 | $sql = 'SELECT pf.fk_facture'; |
||
1097 | $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf, ' . MAIN_DB_PREFIX . 'facture as f'; // We keep link on invoice to allow use of some filters on invoice |
||
1098 | $sql .= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = ' . ((int) $this->id); |
||
1099 | if ($filter) { |
||
1100 | $sql .= ' AND ' . $filter; |
||
1101 | } |
||
1102 | $resql = $this->db->query($sql); |
||
1103 | if ($resql) { |
||
1104 | $i = 0; |
||
1105 | $num = $this->db->num_rows($resql); |
||
1106 | $billsarray = array(); |
||
1107 | |||
1108 | while ($i < $num) { |
||
1109 | $obj = $this->db->fetch_object($resql); |
||
1110 | $billsarray[$i] = $obj->fk_facture; |
||
1111 | $i++; |
||
1112 | } |
||
1113 | |||
1114 | return $billsarray; |
||
1115 | } else { |
||
1116 | $this->error = $this->db->error(); |
||
1117 | dol_syslog(get_class($this) . '::getBillsArray Error ' . $this->error . ' -', LOG_DEBUG); |
||
1118 | return -1; |
||
1119 | } |
||
1120 | } |
||
1121 | |||
1122 | /** |
||
1123 | * Return list of amounts of payments. |
||
1124 | * |
||
1125 | * @return int|array Array of amount of payments |
||
1126 | * @see getBillsArray() |
||
1127 | */ |
||
1128 | public function getAmountsArray() |
||
1129 | { |
||
1130 | $sql = 'SELECT pf.fk_facture, pf.amount'; |
||
1131 | $sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf'; |
||
1132 | $sql .= ' WHERE pf.fk_paiement = ' . ((int) $this->id); |
||
1133 | $resql = $this->db->query($sql); |
||
1134 | if ($resql) { |
||
1135 | $i = 0; |
||
1136 | $num = $this->db->num_rows($resql); |
||
1137 | $amounts = array(); |
||
1138 | |||
1139 | while ($i < $num) { |
||
1140 | $obj = $this->db->fetch_object($resql); |
||
1141 | $amounts[$obj->fk_facture] = $obj->amount; |
||
1142 | $i++; |
||
1143 | } |
||
1144 | |||
1145 | return $amounts; |
||
1146 | } else { |
||
1147 | $this->error = $this->db->error(); |
||
1148 | dol_syslog(get_class($this) . '::getAmountsArray Error ' . $this->error . ' -', LOG_DEBUG); |
||
1149 | return -1; |
||
1150 | } |
||
1151 | } |
||
1152 | |||
1153 | /** |
||
1154 | * Return next reference of customer invoice not already used (or last reference) |
||
1155 | * according to numbering module defined into constant FACTURE_ADDON |
||
1156 | * |
||
1157 | * @param Societe $soc object company |
||
1158 | * @param string $mode 'next' for next value or 'last' for last value |
||
1159 | * @return string free ref or last ref |
||
1160 | */ |
||
1161 | public function getNextNumRef($soc, $mode = 'next') |
||
1162 | { |
||
1163 | global $conf, $db, $langs; |
||
1164 | $langs->load("bills"); |
||
1165 | |||
1166 | // Clean parameters (if not defined or using deprecated value) |
||
1167 | if (!getDolGlobalString('PAYMENT_ADDON')) { |
||
1168 | $conf->global->PAYMENT_ADDON = 'mod_payment_cicada'; |
||
1169 | } elseif (getDolGlobalString('PAYMENT_ADDON') == 'ant') { |
||
1170 | $conf->global->PAYMENT_ADDON = 'mod_payment_ant'; |
||
1171 | } elseif (getDolGlobalString('PAYMENT_ADDON') == 'cicada') { |
||
1172 | $conf->global->PAYMENT_ADDON = 'mod_payment_cicada'; |
||
1173 | } |
||
1174 | |||
1175 | if (getDolGlobalString('PAYMENT_ADDON')) { |
||
1176 | $mybool = false; |
||
1177 | |||
1178 | $file = getDolGlobalString('PAYMENT_ADDON') . ".php"; |
||
1179 | $classname = getDolGlobalString('PAYMENT_ADDON'); |
||
1180 | |||
1181 | // Include file with class |
||
1182 | $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); |
||
1183 | |||
1184 | foreach ($dirmodels as $reldir) { |
||
1185 | $dir = dol_buildpath($reldir . "core/modules/payment/"); |
||
1186 | |||
1187 | // Load file with numbering class (if found) |
||
1188 | if (is_file($dir . $file) && is_readable($dir . $file)) { |
||
1189 | $mybool = (include_once $dir . $file) || $mybool; |
||
1190 | } |
||
1191 | } |
||
1192 | |||
1193 | // For compatibility |
||
1194 | if (!$mybool) { |
||
1195 | $file = getDolGlobalString('PAYMENT_ADDON') . ".php"; |
||
1196 | $classname = "mod_payment_" . getDolGlobalString('PAYMENT_ADDON'); |
||
1197 | $classname = preg_replace('/\-.*$/', '', $classname); |
||
1198 | // Include file with class |
||
1199 | foreach ($conf->file->dol_document_root as $dirroot) { |
||
1200 | $dir = $dirroot . "/core/modules/payment/"; |
||
1201 | |||
1202 | // Load file with numbering class (if found) |
||
1203 | if (is_file($dir . $file) && is_readable($dir . $file)) { |
||
1204 | $mybool = (include_once $dir . $file) || $mybool; |
||
1205 | } |
||
1206 | } |
||
1207 | } |
||
1208 | |||
1209 | if (!$mybool) { |
||
1210 | dol_print_error(null, "Failed to include file " . $file); |
||
1211 | return ''; |
||
1212 | } |
||
1213 | |||
1214 | $obj = new $classname(); |
||
1215 | $numref = ""; |
||
1216 | $numref = $obj->getNextValue($soc, $this); |
||
1217 | |||
1218 | /** |
||
1219 | * $numref can be empty in case we ask for the last value because if there is no invoice created with the |
||
1220 | * set up mask. |
||
1221 | */ |
||
1222 | if ($mode != 'last' && !$numref) { |
||
1223 | dol_print_error($db, "Payment::getNextNumRef " . $obj->error); |
||
1224 | return ""; |
||
1225 | } |
||
1226 | |||
1227 | return $numref; |
||
1228 | } else { |
||
1229 | $langs->load("errors"); |
||
1230 | print $langs->trans("Error") . " " . $langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Invoice")); |
||
1231 | return ""; |
||
1232 | } |
||
1233 | } |
||
1234 | |||
1235 | /** |
||
1236 | * get the right way of payment |
||
1237 | * |
||
1238 | * @return string 'dolibarr' if standard comportment or paid in main currency, 'customer' if payment received from multicurrency inputs |
||
1239 | */ |
||
1240 | public function getWay() |
||
1255 | } |
||
1256 | |||
1257 | /** |
||
1258 | * Initialise an instance with random values. |
||
1259 | * Used to build previews or test instances. |
||
1260 | * id must be 0 if object instance is a specimen. |
||
1261 | * |
||
1262 | * @param string $option ''=Create a specimen invoice with lines, 'nolines'=No lines |
||
1263 | * @return int |
||
1264 | */ |
||
1265 | public function initAsSpecimen($option = '') |
||
1266 | { |
||
1267 | global $user, $langs, $conf; |
||
1268 | |||
1269 | $now = dol_now(); |
||
1270 | $arraynow = dol_getdate($now); |
||
1271 | $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); |
||
1272 | |||
1273 | // Initialize parameters |
||
1274 | $this->id = 0; |
||
1275 | $this->ref = 'SPECIMEN'; |
||
1276 | $this->specimen = 1; |
||
1277 | $this->facid = 1; |
||
1278 | $this->datepaye = $nownotime; |
||
1279 | |||
1280 | return 1; |
||
1281 | } |
||
1282 | |||
1283 | |||
1284 | /** |
||
1285 | * Return clicable name (with picto eventually) |
||
1286 | * |
||
1287 | * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto |
||
1288 | * @param string $option Sur quoi pointe le lien |
||
1289 | * @param string $mode 'withlistofinvoices'=Include list of invoices into tooltip |
||
1290 | * @param int $notooltip 1=Disable tooltip |
||
1291 | * @param string $morecss Add more CSS |
||
1292 | * @return string Chaine avec URL |
||
1293 | */ |
||
1294 | public function getNomUrl($withpicto = 0, $option = '', $mode = 'withlistofinvoices', $notooltip = 0, $morecss = '') |
||
1295 | { |
||
1296 | global $conf, $langs, $hookmanager; |
||
1297 | |||
1298 | if (!empty($conf->dol_no_mouse_hover)) { |
||
1299 | $notooltip = 1; // Force disable tooltips |
||
1300 | } |
||
1301 | |||
1302 | $result = ''; |
||
1303 | |||
1304 | $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Payment") . '</u><br>'; |
||
1305 | $label .= '<strong>' . $langs->trans("Ref") . ':</strong> ' . $this->ref; |
||
1306 | $dateofpayment = ($this->datepaye ? $this->datepaye : $this->date); |
||
1307 | if ($dateofpayment) { |
||
1308 | $label .= '<br><strong>' . $langs->trans("Date") . ':</strong> '; |
||
1309 | $tmparray = dol_getdate($dateofpayment); |
||
1310 | if ($tmparray['seconds'] == 0 && $tmparray['minutes'] == 0 && ($tmparray['hours'] == 0 || $tmparray['hours'] == 12)) { // We set hours to 0:00 or 12:00 because we don't know it |
||
1311 | $label .= dol_print_date($dateofpayment, 'day'); |
||
1312 | } else { // Hours was set to real date of payment (special case for POS for example) |
||
1313 | $label .= dol_print_date($dateofpayment, 'dayhour', 'tzuser'); |
||
1314 | } |
||
1315 | } |
||
1316 | if ($this->amount) { |
||
1317 | $label .= '<br><strong>' . $langs->trans("Amount") . ':</strong> ' . price($this->amount, 0, $langs, 1, -1, -1, $conf->currency); |
||
1318 | } |
||
1319 | if ($mode == 'withlistofinvoices') { |
||
1320 | $arraybill = $this->getBillsArray(); |
||
1321 | if (is_array($arraybill) && count($arraybill) > 0) { |
||
1322 | $facturestatic = new Facture($this->db); |
||
1323 | foreach ($arraybill as $billid) { |
||
1324 | $facturestatic->fetch($billid); |
||
1325 | $label .= '<br> ' . $facturestatic->getNomUrl(1, '', 0, 0, '', 1) . ' ' . $facturestatic->getLibStatut(2, 1); |
||
1326 | } |
||
1327 | } |
||
1328 | } |
||
1329 | |||
1330 | $linkclose = ''; |
||
1331 | if (empty($notooltip)) { |
||
1332 | if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) { |
||
1333 | $label = $langs->trans("Payment"); |
||
1334 | $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"'; |
||
1335 | } |
||
1336 | $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"'; |
||
1337 | $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"'; |
||
1338 | } else { |
||
1339 | $linkclose = ($morecss ? ' class="' . $morecss . '"' : ''); |
||
1340 | } |
||
1341 | |||
1342 | $url = constant('BASE_URL') . '/compta/paiement/card.php?id=' . $this->id; |
||
1343 | |||
1344 | $linkstart = '<a href="' . $url . '"'; |
||
1345 | $linkstart .= $linkclose . '>'; |
||
1346 | $linkend = '</a>'; |
||
1347 | |||
1348 | $result .= $linkstart; |
||
1349 | if ($withpicto) { |
||
1350 | $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="' . (($withpicto != 2) ? 'paddingright ' : '') . 'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); |
||
1351 | } |
||
1352 | if ($withpicto && $withpicto != 2) { |
||
1353 | $result .= ($this->ref ? $this->ref : $this->id); |
||
1354 | } |
||
1355 | $result .= $linkend; |
||
1356 | global $action; |
||
1357 | $hookmanager->initHooks(array($this->element . 'dao')); |
||
1358 | $parameters = array('id' => $this->id, 'getnomurl' => &$result); |
||
1359 | $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks |
||
1360 | if ($reshook > 0) { |
||
1361 | $result = $hookmanager->resPrint; |
||
1362 | } else { |
||
1363 | $result .= $hookmanager->resPrint; |
||
1364 | } |
||
1365 | return $result; |
||
1366 | } |
||
1367 | |||
1368 | /** |
||
1369 | * Return the label of the status |
||
1370 | * |
||
1371 | * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto |
||
1372 | * @return string Label of status |
||
1373 | */ |
||
1374 | public function getLibStatut($mode = 0) |
||
1375 | { |
||
1376 | return $this->LibStatut($this->statut, $mode); |
||
1377 | } |
||
1378 | |||
1379 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
1380 | /** |
||
1381 | * Return the label of a given status |
||
1382 | * |
||
1383 | * @param int $status Id status |
||
1384 | * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto |
||
1385 | * @return string Label of status |
||
1386 | */ |
||
1387 | public function LibStatut($status, $mode = 0) |
||
1388 | { |
||
1389 | // phpcs:enable |
||
1390 | global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage |
||
1391 | |||
1392 | $langs->load('compta'); |
||
1393 | /*if ($mode == 0) |
||
1394 | { |
||
1395 | if ($status == 0) return $langs->trans('ToValidate'); |
||
1396 | if ($status == 1) return $langs->trans('Validated'); |
||
1397 | } |
||
1398 | if ($mode == 1) |
||
1399 | { |
||
1400 | if ($status == 0) return $langs->trans('ToValidate'); |
||
1401 | if ($status == 1) return $langs->trans('Validated'); |
||
1402 | } |
||
1403 | if ($mode == 2) |
||
1404 | { |
||
1405 | if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate'); |
||
1406 | if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated'); |
||
1407 | } |
||
1408 | if ($mode == 3) |
||
1409 | { |
||
1410 | if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1'); |
||
1411 | if ($status == 1) return img_picto($langs->trans('Validated'),'statut4'); |
||
1412 | } |
||
1413 | if ($mode == 4) |
||
1414 | { |
||
1415 | if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut1').' '.$langs->trans('ToValidate'); |
||
1416 | if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated'); |
||
1417 | } |
||
1418 | if ($mode == 5) |
||
1419 | { |
||
1420 | if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); |
||
1421 | if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); |
||
1422 | } |
||
1423 | if ($mode == 6) |
||
1424 | { |
||
1425 | if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut1'); |
||
1426 | if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4'); |
||
1427 | }*/ |
||
1428 | return ''; |
||
1429 | } |
||
1430 | |||
1431 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
1432 | /** |
||
1433 | * Load the third party of object, from id into this->thirdparty. |
||
1434 | * For payments, take the thirdparty linked to the first invoice found. This is enough because payments are done on invoices of the same thirdparty. |
||
1435 | * |
||
1436 | * @param int $force_thirdparty_id Force thirdparty id |
||
1437 | * @return int Return integer <0 if KO, >0 if OK |
||
1438 | */ |
||
1439 | public function fetch_thirdparty($force_thirdparty_id = 0) |
||
1440 | { |
||
1441 | // phpcs:enable |
||
1442 | |||
1443 | if (empty($force_thirdparty_id)) { |
||
1444 | $billsarray = $this->getBillsArray(); // From payment, the fk_soc isn't available, we should load the first supplier invoice to get him |
||
1445 | if (!empty($billsarray)) { |
||
1446 | $invoice = new Facture($this->db); |
||
1447 | if ($invoice->fetch($billsarray[0]) > 0) { |
||
1448 | $force_thirdparty_id = $invoice->socid; |
||
1449 | } |
||
1450 | } |
||
1451 | } |
||
1452 | |||
1453 | return parent::fetch_thirdparty($force_thirdparty_id); |
||
1454 | } |
||
1455 | |||
1456 | |||
1457 | /** |
||
1458 | * Return if payment is reconciled |
||
1459 | * |
||
1460 | * @return boolean True if payment is reconciled |
||
1461 | */ |
||
1462 | public function isReconciled() |
||
1467 | } |
||
1468 | } |
||
1469 |