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