From 373449900f353d8ea3d6ec6dd845a147cb260ff4 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 15 Sep 2022 05:21:22 +0200 Subject: [PATCH] FIX Accountancy - Review reconcile function (separate manuel & auto reconcile) --- htdocs/accountancy/bookkeeping/list.php | 101 +++- .../accountancy/bookkeeping/listbyaccount.php | 97 ++- htdocs/accountancy/class/lettering.class.php | 567 +++++++++++------- .../accountancy/journal/purchasesjournal.php | 2 +- htdocs/accountancy/journal/sellsjournal.php | 2 +- htdocs/langs/en_US/accountancy.lang | 9 +- 6 files changed, 485 insertions(+), 293 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 23d33acd3b7..8e2ac22520d 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -234,7 +234,7 @@ $param = ''; if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunlettering' && $massaction != 'predeletebookkeepingwriting') { +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunletteringauto' && $massaction != 'preunletteringmanual' && $massaction != 'predeletebookkeepingwriting') { $massaction = ''; } @@ -485,44 +485,61 @@ if (empty($reshook)) { $uploaddir = $conf->societe->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; - if (!$error && $action == 'deletebookkeepingwriting' && $confirm == "yes" && $user->rights->accounting->mouvements->supprimer) { + if (!$error && $action == 'deletebookkeepingwritingauto' && $confirm == "yes" && $user->rights->accounting->mouvements->supprimer) { + $db->begin(); + + if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) { + $lettering = new Lettering($db); + $nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true); + if ($nb_lettering < 0) { + setEventMessages('', $lettering->errors, 'errors'); + $error++; + } + } + $nbok = 0; - foreach ($toselect as $toselectid) { - $result = $object->fetch($toselectid); - if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) { - $result = $object->deleteMvtNum($object->piece_num); - if ($result > 0) { - $nbok++; - } else { + if (!$error) { + foreach ($toselect as $toselectid) { + $result = $object->fetch($toselectid); + if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) { + $result = $object->deleteMvtNum($object->piece_num); + if ($result > 0) { + $nbok++; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + break; + } + } elseif ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; break; } - } elseif ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - $error++; - break; } } - // Message for elements well deleted - if ($nbok > 1) { - setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs'); - } elseif ($nbok > 0) { - setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs'); - } elseif (!$error) { - setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs'); - } - if (!$error) { + $db->commit(); + + // Message for elements well deleted + if ($nbok > 1) { + setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs'); + } elseif ($nbok > 0) { + setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs'); + } else { + setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs'); + } + header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : '')); exit; + } else { + $db->rollback(); } } // others mass actions if (!$error && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) { - if ($massaction == 'lettering') { + if ($massaction == 'letteringauto') { $lettering = new Lettering($db); $nb_lettering = $lettering->bookkeepingLetteringAll($toselect); if ($nb_lettering < 0) { @@ -543,7 +560,17 @@ if (empty($reshook)) { header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); exit(); } - } elseif ($action == 'unlettering' && $confirm == "yes") { + } elseif ($massaction == 'letteringmanual') { + $lettering = new Lettering($db); + $result = $lettering->updateLettering($toselect); + if ($result < 0) { + setEventMessages('', $lettering->errors, 'errors'); + } else { + setEventMessages($langs->trans('AccountancyOneLetteringModifiedSuccessfully'), array(), 'mesgs'); + header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); + exit(); + } + } elseif ($action == 'unletteringauto' && $confirm == "yes") { $lettering = new Lettering($db); $nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true); if ($nb_lettering < 0) { @@ -564,6 +591,16 @@ if (empty($reshook)) { header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); exit(); } + } elseif ($action == 'unletteringmanual' && $confirm == "yes") { + $lettering = new Lettering($db); + $nb_lettering = $lettering->deleteLettering($toselect); + if ($result < 0) { + setEventMessages('', $lettering->errors, 'errors'); + } else { + setEventMessages($langs->trans('AccountancyOneUnletteringModifiedSuccessfully'), array(), 'mesgs'); + header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); + exit(); + } } } } @@ -839,16 +876,16 @@ if ($limit > 0 && $limit != $conf->liste_limit) { // List of mass actions available $arrayofmassactions = array(); -/* if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) { - $arrayofmassactions['lettering'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('Lettering'); - $arrayofmassactions['preunlettering'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('Unlettering'); + $arrayofmassactions['letteringauto'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('LetteringAuto'); + $arrayofmassactions['preunletteringauto'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('UnletteringAuto'); + $arrayofmassactions['letteringmanual'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('LetteringManual'); + $arrayofmassactions['preunletteringmanual'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('UnletteringManual'); } -*/ if ($user->rights->accounting->mouvements->supprimer) { $arrayofmassactions['predeletebookkeepingwriting'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } -if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunlettering', 'predeletebookkeepingwriting'))) { +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunletteringauto', 'preunletteringmanual', 'predeletebookkeepingwriting'))) { $arrayofmassactions = array(); } $massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions); @@ -898,8 +935,10 @@ if (empty($reshook)) { print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); -if ($massaction == 'preunlettering') { - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnlettering"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unlettering", null, '', 0, 200, 500, 1); +if ($massaction == 'preunletteringauto') { + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnletteringAuto"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unletteringauto", null, '', 0, 200, 500, 1); +} elseif ($massaction == 'preunletteringmanual') { + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnletteringManual"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unletteringmanual", null, '', 0, 200, 500, 1); } elseif ($massaction == 'predeletebookkeepingwriting') { print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDeleteBookkeepingWriting"), $langs->trans("ConfirmMassDeleteBookkeepingWritingQuestion", count($toselect)), "deletebookkeepingwriting", null, '', 0, 200, 500, 1); } diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 4b5f0d9bad6..cbb827d7f04 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -208,7 +208,7 @@ if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunlettering' && $massaction != 'predeletebookkeepingwriting') { +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunletteringauto' && $massaction != 'preunletteringmanual' && $massaction != 'predeletebookkeepingwriting') { $massaction = ''; } @@ -401,43 +401,60 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; if (!$error && $action == 'deletebookkeepingwriting' && $confirm == "yes" && $user->rights->accounting->mouvements->supprimer) { + $db->begin(); + + if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) { + $lettering = new Lettering($db); + $nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true); + if ($nb_lettering < 0) { + setEventMessages('', $lettering->errors, 'errors'); + $error++; + } + } + $nbok = 0; - foreach ($toselect as $toselectid) { - $result = $object->fetch($toselectid); - if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) { - $result = $object->deleteMvtNum($object->piece_num); - if ($result > 0) { - $nbok++; - } else { + if (!$error) { + foreach ($toselect as $toselectid) { + $result = $object->fetch($toselectid); + if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) { + $result = $object->deleteMvtNum($object->piece_num); + if ($result > 0) { + $nbok++; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + break; + } + } elseif ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; break; } - } elseif ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - $error++; - break; } } - // Message for elements well deleted - if ($nbok > 1) { - setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs'); - } elseif ($nbok > 0) { - setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs'); - } elseif (!$error) { - setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs'); - } - if (!$error) { + $db->commit(); + + // Message for elements well deleted + if ($nbok > 1) { + setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs'); + } elseif ($nbok > 0) { + setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs'); + } elseif (!$error) { + setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs'); + } + header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : '')); exit; + } else { + $db->rollback(); } } // others mass actions if (!$error && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) { - if ($massaction == 'lettering') { + if ($massaction == 'letteringauto') { $lettering = new Lettering($db); $nb_lettering = $lettering->bookkeepingLetteringAll($toselect); if ($nb_lettering < 0) { @@ -458,7 +475,17 @@ if (empty($reshook)) { header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); exit(); } - } elseif ($action == 'unlettering' && $confirm == "yes") { + } elseif ($massaction == 'letteringmanual') { + $lettering = new Lettering($db); + $result = $lettering->updateLettering($toselect); + if ($result < 0) { + setEventMessages('', $lettering->errors, 'errors'); + } else { + setEventMessages($langs->trans('AccountancyOneLetteringModifiedSuccessfully'), array(), 'mesgs'); + header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); + exit(); + } + } elseif ($action == 'unletteringauto' && $confirm == "yes") { $lettering = new Lettering($db); $nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true); if ($nb_lettering < 0) { @@ -479,6 +506,16 @@ if (empty($reshook)) { header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); exit(); } + } elseif ($action == 'unletteringmanual' && $confirm == "yes") { + $lettering = new Lettering($db); + $nb_lettering = $lettering->deleteLettering($toselect); + if ($result < 0) { + setEventMessages('', $lettering->errors, 'errors'); + } else { + setEventMessages($langs->trans('AccountancyOneUnletteringModifiedSuccessfully'), array(), 'mesgs'); + header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); + exit(); + } } } } @@ -579,13 +616,15 @@ print $formconfirm; // List of mass actions available $arrayofmassactions = array(); if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) { - $arrayofmassactions['lettering'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('Lettering'); - $arrayofmassactions['preunlettering'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('Unlettering'); + $arrayofmassactions['letteringauto'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('LetteringAuto'); + $arrayofmassactions['preunletteringauto'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('UnletteringAuto'); + $arrayofmassactions['letteringmanual'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('LetteringManual'); + $arrayofmassactions['preunletteringmanual'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('UnletteringManual'); } if ($user->rights->accounting->mouvements->supprimer) { $arrayofmassactions['predeletebookkeepingwriting'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } -if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunlettering', 'predeletebookkeepingwriting'))) { +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunletteringauto', 'preunletteringmanual', 'predeletebookkeepingwriting'))) { $arrayofmassactions = array(); } $massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions); @@ -625,8 +664,10 @@ if ($limit > 0 && $limit != $conf->liste_limit) { print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); -if ($massaction == 'preunlettering') { - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnlettering"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unlettering", null, '', 0, 200, 500, 1); +if ($massaction == 'preunletteringauto') { + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnletteringAuto"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unletteringauto", null, '', 0, 200, 500, 1); +} elseif ($massaction == 'preunletteringmanual') { + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnletteringManual"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unletteringmanual", null, '', 0, 200, 500, 1); } elseif ($massaction == 'predeletebookkeepingwriting') { print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDeleteBookkeepingWriting"), $langs->trans("ConfirmMassDeleteBookkeepingWritingQuestion", count($toselect)), "deletebookkeepingwriting", null, '', 0, 200, 500, 1); } diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php index 405a630942e..5f3d23a72eb 100644 --- a/htdocs/accountancy/class/lettering.class.php +++ b/htdocs/accountancy/class/lettering.class.php @@ -33,11 +33,52 @@ include_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; */ class Lettering extends BookKeeping { - /** - * @var BookKeeping[] Bookkeeping cached - */ - public static $bookkeeping_cached = array(); - + public static $doc_type_infos = array( + 'customer_invoice' => array( + 'payment_table' => 'paiement', + 'payment_table_fk_bank' => 'fk_bank', + 'doc_payment_table' => 'paiement_facture', + 'doc_payment_table_fk_payment' => 'fk_paiement', + 'doc_payment_table_fk_doc' => 'fk_facture', + 'linked_info' => array( + array( + 'table' => 'paiement_facture', + 'fk_doc' => 'fk_facture', + 'fk_link' => 'fk_paiement', + 'prefix' => 'p', + ), + array( + 'table' => 'societe_remise_except', + 'fk_doc' => 'fk_facture_source', + 'fk_link' => 'fk_facture', + 'prefix' => 'a', + 'is_fk_link_is_also_fk_doc' => true, + ), + ), + ), + 'supplier_invoice' => array( + 'payment_table' => 'paiementfourn', + 'payment_table_fk_bank' => 'fk_bank', + 'doc_payment_table' => 'paiementfourn_facturefourn', + 'doc_payment_table_fk_payment' => 'fk_paiementfourn', + 'doc_payment_table_fk_doc' => 'fk_facturefourn', + 'linked_info' => array( + array( + 'table' => 'paiementfourn_facturefourn', + 'fk_doc' => 'fk_facturefourn', + 'fk_link' => 'fk_paiementfourn', + 'prefix' => 'p', + ), + array( + 'table' => 'societe_remise_except', + 'fk_doc' => 'fk_invoice_supplier_source', + 'fk_link' => 'fk_invoice_supplier', + 'prefix' => 'a', + 'is_fk_link_is_also_fk_doc' => true, + ), + ), + ), + ); /** * letteringThirdparty @@ -250,26 +291,17 @@ class Lettering extends BookKeeping $lettre = 'AAA'; $sql = "SELECT DISTINCT ab2.lettering_code"; - $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping As ab"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu ON bu.fk_bank = ab.fk_doc"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu2 ON bu2.url_id = bu.url_id"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab2 ON ab2.fk_doc = bu2.fk_bank"; - $sql .= " WHERE ab.rowid IN (" . $this->db->sanitize(implode(',', $ids)) . ")"; - $sql .= " AND ab.doc_type = 'bank'"; - $sql .= " AND ab2.doc_type = 'bank'"; - $sql .= " AND bu.type = 'company'"; - $sql .= " AND bu2.type = 'company'"; - $sql .= " AND ab.subledger_account != ''"; - $sql .= " AND ab2.subledger_account != ''"; - $sql .= " AND ab.lettering_code IS NULL"; - $sql .= " AND ab2.lettering_code != ''"; - $sql .= " ORDER BY ab2.lettering_code DESC"; - $sql .= " LIMIT 1 "; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab2 ON ab2.subledger_account = ab.subledger_account"; + $sql .= " WHERE ab.rowid IN (" . $this->db->sanitize(implode(',', $ids)) . ")"; + $sql .= " AND ab2.lettering_code != ''"; + $sql .= " ORDER BY ab2.lettering_code DESC"; + $sql .= " LIMIT 1 "; $resqla = $this->db->query($sql); if ($resqla) { $obj = $this->db->fetch_object($resqla); - $lettre = (empty($obj->lettering_code) ? 'AAA' : $obj->lettering_code); + $lettre = (empty($obj->lettering_code) ? $lettre : $obj->lettering_code); if (!empty($obj->lettering_code)) { $lettre++; } @@ -301,7 +333,7 @@ class Lettering extends BookKeeping if (!$error) { $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET"; $sql .= " lettering_code='".$this->db->escape($lettre)."'"; - $sql .= " , date_lettering = '".$this->db->idate($now)."'"; // todo correct date it's false + $sql .= ", date_lettering = '".$this->db->idate($now)."'"; // todo correct date it's false $sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND lettering_code IS NULL AND subledger_account != ''"; dol_syslog(get_class($this)."::update", LOG_DEBUG); @@ -336,7 +368,7 @@ class Lettering extends BookKeeping $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET"; $sql .= " lettering_code = NULL"; - $sql .= " , date_lettering = NULL"; + $sql .= ", date_lettering = NULL"; $sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).")"; $sql .= " AND subledger_account != ''"; @@ -374,16 +406,7 @@ class Lettering extends BookKeeping $errors = array(); $nb_lettering = 0; - $result = $this->bookkeepingLettering($bookkeeping_ids, 'customer_invoice', $unlettering); - if ($result < 0) { - $error++; - $errors = array_merge($errors, $this->errors); - $nb_lettering += abs($result) - 2; - } else { - $nb_lettering += $result; - } - - $result = $this->bookkeepingLettering($bookkeeping_ids, 'supplier_invoice', $unlettering); + $result = $this->bookkeepingLettering($bookkeeping_ids, $unlettering); if ($result < 0) { $error++; $errors = array_merge($errors, $this->errors); @@ -404,11 +427,10 @@ class Lettering extends BookKeeping * Lettering bookkeeping lines * * @param array $bookkeeping_ids Lettering specific list of bookkeeping id - * @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice') * @param bool $unlettering Do unlettering * @return int <0 if error (nb lettered = result -1), 0 if noting to lettering, >0 if OK (nb lettered) */ - public function bookkeepingLettering($bookkeeping_ids, $type = 'customer_invoice', $unlettering = false) + public function bookkeepingLettering($bookkeeping_ids, $unlettering = false) { global $langs; @@ -416,11 +438,14 @@ class Lettering extends BookKeeping // Clean parameters $bookkeeping_ids = is_array($bookkeeping_ids) ? $bookkeeping_ids : array(); - $type = trim($type); $error = 0; $nb_lettering = 0; - $grouped_lines = $this->getLinkedLines($bookkeeping_ids, $type); + $grouped_lines = $this->getLinkedLines($bookkeeping_ids); + if (!is_array($grouped_lines)) { + return -2; + } + foreach ($grouped_lines as $lines) { $group_error = 0; $total = 0; @@ -440,7 +465,7 @@ class Lettering extends BookKeeping $group_error++; break; } - if (!isset($lettering_code)) $lettering_code = (string) $line_infos['lettering_code']; + if (!isset($lettering_code)) $lettering_code = (string)$line_infos['lettering_code']; if (!empty($line_infos['lettering_code'])) $do_it = true; } elseif (!empty($line_infos['lettering_code'])) $do_it = false; } @@ -478,52 +503,215 @@ class Lettering extends BookKeeping /** * Lettering bookkeeping lines * - * @param array $bookkeeping_ids Lettering specific list of bookkeeping id - * @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice') - * @return array|int <0 if error otherwise all linked lines by block + * @param array $bookkeeping_ids Lettering specific list of bookkeeping id + * @param bool $only_has_subledger_account Get only lines who have subledger account + * @return array|int <0 if error otherwise all linked lines by block */ - public function getLinkedLines($bookkeeping_ids, $type = 'customer_invoice') + public function getLinkedLines($bookkeeping_ids, $only_has_subledger_account = true) { global $conf, $langs; $this->errors = array(); // Clean parameters $bookkeeping_ids = is_array($bookkeeping_ids) ? $bookkeeping_ids : array(); - $type = trim($type); - if ($type == 'customer_invoice') { - $doc_type = 'customer_invoice'; - $bank_url_type = 'payment'; - $payment_element = 'paiement_facture'; - $fk_payment_element = 'fk_paiement'; - $fk_element = 'fk_facture'; - $account_number = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER; - } elseif ($type == 'supplier_invoice') { - $doc_type = 'supplier_invoice'; - $bank_url_type = 'payment_supplier'; - $payment_element = 'paiementfourn_facturefourn'; - $fk_payment_element = 'fk_paiementfourn'; - $fk_element = 'fk_facturefourn'; - $account_number = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER; - } else { + // Get all bookkeeping lines + $sql = "SELECT DISTINCT ab.doc_type, ab.fk_doc"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; + if (!empty($bookkeeping_ids)) { + // Get all bookkeeping lines of piece number + $sql .= " LEFT JOIN ("; + $sql .= " SELECT DISTINCT piece_num"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE entity IN (" . getEntity('accountancy') . ")"; + $sql .= " AND rowid IN (" . $this->db->sanitize(implode(',', $bookkeeping_ids)) . ")"; + $sql .= " ) AS pn ON pn.piece_num = ab.piece_num"; + } + $sql .= " WHERE ab.entity IN (" . getEntity('accountancy') . ")"; + $sql .= " AND ab.fk_doc > 0"; + if (!empty($bookkeeping_ids)) $sql .= " AND pn.piece_num IS NOT NULL"; + if ($only_has_subledger_account) $sql .= " AND ab.subledger_account != ''"; + + dol_syslog(__METHOD__ . " - Get all bookkeeping lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + $bookkeeping_lines_by_type = array(); + while ($obj = $this->db->fetch_object($resql)) { + $bookkeeping_lines_by_type[$obj->doc_type][$obj->fk_doc] = $obj->fk_doc; + } + $this->db->free($resql); + + if (empty($bookkeeping_lines_by_type)) { + return array(); + } + + if (!empty($bookkeeping_lines_by_type['bank'])) { + $new_bookkeeping_lines_by_type = $this->getDocTypeAndFkDocFromBankLines($bookkeeping_lines_by_type['bank']); + if (!is_array($new_bookkeeping_lines_by_type)) { + return -1; + } + foreach ($new_bookkeeping_lines_by_type as $doc_type => $fk_docs) { + foreach ($fk_docs as $fk_doc) { + $bookkeeping_lines_by_type[$doc_type][$fk_doc] = $fk_doc; + } + } + } + + $grouped_lines = array(); + foreach (self::$doc_type_infos as $doc_type => $doc_type_info) { + if (!is_array($bookkeeping_lines_by_type[$doc_type])) { + continue; + } + + // Get all document ids grouped + $doc_grouped = $this->getLinkedDocumentByGroup($bookkeeping_lines_by_type[$doc_type], $doc_type); + if (!is_array($doc_grouped)) { + return -1; + } + + // Group all lines by document/piece number + foreach ($doc_grouped as $doc_ids) { + $bank_ids = $this->getBankLinesFromFkDocAndDocType($doc_ids, $doc_type); + if (!is_array($bank_ids)) { + return -1; + } + + // Get all bookkeeping lines linked + $sql = "SELECT DISTINCT ab.rowid, ab.piece_num, ab.debit, ab.credit, ab.lettering_code"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; + if (!empty($bank_ids)) { + $sql .= " LEFT JOIN ("; + $sql .= " SELECT DISTINCT ab.piece_num"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; + $sql .= " WHERE ab.entity IN (" . getEntity('accountancy') . ")"; + $sql .= " AND ab.doc_type = 'bank'"; + $sql .= " AND ab.fk_doc IN (" . $this->db->sanitize(implode(',', $bank_ids)) . ")"; + $sql .= " ) AS bpn ON bpn.piece_num = ab.piece_num"; + } + $sql .= " LEFT JOIN ("; + $sql .= " SELECT DISTINCT ab.piece_num"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; + $sql .= " WHERE ab.entity IN (" . getEntity('accountancy') . ")"; + $sql .= " AND ab.doc_type = '" . $this->db->escape($doc_type) . "'"; + $sql .= " AND ab.fk_doc IN (" . $this->db->sanitize(implode(',', $doc_ids)) . ")"; + $sql .= " ) AS dpn ON dpn.piece_num = ab.piece_num"; + $sql .= " WHERE ab.entity IN (" . getEntity('accountancy') . ")"; + $sql .= " AND ("; + if (!empty($bank_ids)) { + $sql .= "bpn.piece_num IS NOT NULL OR "; + } + $sql .= "dpn.piece_num IS NOT NULL)"; + if ($only_has_subledger_account) $sql .= " AND ab.subledger_account != ''"; + + dol_syslog(__METHOD__ . " - Get all bookkeeping lines linked", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + $group = array(); + while ($obj = $this->db->fetch_object($resql)) { + $group[$obj->rowid] = array( + 'id' => $obj->rowid, + 'piece_num' => $obj->piece_num, + 'debit' => $obj->debit, + 'credit' => $obj->credit, + 'lettering_code' => $obj->lettering_code, + ); + } + $this->db->free($resql); + + if (!empty($group)) $grouped_lines[] = $group; + } + } + + return $grouped_lines; + } + + /** + * Get all fk_doc by doc_type from list of bank ids + * + * @param array $bank_ids List of bank ids + * @return array|int <0 if error otherwise all fk_doc by doc_type + */ + public function getDocTypeAndFkDocFromBankLines($bank_ids) + { + dol_syslog(__METHOD__ . " - bank_ids=".json_encode($bank_ids), LOG_DEBUG); + + // Clean parameters + $bank_ids = is_array($bank_ids) ? $bank_ids : array(); + + if (empty($bank_ids)) { + return array(); + } + + $bookkeeping_lines_by_type = array(); + foreach (self::$doc_type_infos as $doc_type => $doc_type_info) { + // Get all fk_doc by doc_type from bank ids + $sql = "SELECT DISTINCT dp." . $doc_type_info['doc_payment_table_fk_doc'] . " AS fk_doc"; + $sql .= " FROM " . MAIN_DB_PREFIX . $doc_type_info['payment_table'] . " AS p"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . $doc_type_info['doc_payment_table'] . " AS dp ON dp." . $doc_type_info['doc_payment_table_fk_payment'] . " = p.rowid"; + $sql .= " WHERE p." . $doc_type_info['payment_table_fk_bank'] . " IN (" . $this->db->sanitize(implode(',', $bank_ids)) . ")"; + $sql .= " AND dp." . $doc_type_info['doc_payment_table_fk_doc'] . " > 0"; + + dol_syslog(__METHOD__ . " - Get all fk_doc by doc_type from list of bank ids for '" . $doc_type . "'", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + while ($obj = $this->db->fetch_object($resql)) { + $bookkeeping_lines_by_type[$doc_type][$obj->fk_doc] = $obj->fk_doc; + } + $this->db->free($resql); + } + + return $bookkeeping_lines_by_type; + } + + /** + * Get all bank ids from list of document ids of a type + * + * @param array $document_ids List of document id + * @param string $doc_type Type of document ('customer_invoice' or 'supplier_invoice', ...) + * @return array|int <0 if error otherwise all all bank ids from list of document ids of a type + */ + public function getBankLinesFromFkDocAndDocType($document_ids, $doc_type) + { + global $langs; + + dol_syslog(__METHOD__ . " - bank_ids=".json_encode($document_ids) . ", doc_type=$doc_type", LOG_DEBUG); + + // Clean parameters + $document_ids = is_array($document_ids) ? $document_ids : array(); + $doc_type = trim($doc_type); + + if (empty($document_ids)) { + return array(); + } + if (!is_array(self::$doc_type_infos[$doc_type])) { $langs->load('errors'); $this->errors[] = $langs->trans('ErrorBadParameters'); return -1; } - $payment_ids = array(); + $doc_type_info = self::$doc_type_infos[$doc_type]; + $bank_ids = array(); - // Get all payment id from bank lines - $sql = "SELECT DISTINCT bu.url_id AS payment_id"; - $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu ON bu.fk_bank = ab.fk_doc"; - $sql .= " WHERE ab.doc_type = 'bank'"; - // $sql .= " AND ab.subledger_account != ''"; - // $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'"; - $sql .= " AND bu.type = '" . $this->db->escape($bank_url_type) . "'"; - if (!empty($bookkeeping_ids)) $sql .= " AND ab.rowid IN (" . $this->db->sanitize(implode(',', $bookkeeping_ids)) . ")"; + // Get all fk_doc by doc_type from bank ids + $sql = "SELECT DISTINCT p." . $doc_type_info['payment_table_fk_bank'] . " AS fk_doc"; + $sql .= " FROM " . MAIN_DB_PREFIX . $doc_type_info['payment_table'] . " AS p"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . $doc_type_info['doc_payment_table'] . " AS dp ON dp." . $doc_type_info['doc_payment_table_fk_payment'] . " = p.rowid"; + $sql .= " WHERE dp." . $doc_type_info['doc_payment_table_fk_doc'] . " IN (" . $this->db->sanitize(implode(',', $document_ids)) . ")"; + $sql .= " AND p." . $doc_type_info['payment_table_fk_bank'] . " > 0"; - dol_syslog(__METHOD__ . " - Get all payment id from bank lines", LOG_DEBUG); + dol_syslog(__METHOD__ . " - Get all bank ids from list of document ids of a type '" . $doc_type . "'", LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $this->errors[] = "Error " . $this->db->lasterror(); @@ -531,218 +719,137 @@ class Lettering extends BookKeeping } while ($obj = $this->db->fetch_object($resql)) { - $payment_ids[$obj->payment_id] = $obj->payment_id; + $bank_ids[$obj->fk_doc] = $obj->fk_doc; } $this->db->free($resql); - // Get all payment id from payment lines - $sql = "SELECT DISTINCT pe.$fk_payment_element AS payment_id"; - $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "$payment_element AS pe ON pe.$fk_element = ab.fk_doc"; - $sql .= " WHERE ab.doc_type = '" . $this->db->escape($doc_type) . "'"; - // $sql .= " AND ab.subledger_account != ''"; - // $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'"; - $sql .= " AND pe.$fk_payment_element IS NOT NULL"; - if (!empty($bookkeeping_ids)) $sql .= " AND ab.rowid IN (" . $this->db->sanitize(implode(',', $bookkeeping_ids)) . ")"; - - dol_syslog(__METHOD__ . " - Get all payment id from bank lines", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $this->errors[] = "Error " . $this->db->lasterror(); - return -1; - } - - while ($obj = $this->db->fetch_object($resql)) { - $payment_ids[$obj->payment_id] = $obj->payment_id; - } - $this->db->free($resql); - - if (empty($payment_ids)) { - return array(); - } - - // Get all payments linked by group - $payment_by_group = $this->getLinkedPaymentByGroup($payment_ids, $type); - - $groups = array(); - foreach ($payment_by_group as $payment_list) { - $lines = array(); - - // Get bank lines - $sql = "SELECT DISTINCT ab.rowid, ab.piece_num, ab.lettering_code, ab.debit, ab.credit"; - $sql .= " FROM " . MAIN_DB_PREFIX . "bank_url AS bu"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab ON ab.fk_doc = bu.fk_bank"; - $sql .= " WHERE bu.url_id IN (" . $this->db->sanitize(implode(',', $payment_list)) . ")"; - $sql .= " AND bu.type = '" . $this->db->escape($bank_url_type) . "'"; - $sql .= " AND ab.doc_type = 'bank'"; - $sql .= " AND ab.subledger_account != ''"; - $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'"; - - dol_syslog(__METHOD__ . " - Get bank lines", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $this->errors[] = "Error " . $this->db->lasterror(); - return -1; - } - - while ($obj = $this->db->fetch_object($resql)) { - $lines[$obj->rowid] = array('id' => $obj->rowid, 'piece_num' => $obj->piece_num, 'lettering_code' => $obj->lettering_code, 'debit' => $obj->debit, 'credit' => $obj->credit); - } - $this->db->free($resql); - - // Get payment lines - $sql = "SELECT DISTINCT ab.rowid, ab.piece_num, ab.lettering_code, ab.debit, ab.credit"; - $sql .= " FROM " . MAIN_DB_PREFIX . "$payment_element AS pe"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab ON ab.fk_doc = pe.$fk_element"; - $sql .= " WHERE pe.$fk_payment_element IN (" . $this->db->sanitize(implode(',', $payment_list)) . ")"; - $sql .= " AND ab.doc_type = '" . $this->db->escape($doc_type) . "'"; - $sql .= " AND ab.subledger_account != ''"; - $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'"; - - dol_syslog(__METHOD__ . " - Get payment lines", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $this->errors[] = "Error " . $this->db->lasterror(); - return -1; - } - - while ($obj = $this->db->fetch_object($resql)) { - $lines[$obj->rowid] = array('id' => $obj->rowid, 'piece_num' => $obj->piece_num, 'lettering_code' => $obj->lettering_code, 'debit' => $obj->debit, 'credit' => $obj->credit); - } - $this->db->free($resql); - - if (!empty($lines)) { - $groups[] = $lines; - } - } - - return $groups; + return $bank_ids; } /** - * Linked payment by group + * Get all linked document ids by group and type * - * @param array $payment_ids list of payment id - * @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice') - * @return array|int <0 if error otherwise all linked lines by block + * @param array $document_ids List of document id + * @param string $doc_type Type of document ('customer_invoice' or 'supplier_invoice', ...) + * @return array|int <0 if error otherwise all linked document ids by group and type [ [ 'doc_type' => [ doc_id, ... ], ... ], ... ] */ - public function getLinkedPaymentByGroup($payment_ids, $type) + public function getLinkedDocumentByGroup($document_ids, $doc_type) { global $langs; // Clean parameters - $payment_ids = is_array($payment_ids) ? $payment_ids : array(); - $type = trim($type); + $document_ids = is_array($document_ids) ? $document_ids : array(); + $doc_type = trim($doc_type); - if (empty($payment_ids)) { + if (empty($document_ids)) { return array(); } - - if ($type == 'customer_invoice') { - $payment_element = 'paiement_facture'; - $fk_payment_element = 'fk_paiement'; - $fk_element = 'fk_facture'; - } elseif ($type == 'supplier_invoice') { - $payment_element = 'paiementfourn_facturefourn'; - $fk_payment_element = 'fk_paiementfourn'; - $fk_element = 'fk_facturefourn'; - } else { + if (!is_array(self::$doc_type_infos[$doc_type])) { $langs->load('errors'); $this->errors[] = $langs->trans('ErrorBadParameters'); return -1; } - // Get payment lines - $sql = "SELECT DISTINCT pe2.$fk_payment_element, pe2.$fk_element"; - $sql .= " FROM " . MAIN_DB_PREFIX . "$payment_element AS pe"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "$payment_element AS pe2 ON pe2.$fk_element = pe.$fk_element"; - $sql .= " WHERE pe.$fk_payment_element IN (" . $this->db->sanitize(implode(',', $payment_ids)) . ")"; + $doc_type_info = self::$doc_type_infos[$doc_type]; - dol_syslog(__METHOD__ . " - Get payment lines", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { - $this->errors[] = "Error " . $this->db->lasterror(); - return -1; + // Get document lines + $current_document_ids = array(); + $link_by_element = array(); + $element_by_link = array(); + foreach ($doc_type_info['linked_info'] as $linked_info) { + $sql = "SELECT DISTINCT tl2." . $linked_info['fk_link'] . " AS fk_link, tl2." . $linked_info['fk_doc'] . " AS fk_doc"; + $sql .= " FROM " . MAIN_DB_PREFIX . $linked_info['table'] . " AS tl"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . $linked_info['table'] . " AS tl2 ON tl2." . $linked_info['fk_link'] . " = tl." . $linked_info['fk_link']; + $sql .= " WHERE tl." . $linked_info['fk_doc'] . " IN (" . $this->db->sanitize(implode(',', $document_ids)) . ")"; + + dol_syslog(__METHOD__ . " - Get document lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + $is_fk_link_is_also_fk_doc = !empty($linked_info['is_fk_link_is_also_fk_doc']); + while ($obj = $this->db->fetch_object($resql)) { + $current_document_ids[$obj->fk_doc] = $obj->fk_doc; + + $link_key = $linked_info['prefix'] . $obj->fk_link; + $element_by_link[$link_key][$obj->fk_doc] = $obj->fk_doc; + $link_by_element[$obj->fk_doc][$link_key] = $link_key; + if ($is_fk_link_is_also_fk_doc) { + $element_by_link[$link_key][$obj->fk_link] = $obj->fk_link; + $link_by_element[$obj->fk_link][$link_key] = $link_key; + } + } + $this->db->free($resql); } - $current_payment_ids = array(); - $payment_by_element = array(); - $element_by_payment = array(); - while ($obj = $this->db->fetch_object($resql)) { - $current_payment_ids[$obj->$fk_payment_element] = $obj->$fk_payment_element; - $element_by_payment[$obj->$fk_payment_element][$obj->$fk_element] = $obj->$fk_element; - $payment_by_element[$obj->$fk_element][$obj->$fk_payment_element] = $obj->$fk_payment_element; - } - $this->db->free($resql); - - if (count(array_diff($payment_ids, $current_payment_ids))) { - return $this->getLinkedPaymentByGroup($current_payment_ids, $type); + if (count(array_diff($document_ids, $current_document_ids))) { + return $this->getLinkedDocumentByGroup($current_document_ids, $doc_type); } - return $this->getGroupElements($payment_by_element, $element_by_payment); + return $this->getGroupElements($link_by_element, $element_by_link); } /** - * Get payment ids grouped by payment id and element id in common + * Get element ids grouped by link or element in common * - * @param array $payment_by_element List of payment ids by element id - * @param array $element_by_payment List of element ids by payment id - * @param int $element_id Element Id (used for recursive function) - * @param array $current_group Current group (used for recursive function) - * @return array List of payment ids grouped by payment id and element id in common + * @param array &$link_by_element List of payment ids by link key + * @param array &$element_by_link List of element ids by link key + * @param string $link_key Link key (used for recursive function) + * @param array &$current_group Current group (used for recursive function) + * @return array List of element ids grouped by link or element in common */ - public function getGroupElements(&$payment_by_element, &$element_by_payment, $element_id = 0, &$current_group = array()) + public function getGroupElements(&$link_by_element, &$element_by_link, $link_key = '', &$current_group = array()) { - $grouped_payments = array(); - if ($element_id > 0 && !isset($payment_by_element[$element_id])) { - // Return if specific element id not found - return $grouped_payments; + $grouped_elements = array(); + if (!empty($link_key) && !isset($element_by_link[$link_key])) { + // Return if specific link key not found + return $grouped_elements; } - $save_payment_by_element = null; - $save_element_by_payment = null; - if ($element_id == 0) { + if (empty($link_key)) { // Save list when is the begin of recursive function - $save_payment_by_element = $payment_by_element; - $save_element_by_payment = $element_by_payment; + $save_link_by_element = $link_by_element; + $save_element_by_link = $element_by_link; } do { // Get current element id, get this payment id list and delete the entry - $current_element_id = $element_id > 0 ? $element_id : array_keys($payment_by_element)[0]; - $payment_ids = $payment_by_element[$current_element_id]; - unset($payment_by_element[$current_element_id]); + $current_link_key = !empty($link_key) ? $link_key : array_keys($element_by_link)[0]; + $element_ids = $element_by_link[$current_link_key]; + unset($element_by_link[$current_link_key]); - foreach ($payment_ids as $payment_id) { - // Continue if payment id in not found - if (!isset($element_by_payment[$payment_id])) continue; + foreach ($element_ids as $element_id) { + // Continue if element id in not found + if (!isset($link_by_element[$element_id])) continue; - // Set the payment in the current group - $current_group[$payment_id] = $payment_id; + // Set the element in the current group + $current_group[$element_id] = $element_id; - // Get current element ids, get this payment id list and delete the entry - $element_ids = $element_by_payment[$payment_id]; - unset($element_by_payment[$payment_id]); + // Get current link keys, get this element id list and delete the entry + $link_keys = $link_by_element[$element_id]; + unset($link_by_element[$element_id]); - // Set payment id on the current group for each element id of the payment - foreach ($element_ids as $id) { - $this->getGroupElements($payment_by_element, $element_by_payment, $id, $current_group); + // Set element id on the current group for each link key of the element + foreach ($link_keys as $key) { + $this->getGroupElements($link_by_element, $element_by_link, $key, $current_group); } } - if ($element_id == 0) { + if (empty($link_key)) { // Save current group and reset the current group when is the begin of recursive function - $grouped_payments[] = $current_group; + $grouped_elements[] = $current_group; $current_group = array(); } - } while (!empty($payment_by_element) && $element_id == 0); + } while(!empty($element_by_link) && empty($link_key)); - if ($element_id == 0) { + if (empty($link_key)) { // Restore list when is the begin of recursive function - $payment_by_element = $save_payment_by_element; - $element_by_payment = $save_element_by_payment; + $link_by_element = $save_link_by_element; + $element_by_link = $save_element_by_link; } - return $grouped_payments; + return $grouped_elements; } } diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 70741aca5d1..3e96804c99f 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -381,7 +381,7 @@ if ($action == 'writebookkeeping') { if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) { require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; $lettering_static = new Lettering($db); - $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id), 'supplier_invoice'); + $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id)); } } } diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 107dda05f4a..ca0dd5089a4 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -394,7 +394,7 @@ if ($action == 'writebookkeeping') { if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) { require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; $lettering_static = new Lettering($db); - $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id), 'customer_invoice'); + $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id)); } } } diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index fcdbca76d5c..d186027ff22 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -398,7 +398,11 @@ Calculated=Calculated Formula=Formula ## Reconcile +LetteringAuto=Reconcile auto +LetteringManual=Reconcile manual Unlettering=Unreconcile +UnletteringAuto=Unreconcile auto +UnletteringManual=Unreconcile manual AccountancyNoLetteringModified=No reconcile modified AccountancyOneLetteringModifiedSuccessfully=One reconcile successfully modified AccountancyLetteringModifiedSuccessfully=%s reconcile successfully modified @@ -407,8 +411,9 @@ AccountancyOneUnletteringModifiedSuccessfully=One unreconcile successfully modif AccountancyUnletteringModifiedSuccessfully=%s unreconcile successfully modified ## Confirm box -ConfirmMassUnlettering=Bulk Unreconcile confirmation -ConfirmMassUnletteringQuestion=Are you sure you want to Unreconcile the %s selected record(s)? +ConfirmMassUnletteringAuto=Bulk auto unreconcile confirmation +ConfirmMassUnletteringManual=Bulk manual unreconcile confirmation +ConfirmMassUnletteringQuestion=Are you sure you want to unreconcile the %s selected record(s)? ConfirmMassDeleteBookkeepingWriting=Bulk Delete confirmation ConfirmMassDeleteBookkeepingWritingQuestion=This will delete the transaction from the accounting (all lines related to the same transaction will be deleted) Are you sure you want to delete the %s selected record(s)?