dolibarr 19.0.3
accountingaccount.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
3 * Copyright (C) 2013-2024 Alexandre Spangaro <aspangaro@easya.solutions>
4 * Copyright (C) 2013-2021 Florian Henry <florian.henry@open-concept.pro>
5 * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
7 * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
29require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
30require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
31require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
32
37{
41 public $element = 'accounting_account';
42
46 public $table_element = 'accounting_account';
47
51 public $picto = 'billr';
52
57 public $ismultientitymanaged = 1;
58
63 public $restrictiononfksoc = 1;
64
68 public $db;
69
73 public $id;
74
78 public $rowid;
79
85 public $datec;
86
90 public $fk_pcg_version;
91
95 public $pcg_type;
96
100 public $account_number;
101
105 public $account_parent;
106
110 public $account_category;
111
115 public $account_category_label;
116
120 public $status;
121
125 public $label;
126
130 public $labelshort;
131
135 public $fk_user_author;
136
140 public $fk_user_modif;
141
145 public $active;
146
150 public $reconcilable;
151
155 private $accountingaccount_codetotid_cache = array();
156
157
158 const STATUS_ENABLED = 1;
159 const STATUS_DISABLED = 0;
160
161
167 public function __construct($db)
168 {
169 $this->db = $db;
170 $this->next_prev_filter = "fk_pcg_version IN (SELECT pcg_version FROM ".MAIN_DB_PREFIX."accounting_system WHERE rowid = ".((int) getDolGlobalInt('CHARTOFACCOUNTS')).")"; // Used to add a filter in Form::showrefnav method
171 }
172
182 public function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0, $limittoachartaccount = '')
183 {
184 global $conf;
185
186 if ($rowid || $account_number) {
187 $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.account_number, a.account_parent, a.label, a.labelshort, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active, a.reconcilable";
188 $sql .= ", ca.label as category_label";
189 $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as a";
190 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as ca ON a.fk_accounting_category = ca.rowid";
191 $sql .= " WHERE";
192 if ($rowid) {
193 $sql .= " a.rowid = ".(int) $rowid;
194 } elseif ($account_number) {
195 $sql .= " a.account_number = '".$this->db->escape($account_number)."'";
196 $sql .= " AND a.entity = ".$conf->entity;
197 }
198 if (!empty($limittocurrentchart)) {
199 $sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM '.MAIN_DB_PREFIX.'accounting_system WHERE rowid = '.((int) getDolGlobalInt('CHARTOFACCOUNTS')).')';
200 }
201 if (!empty($limittoachartaccount)) {
202 $sql .= " AND a.fk_pcg_version = '".$this->db->escape($limittoachartaccount)."'";
203 }
204
205 dol_syslog(get_class($this)."::fetch rowid=".$rowid." account_number=".$account_number, LOG_DEBUG);
206
207 $result = $this->db->query($sql);
208 if ($result) {
209 $obj = $this->db->fetch_object($result);
210
211 if ($obj) {
212 $this->id = $obj->rowid;
213 $this->rowid = $obj->rowid;
214 $this->ref = $obj->account_number;
215 $this->datec = $this->db->jdate($obj->datec);
216 $this->date_creation = $this->db->jdate($obj->datec);
217 $this->date_modification = $this->db->jdate($obj->tms);
218 //$this->tms = $this->datem;
219 $this->fk_pcg_version = $obj->fk_pcg_version;
220 $this->pcg_type = $obj->pcg_type;
221 $this->account_number = $obj->account_number;
222 $this->account_parent = $obj->account_parent;
223 $this->label = $obj->label;
224 $this->labelshort = $obj->labelshort;
225 $this->account_category = $obj->fk_accounting_category;
226 $this->account_category_label = $obj->category_label;
227 $this->fk_user_author = $obj->fk_user_author;
228 $this->fk_user_modif = $obj->fk_user_modif;
229 $this->active = $obj->active;
230 $this->status = $obj->active;
231 $this->reconcilable = $obj->reconcilable;
232
233 return $this->id;
234 } else {
235 return 0;
236 }
237 } else {
238 $this->error = "Error ".$this->db->lasterror();
239 $this->errors[] = "Error ".$this->db->lasterror();
240 }
241 }
242 return -1;
243 }
244
252 public function create($user, $notrigger = 0)
253 {
254 global $conf;
255 $error = 0;
256 $now = dol_now();
257
258 // Clean parameters
259 if (isset($this->fk_pcg_version)) {
260 $this->fk_pcg_version = trim($this->fk_pcg_version);
261 }
262 if (isset($this->pcg_type)) {
263 $this->pcg_type = trim($this->pcg_type);
264 }
265 if (isset($this->account_number)) {
266 $this->account_number = trim($this->account_number);
267 }
268 if (isset($this->label)) {
269 $this->label = trim($this->label);
270 }
271 if (isset($this->labelshort)) {
272 $this->labelshort = trim($this->labelshort);
273 }
274
275 if (empty($this->pcg_type) || $this->pcg_type == '-1') {
276 $this->pcg_type = 'XXXXXX';
277 }
278 // Check parameters
279 // Put here code to add control on parameters values
280
281 // Insert request
282 $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account(";
283 $sql .= "datec";
284 $sql .= ", entity";
285 $sql .= ", fk_pcg_version";
286 $sql .= ", pcg_type";
287 $sql .= ", account_number";
288 $sql .= ", account_parent";
289 $sql .= ", label";
290 $sql .= ", labelshort";
291 $sql .= ", fk_accounting_category";
292 $sql .= ", fk_user_author";
293 $sql .= ", active";
294 $sql .= ", reconcilable";
295 $sql .= ") VALUES (";
296 $sql .= " '".$this->db->idate($now)."'";
297 $sql .= ", ".((int) $conf->entity);
298 $sql .= ", ".(empty($this->fk_pcg_version) ? 'NULL' : "'".$this->db->escape($this->fk_pcg_version)."'");
299 $sql .= ", ".(empty($this->pcg_type) ? 'NULL' : "'".$this->db->escape($this->pcg_type)."'");
300 $sql .= ", ".(empty($this->account_number) ? 'NULL' : "'".$this->db->escape($this->account_number)."'");
301 $sql .= ", ".(empty($this->account_parent) ? 0 : (int) $this->account_parent);
302 $sql .= ", ".(empty($this->label) ? "''" : "'".$this->db->escape($this->label)."'");
303 $sql .= ", ".(empty($this->labelshort) ? "''" : "'".$this->db->escape($this->labelshort)."'");
304 $sql .= ", ".(empty($this->account_category) ? 0 : (int) $this->account_category);
305 $sql .= ", ".((int) $user->id);
306 $sql .= ", ".(int) $this->active;
307 $sql .= ", ".(int) $this->reconcilable;
308 $sql .= ")";
309
310 $this->db->begin();
311
312 dol_syslog(get_class($this)."::create", LOG_DEBUG);
313 $resql = $this->db->query($sql);
314 if (!$resql) {
315 $error++;
316 $this->errors[] = "Error " . $this->db->lasterror();
317 }
318
319 if (!$error) {
320 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account");
321
322 // Uncomment this and change MYOBJECT to your own tag if you
323 // want this action to call a trigger.
324 //if (! $error && ! $notrigger) {
325
326 // // Call triggers
327 // $result=$this->call_trigger('MYOBJECT_CREATE',$user);
328 // if ($result < 0) $error++;
329 // // End call triggers
330 //}
331 }
332
333 // Commit or rollback
334 if ($error) {
335 foreach ($this->errors as $errmsg) {
336 dol_syslog(get_class($this) . "::create " . $errmsg, LOG_ERR);
337 $this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
338 }
339 $this->db->rollback();
340 return -1 * $error;
341 } else {
342 $this->db->commit();
343 return $this->id;
344 }
345 }
346
353 public function update($user)
354 {
355 // Check parameters
356 if (empty($this->pcg_type) || $this->pcg_type == '-1') {
357 $this->pcg_type = 'XXXXXX';
358 }
359
360 $this->db->begin();
361
362 $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account ";
363 $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null");
364 $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null");
365 $sql .= " , account_number = '" . $this->db->escape($this->account_number) . "'";
366 $sql .= " , account_parent = " . (int) $this->account_parent;
367 $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "''");
368 $sql .= " , labelshort = " . ($this->labelshort ? "'" . $this->db->escape($this->labelshort) . "'" : "''");
369 $sql .= " , fk_accounting_category = " . (empty($this->account_category) ? 0 : (int) $this->account_category);
370 $sql .= " , fk_user_modif = " . ((int) $user->id);
371 $sql .= " , active = " . (int) $this->active;
372 $sql .= " , reconcilable = " . (int) $this->reconcilable;
373 $sql .= " WHERE rowid = " . ((int) $this->id);
374
375 dol_syslog(get_class($this)."::update", LOG_DEBUG);
376 $result = $this->db->query($sql);
377 if ($result) {
378 $this->db->commit();
379 return 1;
380 } else {
381 if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
382 $this->error = $this->db->lasterror();
383 $this->db->rollback();
384 return -2;
385 }
386
387 $this->error = $this->db->lasterror();
388 $this->db->rollback();
389 return -1;
390 }
391 }
392
398 public function checkUsage()
399 {
400 global $langs;
401
402 // TODO Looks a stupid check
403 $sql = "(SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facturedet";
404 $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")";
405 $sql .= "UNION";
406 $sql .= " (SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facture_fourn_det";
407 $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")";
408
409 dol_syslog(get_class($this)."::checkUsage", LOG_DEBUG);
410 $resql = $this->db->query($sql);
411
412 if ($resql) {
413 $num = $this->db->num_rows($resql);
414 if ($num > 0) {
415 $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse');
416 return 0;
417 } else {
418 return 1;
419 }
420 } else {
421 $this->error = $this->db->lasterror();
422 return -1;
423 }
424 }
425
433 public function delete($user, $notrigger = 0)
434 {
435 $error = 0;
436
437 $result = $this->checkUsage();
438
439 if ($result > 0) {
440 $this->db->begin();
441
442 if (!$error) {
443 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account";
444 $sql .= " WHERE rowid=" . ((int) $this->id);
445
446 dol_syslog(get_class($this) . "::delete sql=" . $sql);
447 $resql = $this->db->query($sql);
448 if (!$resql) {
449 $error++;
450 $this->errors[] = "Error " . $this->db->lasterror();
451 }
452 }
453
454 // Commit or rollback
455 if ($error) {
456 foreach ($this->errors as $errmsg) {
457 dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
458 $this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
459 }
460 $this->db->rollback();
461 return -1 * $error;
462 } else {
463 $this->db->commit();
464 return 1;
465 }
466 } else {
467 return -1;
468 }
469 }
470
484 public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '')
485 {
486 global $langs, $conf, $hookmanager;
487 require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
488
489 if (!empty($conf->dol_no_mouse_hover)) {
490 $notooltip = 1; // Force disable tooltips
491 }
492
493 $result = '';
494
495 $url = '';
496 $labelurl = '';
497 if (empty($option) || $option == 'ledger') {
498 $url = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode((isset($this->account_number) ? $this->account_number : '')) . '&search_accountancy_code_end=' . urlencode((isset($this->account_number) ? $this->account_number : ''));
499 $labelurl = $langs->trans("ShowAccountingAccountInLedger");
500 } elseif ($option == 'journals') {
501 $url = DOL_URL_ROOT . '/accountancy/bookkeeping/list.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number);
502 $labelurl = $langs->trans("ShowAccountingAccountInJournals");
503 } elseif ($option == 'accountcard') {
504 $url = DOL_URL_ROOT . '/accountancy/admin/card.php?id=' . urlencode($this->id);
505 $labelurl = $langs->trans("ShowAccountingAccount");
506 }
507
508 // Add param to save lastsearch_values or not
509 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
510 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
511 $add_save_lastsearch_values = 1;
512 }
513 if ($add_save_lastsearch_values) {
514 $url .= '&save_lastsearch_values=1';
515 }
516
517 $picto = 'accounting_account';
518 $label = '';
519
520 if (empty($this->labelshort) || $withcompletelabel == 1) {
521 $labeltoshow = $this->label;
522 } else {
523 $labeltoshow = $this->labelshort;
524 }
525
526 $label = '<u>' . $labelurl . '</u>';
527 if (!empty($this->account_number)) {
528 $label .= '<br><b>' . $langs->trans('AccountAccounting') . ':</b> ' . length_accountg($this->account_number);
529 }
530 if (!empty($labeltoshow)) {
531 $label .= '<br><b>' . $langs->trans('Label') . ':</b> ' . $labeltoshow;
532 }
533 if ($moretitle) {
534 $label .= ' - ' . $moretitle;
535 }
536
537 $linkclose = '';
538 if (empty($notooltip)) {
539 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
540 $label = $labelurl;
541 $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
542 }
543 $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
544 $linkclose .= ' class="classfortooltip"';
545 }
546
547 $linkstart = '<a href="' . $url . '"';
548 $linkstart .= $linkclose . '>';
549 $linkend = '</a>';
550
551 if ($nourl) {
552 $linkstart = '';
553 $linkclose = '';
554 $linkend = '';
555 }
556
557 $label_link = length_accountg($this->account_number);
558 if ($withlabel) {
559 $label_link .= ' - ' . ($nourl ? '<span class="opacitymedium">' : '') . $labeltoshow . ($nourl ? '</span>' : '');
560 }
561
562 if ($withpicto) {
563 $result .= ($linkstart . img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1) . $linkend);
564 }
565 if ($withpicto && $withpicto != 2) {
566 $result .= ' ';
567 }
568 if ($withpicto != 2) {
569 $result .= $linkstart . $label_link . $linkend;
570 }
571 global $action;
572 $hookmanager->initHooks(array($this->element . 'dao'));
573 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
574 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
575 if ($reshook > 0) {
576 $result = $hookmanager->resPrint;
577 } else {
578 $result .= $hookmanager->resPrint;
579 }
580 return $result;
581 }
582
589 public function info($id)
590 {
591 $sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms as date_modification';
592 $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a';
593 $sql .= ' WHERE a.rowid = ' . ((int) $id);
594
595 dol_syslog(get_class($this) . '::info sql=' . $sql);
596 $resql = $this->db->query($sql);
597
598 if ($resql) {
599 if ($this->db->num_rows($resql)) {
600 $obj = $this->db->fetch_object($resql);
601
602 $this->id = $obj->rowid;
603
604 $this->user_creation_id = $obj->fk_user_author;
605 $this->user_modification_id = $obj->fk_user_modif;
606 $this->date_creation = $this->db->jdate($obj->datec);
607 $this->date_modification = $this->db->jdate($obj->date_modification);
608 }
609 $this->db->free($resql);
610 } else {
611 dol_print_error($this->db);
612 }
613 }
614
622 public function accountDeactivate($id, $mode = 0)
623 {
624 $result = $this->checkUsage();
625
626 $fieldtouse = 'active';
627 if ($mode == 1) {
628 $fieldtouse = 'reconcilable';
629 }
630
631 if ($result > 0) {
632 $this->db->begin();
633
634 $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account ";
635 $sql .= "SET ".$fieldtouse." = '0'";
636 $sql .= " WHERE rowid = ".((int) $id);
637
638 dol_syslog(get_class($this)."::accountDeactivate ".$fieldtouse, LOG_DEBUG);
639 $result = $this->db->query($sql);
640
641 if ($result) {
642 $this->db->commit();
643 return 1;
644 } else {
645 $this->error = $this->db->lasterror();
646 $this->db->rollback();
647 return -1;
648 }
649 } else {
650 return -1;
651 }
652 }
653
654
662 public function accountActivate($id, $mode = 0)
663 {
664 // phpcs:enable
665 $this->db->begin();
666
667 $fieldtouse = 'active';
668 if ($mode == 1) {
669 $fieldtouse = 'reconcilable';
670 }
671
672 $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account";
673 $sql .= " SET ".$fieldtouse." = '1'";
674 $sql .= " WHERE rowid = ".((int) $id);
675
676 dol_syslog(get_class($this)."::account_activate ".$fieldtouse, LOG_DEBUG);
677 $result = $this->db->query($sql);
678 if ($result) {
679 $this->db->commit();
680 return 1;
681 } else {
682 $this->error = $this->db->lasterror();
683 $this->db->rollback();
684 return -1;
685 }
686 }
687
694 public function getLibStatut($mode = 0)
695 {
696 return $this->LibStatut($this->status, $mode);
697 }
698
699 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
707 public function LibStatut($status, $mode = 0)
708 {
709 // phpcs:enable
710 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
711 global $langs;
712 $langs->load("users");
713 $this->labelStatus[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
714 $this->labelStatus[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
715 $this->labelStatusShort[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
716 $this->labelStatusShort[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
717 }
718
719 $statusType = 'status4';
720 if ($status == self::STATUS_DISABLED) {
721 $statusType = 'status5';
722 }
723
724 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
725 }
726
741 public function getAccountingCodeToBind(Societe $buyer, Societe $seller, Product $product, $facture, $factureDet, $accountingAccount = array(), $type = '')
742 {
743 global $conf;
744 global $hookmanager;
745
746 // Instantiate hooks for external modules
747 $hookmanager->initHooks(array('accountancyBindingCalculation'));
748
749 // Execute hook accountancyBindingCalculation
750 $parameters = array('buyer' => $buyer, 'seller' => $seller, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount, $type);
751 $reshook = $hookmanager->executeHooks('accountancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks
752
753 if (empty($reshook)) {
754 $const_name = '';
755 if ($type == 'customer') {
756 $const_name = "SOLD";
757 } elseif ($type == 'supplier') {
758 $const_name = "BUY";
759 }
760
761 require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
762 $isBuyerInEEC = isInEEC($buyer);
763 $isSellerInEEC = isInEEC($seller);
764 $code_l = ''; // Default value for generic product/service
765 $code_p = ''; // Value for the product/service in parameter ($product)
766 $code_t = ''; // Default value of product account for the thirdparty
767 $suggestedid = '';
768
769 // Level 1 (define $code_l): Search suggested default account for product/service
770 $suggestedaccountingaccountbydefaultfor = '';
771 if ($factureDet->product_type == 1) {
772 if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country)
773 $code_l = getDolGlobalString('ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT');
774 $suggestedaccountingaccountbydefaultfor = '';
775 } else {
776 if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT
777 $code_l = getDolGlobalString('ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT');
778 $suggestedaccountingaccountbydefaultfor = 'eecwithvat';
779 } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number
780 $code_l = getDolGlobalString('ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT');
781 $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
782 } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
783 $code_l = getDolGlobalString('ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT');
784 $suggestedaccountingaccountbydefaultfor = 'eec';
785 } else { // Foreign sale
786 $code_l = getDolGlobalString('ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT');
787 $suggestedaccountingaccountbydefaultfor = 'export';
788 }
789 }
790 } elseif ($factureDet->product_type == 0) {
791 if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country)
792 $code_l = getDolGlobalString('ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT');
793 $suggestedaccountingaccountbydefaultfor = '';
794 } else {
795 if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT
796 $code_l = getDolGlobalString('ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT');
797 $suggestedaccountingaccountbydefaultfor = 'eecwithvat';
798 } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number
799 $code_l = getDolGlobalString('ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT');
800 $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
801 } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
802 $code_l = getDolGlobalString('ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT');
803 $suggestedaccountingaccountbydefaultfor = 'eec';
804 } else {
805 $code_l = getDolGlobalString('ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT');
806 $suggestedaccountingaccountbydefaultfor = 'export';
807 }
808 }
809 }
810 if ($code_l == -1) {
811 $code_l = '';
812 }
813
814 // Level 2 (define $code_p): Search suggested account for product/service (similar code exists in page index.php to make automatic binding)
815 $suggestedaccountingaccountfor = '';
816 if ((($buyer->country_code == $seller->country_code) || empty($buyer->country_code))) {
817 // If buyer in same country than seller (if not defined, we assume it is same country)
818 if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
819 $code_p = $product->accountancy_code_sell;
820 } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
821 $code_p = $product->accountancy_code_buy;
822 }
823 $suggestedid = $accountingAccount['dom'];
824 $suggestedaccountingaccountfor = 'prodserv';
825 } else {
826 if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) {
827 // European intravat sale, but with VAT
828 if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
829 $code_p = $product->accountancy_code_sell;
830 } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
831 $code_p = $product->accountancy_code_buy;
832 }
833 $suggestedid = $accountingAccount['dom'];
834 $suggestedaccountingaccountfor = 'eecwithvat';
835 } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) {
836 // European intravat sale, without VAT intra community number
837 if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
838 $code_p = $product->accountancy_code_sell;
839 } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
840 $code_p = $product->accountancy_code_buy;
841 }
842 $suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ?
843 $suggestedaccountingaccountfor = 'eecwithoutvatnumber';
844 } elseif ($isSellerInEEC && $isBuyerInEEC && (($type == 'customer' && !empty($product->accountancy_code_sell_intra)) || ($type == 'supplier' && !empty($product->accountancy_code_buy_intra)))) {
845 // European intravat sale
846 if ($type == 'customer' && !empty($product->accountancy_code_sell_intra)) {
847 $code_p = $product->accountancy_code_sell_intra;
848 } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy_intra)) {
849 $code_p = $product->accountancy_code_buy_intra;
850 }
851 $suggestedid = $accountingAccount['intra'];
852 $suggestedaccountingaccountfor = 'eec';
853 } else {
854 // Foreign sale
855 if ($type == 'customer' && !empty($product->accountancy_code_sell_export)) {
856 $code_p = $product->accountancy_code_sell_export;
857 } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy_export)) {
858 $code_p = $product->accountancy_code_buy_export;
859 }
860 $suggestedid = $accountingAccount['export'];
861 $suggestedaccountingaccountfor = 'export';
862 }
863 }
864
865 // Level 3 (define $code_t): Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding)
866 if (getDolGlobalString('ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY')) {
867 if ($type == 'customer' && !empty($buyer->code_compta_product)) {
868 $code_t = $buyer->code_compta_product;
869 $suggestedid = $accountingAccount['thirdparty'];
870 $suggestedaccountingaccountfor = 'thirdparty';
871 } elseif ($type == 'supplier' && !empty($seller->code_compta_product)) {
872 $code_t = $seller->code_compta_product;
873 $suggestedid = $accountingAccount['thirdparty'];
874 $suggestedaccountingaccountfor = 'thirdparty';
875 }
876 }
877
878 // Manage Deposit
879 if (getDolGlobalString('ACCOUNTING_ACCOUNT_' . strtoupper($type) . '_DEPOSIT')) {
880 if ($factureDet->desc == "(DEPOSIT)" || $facture->type == $facture::TYPE_DEPOSIT) {
881 $accountdeposittoventilated = new self($this->db);
882 if ($type == 'customer') {
883 $result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
884 } elseif ($type == 'supplier') {
885 $result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT, 1);
886 }
887 if (isset($result) && $result < 0) {
888 return -1;
889 }
890
891 $code_l = $accountdeposittoventilated->ref;
892 $code_p = '';
893 $code_t = '';
894 $suggestedid = $accountdeposittoventilated->rowid;
895 $suggestedaccountingaccountfor = 'deposit';
896 }
897
898 // For credit note invoice, if origin invoice is a deposit invoice, force also on specific customer/supplier deposit account
899 if (!empty($facture->fk_facture_source)) {
900 $invoiceSource = new $facture($this->db);
901 $invoiceSource->fetch($facture->fk_facture_source);
902
903 if ($facture->type == $facture::TYPE_CREDIT_NOTE && $invoiceSource->type == $facture::TYPE_DEPOSIT) {
904 $accountdeposittoventilated = new self($this->db);
905 if ($type == 'customer') {
906 $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
907 } elseif ($type == 'supplier') {
908 $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT, 1);
909 }
910 $code_l = $accountdeposittoventilated->ref;
911 $code_p = '';
912 $code_t = '';
913 $suggestedid = $accountdeposittoventilated->rowid;
914 $suggestedaccountingaccountfor = 'deposit';
915 }
916 }
917 }
918
919 // If $suggestedid could not be guessed yet, we set it from the generic default accounting code $code_l
920 if (empty($suggestedid) && empty($code_p) && !empty($code_l) && !getDolGlobalString('ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC')) {
921 if (empty($this->accountingaccount_codetotid_cache[$code_l])) {
922 $tmpaccount = new self($this->db);
923 $result = $tmpaccount->fetch(0, $code_l, 1);
924 if ($result < 0) {
925 return -1;
926 }
927 if ($tmpaccount->id > 0) {
928 $suggestedid = $tmpaccount->id;
929 }
930 $this->accountingaccount_codetotid_cache[$code_l] = $tmpaccount->id;
931 } else {
932 $suggestedid = $this->accountingaccount_codetotid_cache[$code_l];
933 }
934 }
935 return array(
936 'suggestedaccountingaccountbydefaultfor' => $suggestedaccountingaccountbydefaultfor,
937 'suggestedaccountingaccountfor' => $suggestedaccountingaccountfor,
938 'suggestedid' => $suggestedid,
939 'code_l' => $code_l,
940 'code_p' => $code_p,
941 'code_t' => $code_t,
942 );
943 } else {
944 if (is_array($hookmanager->resArray) && !empty($hookmanager->resArray)) {
945 return $hookmanager->resArray;
946 }
947 }
948
949 return -1;
950 }
951}
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition security.php:604
$object ref
Definition info.php:79
Class to manage accounting accounts.
LibStatut($status, $mode=0)
Return the label of a given status.
accountDeactivate($id, $mode=0)
Deactivate an account (for status active or status reconcilable)
checkUsage()
Check usage of accounting code.
update($user)
Update record.
getNomUrl($withpicto=0, $withlabel=0, $nourl=0, $moretitle='', $notooltip=0, $save_lastsearch_value=-1, $withcompletelabel=0, $option='')
Return clicable name (with picto eventually)
create($user, $notrigger=0)
Insert new accounting account in chart of accounts.
accountActivate($id, $mode=0)
Account activated.
info($id)
Information on record.
fetch($rowid=null, $account_number=null, $limittocurrentchart=0, $limittoachartaccount='')
Load record in memory.
getAccountingCodeToBind(Societe $buyer, Societe $seller, Product $product, $facture, $factureDet, $accountingAccount=array(), $type='')
Return a suggested account (from chart of accounts) to bind.
getLibStatut($mode=0)
Return the label of the status.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Class to manage products or services.
Class to manage third parties objects (customers, suppliers, prospects...)
isInEEC($object)
Return if a country of an object is inside the EEC (European Economic Community)
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
Definition invoice.php:1926