diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 094dcd81b50..ad8be2608c1 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -695,8 +695,8 @@ if ($num > 0) // Action column print ''; - print '' . img_edit() . ' '; - print '' . img_delete() . ''; + print '' . img_edit() . ' '; + print '' . img_delete() . ''; print ''; if (! $i) $totalarray['nbfield']++; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 904c8668b94..4d9d7532d7e 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -223,7 +223,7 @@ $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON p.accountan $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa2 ON p.accountancy_code_sell_intra = aa2.account_number AND aa2.fk_pcg_version = '" . $chartaccountcode."'"; $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa3 ON p.accountancy_code_sell_export = aa3.account_number AND aa3.fk_pcg_version = '" . $chartaccountcode."'"; $sql.= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; -$sql.= " AND product_type <= 2"; +$sql.= " AND l.product_type <= 2"; // Add search filter like if ($search_lineid) { $sql .= natural_search("l.rowid", $search_lineid, 1); diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 7794cccf658..e7ab6adbba4 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -98,14 +98,12 @@ $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.product_type, fd.total_ht, fd.tva as total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, 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 , 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"; // TODO Facture annulée ? +$sql .= " WHERE f.fk_statut > 0"; $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)) { @@ -214,6 +212,29 @@ if ($result) { dol_print_error($db); } +$errorforinvoice = array(); + +// Loop in invoices to detect lines with not binding lines +foreach ($tabfac as $key => $val) { // Loop on each invoice + $sql = "SELECT COUNT(fd.rowid) as nb"; + $sql.= " FROM " . MAIN_DB_PREFIX . "facture_fourn_det as fd"; + $sql.= " WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0"; + $sql.= " AND fd.total_ttc <> 0 AND fk_facture_fourn = ".$key; + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + if ($obj->nb > 0) + { + $errorforinvoice[$key]='somelinesarenotbound'; + } + } + else dol_print_error($db); +} +//var_dump($errorforinvoice);exit; + + + // Bookkeeping Write if ($action == 'writebookkeeping') { $now = dol_now(); @@ -222,8 +243,6 @@ if ($action == 'writebookkeeping') { $companystatic = new Societe($db); $invoicestatic = new FactureFournisseur($db); - $errorforinvoice = array(); - foreach ($tabfac as $key => $val) { // Loop on each invoice $errorforline = 0; @@ -301,14 +320,14 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -354,14 +373,14 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -413,14 +432,14 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -431,7 +450,7 @@ if ($action == 'writebookkeeping') { // Counterpart of VAT for VAT NPR // var_dump($tabother); - if (! $errorforline) + if (! $errorforline && is_array($tabother[$key])) { foreach ( $tabother[$key] as $k => $mt ) { if ($mt) { @@ -465,14 +484,14 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -485,14 +504,17 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='amountsnotbalanced'; setEventMessages('Try to insert a non balanced transaction in book for '.$invoicestatic->ref.'. Canceled. Surely a bug.', null, 'errors'); } - // Check totaldebit is also same than total of invoice. If not, some record are not yet ready to be journalized - - - + // Error if some lines are not binded/ready to be journalized + if ($errorforinvoice[$key] == 'somelinesarenotbound') + { + $error++; + $errorforline++; + setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors'); + } if (! $errorforline) { @@ -810,6 +832,25 @@ if (empty($action) || $action == 'view') { continue; } + if ($errorforinvoice[$key] == 'somelinesarenotbound') + { + print ''; + print ""; + print "" . $date . ""; + print "" . $invoicestatic->getNomUrl(1) . ""; + // Account + print ""; + print ''.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).''; + print ''; + // Subledger account + print ""; + print ''; + print ""; + print ""; + print ''; + print ''; + print ""; + } // Third party foreach ( $tabttc[$key] as $k => $mt ) { diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 81f0bd1c5c8..4ed70d41c4b 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -93,16 +93,14 @@ $sql = "SELECT f.rowid, f.facnumber, f.type, f.datef as df, f.ref_client, f.date $sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.total_localtax1, fd.total_localtax2, 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 .= " 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.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, we use source object sharing -$sql .= " AND f.fk_statut > 0"; // TODO Facture annulée ? +$sql .= " AND f.fk_statut > 0"; if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { // Non common setup $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_SITUATION . ")"; } else { @@ -218,6 +216,28 @@ if ($result) { dol_print_error($db); } +$errorforinvoice = array(); + +// Loop in invoices to detect lines with not binding lines +foreach ($tabfac as $key => $val) { // Loop on each invoice + $sql = "SELECT COUNT(fd.rowid) as nb"; + $sql.= " FROM " . MAIN_DB_PREFIX . "facturedet as fd"; + $sql.= " WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0"; + $sql.= " AND fd.total_ttc <> 0 AND fk_facture = ".$key; + $resql=$db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + if ($obj->nb > 0) + { + $errorforinvoice[$key]='somelinesarenotbound'; + } + } + else dol_print_error($db); +} +//var_dump($errorforinvoice);exit; + + // Bookkeeping Write if ($action == 'writebookkeeping') { $now = dol_now(); @@ -226,8 +246,6 @@ if ($action == 'writebookkeeping') { $companystatic = new Societe($db); $invoicestatic = new Facture($db); - $errorforinvoice = array(); - foreach ($tabfac as $key => $val) { // Loop on each invoice $errorforline = 0; @@ -303,14 +321,14 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -356,14 +374,14 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -414,14 +432,14 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='alreadyjournalized'; //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); } else { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='other'; setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); } } @@ -435,22 +453,17 @@ if ($action == 'writebookkeeping') { { $error++; $errorforline++; - $errorforinvoice[$key]=1; + $errorforinvoice[$key]='amountsnotbalanced'; setEventMessages('Try to insert a non balanced transaction in book for '.$invoicestatic->ref.'. Canceled. Surely a bug.', null, 'errors'); } - // Check totaldebit is also same than total of invoice. If not, some record are not yet ready to be journalized, - // so we refuse to journalize any lines of the invoice. - /*$tmpinvoice = new Facture($db); - $tmpinvoice->fetch($key); - //var_dump($key); var_dump($tmpinvoice->ref); var_dump(price2num($tmpinvoice->total_ttc,'MT')); var_dump($totaldebit); - if (price2num($tmpinvoice->total_ttc,'MT') != price2num($totaldebit)) + // Error if some lines are not binded/ready to be journalized + if ($errorforinvoice[$key] == 'somelinesarenotbound') { $error++; $errorforline++; - $errorforinvoice[$key]=1; - setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $tmpinvoice->ref), null, 'errors'); - }*/ + setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors'); + } if (! $errorforline) { @@ -747,6 +760,25 @@ if (empty($action) || $action == 'view') { continue; } + if ($errorforinvoice[$key] == 'somelinesarenotbound') + { + print ''; + print ""; + print "" . $date . ""; + print "" . $invoicestatic->getNomUrl(1) . ""; + // Account + print ""; + print ''.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).''; + print ''; + // Subledger account + print ""; + print ''; + print ""; + print ""; + print ''; + print ''; + print ""; + } // Third party foreach ($tabttc[$key] as $k => $mt) diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 49d81d5d11d..c19e1d2716c 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -222,7 +222,7 @@ $sql.= " INNER JOIN " . MAIN_DB_PREFIX . "facture_fourn_det as l ON f.rowid = l. $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = l.fk_product"; $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON p.accountancy_code_buy = aa.account_number AND aa.fk_pcg_version = '" . $chartaccountcode."'"; $sql.= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; -$sql.= " AND product_type <= 2"; +$sql.= " AND l.product_type <= 2"; // Add search filter like if ($search_lineid) { $sql .= natural_search("l.rowid", $search_lineid, 1); diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 987ab6b31a6..28a77095084 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -285,6 +285,7 @@ Formula=Formula SomeMandatoryStepsOfSetupWereNotDone=Some mandatory steps of setup was not done, please complete them ErrorNoAccountingCategoryForThisCountry=No accounting account group available for country %s (See Home - Setup - Dictionaries) ErrorInvoiceContainsLinesNotYetBounded=You try to journalize some lines of the invoice %s, but some other lines are not yet bounded to accounting account. Journalization of all invoice lines for this invoice are refused. +ErrorInvoiceContainsLinesNotYetBoundedShort=Some lines on invoice are not bound to accounting account. ExportNotSupported=The export format setuped is not supported into this page BookeppingLineAlreayExists=Lines already existing into bookeeping NoJournalDefined=No journal defined diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 5ed49679e04..668090129ff 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -119,7 +119,7 @@ StatusOfGeneratedInvoices=Status of generated invoices BillStatusDraft=Draft (needs to be validated) BillStatusPaid=Paid BillStatusPaidBackOrConverted=Credit note refund or converted into discount -BillStatusConverted=Paid (ready for final invoice) +BillStatusConverted=Paid (ready for consumption in final invoice) BillStatusCanceled=Abandoned BillStatusValidated=Validated (needs to be paid) BillStatusStarted=Started