From ac708a8ee993457e43da17b7ddbcb1a06cd1e296 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 15 Jun 2017 23:58:56 +0200 Subject: [PATCH] Debug accounting module with new structure v6 Make accounting module compatible with the new vat code to identify 2 vat code with same rate. --- .../accountancy/class/bookkeeping.class.php | 7 +- htdocs/accountancy/journal/bankjournal.php | 10 ++- .../journal/expensereportsjournal.php | 28 ++++--- .../accountancy/journal/purchasesjournal.php | 47 ++++++++---- htdocs/accountancy/journal/sellsjournal.php | 48 +++++++----- .../core/class/html.formaccounting.class.php | 4 +- htdocs/core/lib/functions.lib.php | 73 ++++++++++++------- htdocs/langs/en_US/errors.lang | 2 + 8 files changed, 142 insertions(+), 77 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index f7c1b4d8b89..9ed4ef29ac1 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -184,7 +184,8 @@ class BookKeeping extends CommonObject } else { - $this->errors[]=$langs->trans('ErrorFieldAccountNotDefinedForInvoiceLine', $this->fk_doc, $this->doc_type); + //$this->errors[]=$langs->trans('ErrorFieldAccountNotDefinedForInvoiceLine', $this->doc_ref, $this->label_compte); + $this->errors[]=$langs->trans('ErrorFieldAccountNotDefinedForLine', $this->label_compte); } return -1; @@ -451,7 +452,7 @@ class BookKeeping extends CommonObject $sql .= ' ' . (! isset($this->thirdparty_code) ? 'NULL' : "'" . $this->db->escape($this->thirdparty_code) . "'") . ','; $sql .= ' ' . (! isset($this->subledger_account) ? 'NULL' : "'" . $this->db->escape($this->subledger_account) . "'") . ','; $sql .= ' ' . (! isset($this->subledger_label) ? 'NULL' : "'" . $this->db->escape($this->subledger_label) . "'") . ','; - $sql .= ' ' . (! isset($this->numero_compte) ? "'NotDefined'" : "'" . $this->db->escape($this->numero_compte) . "'") . ','; + $sql .= ' ' . (! isset($this->numero_compte) ? "NULL" : "'" . $this->db->escape($this->numero_compte) . "'") . ','; $sql .= ' ' . (! isset($this->label_compte) ? 'NULL' : "'" . $this->db->escape($this->label_compte) . "'") . ','; $sql .= ' ' . (! isset($this->debit) ? 'NULL' : $this->debit ). ','; $sql .= ' ' . (! isset($this->credit) ? 'NULL' : $this->credit ). ','; @@ -461,7 +462,7 @@ class BookKeeping extends CommonObject $sql .= ' ' . (! isset($this->import_key) ? 'NULL' : "'" . $this->db->escape($this->import_key) . "'") . ','; $sql .= ' ' . (empty($this->code_journal) ? 'NULL' : "'" . $this->db->escape($this->code_journal) . "'") . ','; $sql .= ' ' . (empty($this->journal_label) ? 'NULL' : "'" . $this->db->escape($this->journal_label) . "'") . ','; - $sql .= ' ' . (empty($this->piece_num) ? 'NULL' : $this->piece_num).','; + $sql .= ' ' . (empty($this->piece_num) ? 'NULL' : $this->db->escape($this->piece_num)).','; $sql .= ' ' . (! isset($this->entity) ? '1' : $this->entity); $sql .= ')'; diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 6c391531662..568edf051ff 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -103,8 +103,7 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); } -$p = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY); -$idpays = $p[0]; +$idpays = $mysoc->country_id; $sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro, b.num_releve, b.num_chq, b.fk_type,"; $sql .= " ba.courant, ba.ref as baref, ba.account_number, ba.fk_accountancy_journal,"; @@ -144,6 +143,7 @@ $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); + // Variables $account_supplier = (! empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER) ? $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER : $langs->trans("CodeNotDef")); $account_customer = (! empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) ? $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER : $langs->trans("CodeNotDef")); @@ -537,6 +537,12 @@ if (! $error && $action == 'writebookkeeping') { else { $db->rollback(); + + if ($error >= 10) + { + setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors'); + break; // Break in the foreach + } } } diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php index 759dca8dae9..ca9d05e7e93 100644 --- a/htdocs/accountancy/journal/expensereportsjournal.php +++ b/htdocs/accountancy/journal/expensereportsjournal.php @@ -86,13 +86,13 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); } -$p = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY); -$idpays = $p[0]; +$idpays = $mysoc->country_id; $sql = "SELECT er.rowid, er.ref, er.date_debut as de,"; -$sql .= " erd.rowid as erdid, erd.comments, erd.total_ttc, erd.tva_tx, erd.total_ht, erd.total_tva, erd.fk_code_ventilation,"; +$sql .= " erd.rowid as erdid, erd.comments, erd.total_ttc, erd.tva_tx, erd.total_ht, erd.total_tva, erd.fk_code_ventilation, erd.vat_src_code, "; $sql .= " u.rowid as uid, u.firstname, u.lastname, u.accountancy_code as user_accountancy_account,"; -$sql .= " f.accountancy_code, ct.accountancy_code_buy as account_tva, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte"; +$sql .= " f.accountancy_code, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte,"; +$sql .= " ct.accountancy_code_buy as account_tva"; $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_tva as ct ON erd.tva_tx = ct.taux AND ct.fk_pays = '" . $idpays . "'"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees"; @@ -110,7 +110,8 @@ dol_syslog('accountancy/journal/expensereportsjournal.php:: $sql=' . $sql); $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); - // les variables + + // Variables $account_salary = (! empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT)) ? $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT : $langs->trans("CodeNotDef"); $account_vat = (! empty($conf->global->ACCOUNTING_VAT_BUY_ACCOUNT)) ? $conf->global->ACCOUNTING_VAT_BUY_ACCOUNT : $langs->trans("CodeNotDef"); @@ -130,8 +131,11 @@ if ($result) { $compta_fees = $obj->compte; $compta_tva = (! empty($obj->account_tva) ? $obj->account_tva : $account_vat); - // Define array for display vat tx - $def_tva[$obj->rowid]=price($obj->tva_tx); + // Define array to display all VAT rates that use this accounting account $compta_tva + if (! empty(price2num($obj->tva_tx)) || ! empty($obj->vat_src_code)) + { + $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')]=(vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')); + } $taber[$obj->rowid]["date"] = $db->jdate($obj->de); $taber[$obj->rowid]["ref"] = $obj->ref; @@ -271,7 +275,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->fk_docdet = $val["fk_expensereportdet"]; $bookkeeping->subledger_account = ''; $bookkeeping->subledger_label = ''; - $bookkeeping->label_compte = $langs->trans("VAT"). ' '.$def_tva[$key]; + $bookkeeping->label_compte = $langs->trans("VAT"). ' '.join(', ',$def_tva[$key][$k]); $bookkeeping->numero_compte = $k; $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt < 0) ? 'C' : 'D'; @@ -307,6 +311,12 @@ if ($action == 'writebookkeeping') { else { $db->rollback(); + + if ($error >= 10) + { + setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors'); + break; // Break in the foreach + } } } @@ -556,7 +566,7 @@ if (empty($action) || $action == 'view') { } else print $accountoshow; print ""; - print "" . $userstatic->getNomUrl(0, 'user', 16) . ' - ' . $langs->trans("VAT"). ' '.$def_tva[$key]. ""; + print "" . $userstatic->getNomUrl(0, 'user', 16) . ' - ' . $langs->trans("VAT"). ' '.join(', ',$def_tva[$key][$k]). ""; print '' . ($mt >= 0 ? price($mt) : '') . ""; print '' . ($mt < 0 ? price(- $mt) : '') . ""; print ""; diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 506c5517821..b5f763fe2b1 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -85,26 +85,27 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); } -$p = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY); -$idpays = $p[0]; +$idpays = $mysoc->country_id; $sql = "SELECT f.rowid, f.ref, f.type, f.datef as df, f.libelle,f.ref_supplier,"; -$sql .= " fd.rowid as fdid, fd.description, fd.total_ttc, fd.tva_tx, fd.total_ht, fd.tva as total_tva, fd.product_type,"; +$sql .= " fd.rowid as fdid, fd.description, fd.total_ttc, fd.tva_tx, fd.total_ht, fd.tva as total_tva, fd.product_type, fd.vat_src_code,"; $sql .= " s.rowid as socid, s.nom as name, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,"; -$sql .= " p.accountancy_code_buy , ct.accountancy_code_buy as account_tva, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte"; +$sql .= " p.accountancy_code_buy , aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte,"; +$sql .= " ct.accountancy_code_buy as account_tva"; $sql .= " FROM " . MAIN_DB_PREFIX . "facture_fourn_det as fd"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_tva as ct ON fd.tva_tx = ct.taux AND ct.fk_pays = '" . $idpays . "'"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = fd.fk_product"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = fd.fk_code_ventilation"; $sql .= " JOIN " . MAIN_DB_PREFIX . "facture_fourn as f ON f.rowid = fd.fk_facture_fourn"; $sql .= " JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid = f.fk_soc"; -$sql .= " WHERE f.fk_statut > 0 "; +$sql .= " WHERE f.fk_statut > 0"; // TODO Facture annulée ? $sql .= " AND fd.fk_code_ventilation > 0 "; $sql .= " AND f.entity IN (" . getEntity('facture_fourn', 0) . ")"; // We don't share object for accountancy -if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) - $sql .= " AND f.type IN (0,1,2)"; -else - $sql .= " AND f.type IN (0,1,2,3)"; +if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_SITUATION . ")"; +} else { + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; +} if ($date_start && $date_end) $sql .= " AND f.datef >= '" . $db->idate($date_start) . "' AND f.datef <= '" . $db->idate($date_end) . "'"; $sql .= " ORDER BY f.datef"; @@ -114,7 +115,7 @@ $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); - // les variables + // Variables $cptfour = (! empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER)) ? $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER : $langs->trans("CodeNotDef"); $cpttva = (! empty($conf->global->ACCOUNTING_VAT_BUY_ACCOUNT)) ? $conf->global->ACCOUNTING_VAT_BUY_ACCOUNT : $langs->trans("CodeNotDef"); @@ -139,10 +140,15 @@ if ($result) { else $compta_prod = (! empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT)) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans("CodeNotDef"); } - $compta_tva = (! empty($obj->account_tva) ? $obj->account_tva : $cpttva); - //Define array for display vat tx - $def_tva[$obj->rowid]=price($obj->tva_tx); + $vatdata = getTaxesFromId($obj->tva_tx.($obj->vat_src_code?' ('.$obj->vat_src_code.')':''), $mysoc, $mysoc, 0); + $compta_tva = (! empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva); + + // Define array to display all VAT rates that use this accounting account $compta_tva + if (! empty(price2num($obj->tva_tx)) || ! empty($obj->vat_src_code)) + { + $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')]=(vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')); + } $tabfac[$obj->rowid]["date"] = $db->jdate($obj->df); $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier . ' (' . $obj->ref . ')'; @@ -214,8 +220,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->doc_type = 'supplier_invoice'; $bookkeeping->fk_doc = $key; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add - $bookkeeping->thirdparty_code = $tabcompany[$key]['code_fournisseur']; + $bookkeeping->thirdparty_code = $companystatic->code_fournisseur; $bookkeeping->subledger_account = $tabcompany[$key]['code_compta_fournisseur']; + $bookkeeping->subledger_label = ''; // TODO To complete $bookkeeping->label_compte = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("subledger_account"); $bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER; $bookkeeping->montant = $mt; @@ -262,6 +269,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->doc_type = 'supplier_invoice'; $bookkeeping->fk_doc = $key; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add + $bookkeeping->thirdparty_code = $companystatic->code_fournisseur; $bookkeeping->subledger_account = ''; $bookkeeping->subledger_label = ''; $bookkeeping->label_compte = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $accountingaccount->label; @@ -308,9 +316,10 @@ if ($action == 'writebookkeeping') { $bookkeeping->doc_type = 'supplier_invoice'; $bookkeeping->fk_doc = $key; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add + $bookkeeping->thirdparty_code = $companystatic->code_fournisseur; $bookkeeping->subledger_account = ''; $bookkeeping->subledger_label = ''; - $bookkeeping->label_compte = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT"). ' '.$def_tva[$key]; + $bookkeeping->label_compte = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT"). ' '.join(', ',$def_tva[$key][$k]); $bookkeeping->numero_compte = $k; $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt < 0) ? 'C' : 'D'; @@ -346,6 +355,12 @@ if ($action == 'writebookkeeping') { else { $db->rollback(); + + if ($error >= 10) + { + setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors'); + break; // Break in the foreach + } } } @@ -615,7 +630,7 @@ if (empty($action) || $action == 'view') { } else print $accountoshow; print ""; - print "" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT"). ' '.$def_tva[$key]. ""; + print "" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT"). ' '.join(', ',$def_tva[$key][$k]). ""; print '' . ($mt >= 0 ? price($mt) : '') . ""; print '' . ($mt < 0 ? price(- $mt) : '') . ""; print ""; diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 8506b2a480b..24f5ae6e7aa 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -89,27 +89,26 @@ if (empty($date_start) || empty($date_end)) // We define date_start and date_end $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); } -$p = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY); -$idpays = $p[0]; +$idpays = $mysoc->country_id; $sql = "SELECT f.rowid, f.facnumber, f.type, f.datef as df, f.ref_client,"; -$sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc,"; +$sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc, fd.situation_percent, fd.vat_src_code,"; $sql .= " s.rowid as socid, s.nom as name, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,"; -$sql .= " p.rowid as pid, p.ref as pref, p.accountancy_code_sell, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte,"; -$sql .= " fd.situation_percent,ct.accountancy_code_sell as account_tva"; +$sql .= " p.rowid as pid, p.ref as pref, p.accountancy_code_sell, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte"; +//$sql .= " ct.accountancy_code_sell as account_tva"; $sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as fd"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = fd.fk_product"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = fd.fk_code_ventilation"; $sql .= " JOIN " . MAIN_DB_PREFIX . "facture as f ON f.rowid = fd.fk_facture"; $sql .= " JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid = f.fk_soc"; -$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_tva as ct ON fd.tva_tx = ct.taux AND ct.fk_pays = '" . $idpays . "'"; +//$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_tva as ct ON ((fd.vat_src_code <> '' AND fd.vat_src_code = ct.code) OR (fd.vat_src_code = '' AND fd.tva_tx = ct.taux)) AND ct.fk_pays = '" . $idpays . "'"; $sql .= " WHERE fd.fk_code_ventilation > 0"; $sql .= " AND f.entity IN (".getEntity('facture', 0).')'; // We don't share object for accountancy $sql .= " AND f.fk_statut > 0"; // TODO Facture annulée ? if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_SITUATION . ")"; } else { - $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_STANDARD . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; + $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")"; } $sql .= " AND fd.product_type IN (0,1)"; if ($date_start && $date_end) @@ -127,29 +126,33 @@ if ($result) { $tabcompany = array (); $num = $db->num_rows($result); - $i = 0; + // Variables $cptcli = (! empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER)) ? $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER : $langs->trans("CodeNotDef"); + $cpttva = (! empty($conf->global->ACCOUNTING_VAT_SOLD_ACCOUNT)) ? $conf->global->ACCOUNTING_VAT_SOLD_ACCOUNT : $langs->trans("CodeNotDef"); + $i = 0; while ( $i < $num ) { $obj = $db->fetch_object($result); - // les variables $compta_soc = (! empty($obj->code_compta)) ? $obj->code_compta : $cptcli; $compta_prod = $obj->compte; if (empty($compta_prod)) { if ($obj->product_type == 0) $compta_prod = (! empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT)) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef"); - else - $compta_prod = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT)) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef"); + else + $compta_prod = (! empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT)) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef"); } - $cpttva = (! empty($conf->global->ACCOUNTING_VAT_SOLD_ACCOUNT)) ? $conf->global->ACCOUNTING_VAT_SOLD_ACCOUNT : $langs->trans("CodeNotDef"); - $compta_tva = (! empty($obj->account_tva) ? $obj->account_tva : $cpttva); + $vatdata = getTaxesFromId($obj->tva_tx.($obj->vat_src_code?' ('.$obj->vat_src_code.')':''), $mysoc, $mysoc, 0); + $compta_tva = (! empty($vatdata['accountancy_code_sell']) ? $vatdata['accountancy_code_sell'] : $cpttva); - //Define array for display vat tx - $def_tva[$obj->rowid]=price($obj->tva_tx); + // Define array to display all VAT rates that use this accounting account $compta_tva + if (! empty(price2num($obj->tva_tx)) || ! empty($obj->vat_src_code)) + { + $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')]=(vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')); + } // Situation invoices handling $line = new FactureLigne($db); @@ -231,8 +234,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->doc_type = 'customer_invoice'; $bookkeeping->fk_doc = $key; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add - $bookkeeping->thirdparty_code = $tabcompany[$key]['code_client']; + $bookkeeping->thirdparty_code = $companystatic->code_client; $bookkeeping->subledger_account = $tabcompany[$key]['code_compta']; + $bookkeeping->subledger_label = ''; // TODO To complete $bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER; $bookkeeping->label_compte = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("subledger_account"); $bookkeeping->montant = $mt; @@ -277,6 +281,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->doc_type = 'customer_invoice'; $bookkeeping->fk_doc = $key; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add; + $bookkeeping->thirdparty_code = $companystatic->code_client; $bookkeeping->subledger_account = ''; $bookkeeping->subledger_label = ''; $bookkeeping->numero_compte = $k; @@ -322,10 +327,11 @@ if ($action == 'writebookkeeping') { $bookkeeping->doc_type = 'customer_invoice'; $bookkeeping->fk_doc = $key; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add + $bookkeeping->thirdparty_code = $companystatic->code_client; $bookkeeping->subledger_account = ''; $bookkeeping->subledger_label = ''; $bookkeeping->numero_compte = $k; - $bookkeeping->label_compte = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("VAT").' '.$def_tva[$key]; + $bookkeeping->label_compte = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("VAT").' '.join(', ',$def_tva[$key][$k]); $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt < 0) ? 'D' : 'C'; $bookkeeping->debit = ($mt < 0) ? $mt : 0; @@ -360,6 +366,12 @@ if ($action == 'writebookkeeping') { else { $db->rollback(); + + if ($error >= 10) + { + setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors'); + break; // Break in the foreach + } } } @@ -651,7 +663,7 @@ if (empty($action) || $action == 'view') { } else print $accountoshow; print ""; - print "" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("VAT") . ' '.$def_tva[$key]. ""; + print "" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("VAT") . ' '.join(', ',$def_tva[$key][$k]). ""; // print "" . $langs->trans("VAT") . ""; print "" . ($mt < 0 ? price(- $mt) : '') . ""; print "" . ($mt >= 0 ? price($mt) : '') . ""; diff --git a/htdocs/core/class/html.formaccounting.class.php b/htdocs/core/class/html.formaccounting.class.php index e37e1690ca2..7248c4bda3a 100644 --- a/htdocs/core/class/html.formaccounting.class.php +++ b/htdocs/core/class/html.formaccounting.class.php @@ -241,7 +241,7 @@ class FormAccounting extends Form * Return list of accounts with label by chart of accounts * * @param string $selectid Preselected id or code of accounting accounts (depends on $select_in) - * @param string $htmlname Name of field in html form + * @param string $htmlname Name of HTML field id. If name start with '.', it is name of HTML css class, so several component with same name in different forms can be used. * @param int $showempty Add an empty field * @param array $event Event options * @param int $select_in 0=selectid value is a aa.rowid (default) or 1=selectid is aa.account_number @@ -284,8 +284,6 @@ class FormAccounting extends Form return -1; } - $out .= ajax_combobox($htmlname, $event); - $selected = 0; while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 49bcc265050..a582263185b 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4099,29 +4099,49 @@ function get_localtax_by_third($local) /** - * Get vat rate and npr from id. - * You can call getLocalTaxesFromRate after to get other fields + * Get vat main information from Id. + * You can call getLocalTaxesFromRate after to get other fields. * - * @param int $vatrowid Line ID into vat rate table. - * @return array array(localtax_type1(1-6 / 0 if not found), rate of localtax1, ...) + * @param int|string $vatrate VAT ID or Rate. Value can be value or the string with code into parenthesis or rowid if $firstparamisid is 1. Example: '8.5' or '8.5 (8.5NPR)' or 123. + * @param Societe $buyer Company object + * @param Societe $seller Company object + * @param int $firstparamisid 1 if first param is id into table (use this if you can) + * @return array array('rowid'=> , 'code'=> ...) + * @see getLocalTaxesFromRate */ -function getTaxesFromId($vatrowid) +function getTaxesFromId($vatrate, $buyer=null, $seller=null, $firstparamisid=1) { global $db, $mysoc; - dol_syslog("getTaxesFromId vatrowid=".$vatrowid); + dol_syslog("getTaxesFromId vatrowid=".$vatrate); // Search local taxes - $sql = "SELECT t.rowid, t.code, t.taux as rate, t.recuperableonly as npr"; + $sql = "SELECT t.rowid, t.code, t.taux as rate, t.recuperableonly as npr, t.accountancy_code_sell, t.accountancy_code_buy"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t"; - $sql.= " WHERE t.rowid ='".$vatrowid."'"; + if ($firstparamisid) $sql.= " WHERE t.rowid = ".(int) $vatrate; + else + { + $vatratecleaned = $vatrate; + $vatratecode = ''; + if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) // If vat is "xx (yy)" + { + $vatratecleaned = $reg[1]; + $vatratecode = $reg[2]; + } + + $sql.=", ".MAIN_DB_PREFIX."c_country as c"; + if ($mysoc->country_code == 'ES') $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$buyer->country_code."'"; // local tax in spain use the buyer country ?? + else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$seller->country_code."'"; + $sql.= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1"; + if ($vatratecode) $sql.= " AND t.code = '".$vatratecode."'"; + } $resql=$db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); - - return array('rowid'=>$obj->rowid, 'code'=>$obj->code, 'rate'=>$obj->rate, 'npr'=>$obj->npr); + if ($obj) return array('rowid'=>$obj->rowid, 'code'=>$obj->code, 'rate'=>$obj->rate, 'npr'=>$obj->npr, 'accountancy_code_sell'=>$obj->accountancy_code_sell, 'accountancy_code_buy'=>$obj->accountancy_code_buy); + else return array(); } else dol_print_error($db); @@ -4135,12 +4155,13 @@ function getTaxesFromId($vatrowid) * Instead this function must be called when adding a line to get the array of localtax and type, and then * provide it to the function calcul_price_total. * - * @param string $vatrate VAT Rate. Value can be value or the string with code into parenthesis or rowid if $firstparamisid is 1. Example: '8.5' or '8.5 (8.5NPR)' or 123. - * @param int $local Number of localtax (1 or 2, or 0 to return 1 & 2) - * @param Societe $buyer Company object - * @param Societe $seller Company object - * @param int $firstparamisid 1 if first param is id into table (use this if you can) - * @return array array(localtax_type1(1-6 / 0 if not found), rate of localtax1, ...) + * @param int|string $vatrate VAT ID or Rate. Value can be value or the string with code into parenthesis or rowid if $firstparamisid is 1. Example: '8.5' or '8.5 (8.5NPR)' or 123. + * @param int $local Number of localtax (1 or 2, or 0 to return 1 & 2) + * @param Societe $buyer Company object + * @param Societe $seller Company object + * @param int $firstparamisid 1 if first param is id into table (use this if you can) + * @return array array(localtax_type1(1-6 / 0 if not found), rate of localtax1, ...) + * @see getTaxesFromId */ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0) { @@ -4148,25 +4169,25 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi dol_syslog("getLocalTaxesFromRate vatrate=".$vatrate." local=".$local); - $vatratecleaned = $vatrate; - $vatratecode = ''; - if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) // If vat is "xx (yy)" - { - $vatratecleaned = $reg[1]; - $vatratecode = $reg[2]; - } - // Search local taxes $sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.accountancy_code_sell, t.accountancy_code_buy"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t"; - if ($firstparamisid) $sql.= " WHERE t.rowid ='".$vatrate."'"; + if ($firstparamisid) $sql.= " WHERE t.rowid = ".(int) $vatrate; else { + $vatratecleaned = $vatrate; + $vatratecode = ''; + if (preg_match('/^(.*)\s*\((.*)\)$/', $vatrate, $reg)) // If vat is "xx (yy)" + { + $vatratecleaned = $reg[1]; + $vatratecode = $reg[2]; + } + $sql.=", ".MAIN_DB_PREFIX."c_country as c"; if ($mysoc->country_code == 'ES') $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$buyer->country_code."'"; // local tax in spain use the buyer country ?? else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$seller->country_code."'"; $sql.= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1"; - if ($vatratecode) $sql.= " AND t.code ='".$vatratecode."'"; + if ($vatratecode) $sql.= " AND t.code = '".$vatratecode."'"; } $resql=$db->query($sql); diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 0f49bd832d6..0f57a23d23c 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -182,6 +182,7 @@ ErrorFailedToLoadLoginFileForMode=Failed to get the login key for mode '%s'. ErrorModuleNotFound=File of module was not found. ErrorFieldAccountNotDefinedForBankLine=Value for Accounting account not defined for source line id %s (%s) ErrorFieldAccountNotDefinedForInvoiceLine=Value for Accounting account not defined for invoice id %s (%s) +ErrorFieldAccountNotDefinedForLine=Value for Accounting account not defined for the line (%s) ErrorBankStatementNameMustFollowRegex=Error, bank statement name must follow the following syntax rule %s ErrorPhpMailDelivery=Check that you don't use a too high number of recipients and that your email content is not similar to a Spam. Ask also your administrator to check firewall and server logs files for a more complete information. ErrorUserNotAssignedToTask=User must be assigned to task to be able to enter time consumed. @@ -191,6 +192,7 @@ ErrorFilenameDosNotMatchDolibarrPackageRules=The name of the module package (