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
29require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
30require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
31require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
32
37{
41 public $element = 'accounting_account';
42
46 public $table_element = 'accounting_account';
47
51 public $picto = 'billr';
52
57 public $ismultientitymanaged = 1;
58
63 public $restrictiononfksoc = 1;
64
68 public $db;
69
73 public $id;
74
78 public $rowid;
79
85 public $datec;
86
90 public $fk_pcg_version;
91
95 public $pcg_type;
96
100 public $account_number;
101
105 public $account_parent;
106
110 public $account_category;
111
115 public $account_category_label;
116
120 public $status;
121
125 public $label;
126
130 public $labelshort;
131
135 public $fk_user_author;
136
140 public $fk_user_modif;
141
145 public $active;
146
150 public $reconcilable;
151
155 private $accountingaccount_codetotid_cache = array();
156
157
158 const STATUS_ENABLED = 1;
159 const STATUS_DISABLED = 0;
160
161
167 public function __construct($db)
168 {
169 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)
checkUsage()
Check usage of accounting code.
update($user)
Update record.
getNomUrl($withpicto=0, $withlabel=0, $nourl=0, $moretitle='', $notooltip=0, $save_lastsearch_value=-1, $withcompletelabel=0, $option='')
Return clicable name (with picto eventually)
create($user, $notrigger=0)
Insert new accounting account in chart of accounts.
accountActivate($id, $mode=0)
Account activated.
info($id)
Information on record.
fetch($rowid=null, $account_number=null, $limittocurrentchart=0, $limittoachartaccount='')
Load record in memory.
getAccountingCodeToBind(Societe $buyer, Societe $seller, Product $product, $facture, $factureDet, $accountingAccount=array(), $type='')
Return a suggested account (from chart of accounts) to bind.
getLibStatut($mode=0)
Return the label of the status.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Class to manage products or services.
Class to manage third parties objects (customers, suppliers, prospects...)
isInEEC($object)
Return if a country of an object is inside the EEC (European Economic Community)
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
Definition invoice.php:1632