dolibarr  17.0.4
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-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
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) $conf->global->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) $conf->global->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 = $obj->datec;
218  $this->tms = $obj->tms;
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  $sql = "(SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facturedet";
403  $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")";
404  $sql .= "UNION";
405  $sql .= " (SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facture_fourn_det";
406  $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")";
407 
408  dol_syslog(get_class($this)."::checkUsage", LOG_DEBUG);
409  $resql = $this->db->query($sql);
410 
411  if ($resql) {
412  $num = $this->db->num_rows($resql);
413  if ($num > 0) {
414  $this->error = $langs->trans('ErrorAccountancyCodeIsAlreadyUse');
415  return 0;
416  } else {
417  return 1;
418  }
419  } else {
420  $this->error = $this->db->lasterror();
421  return -1;
422  }
423  }
424 
432  public function delete($user, $notrigger = 0)
433  {
434  $error = 0;
435 
436  $result = $this->checkUsage();
437 
438  if ($result > 0) {
439  $this->db->begin();
440 
441  if (!$error) {
442  $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account";
443  $sql .= " WHERE rowid=" . ((int) $this->id);
444 
445  dol_syslog(get_class($this) . "::delete sql=" . $sql);
446  $resql = $this->db->query($sql);
447  if (!$resql) {
448  $error++;
449  $this->errors[] = "Error " . $this->db->lasterror();
450  }
451  }
452 
453  // Commit or rollback
454  if ($error) {
455  foreach ($this->errors as $errmsg) {
456  dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
457  $this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
458  }
459  $this->db->rollback();
460  return -1 * $error;
461  } else {
462  $this->db->commit();
463  return 1;
464  }
465  } else {
466  return -1;
467  }
468  }
469 
483  public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '')
484  {
485  global $langs, $conf, $hookmanager;
486  require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
487 
488  if (!empty($conf->dol_no_mouse_hover)) {
489  $notooltip = 1; // Force disable tooltips
490  }
491 
492  $result = '';
493 
494  $url = '';
495  $labelurl = '';
496  if (empty($option) || $option == 'ledger') {
497  $url = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number);
498  $labelurl = $langs->trans("ShowAccountingAccountInLedger");
499  } elseif ($option == 'journals') {
500  $url = DOL_URL_ROOT . '/accountancy/bookkeeping/list.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number);
501  $labelurl = $langs->trans("ShowAccountingAccountInJournals");
502  } elseif ($option == 'accountcard') {
503  $url = DOL_URL_ROOT . '/accountancy/admin/card.php?id=' . urlencode($this->id);
504  $labelurl = $langs->trans("ShowAccountingAccount");
505  }
506 
507  // Add param to save lastsearch_values or not
508  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
509  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
510  $add_save_lastsearch_values = 1;
511  }
512  if ($add_save_lastsearch_values) {
513  $url .= '&save_lastsearch_values=1';
514  }
515 
516  $picto = 'accounting_account';
517  $label = '';
518 
519  if (empty($this->labelshort) || $withcompletelabel == 1) {
520  $labeltoshow = $this->label;
521  } else {
522  $labeltoshow = $this->labelshort;
523  }
524 
525  $label = '<u>' . $labelurl . '</u>';
526  if (!empty($this->account_number)) {
527  $label .= '<br><b>' . $langs->trans('AccountAccounting') . ':</b> ' . length_accountg($this->account_number);
528  }
529  if (!empty($labeltoshow)) {
530  $label .= '<br><b>' . $langs->trans('Label') . ':</b> ' . $labeltoshow;
531  }
532  if ($moretitle) {
533  $label .= ' - ' . $moretitle;
534  }
535 
536  $linkclose = '';
537  if (empty($notooltip)) {
538  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
539  $label = $labelurl;
540  $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
541  }
542  $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
543  $linkclose .= ' class="classfortooltip"';
544  }
545 
546  $linkstart = '<a href="' . $url . '"';
547  $linkstart .= $linkclose . '>';
548  $linkend = '</a>';
549 
550  if ($nourl) {
551  $linkstart = '';
552  $linkclose = '';
553  $linkend = '';
554  }
555 
556  $label_link = length_accountg($this->account_number);
557  if ($withlabel) {
558  $label_link .= ' - ' . ($nourl ? '<span class="opacitymedium">' : '') . $labeltoshow . ($nourl ? '</span>' : '');
559  }
560 
561  if ($withpicto) {
562  $result .= ($linkstart . img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1) . $linkend);
563  }
564  if ($withpicto && $withpicto != 2) {
565  $result .= ' ';
566  }
567  if ($withpicto != 2) {
568  $result .= $linkstart . $label_link . $linkend;
569  }
570  global $action;
571  $hookmanager->initHooks(array($this->element . 'dao'));
572  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
573  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
574  if ($reshook > 0) {
575  $result = $hookmanager->resPrint;
576  } else {
577  $result .= $hookmanager->resPrint;
578  }
579  return $result;
580  }
581 
588  public function info($id)
589  {
590  $sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms';
591  $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a';
592  $sql .= ' WHERE a.rowid = ' . ((int) $id);
593 
594  dol_syslog(get_class($this) . '::info sql=' . $sql);
595  $resql = $this->db->query($sql);
596 
597  if ($resql) {
598  if ($this->db->num_rows($resql)) {
599  $obj = $this->db->fetch_object($resql);
600  $this->id = $obj->rowid;
601 
602  $this->user_creation_id = $obj->fk_user_author;
603  $this->user_modification_id = $obj->fk_user_modif;
604  $this->date_creation = $this->db->jdate($obj->datec);
605  $this->date_modification = $this->db->jdate($obj->tms);
606  }
607  $this->db->free($resql);
608  } else {
609  dol_print_error($this->db);
610  }
611  }
612 
620  public function accountDeactivate($id, $mode = 0)
621  {
622  $result = $this->checkUsage();
623 
624  $fieldtouse = 'active';
625  if ($mode == 1) {
626  $fieldtouse = 'reconcilable';
627  }
628 
629  if ($result > 0) {
630  $this->db->begin();
631 
632  $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account ";
633  $sql .= "SET ".$fieldtouse." = '0'";
634  $sql .= " WHERE rowid = ".((int) $id);
635 
636  dol_syslog(get_class($this)."::accountDeactivate ".$fieldtouse, LOG_DEBUG);
637  $result = $this->db->query($sql);
638 
639  if ($result) {
640  $this->db->commit();
641  return 1;
642  } else {
643  $this->error = $this->db->lasterror();
644  $this->db->rollback();
645  return -1;
646  }
647  } else {
648  return -1;
649  }
650  }
651 
652 
660  public function accountActivate($id, $mode = 0)
661  {
662  // phpcs:enable
663  $this->db->begin();
664 
665  $fieldtouse = 'active';
666  if ($mode == 1) {
667  $fieldtouse = 'reconcilable';
668  }
669 
670  $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account";
671  $sql .= " SET ".$fieldtouse." = '1'";
672  $sql .= " WHERE rowid = ".((int) $id);
673 
674  dol_syslog(get_class($this)."::account_activate ".$fieldtouse, LOG_DEBUG);
675  $result = $this->db->query($sql);
676  if ($result) {
677  $this->db->commit();
678  return 1;
679  } else {
680  $this->error = $this->db->lasterror();
681  $this->db->rollback();
682  return -1;
683  }
684  }
685 
692  public function getLibStatut($mode = 0)
693  {
694  return $this->LibStatut($this->status, $mode);
695  }
696 
697  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
705  public function LibStatut($status, $mode = 0)
706  {
707  // phpcs:enable
708  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
709  global $langs;
710  $langs->load("users");
711  $this->labelStatus[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
712  $this->labelStatus[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
713  $this->labelStatusShort[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
714  $this->labelStatusShort[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
715  }
716 
717  $statusType = 'status4';
718  if ($status == self::STATUS_DISABLED) {
719  $statusType = 'status5';
720  }
721 
722  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
723  }
724 
739  public function getAccountingCodeToBind(Societe $buyer, Societe $seller, Product $product, $facture, $factureDet, $accountingAccount = array(), $type = '')
740  {
741  global $conf;
742  global $hookmanager;
743 
744  // Instantiate hooks for external modules
745  $hookmanager->initHooks(array('accountancyBindingCalculation'));
746 
747  // Execute hook accountancyBindingCalculation
748  $parameters = array('buyer' => $buyer, 'seller' => $seller, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount, $type);
749  $reshook = $hookmanager->executeHooks('accountancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks
750 
751  if (empty($reshook)) {
752  $const_name = '';
753  if ($type == 'customer') {
754  $const_name = "SOLD";
755  } elseif ($type == 'supplier') {
756  $const_name = "BUY";
757  }
758 
759  require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
760  $isBuyerInEEC = isInEEC($buyer);
761  $isSellerInEEC = isInEEC($seller);
762  $code_l = ''; // Default value for generic product/service
763  $code_p = ''; // Value for the product/service in parameter ($product)
764  $code_t = ''; // Default value of product account for the thirdparty
765  $suggestedid = '';
766 
767  // Level 1 (define $code_l): Search suggested default account for product/service
768  $suggestedaccountingaccountbydefaultfor = '';
769  if ($factureDet->product_type == 1) {
770  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)
771  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
772  $suggestedaccountingaccountbydefaultfor = '';
773  } else {
774  if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT
775  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
776  $suggestedaccountingaccountbydefaultfor = 'eecwithvat';
777  } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number
778  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
779  $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
780  } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
781  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT'} : '');
782  $suggestedaccountingaccountbydefaultfor = 'eec';
783  } else { // Foreign sale
784  $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT'} : '');
785  $suggestedaccountingaccountbydefaultfor = 'export';
786  }
787  }
788  } elseif ($factureDet->product_type == 0) {
789  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)
790  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
791  $suggestedaccountingaccountbydefaultfor = '';
792  } else {
793  if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT
794  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
795  $suggestedaccountingaccountbydefaultfor = 'eecwithvat';
796  } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number
797  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
798  $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
799  } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
800  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT'} : '');
801  $suggestedaccountingaccountbydefaultfor = 'eec';
802  } else {
803  $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT'} : '');
804  $suggestedaccountingaccountbydefaultfor = 'export';
805  }
806  }
807  }
808  if ($code_l == -1) {
809  $code_l = '';
810  }
811 
812  // Level 2 (define $code_p): Search suggested account for product/service (similar code exists in page index.php to make automatic binding)
813  $suggestedaccountingaccountfor = '';
814  if ((($buyer->country_code == $seller->country_code) || empty($buyer->country_code))) {
815  // If buyer in same country than seller (if not defined, we assume it is same country)
816  if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
817  $code_p = $product->accountancy_code_sell;
818  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
819  $code_p = $product->accountancy_code_buy;
820  }
821  $suggestedid = $accountingAccount['dom'];
822  $suggestedaccountingaccountfor = 'prodserv';
823  } else {
824  if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) {
825  // European intravat sale, but with VAT
826  if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
827  $code_p = $product->accountancy_code_sell;
828  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
829  $code_p = $product->accountancy_code_buy;
830  }
831  $suggestedid = $accountingAccount['dom'];
832  $suggestedaccountingaccountfor = 'eecwithvat';
833  } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) {
834  // European intravat sale, without VAT intra community number
835  if ($type == 'customer' && !empty($product->accountancy_code_sell)) {
836  $code_p = $product->accountancy_code_sell;
837  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy)) {
838  $code_p = $product->accountancy_code_buy;
839  }
840  $suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ?
841  $suggestedaccountingaccountfor = 'eecwithoutvatnumber';
842  } elseif ($isSellerInEEC && $isBuyerInEEC) {
843  // European intravat sale
844  if ($type == 'customer' && !empty($product->accountancy_code_sell_intra)) {
845  $code_p = $product->accountancy_code_sell_intra;
846  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy_intra)) {
847  $code_p = $product->accountancy_code_buy_intra;
848  }
849  $suggestedid = $accountingAccount['intra'];
850  $suggestedaccountingaccountfor = 'eec';
851  } else {
852  // Foreign sale
853  if ($type == 'customer' && !empty($product->accountancy_code_sell_export)) {
854  $code_p = $product->accountancy_code_sell_export;
855  } elseif ($type == 'supplier' && !empty($product->accountancy_code_buy_export)) {
856  $code_p = $product->accountancy_code_buy_export;
857  }
858  $suggestedid = $accountingAccount['export'];
859  $suggestedaccountingaccountfor = 'export';
860  }
861  }
862 
863  // Level 3 (define $code_t): Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding)
864  if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
865  if (!empty($buyer->code_compta_product)) {
866  $code_t = $buyer->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('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
878  } elseif ($type == 'supplier') {
879  $result = $accountdeposittoventilated->fetch('', $conf->global->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('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
901  } elseif ($type == 'supplier') {
902  $accountdeposittoventilated->fetch('', $conf->global->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) && empty($conf->global->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 }
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)
Renvoi le libelle d'un statut donne.
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)
Retourne le libelle du statut d'un user (actif, inactif)
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') &&!empty($user->rights->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') &&!empty($user->rights->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)) $resql
Social contributions to pay.
Definition: index.php:745
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
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.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) 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.
$conf db
API class for accounts.
Definition: inc.php:41