dolibarr  18.0.6
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 
29 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
31 require_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  global $conf;
170 
171  $this->db = $db;
172  $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
173  }
174 
184  public function fetch($rowid = null, $account_number = null, $limittocurrentchart = 0, $limittoachartaccount = '')
185  {
186  global $conf;
187 
188  if ($rowid || $account_number) {
189  $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";
190  $sql .= ", ca.label as category_label";
191  $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as a";
192  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as ca ON a.fk_accounting_category = ca.rowid";
193  $sql .= " WHERE";
194  if ($rowid) {
195  $sql .= " a.rowid = ".(int) $rowid;
196  } elseif ($account_number) {
197  $sql .= " a.account_number = '".$this->db->escape($account_number)."'";
198  $sql .= " AND a.entity = ".$conf->entity;
199  }
200  if (!empty($limittocurrentchart)) {
201  $sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM '.MAIN_DB_PREFIX.'accounting_system WHERE rowid = '.((int) getDolGlobalInt('CHARTOFACCOUNTS')).')';
202  }
203  if (!empty($limittoachartaccount)) {
204  $sql .= " AND a.fk_pcg_version = '".$this->db->escape($limittoachartaccount)."'";
205  }
206 
207  dol_syslog(get_class($this)."::fetch rowid=".$rowid." account_number=".$account_number, LOG_DEBUG);
208 
209  $result = $this->db->query($sql);
210  if ($result) {
211  $obj = $this->db->fetch_object($result);
212 
213  if ($obj) {
214  $this->id = $obj->rowid;
215  $this->rowid = $obj->rowid;
216  $this->ref = $obj->account_number;
217  $this->datec = $this->db->jdate($obj->datec);
218  $this->date_creation = $this->db->jdate($obj->datec);
219  $this->date_modification = $this->db->jdate($obj->tms);
220  //$this->tms = $this->datem;
221  $this->fk_pcg_version = $obj->fk_pcg_version;
222  $this->pcg_type = $obj->pcg_type;
223  $this->account_number = $obj->account_number;
224  $this->account_parent = $obj->account_parent;
225  $this->label = $obj->label;
226  $this->labelshort = $obj->labelshort;
227  $this->account_category = $obj->fk_accounting_category;
228  $this->account_category_label = $obj->category_label;
229  $this->fk_user_author = $obj->fk_user_author;
230  $this->fk_user_modif = $obj->fk_user_modif;
231  $this->active = $obj->active;
232  $this->status = $obj->active;
233  $this->reconcilable = $obj->reconcilable;
234 
235  return $this->id;
236  } else {
237  return 0;
238  }
239  } else {
240  $this->error = "Error ".$this->db->lasterror();
241  $this->errors[] = "Error ".$this->db->lasterror();
242  }
243  }
244  return -1;
245  }
246 
254  public function create($user, $notrigger = 0)
255  {
256  global $conf;
257  $error = 0;
258  $now = dol_now();
259 
260  // Clean parameters
261  if (isset($this->fk_pcg_version)) {
262  $this->fk_pcg_version = trim($this->fk_pcg_version);
263  }
264  if (isset($this->pcg_type)) {
265  $this->pcg_type = trim($this->pcg_type);
266  }
267  if (isset($this->account_number)) {
268  $this->account_number = trim($this->account_number);
269  }
270  if (isset($this->label)) {
271  $this->label = trim($this->label);
272  }
273  if (isset($this->labelshort)) {
274  $this->labelshort = trim($this->labelshort);
275  }
276 
277  if (empty($this->pcg_type) || $this->pcg_type == '-1') {
278  $this->pcg_type = 'XXXXXX';
279  }
280  // Check parameters
281  // Put here code to add control on parameters values
282 
283  // Insert request
284  $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account(";
285  $sql .= "datec";
286  $sql .= ", entity";
287  $sql .= ", fk_pcg_version";
288  $sql .= ", pcg_type";
289  $sql .= ", account_number";
290  $sql .= ", account_parent";
291  $sql .= ", label";
292  $sql .= ", labelshort";
293  $sql .= ", fk_accounting_category";
294  $sql .= ", fk_user_author";
295  $sql .= ", active";
296  $sql .= ", reconcilable";
297  $sql .= ") VALUES (";
298  $sql .= " '".$this->db->idate($now)."'";
299  $sql .= ", ".((int) $conf->entity);
300  $sql .= ", ".(empty($this->fk_pcg_version) ? 'NULL' : "'".$this->db->escape($this->fk_pcg_version)."'");
301  $sql .= ", ".(empty($this->pcg_type) ? 'NULL' : "'".$this->db->escape($this->pcg_type)."'");
302  $sql .= ", ".(empty($this->account_number) ? 'NULL' : "'".$this->db->escape($this->account_number)."'");
303  $sql .= ", ".(empty($this->account_parent) ? 0 : (int) $this->account_parent);
304  $sql .= ", ".(empty($this->label) ? "''" : "'".$this->db->escape($this->label)."'");
305  $sql .= ", ".(empty($this->labelshort) ? "''" : "'".$this->db->escape($this->labelshort)."'");
306  $sql .= ", ".(empty($this->account_category) ? 0 : (int) $this->account_category);
307  $sql .= ", ".((int) $user->id);
308  $sql .= ", ".(int) $this->active;
309  $sql .= ", ".(int) $this->reconcilable;
310  $sql .= ")";
311 
312  $this->db->begin();
313 
314  dol_syslog(get_class($this)."::create", LOG_DEBUG);
315  $resql = $this->db->query($sql);
316  if (!$resql) {
317  $error++;
318  $this->errors[] = "Error " . $this->db->lasterror();
319  }
320 
321  if (!$error) {
322  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account");
323 
324  // Uncomment this and change MYOBJECT to your own tag if you
325  // want this action to call a trigger.
326  //if (! $error && ! $notrigger) {
327 
328  // // Call triggers
329  // $result=$this->call_trigger('MYOBJECT_CREATE',$user);
330  // if ($result < 0) $error++;
331  // // End call triggers
332  //}
333  }
334 
335  // Commit or rollback
336  if ($error) {
337  foreach ($this->errors as $errmsg) {
338  dol_syslog(get_class($this) . "::create " . $errmsg, LOG_ERR);
339  $this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
340  }
341  $this->db->rollback();
342  return -1 * $error;
343  } else {
344  $this->db->commit();
345  return $this->id;
346  }
347  }
348 
355  public function update($user)
356  {
357  // Check parameters
358  if (empty($this->pcg_type) || $this->pcg_type == '-1') {
359  $this->pcg_type = 'XXXXXX';
360  }
361 
362  $this->db->begin();
363 
364  $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account ";
365  $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null");
366  $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null");
367  $sql .= " , account_number = '" . $this->db->escape($this->account_number) . "'";
368  $sql .= " , account_parent = " . (int) $this->account_parent;
369  $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "''");
370  $sql .= " , labelshort = " . ($this->labelshort ? "'" . $this->db->escape($this->labelshort) . "'" : "''");
371  $sql .= " , fk_accounting_category = " . (empty($this->account_category) ? 0 : (int) $this->account_category);
372  $sql .= " , fk_user_modif = " . ((int) $user->id);
373  $sql .= " , active = " . (int) $this->active;
374  $sql .= " , reconcilable = " . (int) $this->reconcilable;
375  $sql .= " WHERE rowid = " . ((int) $this->id);
376 
377  dol_syslog(get_class($this)."::update", LOG_DEBUG);
378  $result = $this->db->query($sql);
379  if ($result) {
380  $this->db->commit();
381  return 1;
382  } else {
383  if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
384  $this->error = $this->db->lasterror();
385  $this->db->rollback();
386  return -2;
387  }
388 
389  $this->error = $this->db->lasterror();
390  $this->db->rollback();
391  return -1;
392  }
393  }
394 
400  public function checkUsage()
401  {
402  global $langs;
403 
404  // TODO Looks a stupid check
405  $sql = "(SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facturedet";
406  $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")";
407  $sql .= "UNION";
408  $sql .= " (SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facture_fourn_det";
409  $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")";
410 
411  dol_syslog(get_class($this)."::checkUsage", LOG_DEBUG);
412  $resql = $this->db->query($sql);
413 
414  if ($resql) {
415  $num = $this->db->num_rows($resql);
416  if ($num > 0) {
417  $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse');
418  return 0;
419  } else {
420  return 1;
421  }
422  } else {
423  $this->error = $this->db->lasterror();
424  return -1;
425  }
426  }
427 
435  public function delete($user, $notrigger = 0)
436  {
437  $error = 0;
438 
439  $result = $this->checkUsage();
440 
441  if ($result > 0) {
442  $this->db->begin();
443 
444  if (!$error) {
445  $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account";
446  $sql .= " WHERE rowid=" . ((int) $this->id);
447 
448  dol_syslog(get_class($this) . "::delete sql=" . $sql);
449  $resql = $this->db->query($sql);
450  if (!$resql) {
451  $error++;
452  $this->errors[] = "Error " . $this->db->lasterror();
453  }
454  }
455 
456  // Commit or rollback
457  if ($error) {
458  foreach ($this->errors as $errmsg) {
459  dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
460  $this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
461  }
462  $this->db->rollback();
463  return -1 * $error;
464  } else {
465  $this->db->commit();
466  return 1;
467  }
468  } else {
469  return -1;
470  }
471  }
472 
486  public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '')
487  {
488  global $langs, $conf, $hookmanager;
489  require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
490 
491  if (!empty($conf->dol_no_mouse_hover)) {
492  $notooltip = 1; // Force disable tooltips
493  }
494 
495  $result = '';
496 
497  $url = '';
498  $labelurl = '';
499  if (empty($option) || $option == 'ledger') {
500  $url = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number);
501  $labelurl = $langs->trans("ShowAccountingAccountInLedger");
502  } elseif ($option == 'journals') {
503  $url = DOL_URL_ROOT . '/accountancy/bookkeeping/list.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number);
504  $labelurl = $langs->trans("ShowAccountingAccountInJournals");
505  } elseif ($option == 'accountcard') {
506  $url = DOL_URL_ROOT . '/accountancy/admin/card.php?id=' . urlencode($this->id);
507  $labelurl = $langs->trans("ShowAccountingAccount");
508  }
509 
510  // Add param to save lastsearch_values or not
511  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
512  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
513  $add_save_lastsearch_values = 1;
514  }
515  if ($add_save_lastsearch_values) {
516  $url .= '&save_lastsearch_values=1';
517  }
518 
519  $picto = 'accounting_account';
520  $label = '';
521 
522  if (empty($this->labelshort) || $withcompletelabel == 1) {
523  $labeltoshow = $this->label;
524  } else {
525  $labeltoshow = $this->labelshort;
526  }
527 
528  $label = '<u>' . $labelurl . '</u>';
529  if (!empty($this->account_number)) {
530  $label .= '<br><b>' . $langs->trans('AccountAccounting') . ':</b> ' . length_accountg($this->account_number);
531  }
532  if (!empty($labeltoshow)) {
533  $label .= '<br><b>' . $langs->trans('Label') . ':</b> ' . $labeltoshow;
534  }
535  if ($moretitle) {
536  $label .= ' - ' . $moretitle;
537  }
538 
539  $linkclose = '';
540  if (empty($notooltip)) {
541  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
542  $label = $labelurl;
543  $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
544  }
545  $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
546  $linkclose .= ' class="classfortooltip"';
547  }
548 
549  $linkstart = '<a href="' . $url . '"';
550  $linkstart .= $linkclose . '>';
551  $linkend = '</a>';
552 
553  if ($nourl) {
554  $linkstart = '';
555  $linkclose = '';
556  $linkend = '';
557  }
558 
559  $label_link = length_accountg($this->account_number);
560  if ($withlabel) {
561  $label_link .= ' - ' . ($nourl ? '<span class="opacitymedium">' : '') . $labeltoshow . ($nourl ? '</span>' : '');
562  }
563 
564  if ($withpicto) {
565  $result .= ($linkstart . img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1) . $linkend);
566  }
567  if ($withpicto && $withpicto != 2) {
568  $result .= ' ';
569  }
570  if ($withpicto != 2) {
571  $result .= $linkstart . $label_link . $linkend;
572  }
573  global $action;
574  $hookmanager->initHooks(array($this->element . 'dao'));
575  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
576  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
577  if ($reshook > 0) {
578  $result = $hookmanager->resPrint;
579  } else {
580  $result .= $hookmanager->resPrint;
581  }
582  return $result;
583  }
584 
591  public function info($id)
592  {
593  $sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms as date_modification';
594  $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a';
595  $sql .= ' WHERE a.rowid = ' . ((int) $id);
596 
597  dol_syslog(get_class($this) . '::info sql=' . $sql);
598  $resql = $this->db->query($sql);
599 
600  if ($resql) {
601  if ($this->db->num_rows($resql)) {
602  $obj = $this->db->fetch_object($resql);
603  $this->id = $obj->rowid;
604 
605  $this->user_creation_id = $obj->fk_user_author;
606  $this->user_modification_id = $obj->fk_user_modif;
607  $this->date_creation = $this->db->jdate($obj->datec);
608  $this->date_modification = $this->db->jdate($obj->date_modification);
609  }
610  $this->db->free($resql);
611  } else {
612  dol_print_error($this->db);
613  }
614  }
615 
623  public function accountDeactivate($id, $mode = 0)
624  {
625  $result = $this->checkUsage();
626 
627  $fieldtouse = 'active';
628  if ($mode == 1) {
629  $fieldtouse = 'reconcilable';
630  }
631 
632  if ($result > 0) {
633  $this->db->begin();
634 
635  $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account ";
636  $sql .= "SET ".$fieldtouse." = '0'";
637  $sql .= " WHERE rowid = ".((int) $id);
638 
639  dol_syslog(get_class($this)."::accountDeactivate ".$fieldtouse, LOG_DEBUG);
640  $result = $this->db->query($sql);
641 
642  if ($result) {
643  $this->db->commit();
644  return 1;
645  } else {
646  $this->error = $this->db->lasterror();
647  $this->db->rollback();
648  return -1;
649  }
650  } else {
651  return -1;
652  }
653  }
654 
655 
663  public function accountActivate($id, $mode = 0)
664  {
665  // phpcs:enable
666  $this->db->begin();
667 
668  $fieldtouse = 'active';
669  if ($mode == 1) {
670  $fieldtouse = 'reconcilable';
671  }
672 
673  $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account";
674  $sql .= " SET ".$fieldtouse." = '1'";
675  $sql .= " WHERE rowid = ".((int) $id);
676 
677  dol_syslog(get_class($this)."::account_activate ".$fieldtouse, LOG_DEBUG);
678  $result = $this->db->query($sql);
679  if ($result) {
680  $this->db->commit();
681  return 1;
682  } else {
683  $this->error = $this->db->lasterror();
684  $this->db->rollback();
685  return -1;
686  }
687  }
688 
695  public function getLibStatut($mode = 0)
696  {
697  return $this->LibStatut($this->status, $mode);
698  }
699 
700  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
708  public function LibStatut($status, $mode = 0)
709  {
710  // phpcs:enable
711  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
712  global $langs;
713  $langs->load("users");
714  $this->labelStatus[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
715  $this->labelStatus[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
716  $this->labelStatusShort[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
717  $this->labelStatusShort[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
718  }
719 
720  $statusType = 'status4';
721  if ($status == self::STATUS_DISABLED) {
722  $statusType = 'status5';
723  }
724 
725  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
726  }
727 
742  public function getAccountingCodeToBind(Societe $buyer, Societe $seller, Product $product, $facture, $factureDet, $accountingAccount = array(), $type = '')
743  {
744  global $conf;
745  global $hookmanager;
746 
747  // Instantiate hooks for external modules
748  $hookmanager->initHooks(array('accountancyBindingCalculation'));
749 
750  // Execute hook accountancyBindingCalculation
751  $parameters = array('buyer' => $buyer, 'seller' => $seller, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount, $type);
752  $reshook = $hookmanager->executeHooks('accountancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks
753 
754  if (empty($reshook)) {
755  $const_name = '';
756  if ($type == 'customer') {
757  $const_name = "SOLD";
758  } elseif ($type == 'supplier') {
759  $const_name = "BUY";
760  }
761 
762  require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
763  $isBuyerInEEC = isInEEC($buyer);
764  $isSellerInEEC = isInEEC($seller);
765  $code_l = ''; // Default value for generic product/service
766  $code_p = ''; // Value for the product/service in parameter ($product)
767  $code_t = ''; // Default value of product account for the thirdparty
768  $suggestedid = '';
769 
770  // Level 1 (define $code_l): Search suggested default account for product/service
771  $suggestedaccountingaccountbydefaultfor = '';
772  if ($factureDet->product_type == 1) {
773  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)
774  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
775  $suggestedaccountingaccountbydefaultfor = '';
776  } else {
777  if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT
778  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
779  $suggestedaccountingaccountbydefaultfor = 'eecwithvat';
780  } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number
781  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
782  $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
783  } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
784  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT'} : '');
785  $suggestedaccountingaccountbydefaultfor = 'eec';
786  } else { // Foreign sale
787  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT'} : '');
788  $suggestedaccountingaccountbydefaultfor = 'export';
789  }
790  }
791  } elseif ($factureDet->product_type == 0) {
792  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)
793  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
794  $suggestedaccountingaccountbydefaultfor = '';
795  } else {
796  if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT
797  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
798  $suggestedaccountingaccountbydefaultfor = 'eecwithvat';
799  } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number
800  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
801  $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
802  } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
803  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT'} : '');
804  $suggestedaccountingaccountbydefaultfor = 'eec';
805  } else {
806  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT'} : '');
807  $suggestedaccountingaccountbydefaultfor = 'export';
808  }
809  }
810  }
811  if ($code_l == -1) {
812  $code_l = '';
813  }
814 
815  // Level 2 (define $code_p): Search suggested account for product/service (similar code exists in page index.php to make automatic binding)
816  $suggestedaccountingaccountfor = '';
817  if ((($buyer->country_code == $seller->country_code) || empty($buyer->country_code))) {
818  // If buyer in same country than seller (if not defined, we assume it is same country)
819  if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
820  $code_p = $product->accountancy_code_sell;
821  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
822  $code_p = $product->accountancy_code_buy;
823  }
824  $suggestedid = $accountingAccount['dom'];
825  $suggestedaccountingaccountfor = 'prodserv';
826  } else {
827  if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) {
828  // European intravat sale, but with VAT
829  if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
830  $code_p = $product->accountancy_code_sell;
831  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
832  $code_p = $product->accountancy_code_buy;
833  }
834  $suggestedid = $accountingAccount['dom'];
835  $suggestedaccountingaccountfor = 'eecwithvat';
836  } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) {
837  // European intravat sale, without VAT intra community number
838  if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
839  $code_p = $product->accountancy_code_sell;
840  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
841  $code_p = $product->accountancy_code_buy;
842  }
843  $suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ?
844  $suggestedaccountingaccountfor = 'eecwithoutvatnumber';
845  } elseif ($isSellerInEEC && $isBuyerInEEC) {
846  // European intravat sale
847  if ($type == 'customer' && !empty($product->accountancy_code_sell_intra)) {
848  $code_p = $product->accountancy_code_sell_intra;
849  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy_intra)) {
850  $code_p = $product->accountancy_code_buy_intra;
851  }
852  $suggestedid = $accountingAccount['intra'];
853  $suggestedaccountingaccountfor = 'eec';
854  } else {
855  // Foreign sale
856  if ($type == 'customer' && !empty($product->accountancy_code_sell_export)) {
857  $code_p = $product->accountancy_code_sell_export;
858  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy_export)) {
859  $code_p = $product->accountancy_code_buy_export;
860  }
861  $suggestedid = $accountingAccount['export'];
862  $suggestedaccountingaccountfor = 'export';
863  }
864  }
865 
866  // Level 3 (define $code_t): Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding)
867  if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
868  if ($type == 'customer' && !empty($buyer->code_compta_product)) {
869  $code_t = $buyer->code_compta_product;
870  $suggestedid = $accountingAccount['thirdparty'];
871  $suggestedaccountingaccountfor = 'thirdparty';
872  } elseif ($type == 'supplier' && !empty($seller->code_compta_product)) {
873  $code_t = $seller->code_compta_product;
874  $suggestedid = $accountingAccount['thirdparty'];
875  $suggestedaccountingaccountfor = 'thirdparty';
876  }
877  }
878 
879  // Manage Deposit
880  if (getDolGlobalString('ACCOUNTING_ACCOUNT_' . strtoupper($type) . '_DEPOSIT')) {
881  if ($factureDet->desc == "(DEPOSIT)" || $facture->type == $facture::TYPE_DEPOSIT) {
882  $accountdeposittoventilated = new self($this->db);
883  if ($type == 'customer') {
884  $result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
885  } elseif ($type == 'supplier') {
886  $result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT, 1);
887  }
888  if (isset($result) && $result < 0) {
889  return -1;
890  }
891 
892  $code_l = $accountdeposittoventilated->ref;
893  $code_p = '';
894  $code_t = '';
895  $suggestedid = $accountdeposittoventilated->rowid;
896  $suggestedaccountingaccountfor = 'deposit';
897  }
898 
899  // For credit note invoice, if origin invoice is a deposit invoice, force also on specific customer/supplier deposit account
900  if (!empty($facture->fk_facture_source)) {
901  $invoiceSource = new $facture($this->db);
902  $invoiceSource->fetch($facture->fk_facture_source);
903 
904  if ($facture->type == $facture::TYPE_CREDIT_NOTE && $invoiceSource->type == $facture::TYPE_DEPOSIT) {
905  $accountdeposittoventilated = new self($this->db);
906  if ($type == 'customer') {
907  $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
908  } elseif ($type == 'supplier') {
909  $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT, 1);
910  }
911  $code_l = $accountdeposittoventilated->ref;
912  $code_p = '';
913  $code_t = '';
914  $suggestedid = $accountdeposittoventilated->rowid;
915  $suggestedaccountingaccountfor = 'deposit';
916  }
917  }
918  }
919 
920  // If $suggestedid could not be guessed yet, we set it from the generic default accounting code $code_l
921  if (empty($suggestedid) && empty($code_p) && !empty($code_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) {
922  if (empty($this->accountingaccount_codetotid_cache[$code_l])) {
923  $tmpaccount = new self($this->db);
924  $result = $tmpaccount->fetch(0, $code_l, 1);
925  if ($result < 0) {
926  return -1;
927  }
928  if ($tmpaccount->id > 0) {
929  $suggestedid = $tmpaccount->id;
930  }
931  $this->accountingaccount_codetotid_cache[$code_l] = $tmpaccount->id;
932  } else {
933  $suggestedid = $this->accountingaccount_codetotid_cache[$code_l];
934  }
935  }
936  return array(
937  'suggestedaccountingaccountbydefaultfor' => $suggestedaccountingaccountbydefaultfor,
938  'suggestedaccountingaccountfor' => $suggestedaccountingaccountfor,
939  'suggestedid' => $suggestedid,
940  'code_l' => $code_l,
941  'code_p' => $code_p,
942  'code_t' => $code_t,
943  );
944  } else {
945  if (is_array($hookmanager->resArray) && !empty($hookmanager->resArray)) {
946  return $hookmanager->resArray;
947  }
948  }
949  }
950 }
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
$object ref
Definition: info.php:78
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)
__construct($db)
Constructor.
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)
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
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 dolibarr global constant int value.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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...