diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 730e52c805a..cdfa3602e73 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -166,7 +166,7 @@ class AccountingAccount extends CommonObject * * @param int $rowid Id * @param string $account_number Account number - * @param int|boolean $limittocurrentchart 1 or true=Load record only if it is into current active char of account + * @param int|boolean $limittocurrentchart 1 or true=Load record only if it is into current active chart of account * @param string $limittoachartaccount 'ABC'=Load record only if it is into chart account with code 'ABC' (better and faster than previous parameter if you have chart of account code). * @return int <0 if KO, 0 if not found, Id of record if OK and found */ diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index e2ed822e35a..62f613a940b 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -120,6 +120,7 @@ if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accou if ($action == 'validatehistory') { $error = 0; $nbbinddone = 0; + $notpossible = 0; $db->begin(); @@ -156,14 +157,13 @@ if ($action == 'validatehistory') { } else { $sql .= " s.accountancy_code_sell as company_code_sell"; } - $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc"; if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays "; - $sql .= " INNER JOIN ".MAIN_DB_PREFIX."facturedet as l ON f.rowid = l.fk_facture"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."facturedet as l ON f.rowid = l.fk_facture"; // the main table $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product"; if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity); @@ -174,8 +174,7 @@ if ($action == 'validatehistory') { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON " . $alias_product_perentity . ".accountancy_code_sell_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON " . $alias_product_perentity . ".accountancy_code_sell_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_sell = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; - $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; - $sql .= " AND l.product_type <= 2"; + $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0 AND l.product_type <= 2 AND f.entity = ".((int) $conf->entity); if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) { $sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'"; } @@ -256,7 +255,7 @@ if ($action == 'validatehistory') { $suggestedid = 0; $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accountingAccountArray, 'customer'); - if (!is_array($return) && $return<0) { + if (!is_array($return) && $return < 0) { setEventMessage($accountingAccount->error, 'errors'); } else { $suggestedid = $return['suggestedid']; @@ -282,17 +281,22 @@ if ($action == 'validatehistory') { } else { $nbbinddone++; } + } else { + $notpossible++; } $i++; } + if ($num_lines > 10000) { + $notpossible += ($num_lines - 10000); + } } if ($error) { $db->rollback(); } else { $db->commit(); - setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone), null, 'mesgs'); + setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone, $notpossible), null, 'mesgs'); } } diff --git a/htdocs/accountancy/expensereport/index.php b/htdocs/accountancy/expensereport/index.php index 0987afb0c6a..37abd56a21d 100644 --- a/htdocs/accountancy/expensereport/index.php +++ b/htdocs/accountancy/expensereport/index.php @@ -99,42 +99,69 @@ if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accou if ($action == 'validatehistory') { $error = 0; + $nbbinddone = 0; + $notpossible = 0; + $db->begin(); // Now make the binding - if ($db->type == 'pgsql') { - $sql1 = "UPDATE ".MAIN_DB_PREFIX."expensereport_det"; - $sql1 .= " SET fk_code_ventilation = accnt.rowid"; - $sql1 .= " FROM ".MAIN_DB_PREFIX."c_type_fees as t, ".MAIN_DB_PREFIX."accounting_account as accnt , ".MAIN_DB_PREFIX."accounting_system as syst"; - $sql1 .= " WHERE ".MAIN_DB_PREFIX."expensereport_det.fk_c_type_fees = t.id AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid = ".((int) $conf->global->CHARTOFACCOUNTS).' AND accnt.entity = '.((int) $conf->entity); - $sql1 .= " AND accnt.active = 1 AND t.accountancy_code = accnt.account_number"; - $sql1 .= " AND ".MAIN_DB_PREFIX."expensereport_det.fk_code_ventilation = 0"; - if ($validatemonth && $validateyear) { - $sql1 .= dolSqlDateFilter('date', 0, $validatemonth, $validateyear); - } - } else { - $sql1 = "UPDATE ".MAIN_DB_PREFIX."expensereport_det as erd, ".MAIN_DB_PREFIX."c_type_fees as t, ".MAIN_DB_PREFIX."accounting_account as accnt , ".MAIN_DB_PREFIX."accounting_system as syst"; - $sql1 .= " SET erd.fk_code_ventilation = accnt.rowid"; - $sql1 .= " WHERE erd.fk_c_type_fees = t.id AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid = ".((int) $conf->global->CHARTOFACCOUNTS).' AND accnt.entity = '.((int) $conf->entity); - $sql1 .= " AND accnt.active = 1 AND t.accountancy_code=accnt.account_number"; - $sql1 .= " AND erd.fk_code_ventilation = 0"; - if ($validatemonth && $validateyear) { - $sql1 .= dolSqlDateFilter('erd.date', 0, $validatemonth, $validateyear); - } + $sql1 = "SELECT erd.rowid, accnt.rowid as suggestedid"; + $sql1 .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd"; + $sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as t ON erd.fk_c_type_fees = t.id"; + $sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as accnt ON t.accountancy_code = accnt.account_number AND accnt.active = 1 AND accnt.entity =".((int) $conf->entity); + $sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_system as syst ON accnt.fk_pcg_version = syst.pcg_version AND syst.rowid = ".((int) $conf->global->CHARTOFACCOUNTS).' AND syst.active = 1,'; + $sql1 .= " ".MAIN_DB_PREFIX."expensereport as er"; + $sql1 .= " WHERE erd.fk_expensereport = er.rowid AND er.entity = ".((int) $conf->entity); + $sql1 .= " AND er.fk_statut IN (".ExpenseReport::STATUS_APPROVED.", ".ExpenseReport::STATUS_CLOSED.") AND erd.fk_code_ventilation <= 0"; + if ($validatemonth && $validateyear) { + $sql1 .= dolSqlDateFilter('erd.date', 0, $validatemonth, $validateyear); } dol_syslog('htdocs/accountancy/expensereport/index.php'); - $resql1 = $db->query($sql1); - if (!$resql1) { + $result = $db->query($sql1); + if (!$result) { $error++; - $db->rollback(); setEventMessages($db->lasterror(), null, 'errors'); } else { - $nbbinddone = $db->affected_rows($resql1); + $num_lines = $db->num_rows($result); + $i = 0; + while ($i < min($num_lines, 10000)) { // No more than 10000 at once + $objp = $db->fetch_object($result); + + $lineid = $objp->rowid; + $suggestedid = $objp->suggestedid; + + if ($suggestedid > 0) { + $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."expensereport_det"; + $sqlupdate .= " SET fk_code_ventilation = ".((int) $suggestedid); + $sqlupdate .= " WHERE fk_code_ventilation <= 0 AND rowid = ".((int) $lineid); + + $resqlupdate = $db->query($sqlupdate); + if (!$resqlupdate) { + $error++; + setEventMessages($db->lasterror(), null, 'errors'); + break; + } else { + $nbbinddone++; + } + } else { + $notpossible++; + } + + $i++; + } + if ($num_lines > 10000) { + $notpossible += ($num_lines - 10000); + } + } + + if ($error) { + $db->rollback(); + } else { $db->commit(); - setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone), null, 'mesgs'); + setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone, $notpossible), null, 'mesgs'); } } @@ -157,7 +184,7 @@ print '
'; $y = $year_current; -$buttonbind = ''.$langs->trans("ValidateHistory").''; +$buttonbind = ''.$langs->trans("ValidateHistory").''; print_barre_liste(img_picto('', 'unlink', 'class="paddingright fa-color-unset"').$langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1); diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index b262f85367a..fb3bf1a6e04 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -394,11 +394,12 @@ if ($result) { print ''.vatrate($objp->tva_tx.($objp->vat_src_code ? ' ('.$objp->vat_src_code.')' : '')).''; // Accounting account affected - print ''; + print ''; print $accountingaccountstatic->getNomUrl(0, 1, 1, '', 1); print ' '; print img_edit(); print ''; + print ''; print ""; diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php index 1a0c8909829..51c9e66cebe 100644 --- a/htdocs/accountancy/supplier/index.php +++ b/htdocs/accountancy/supplier/index.php @@ -118,6 +118,7 @@ if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accou if ($action == 'validatehistory') { $error = 0; $nbbinddone = 0; + $notpossible = 0; $db->begin(); @@ -154,7 +155,6 @@ if ($action == 'validatehistory') { } else { $sql .= " s.accountancy_code_buy as company_code_buy"; } - $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc"; if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { @@ -172,8 +172,7 @@ if ($action == 'validatehistory') { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON " . $alias_product_perentity . ".accountancy_code_buy_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON " . $alias_product_perentity . ".accountancy_code_buy_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_buy = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; - $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; - $sql .= " AND l.product_type <= 2"; + $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0 AND l.product_type <= 2 AND f.entity = ".((int) $conf->entity); if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) { $sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'"; } @@ -278,17 +277,22 @@ if ($action == 'validatehistory') { } else { $nbbinddone++; } + } else { + $notpossible++; } $i++; } + if ($num_lines > 10000) { + $notpossible += ($num_lines - 10000); + } } if ($error) { $db->rollback(); } else { $db->commit(); - setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone), null, 'mesgs'); + setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone, $notpossible), null, 'mesgs'); } } diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 38f7703f744..db358964f16 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -2094,8 +2094,22 @@ if ($action == 'create') { print ''; } + $titlealt = ''; + if (!empty($conf->accounting->enabled)) { + $accountingaccount = new AccountingAccount($db); + $resaccountingaccount = $accountingaccount->fetch(0, $line->type_fees_accountancy_code, 1); + //$titlealt .= ''; + $titlealt .= $langs->trans("AccountancyCode").': '; + if ($resaccountingaccount > 0) { + $titlealt .= $accountingaccount->account_number; + } else { + $titlealt .= $langs->trans("NotFound"); + } + //$titlealt .= ''; + } + // Type of fee - print ''; + print ''; $labeltype = ($langs->trans(($line->type_fees_code)) == $line->type_fees_code ? $line->type_fees_libelle : $langs->trans($line->type_fees_code)); print $labeltype; print ''; @@ -2109,8 +2123,10 @@ if ($action == 'create') { // Comment print ''.dol_nl2br($line->comments).''; + // VAT rate print ''.vatrate($line->vatrate.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''), true).''; + // Unit price HT print ''; if (!empty($line->value_unit_ht)) { diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 877a7c79ade..d5695c7e49a 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -999,7 +999,7 @@ class ExpenseReport extends CommonObject $sql .= ' de.fk_ecm_files,'; $sql .= ' de.total_ht, de.total_tva, de.total_ttc,'; $sql .= ' de.total_localtax1, de.total_localtax2, de.rule_warning_message,'; - $sql .= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,'; + $sql .= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees, ctf.accountancy_code as accountancy_code_type_fees,'; $sql .= ' p.ref as ref_projet, p.title as title_projet'; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as de'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id'; @@ -1043,6 +1043,7 @@ class ExpenseReport extends CommonObject $deplig->type_fees_code = empty($objp->code_type_fees) ? 'TF_OTHER' : $objp->code_type_fees; $deplig->type_fees_libelle = $objp->libelle_type_fees; + $deplig->type_fees_accountancy_code = $objp->accountancy_code_type_fees; $deplig->tva_tx = $objp->tva_tx; $deplig->vatrate = $objp->tva_tx; @@ -2579,6 +2580,7 @@ class ExpenseReportLine public $type_fees_code; public $type_fees_libelle; + public $type_fees_accountancy_code; public $projet_ref; public $projet_title; diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index b9f84588079..7999d46363e 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -286,7 +286,7 @@ ValidateMovements=Validate movements DescValidateMovements=Any modification or deletion of writing, lettering and deletes will be prohibited. All entries for an exercise must be validated otherwise closing will not be possible ValidateHistory=Bind Automatically -AutomaticBindingDone=Automatic bindings done (%s) +AutomaticBindingDone=Automatic bindings done (%s) - Automatic binding not possible for some record (%s) ErrorAccountancyCodeIsAlreadyUse=Error, you cannot delete this accounting account because it is used MvtNotCorrectlyBalanced=Movement not correctly balanced. Debit = %s | Credit = %s diff --git a/htdocs/langs/fr_FR/accountancy.lang b/htdocs/langs/fr_FR/accountancy.lang index 675e9ac338e..f5b9b5dcf3e 100644 --- a/htdocs/langs/fr_FR/accountancy.lang +++ b/htdocs/langs/fr_FR/accountancy.lang @@ -286,7 +286,7 @@ ValidateMovements=Valider les mouvements DescValidateMovements=Toute modification ou suppression d'écriture, de lettrage et de suppression sera interdite. Toutes les entrées pour un exercice doivent être validées, sinon la fermeture ne sera pas possible ValidateHistory=Lier automatiquement -AutomaticBindingDone=Liaisons automatiques faites (%s) +AutomaticBindingDone=Liaisons automatiques faites (%s) - Liaison automatique non possible pour certains cas (%s) ErrorAccountancyCodeIsAlreadyUse=Erreur, vous ne pouvez pas détruire de compte comptable car il est utilisé MvtNotCorrectlyBalanced=Mouvement non équilibré. Débit = %s| Crédit = %s