diff --git a/ChangeLog b/ChangeLog index 2527864a862..19c77c702fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -104,8 +104,8 @@ NEW: class tool for converting units NEW: Close #13011 Add button create thirdparty when creating intervention NEW: Colorful theme for TakePOS NEW: columns units in product list -NEW: compatibility of translabel with more dict -NEW: Confirm file delete on fracture card +NEW: compatibility of translabel with more dictionaries +NEW: Confirm file delete on invoice card NEW: "contact_civility" for ODT templates NEW: CUPS printing compatibility for TakePOS NEW: Customer command list - Add date start & date end @@ -113,16 +113,11 @@ NEW: display weight in shipment list NEW: Documentation about PHP support in Dolibarr NEW: Donation - Update FR CERFA to 11580*04 NEW: Easier way to setup the different types of tax. Better visibility. -NEW: enable put for agendaevents api NEW: Expedition list - Add date start & date end NEW: Experiment supplier packaging with option PRODUCT_USE_SUPPLIER_PACKAGING: Using price according to the minimum quantity NEW: Export module, add extrafields for Contract and Contract line NEW: Extend retained warranty to be available for all invoices -NEW: filter by product on supplier order API NEW: French new regions -NEW: get documents for categories with RESP API -NEW: get proposal by ref with API -NEW: Hidden option MAIN_TEMP_DIR NEW: hook and data id NEW: hook on ics generation to add more events in eventarray NEW: hook on product load stats @@ -195,7 +190,6 @@ NEW: API filter bankaccounts by category NEW: API filter contacts by category NEW: API filter members by category NEW: API filter projects by category -NEW: API filter thirdpartie by category NEW: API filter thirdparty by category NEW: API filter user by category NEW: API filter warehouses by categorie @@ -209,6 +203,11 @@ NEW: Bookkeeping by account - Add selectfields & hook NEW: Can force position of legend of graph on right (instead of top) NEW: Can change destination of "Back to list" using a "backtolist" parameter NEW: add more category types from hook +NEW: enable put for agendaevents api +NEW: filter by product on supplier order API +NEW: get documents for categories with RESP API +NEW: get proposal by ref with API +NEW: Hidden option MAIN_TEMP_DIR WARNING: @@ -242,6 +241,52 @@ Only people that installed Dolibarr using the all-in-one autoinstaller for Windo DoliWAMP remains a solution for fast test or demo purposes. +***** ChangeLog for 11.0.5 compared to 11.0.4 ***** +FIX: $arraydefaultmessage is an object, as well as in /htdocs/core/class/html.formmail.class.php +FIX: 10.0 - pagination in prelevement/bons.php +FIX: 10.0 - undefined $langs if template file copy fails during activation of modContrat +FIX: 11.0 - fatal with postgres on contact/agenda.php +FIX: 11.0 - multicurrency amount not fetched when fetching payments from llx_paiement or llx_paiementfourn +FIX: 11.0 - when using pdftk as per hidden conf USE_PDFTK_FOR_PDF_CONCAT, check that the file exists before displaying a success message +FIX: #13841 +FIX: #13877 - Can validate invoice if there is a credit note with VAT 0% on an invoice with other lines with a VAT non 0% +FIX: #13968 +FIX: #14001 +FIX: #14002 +FIX: 9.0 - delete unused mandatory argument from migrate_clean_association: argument count mismatch causes a fatal error since php7 +FIX: 9.0 - fatal during migration from 3.1 using PHP 7 +FIX: Accountancy - Binding index - Add a filter on sql request for module Subtotal & Jalon +FIX: avoid error "Call to undefined function measuringUnitString()" +FIX: BlindBoolean SQL injection reported by Christian Weiler +FIX: Can create a credit note on situation invoice if previous is also +FIX: can install module even if (x) was appended during download. +FIX: copy value date of VariousPayment onto the new AccountLine +FIX: count of open day when date and start are not open should be 0 +FIX: Default bank account was not loaded for document generation. +FIX: Do not show stats panel if the user does not have permissions +FIX: Fix link of the button to create a credit note and fix the awareness of a error that happen when wo create a credit note +FIX: force rounding 2 on export ld compta +FIX: free text on cash desk +FIX: links into emails of notifications +FIX: missing file manifest.json.php +FIX: missing GetNomURL Hook in warehouse class +FIX: missing hook init + table class + $page not set +FIX: missing rollbacks on trigger bad return +FIX: missing translation value for key "NoMorePredefinedProductToDispatch" +FIX: percent must be displayed on one line +FIX: php error if multicompany disabled +FIX: Privilege escalation reported by wizlynx WLX-2020-011 +FIX: replace filter parameter "none" by "restricthtml" +FIX: Rounding Total TVA in "crabe" model pdf +FIX: Show ref_customer, amount on contract link object +FIX: Site ec.europa.eu has moved to https:// +FIX: Tickets mail models doesn't work +FIX: vulnerability reported by wizlynx WLX-2020-012 +FIX: We must only rename current bank receipt +FIX: when creating a VariousPayment, the value date is not copied onto the AccountLine that gets created at the same time, so the bank transaction's value date will be the payment date instead of the payment's value date +FIX: wrong url param +FIX: XSS using the renaming of .noexe files - reported by Nolan. + ***** ChangeLog for 11.0.4 compared to 11.0.3 ***** FIX: #13749 FIX: #7594 Expense report multi pagebreak diff --git a/README.md b/README.md index f611f333e6a..fa5326079ec 100644 --- a/README.md +++ b/README.md @@ -91,14 +91,15 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Products and/or Services catalog - Commercial proposals management - Customer & Supplier Orders management +- Invoices and payment management - Shipping management - Warehouse/Stock management -- Invoices and payment management -- Standing orders management (European SEPA) +- Manufacturing Orders - Bank accounts management +- Direct debit orders management (European SEPA) - Accounting management - Shared calendar/agenda (with ical and vcal export for third party tools integration) -- Opportunities and/or project management +- Opportunities or Leads management - Projects & Tasks management - Contracts management - Interventions management diff --git a/build/doxygen/doxygen_footer.html b/build/doxygen/doxygen_footer.html index 1426885a565..2615af0b485 100644 --- a/build/doxygen/doxygen_footer.html +++ b/build/doxygen/doxygen_footer.html @@ -5,7 +5,7 @@ File added into doxygen generated documentation - +
@@ -22,31 +22,5 @@ File added into doxygen generated documentation gtag('config', 'UA-9049390-16'); - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/doxygen/doxygen_header.html b/build/doxygen/doxygen_header.html index 5810182050f..235797bb6c9 100644 --- a/build/doxygen/doxygen_header.html +++ b/build/doxygen/doxygen_header.html @@ -12,21 +12,6 @@ - - - - - @@ -48,15 +33,6 @@ src="https://www.facebook.com/tr?id=1998533953704960&ev=PageView&noscript=1"
- - - -
diff --git a/build/exe/doliwamp/Languages/MyEnglish.isl b/build/exe/doliwamp/Languages/MyEnglish.isl index 371e724d6d0..7ad94c4ca86 100644 --- a/build/exe/doliwamp/Languages/MyEnglish.isl +++ b/build/exe/doliwamp/Languages/MyEnglish.isl @@ -32,6 +32,7 @@ PortAlreadyInUse=Port %1 seems to be already in use. You should cancel to go bac FirefoxDetected=Firefox has been detected on your computer. Would you like to use it as the default browser for Dolibarr ? ChromeDetected=Chrome has been detected on your computer. Would you like to use it as the default browser for Dolibarr ? +MicrosoftEdgeDetected=Microsoft Edge has been detected on your computer. Would you like to use it as the default browser for Dolibarr ? ChooseDefaultBrowser=Please choose your default browser (iexplore.exe, firefox.exe, chrome.exe, MicrosoftEdge.exe...). If you are not sure, just click Open : LaunchNow=Launch Dolibarr now diff --git a/build/exe/doliwamp/doliwamp.iss b/build/exe/doliwamp/doliwamp.iss index 1b79648279c..4a6dca3af01 100644 --- a/build/exe/doliwamp/doliwamp.iss +++ b/build/exe/doliwamp/doliwamp.iss @@ -519,7 +519,7 @@ begin // check that we don't try an upgrade (mysql upgrade no supported) //---------------------------------------------- - if FileExists (pathWithSlashes+'/bin/mysql/mysql5.0.45'+phpVersion+'/bin/mysqld-nt.exe') then + if FileExists (pathWithSlashes+'/bin/mysql/mysql5.0.45/bin/mysqld-nt.exe') then begin MsgBox('An existing installation using an old version of Mysql exists. Sorry, upgrade with this installer is not possible.', mbInformation, MB_OK); Abort(); @@ -588,15 +588,26 @@ begin end; end; + if browser = 'iexplore.exe' then + begin + if FileExists (winPath+'/SystemApps/Microsoft.MicrosoftEdge_8wekyb3d8bbwe/MicrosoftEdge.exe') then + begin + if MsgBox(CustomMessage('MicrosoftEdgeDetected'),mbConfirmation,MB_YESNO) = IDYES then + begin + browser := winPath+'/SystemApps/Microsoft.MicrosoftEdge_8wekyb3d8bbwe/MicrosoftEdge.exe'; + end; + end; + end; + if browser = 'iexplore.exe' then begin if FileExists (pfPath+'/Internet Explorer/iexplore.exe') then begin - GetOpenFileName(CustomMessage('ChooseDefaultBrowser'), browser, pfPath+'/Internet Explorer','exe files (*.exe)|*.exe|All files (*.*)|*.*' ,'exe'); + GetOpenFileName(CustomMessage('ChooseDefaultBrowser'), browser, pfPath+'/Internet Explorer', 'exe files (*.exe)|*.exe|All files (*.*)|*.*' ,'exe'); end else begin - GetOpenFileName(CustomMessage('ChooseDefaultBrowser'), browser, winPath,'exe files (*.exe)|*.exe|All files (*.*)|*.*' ,'exe'); + GetOpenFileName(CustomMessage('ChooseDefaultBrowser'), browser, winPath, 'exe files (*.exe)|*.exe|All files (*.*)|*.*' ,'exe'); end; end; diff --git a/htdocs/admin/menus/index.php b/htdocs/admin/menus/index.php index 97f0246ac88..1dea0ca4473 100644 --- a/htdocs/admin/menus/index.php +++ b/htdocs/admin/menus/index.php @@ -328,18 +328,18 @@ if ($conf->use_javascript_ajax) $entry = '
'; $entry .= '   '.$titre.''; $entry .= ''; - $entry .= ''.img_edit('default', 0, 'class="menuEdit" id="edit'.$menu['rowid'].'"').' '; - $entry .= ''.img_edit_add('default').' '; - $entry .= ''.img_delete('default').' '; + $entry .= ''.img_edit('default', 0, 'class="menuEdit" id="edit'.$menu['rowid'].'"').' '; + $entry .= ''.img_edit_add('default').' '; + $entry .= ''.img_delete('default').' '; $entry .= '     '; - $entry .= ''.img_picto("Up", "1uparrow").''.img_picto("Down", "1downarrow").''; + $entry .= ''.img_picto("Up", "1uparrow").''.img_picto("Down", "1downarrow").''; $entry .= '
'; - $buttons = ''.img_edit('default', 0, 'class="menuEdit" id="edit'.$menu['rowid'].'"').' '; - $buttons .= ''.img_edit_add('default').' '; - $buttons .= ''.img_delete('default').' '; + $buttons = ''.img_edit('default', 0, 'class="menuEdit" id="edit'.$menu['rowid'].'"').' '; + $buttons .= ''.img_edit_add('default').' '; + $buttons .= ''.img_delete('default').' '; $buttons .= '     '; - $buttons .= ''.img_picto("Up", "1uparrow").''.img_picto("Down", "1downarrow").''; + $buttons .= ''.img_picto("Up", "1uparrow").''.img_picto("Down", "1downarrow").''; $data[] = array( 'rowid'=>$menu['rowid'], diff --git a/htdocs/admin/system/perf.php b/htdocs/admin/system/perf.php index dd77c41a673..8d4360b37c0 100644 --- a/htdocs/admin/system/perf.php +++ b/htdocs/admin/system/perf.php @@ -552,13 +552,6 @@ else } print '
'; -// Database statistics update -/* -print '
'; -print ''.$langs->trans("DatabaseStatistics").': '; -print '
'; -*/ - // End of page llxFooter(); $db->close(); diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 716e02ae678..d733cb61ba3 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -815,6 +815,7 @@ if ($action == 'create') } setdatefields(); $("#fullday").change(function() { + console.log("setdatefields"); setdatefields(); }); $("#selectcomplete").change(function() { @@ -869,9 +870,7 @@ if ($action == 'create') if (GETPOST('datep', 'int', 1)) $datep = dol_stringtotime(GETPOST('datep', 'int', 1), 0); print ''.$langs->trans("DateActionStart").''; if (GETPOST("afaire") == 1) { - print $form->selectDate($datep, 'ap', 1, 1, 0, "action", 1, 2, 0, 'fulldayend'); - } elseif (GETPOST("afaire") == 2) { - print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 2, 0, 'fulldayend'); + print $form->selectDate($datep, 'ap', 1, 1, 0, "action", 1, 2, 0, 'fulldaystart'); // Empty value not allowed for start date and hours if "todo" } else { print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 2, 0, 'fulldaystart'); } @@ -886,11 +885,9 @@ if ($action == 'create') } print ''.$langs->trans("DateActionEnd").''; if (GETPOST("afaire") == 1) { - print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend'); - } elseif (GETPOST("afaire") == 2) { - print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend'); + print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 2, 0, 'fulldayend'); } else { - print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend'); + print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 2, 0, 'fulldayend'); } print ''; diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 5b3ddefa0f5..f35c17d375d 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1704,7 +1704,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($event->type_code == 'ICALEVENT') print '
('.dol_trunc($event->icalname, $maxnbofchar).')'; $thirdparty_id = ($event->thirdparty_id > 0 ? $event->thirdparty_id : ((is_object($event->societe) && $event->societe->id > 0) ? $event->societe->id : 0)); - $contact_id = ($event->contact_id > 0 ? $event->contact_id : ((is_object($event->contact) && $event->cotact->id > 0) ? $event->contact->id : 0)); + $contact_id = ($event->contact_id > 0 ? $event->contact_id : ((is_object($event->contact) && $event->contact->id > 0) ? $event->contact->id : 0)); // If action related to company / contact $linerelatedto = ''; diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 4ff16cd7c03..9b385ea7ead 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -86,6 +86,7 @@ $extrafields->fetch_name_optionals_label($object->table_element); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('thirdpartycomm', 'globalcard')); +$now = dol_now(); /* @@ -580,7 +581,7 @@ if ($object->id > 0) // Lien recap $boxstat .= '
'; $boxstat .= ''; - $boxstat .= '\n"; @@ -898,11 +898,11 @@ if ($object->id > 0) } /* - * Latest linked contracts + * Latest contracts */ if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire) { - $sql = "SELECT s.nom, s.rowid, c.rowid as id, c.ref as ref, c.statut, c.datec as dc, c.date_contrat as dcon, c.ref_customer as refcus, c.ref_supplier as refsup"; + $sql = "SELECT s.nom, s.rowid, c.rowid as id, c.ref as ref, c.statut as contract_status, c.datec as dc, c.date_contrat as dcon, c.ref_customer as refcus, c.ref_supplier as refsup"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as c"; $sql .= " WHERE c.fk_soc = s.rowid "; $sql .= " AND s.rowid = ".$object->id; @@ -921,7 +921,7 @@ if ($object->id > 0) print '
'; + $boxstat .= '
'; if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { @@ -664,7 +665,6 @@ if ($object->id > 0) print $boxstat; - $now = dol_now(); /* * Latest proposals @@ -677,7 +677,7 @@ if ($object->id > 0) $sql .= ", p.tva as total_tva"; $sql .= ", p.total as total_ttc"; $sql .= ", p.ref, p.ref_client, p.remise"; - $sql .= ", p.datep as dp, p.fin_validite as datelimite"; + $sql .= ", p.datep as dp, p.fin_validite as date_limit"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p, ".MAIN_DB_PREFIX."c_propalst as c"; $sql .= " WHERE p.fk_soc = s.rowid AND p.fk_statut = c.id"; $sql .= " AND s.rowid = ".$object->id; @@ -716,7 +716,7 @@ if ($object->id > 0) $propal_static->total_tva = $objp->total_tva; $propal_static->total_ttc = $objp->total_ttc; print $propal_static->getNomUrl(1); - if (($db->jdate($objp->datelimite) < ($now - $conf->propal->cloture->warning_delay)) && $objp->fk_statut == 1) { + if (($db->jdate($objp->date_limit) < ($now - $conf->propal->cloture->warning_delay)) && $objp->fk_statut == $propal_static::STATUS_VALIDATED) { print " ".img_warning(); } print ''.dol_print_date($db->jdate($objp->dp), 'day')."
'; print ''; - print '
'; + print ''; @@ -937,15 +937,24 @@ if ($object->id > 0) $contrat->ref = $objp->ref ? $objp->ref : $objp->id; $contrat->ref_customer = $objp->refcus; $contrat->ref_supplier = $objp->refsup; + $contrat->statut = $objp->contract_status; $contrat->fetch_lines(); + $late = ''; + foreach ($contrat->lines as $line) { + if ($contrat->statut == Contrat::STATUS_VALIDATED && $line->statut == ContratLigne::STATUS_OPEN) { + if (((!empty($line->date_fin_validite)?$line->date_fin_validite:0) + $conf->contrat->services->expires->warning_delay) < $now) $late = img_warning($langs->trans("Late")); + } + } + print ''; print '\n"; print '\n"; - print '\n"; - print '\n"; + //print '\n"; + print '\n"; print ''; print ''; print ''; + print '
'.$langs->trans("LastContracts", ($num <= $MAXLIST ? "" : $MAXLIST)).''; print ''; //print ''; print '
'.$langs->trans("LastContracts", ($num <= $MAXLIST ? "" : $MAXLIST)).''.$langs->trans("AllContracts").''.$num.''.img_picto($langs->trans("Statistics"),'stats').'
'; print $contrat->getNomUrl(1, 12); + print $late; print "'.dol_trunc($objp->refsup, 12)."'.dol_print_date($db->jdate($objp->dc), 'day')."'.dol_print_date($db->jdate($objp->dcon), 'day')."'.dol_print_date($db->jdate($objp->dc), 'day')."'.dol_print_date($db->jdate($objp->dcon), 'day')." '; print $contrat->getLibStatut(4); diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 28fdc7845d2..8f743015f06 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -194,7 +194,7 @@ if (empty($reshook)) } } - $result = $object->createFromClone($user, $socid); + $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null)); if ($result > 0) { header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); exit(); @@ -1138,6 +1138,9 @@ if (empty($reshook)) $outputlangs->setDefaultLang($newlang); } $ret = $object->fetch($id); // Reload to get new records + if ($ret > 0) { + $object->fetch_thirdparty(); + } $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } @@ -1832,10 +1835,9 @@ if ($action == 'create') print '
'.$langs->trans("CreateEmptyPropal").'
'; } - if (!empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE)) print '
'; - dol_fiche_end(); $langs->load("bills"); @@ -1878,11 +1880,11 @@ if ($action == 'create') if ($action == 'clone') { // Create an array for form $formquestion = array( - // 'text' => $langs->trans("ConfirmClone"), - // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => - // 1), - array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)'))); + // 'text' => $langs->trans("ConfirmClone"), + // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')) + ); if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->date_livraison)) { $formquestion[] = array('type' => 'date', 'name' => 'date_delivery', 'label' => $langs->trans("DeliveryDate"), 'value' => $object->date_livraison); } diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 3c7cfe0006c..3fd122c0103 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1324,9 +1324,10 @@ class Propal extends CommonObject * * @param User $user User making the clone * @param int $socid Id of thirdparty + * @param int $forceentity Entity id to force * @return int New id of clone */ - public function createFromClone(User $user, $socid = 0) + public function createFromClone(User $user, $socid = 0, $forceentity = null) { global $conf, $hookmanager; @@ -1382,6 +1383,7 @@ class Propal extends CommonObject $object->id = 0; $object->ref = ''; + $object->entity = (! empty($forceentity) ? $forceentity : $object->entity); $object->statut = self::STATUS_DRAFT; // Clear fields @@ -1537,7 +1539,9 @@ class Propal extends CommonObject $this->note = $obj->note_private; // TODO deprecated $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; - $this->statut = (int) $obj->fk_statut; + + $this->status = (int) $obj->fk_statut; + $this->statut = $this->status; // deprecated $this->statut_libelle = $obj->statut_label; $this->datec = $this->db->jdate($obj->datec); // TODO deprecated diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index ca6a2e8d589..07e4abb0197 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1389,6 +1389,8 @@ class Account extends CommonObject $label = ''.$langs->trans("BankAccount").''; $label .= '
'.$langs->trans('Label').': '.$this->label; $label .= '
'.$langs->trans('AccountNumber').': '.$this->number; + $label .= '
'.$langs->trans('IBAN').': '.$this->iban; + $label .= '
'.$langs->trans('BIC').': '.$this->bic; $label .= '
'.$langs->trans("AccountCurrency").': '.$this->currency_code; if (empty($user->rights->banque->lire) || !empty($user->socid)) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 3270c3a9663..2038fea438c 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1489,7 +1489,7 @@ if (empty($reshook)) $result = $srcobject->fetch($object->origin_id); $typeamount = GETPOST('typedeposit', 'aZ09'); - $valuedeposit = GETPOST('valuedeposit', 'int'); + $valuedeposit = price2num(GETPOST('valuedeposit', 'alpha'), 'MU'); // If deposit invoice if ($_POST['type'] == Facture::TYPE_DEPOSIT && in_array($typeamount, array('amount', 'variable'))) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 9a80ad91d24..8957da7b9db 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4078,161 +4078,6 @@ class Facture extends CommonInvoice } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Create a withdrawal request for a direct debit order or a credit transfer order. - * Use the remain to pay excluding all existing open direct debit requests. - * - * @param User $fuser User asking the direct debit transfer - * @param float $amount Amount we request direct debit for - * @param string $type 'direct-debit' or 'bank-transfer' - * @param string $sourcetype Source ('facture' or 'supplier_invoice') - * @return int <0 if KO, >0 if OK - */ - public function demande_prelevement($fuser, $amount = 0, $type = 'direct-debit', $sourcetype = 'facture') - { - // phpcs:enable - global $conf; - - $error = 0; - - dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); - - if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) - { - require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; - $bac = new CompanyBankAccount($this->db); - $bac->fetch(0, $this->socid); - - $sql = 'SELECT count(*)'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; - if ($type == 'bank-transfer') { - $sql .= ' WHERE fk_facture_fourn = '.$this->id; - } else { - $sql .= ' WHERE fk_facture = '.$this->id; - } - $sql .= ' AND ext_payment_id IS NULL'; // To exclude record done for some online payments - $sql .= ' AND traite = 0'; - - dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $row = $this->db->fetch_row($resql); - if ($row[0] == 0) - { - $now = dol_now(); - - $totalpaye = $this->getSommePaiement(); - $totalcreditnotes = $this->getSumCreditNotesUsed(); - $totaldeposits = $this->getSumDepositsUsed(); - //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits; - - // We can also use bcadd to avoid pb with floating points - // For example print 239.2 - 229.3 - 9.9; does not return 0. - //$resteapayer=bcadd($this->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); - //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); - if (empty($amount)) $amount = price2num($this->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); - - if (is_numeric($amount) && $amount != 0) - { - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande('; - if ($type == 'bank-transfer') { - $sql .= 'fk_facture_fourn, '; - } else { - $sql .= 'fk_facture, '; - } - $sql .= ' amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib, sourcetype, entity)'; - $sql .= ' VALUES ('.$this->id; - $sql .= ",'".price2num($amount)."'"; - $sql .= ",'".$this->db->idate($now)."'"; - $sql .= ",".$fuser->id; - $sql .= ",'".$this->db->escape($bac->code_banque)."'"; - $sql .= ",'".$this->db->escape($bac->code_guichet)."'"; - $sql .= ",'".$this->db->escape($bac->number)."'"; - $sql .= ",'".$this->db->escape($bac->cle_rib)."'"; - $sql .= ",'".$this->db->escape($sourcetype)."'"; - $sql .= ",".$conf->entity; - $sql .= ")"; - - dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) - { - $this->error = $this->db->lasterror(); - dol_syslog(get_class($this).'::demandeprelevement Erreur'); - $error++; - } - } - else - { - $this->error = 'WithdrawRequestErrorNilAmount'; - dol_syslog(get_class($this).'::demandeprelevement WithdrawRequestErrorNilAmount'); - $error++; - } - - if (!$error) - { - // Force payment mode of invoice to withdraw - $payment_mode_id = dol_getIdFromCode($this->db, 'PRE', 'c_paiement', 'code', 'id', 1); - if ($payment_mode_id > 0) - { - $result = $this->setPaymentMethods($payment_mode_id); - } - } - - if ($error) return -1; - return 1; - } - else - { - $this->error = "A request already exists"; - dol_syslog(get_class($this).'::demandeprelevement Impossible de creer une demande, demande deja en cours'); - return 0; - } - } - else - { - $this->error = $this->db->error(); - dol_syslog(get_class($this).'::demandeprelevement Erreur -2'); - return -2; - } - } - else - { - $this->error = "Status of invoice does not allow this"; - dol_syslog(get_class($this)."::demandeprelevement ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id"); - return -3; - } - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Supprime une demande de prelevement - * - * @param User $fuser User making delete - * @param int $did id de la demande a supprimer - * @return int <0 if OK, >0 if KO - */ - public function demande_prelevement_delete($fuser, $did) - { - // phpcs:enable - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; - $sql .= ' WHERE rowid = '.$did; - $sql .= ' AND traite = 0'; - if ($this->db->query($sql)) - { - return 0; - } - else - { - $this->error = $this->db->lasterror(); - dol_syslog(get_class($this).'::demande_prelevement_delete Error '.$this->error); - return -1; - } - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Load indicators for dashboard (this->nbtodo and this->nbtodolate) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 6bb3e0cc5ca..128e0502344 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -558,7 +558,8 @@ if (!$sall) $sql .= ' typent.code,'; $sql .= ' state.code_departement, state.nom,'; $sql .= ' country.code,'; - $sql .= " p.rowid, p.ref, p.title"; + $sql .= " p.rowid, p.ref, p.title,"; + $sql .= " u.login"; if ($search_categ_cus) $sql .= ", cc.fk_categorie, cc.fk_soc"; // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index bc3762b41ea..b24723330a0 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -29,11 +29,14 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; if (!$user->rights->facture->lire) accessforbidden(); @@ -44,14 +47,17 @@ $id = (GETPOST('id', 'int') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // $ref = GETPOST('ref', 'alpha'); $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'alpha'); - $type = GETPOST('type', 'aZ09'); $fieldid = (!empty($ref) ? 'ref' : 'rowid'); if ($user->socid) $socid = $user->socid; $result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid); -$object = new Facture($db); +if ($type == 'bank-transfer') { + $object = new FactureFournisseur($db); +} else { + $object = new Facture($db); +} // Load object if ($id > 0 || !empty($ref)) @@ -87,6 +93,7 @@ if (empty($reshook)) $sourcetype = 'facture'; if ($type == 'bank-transfer') { $sourcetype = 'supplier_invoice'; + $newtype = 'bank-transfer'; } $result = $object->demande_prelevement($user, price2num(GETPOST('withdraw_request_amount', 'alpha')), $newtype, $sourcetype); @@ -107,12 +114,12 @@ if (empty($reshook)) if ($action == "delete") { - if ($object->id > 0) + if ($object->id > 0) { $result = $object->demande_prelevement_delete($user, GETPOST('did', 'int')); if ($result == 0) { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id.'&type='.$type); exit; } } @@ -124,13 +131,20 @@ if (empty($reshook)) * View */ +$form = new Form($db); + $now = dol_now(); -$title = $langs->trans('InvoiceCustomer')." - ".$langs->trans('StandingOrders'); -$helpurl = "EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes"; +if ($type == 'bank-transfer') { + $title = $langs->trans('InvoiceSupplier')." - ".$langs->trans('CreditTransfer'); + $helpurl = ""; +} else { + $title = $langs->trans('InvoiceCustomer')." - ".$langs->trans('StandingOrders'); + $helpurl = "EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes"; +} + llxHeader('', $title, $helpurl); -$form = new Form($db); /* *************************************************************************** */ /* */ @@ -156,18 +170,33 @@ if ($object->id > 0) if ($object->paye) $resteapayer = 0; $resteapayeraffiche = $resteapayer; - if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { - $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice - } else { - $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')"; - $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')"; - } + if ($type == 'bank-transfer') { + if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { // Never use this + $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } else { + $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')"; + $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')"; + } - $absolute_discount = $object->thirdparty->getAvailableDiscounts('', $filterabsolutediscount); - $absolute_creditnote = $object->thirdparty->getAvailableDiscounts('', $filtercreditnote); - $absolute_discount = price2num($absolute_discount, 'MT'); - $absolute_creditnote = price2num($absolute_creditnote, 'MT'); + $absolute_discount = $object->thirdparty->getAvailableDiscounts('', $filterabsolutediscount, 0, 1); + $absolute_creditnote = $object->thirdparty->getAvailableDiscounts('', $filtercreditnote, 0, 1); + $absolute_discount = price2num($absolute_discount, 'MT'); + $absolute_creditnote = price2num($absolute_creditnote, 'MT'); + } else { + if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice + } else { + $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')"; + $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')"; + } + + $absolute_discount = $object->thirdparty->getAvailableDiscounts('', $filterabsolutediscount); + $absolute_creditnote = $object->thirdparty->getAvailableDiscounts('', $filtercreditnote); + $absolute_discount = price2num($absolute_discount, 'MT'); + $absolute_creditnote = price2num($absolute_creditnote, 'MT'); + } $author = new User($db); if ($object->user_author) @@ -175,20 +204,37 @@ if ($object->id > 0) $author->fetch($object->user_author); } - $head = facture_prepare_head($object); + if ($type == 'bank-transfer') { + $head = facturefourn_prepare_head($object); + } else { + $head = facture_prepare_head($object); + } - dol_fiche_head($head, 'standingorders', $langs->trans('InvoiceCustomer'), -1, 'bill'); + dol_fiche_head($head, 'standingorders', $title, -1, 'bill'); // Invoice content - - $linkback = ''.$langs->trans("BackToList").''; + if ($type == 'bank-transfer') { + $linkback = ''.$langs->trans("BackToList").''; + } else { + $linkback = ''.$langs->trans("BackToList").''; + } $morehtmlref = '
'; // Ref customer - $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); - $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + if ($type == 'bank-transfer') { + $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', 0, 1); + $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', null, null, '', 1); + } else { + $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + } // Thirdparty $morehtmlref .= '
'.$langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1); + if ($type == 'bank-transfer') { + if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) $morehtmlref .= ' ('.$langs->trans("OtherBills").')'; + } else { + if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) $morehtmlref .= ' ('.$langs->trans("OtherBills").')'; + } // Project if (!empty($conf->projet->enabled)) { @@ -239,15 +285,26 @@ if ($object->id > 0) // Type print ''.$langs->trans('Type').''; print $object->getLibType(); - if ($object->type == Facture::TYPE_REPLACEMENT) + if ($object->module_source) { + print ' ('.$langs->trans("POS").' '.$object->module_source.' - '.$langs->trans("Terminal").' '.$object->pos_source.')'; + } + if ($object->type == $object::TYPE_REPLACEMENT) { - $facreplaced = new Facture($db); + if ($type == 'bank-transfer') { + $facreplaced = new FactureFournisseur($db); + } else { + $facreplaced = new Facture($db); + } $facreplaced->fetch($object->fk_facture_source); print ' ('.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)).')'; } - if ($object->type == Facture::TYPE_CREDIT_NOTE) + if ($object->type == $object::TYPE_CREDIT_NOTE) { - $facusing = new Facture($db); + if ($type == 'bank-transfer') { + $facusing = new FactureFournisseur($db); + } else { + $facusing = new Facture($db); + } $facusing->fetch($object->fk_facture_source); print ' ('.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).')'; } @@ -261,7 +318,11 @@ if ($object->id > 0) { if ($i == 0) print ' '; else print ','; - $facavoir = new Facture($db); + if ($type == 'bank-transfer') { + $facavoir = new FactureFournisseur($db); + } else { + $facavoir = new Facture($db); + } $facavoir->fetch($id); print $facavoir->getNomUrl(1); } @@ -280,24 +341,39 @@ if ($object->id > 0) // Discounts print ''.$langs->trans('Discounts').''; - $thirdparty = $object->thirdparty; - $discount_type = 0; + if ($type == 'bank-transfer') { + //$societe = new Fournisseur($db); + //$result = $societe->fetch($object->socid); + $thirdparty = $object->thirdparty; + $discount_type = 1; + } else { + $thirdparty = $object->thirdparty; + $discount_type = 0; + } $backtopage = urlencode($_SERVER["PHP_SELF"].'?facid='.$object->id); $cannotApplyDiscount = 1; include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php'; print ''; + // Label + if ($type == 'bank-transfer') { + print ''; + print ''.$form->editfieldkey("Label", 'label', $object->label, $object, 0).''; + print ''.$form->editfieldval("Label", 'label', $object->label, $object, 0).''; + print ''; + } + // Date invoice print ''; print ''; - if ($object->type != Facture::TYPE_CREDIT_NOTE && $action != 'editinvoicedate' && !empty($object->brouillon) && $user->rights->facture->creer) print ''; + if ($object->type != $object::TYPE_CREDIT_NOTE && $action != 'editinvoicedate' && !empty($object->brouillon) && $user->rights->facture->creer) print ''; print '
'; print $langs->trans('DateInvoice'); print 'id.'">'.img_edit($langs->trans('SetDate'), 1).'id.'">'.img_edit($langs->trans('SetDate'), 1).'
'; print ''; - if ($object->type != Facture::TYPE_CREDIT_NOTE) + if ($object->type != $object::TYPE_CREDIT_NOTE) { if ($action == 'editinvoicedate') { @@ -305,12 +381,12 @@ if ($object->id > 0) } else { - print dol_print_date($object->date, 'daytext'); + print dol_print_date($object->date, 'day'); } } else { - print dol_print_date($object->date, 'daytext'); + print dol_print_date($object->date, 'day'); } print ''; print ''; @@ -320,10 +396,10 @@ if ($object->id > 0) print ''; - if ($object->type != Facture::TYPE_CREDIT_NOTE && $action != 'editconditions' && !empty($object->brouillon) && $user->rights->facture->creer) print ''; + if ($object->type != $object::TYPE_CREDIT_NOTE && $action != 'editconditions' && !empty($object->brouillon) && $user->rights->facture->creer) print ''; print '
'; print $langs->trans('PaymentConditionsShort'); print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).'id.'">'.img_edit($langs->trans('SetConditions'), 1).'
'; print ''; - if ($object->type != Facture::TYPE_CREDIT_NOTE) + if ($object->type != $object::TYPE_CREDIT_NOTE) { if ($action == 'editconditions') { @@ -345,18 +421,23 @@ if ($object->id > 0) print ''; - if ($object->type != Facture::TYPE_CREDIT_NOTE && $action != 'editpaymentterm' && !empty($object->brouillon) && $user->rights->facture->creer) print ''; + if ($object->type != $object::TYPE_CREDIT_NOTE && $action != 'editpaymentterm' && !empty($object->brouillon) && $user->rights->facture->creer) print ''; print '
'; print $langs->trans('DateMaxPayment'); print 'id.'">'.img_edit($langs->trans('SetDate'), 1).'id.'">'.img_edit($langs->trans('SetDate'), 1).'
'; print ''; - if ($object->type != Facture::TYPE_CREDIT_NOTE) + if ($object->type != $object::TYPE_CREDIT_NOTE) { + $duedate = $object->date_lim_reglement; + if ($type == 'bank-transfer') { + $duedate = $object->date_echeance; + } + if ($action == 'editpaymentterm') { - $form->form_date($_SERVER['PHP_SELF'].'?id='.$object->id, $object->date_lim_reglement, 'paymentterm'); + $form->form_date($_SERVER['PHP_SELF'].'?id='.$object->id, $duedate, 'paymentterm'); } else { - print dol_print_date($object->date_lim_reglement, 'daytext'); + print dol_print_date($duedate, 'day'); if ($object->hasDelay()) { print img_warning($langs->trans('Late')); } @@ -406,13 +487,21 @@ if ($object->id > 0) print ""; print ''; - print ''.$langs->trans("RIB").''; + $title = 'CustomerIBAN'; + if ($type == 'bank-transfer') { + $title = 'SupplierIBAN'; + } + print ''.$langs->trans($title).''; $bac = new CompanyBankAccount($db); $bac->fetch(0, $object->thirdparty->id); print $bac->iban.(($bac->iban && $bac->bic) ? ' / ' : '').$bac->bic; - if ($bac->verif() <= 0) print img_warning('Error on default bank number for IBAN : '.$bac->error_message); + if (!empty($bac->iban)) { + if ($bac->verif() <= 0) print img_warning('Error on default bank number for IBAN : '.$bac->error_message); + } else { + print img_warning($langs->trans("NoDefaultIBANFound")); + } print ''; @@ -559,8 +648,13 @@ if ($object->id > 0) print "\n
\n"; + $buttonlabel = $langs->trans("MakeWithdrawRequest"); + if ($type == 'bank-transfer') { + $buttonlabel = $langs->trans("MakeBankTransferOrder"); + } + // Add a transfer request - if ($object->statut > Facture::STATUS_DRAFT && $object->paye == 0 && $num == 0) + if ($object->statut > $object::STATUS_DRAFT && $object->paye == 0 && $num == 0) { if ($resteapayer > 0) { @@ -571,37 +665,41 @@ if ($object->id > 0) print '
'; print ''; print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print '
'; } else { - print ''.$langs->trans("MakeWithdrawRequest").''; + print ''.$buttonlabel.''; } } else { - print ''.$langs->trans("MakeWithdrawRequest").''; + print ''.$buttonlabel.''; } } else { if ($num == 0) { - if ($object->statut > Facture::STATUS_DRAFT) print ''.$langs->trans("MakeWithdrawRequest").''; - else print ''.$langs->trans("MakeWithdrawRequest").''; + if ($object->statut > $object::STATUS_DRAFT) print ''.$buttonlabel.''; + else print ''.$buttonlabel.''; } - else print ''.$langs->trans("MakeWithdrawRequest").''; + else print ''.$buttonlabel.''; } print "

\n"; - print '
'.$langs->trans("DoStandingOrdersBeforePayments").'

'; - + if ($type == 'bank-transfer') { + print '
'.$langs->trans("DoCreditTransferBeforePayments").'

'; + } else { + print '
'.$langs->trans("DoStandingOrdersBeforePayments").'

'; + } /* * Withdrawals @@ -614,7 +712,11 @@ if ($object->id > 0) print ''.$langs->trans("DateRequest").''; print ''.$langs->trans("User").''; print ''.$langs->trans("Amount").''; - print ''.$langs->trans("WithdrawalReceipt").''; + if ($type == 'bank-transfer') { + print ''.$langs->trans("BankTransferReceipt").''; + } else { + print ''.$langs->trans("WithdrawalReceipt").''; + } print ' '; print ''.$langs->trans("DateProcess").''; print ' '; @@ -622,7 +724,7 @@ if ($object->id > 0) $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande,"; $sql .= " pfd.date_traite as date_traite, pfd.amount,"; - $sql .= " u.rowid as user_id, u.lastname, u.firstname, u.login"; + $sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_bons as pb ON pb.rowid = pfd.fk_prelevement_bons"; @@ -642,14 +744,29 @@ if ($object->id > 0) { $i = 0; + $tmpuser = new User($db); + $num = $db->num_rows($result); while ($i < $num) { $obj = $db->fetch_object($result_sql); + $tmpuser->id = $obj->user_id; + $tmpuser->login = $obj->login; + $tmpuser->ref = $obj->login; + $tmpuser->email = $obj->email; + $tmpuser->lastname = $obj->lastname; + $tmpuser->firstname = $obj->firstname; + $tmpuser->statut = $obj->user_status; + print ''; - print ''.dol_print_date($db->jdate($obj->date_demande), 'day')."\n"; - print ''.img_object($langs->trans("ShowUser"), 'user').' '.$obj->login.''; + + print ''.dol_print_date($db->jdate($obj->date_demande), 'dayhour')."\n"; + + print ''; + print $tmpuser->getNomUrl(1, '', 0, 0, 0, 0, 'login'); + print ''; + print ''.price($obj->amount).''; print '-'; print ' '; @@ -657,7 +774,7 @@ if ($object->id > 0) print ''.$langs->trans("OrderWaiting").''; print ''; - print ''; + print ''; print img_delete(); print ''; @@ -677,7 +794,7 @@ if ($object->id > 0) $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande, pfd.date_traite, pfd.fk_prelevement_bons, pfd.amount,"; $sql .= " pb.ref,"; - $sql .= " u.rowid as user_id, u.lastname, u.firstname, u.login"; + $sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_bons as pb ON pb.rowid = pfd.fk_prelevement_bons"; @@ -697,15 +814,27 @@ if ($object->id > 0) $numclosed = $num; $i = 0; + $tmpuser = new User($db); + while ($i < $num) { $obj = $db->fetch_object($result); + $tmpuser->id = $obj->user_id; + $tmpuser->login = $obj->login; + $tmpuser->ref = $obj->login; + $tmpuser->email = $obj->email; + $tmpuser->lastname = $obj->lastname; + $tmpuser->firstname = $obj->firstname; + $tmpuser->statut = $obj->user_status; + print ''; print ''.dol_print_date($db->jdate($obj->date_demande), 'day')."\n"; - print ''.img_object($langs->trans("ShowUser"), 'user').' '.$obj->login.''; + print ''; + print $tmpuser->getNomUrl(1, '', 0, 0, 0, 0, 'login'); + print ''; print ''.price($obj->amount).''; diff --git a/htdocs/compta/paymentbybanktransfer/index.php b/htdocs/compta/paymentbybanktransfer/index.php index 6172b3f1284..1fc6c53cf99 100644 --- a/htdocs/compta/paymentbybanktransfer/index.php +++ b/htdocs/compta/paymentbybanktransfer/index.php @@ -94,11 +94,11 @@ print '

'; */ $sql = "SELECT f.ref, f.rowid, f.total_ttc, f.fk_statut, f.paye, f.type,"; $sql .= " pfd.date_demande, pfd.amount,"; -$sql .= " s.nom as name, s.rowid as socid"; -$sql .= " FROM ".MAIN_DB_PREFIX."facture as f,"; +$sql .= " s.nom as name, s.email, s.rowid as socid"; +$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; -$sql .= " , ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd"; +$sql .= ", ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd"; $sql .= " WHERE s.rowid = f.fk_soc"; $sql .= " AND f.entity IN (".getEntity('supplier_invoice').")"; $sql .= " AND f.total_ttc > 0"; @@ -106,7 +106,9 @@ if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS)) { $sql .= " AND f.fk_statut = ".FactureFournisseur::STATUS_VALIDATED; } -$sql .= " AND pfd.traite = 0 AND pfd.fk_facture_fourn = f.rowid"; +$sql .= " AND pfd.traite = 0"; +$sql .= " AND pfd.ext_payment_id IS NULL"; +$sql .= " AND pfd.fk_facture_fourn = f.rowid"; if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; if ($socid) $sql .= " AND f.fk_soc = ".$socid; @@ -133,14 +135,15 @@ if ($resql) $invoicestatic->type = $obj->type; $alreadypayed = $invoicestatic->getSommePaiement(); + $thirdpartystatic->id = $obj->socid; + $thirdpartystatic->name = $obj->name; + $thirdpartystatic->email = $obj->email; print ''; print $invoicestatic->getNomUrl(1, 'withdraw'); print ''; print ''; - $thirdpartystatic->id = $obj->socid; - $thirdpartystatic->name = $obj->name; print $thirdpartystatic->getNomUrl(1, 'customer'); print ''; @@ -194,7 +197,8 @@ if ($result) print"\n\n"; print '
'; print ''; - print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -221,7 +225,7 @@ if ($result) $i++; } } else { - print ''; + print ''; } print "
'.$langs->trans("LatestBankTransferReceipts", $limit).'
'.$langs->trans("LatestBankTransferReceipts", $limit).''.$langs->trans("Date").''.$langs->trans("Amount").''.$langs->trans("Status").'
'.$langs->trans("None").'
'.$langs->trans("None").'

"; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 1a13eb2edb9..5db9ccde671 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -28,6 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; @@ -118,7 +119,7 @@ class BonPrelevement extends CommonObject /** * Add invoice to withdrawal * - * @param int $facture_id id invoice to add + * @param int $invoice_id id invoice to add * @param int $client_id id invoice customer * @param string $client_nom customer name * @param int $amount amount of invoice @@ -126,14 +127,16 @@ class BonPrelevement extends CommonObject * @param string $code_guichet code of bank's office * @param string $number bank account number * @param string $number_key number key of account number + * @param string $type 'debit-order' or 'bank-transfer' * @return int >0 if OK, <0 if KO */ - public function AddFacture($facture_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key) + public function AddFacture($invoice_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $type = 'debit-order') { // phpcs:enable $result = 0; $line_id = 0; + // Add lines $result = $this->addline($line_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key); if ($result == 0) @@ -141,10 +144,14 @@ class BonPrelevement extends CommonObject if ($line_id > 0) { $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_facture ("; - $sql .= "fk_facture"; + if ($type != 'bank-transfer') { + $sql .= "fk_facture"; + } else { + $sql .= "fk_facture_fourn"; + } $sql .= ",fk_prelevement_lignes"; $sql .= ") VALUES ("; - $sql .= $facture_id; + $sql .= $invoice_id; $sql .= ", ".$line_id; $sql .= ")"; @@ -155,19 +162,19 @@ class BonPrelevement extends CommonObject else { $result = -1; - dol_syslog(get_class($this)."::AddFacture Erreur $result"); + dol_syslog(get_class($this)."::AddFacture Error $result"); } } else { $result = -2; - dol_syslog(get_class($this)."::AddFacture Erreur $result"); + dol_syslog(get_class($this)."::AddFacture Error $result"); } } else { $result = -3; - dol_syslog(get_class($this)."::AddFacture Erreur $result"); + dol_syslog(get_class($this)."::AddFacture Error $result"); } return $result; @@ -686,7 +693,7 @@ class BonPrelevement extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Returns amount of withdrawal + * Returns amount waiting for direct debit payment or credit transfer payment * * @param string $mode 'direct-debit' or 'bank-transfer' * @return double global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS)) + { + $sql .= " AND f.fk_statut = ".Facture::STATUS_VALIDATED; + } + if ($mode != 'bank-transfer') { + $sql .= " AND f.rowid = pfd.fk_facture"; + } else { + $sql .= " AND f.rowid = pfd.fk_facture_fourn"; + } $sql .= " AND f.paye = 0"; $sql .= " AND pfd.traite = 0"; + $sql .= " AND pfd.ext_payment_id IS NULL"; $sql .= " AND f.total_ttc > 0"; $resql = $this->db->query($sql); @@ -742,18 +757,18 @@ class BonPrelevement extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Get number of invoices to withdrawal + * Get number of invoices to pay * - * @param string $mode 'direct-debit' or 'bank-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return int global->PRELEVEMENT_CODE_BANQUE."'"; //if ($agence) $sql.= " AND sr.code_guichet = '".$conf->global->PRELEVEMENT_CODE_GUICHET."'"; @@ -867,6 +893,12 @@ class BonPrelevement extends CommonObject { $row = $this->db->fetch_row($resql); $factures[$i] = $row; // All fields + if ($row[7] == 0) { + $error++; + dol_syslog(__METHOD__."::Read invoices error Found a null invoice", LOG_ERR); + $this->invoice_in_error[$row[0]] = "Error for invoice id ".$row[0].", found a null amount"; + break; + } $i++; } $this->db->free($resql); @@ -884,15 +916,19 @@ class BonPrelevement extends CommonObject require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; $soc = new Societe($this->db); - // Check RIB + // Check BAN $i = 0; - dol_syslog(__METHOD__."::Check RIB", LOG_DEBUG); + dol_syslog(__METHOD__."::Check BAN", LOG_DEBUG); if (count($factures) > 0) { foreach ($factures as $key => $fac) { - $fact = new Facture($this->db); + if ($type != 'bank-transfer') { + $fact = new Facture($this->db); + } else { + $fact = new FactureFournisseur($this->db); + } $resfetch = $fact->fetch($fac[0]); if ($resfetch >= 0) // Field 0 of $fac is rowid of invoice { @@ -901,13 +937,15 @@ class BonPrelevement extends CommonObject $bac = new CompanyBankAccount($this->db); $bac->fetch(0, $soc->id); - if ($format == 'FRST' && $bac->frstrecur != 'FRST') - { - continue; - } - if ($format == 'RCUR' && ($bac->frstrecur != 'RCUR' && $bac->frstrecur != 'RECUR')) - { - continue; + if ($type != 'bank-transfer') { + if ($format == 'FRST' && $bac->frstrecur != 'FRST') + { + continue; + } + if ($format == 'RCUR' && ($bac->frstrecur != 'RCUR' && $bac->frstrecur != 'RECUR')) + { + continue; + } } if ($bac->verif() >= 1) @@ -920,32 +958,32 @@ class BonPrelevement extends CommonObject } else { - dol_syslog(__METHOD__."::Check RIB Error on default bank number IBAN/BIC for thirdparty reported by verif() ".$fact->socid." ".$soc->name, LOG_WARNING); + dol_syslog(__METHOD__."::Check BAN Error on default bank number IBAN/BIC for thirdparty reported by verif() ".$fact->socid." ".$soc->name, LOG_WARNING); $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for invoice ".$fact->getNomUrl(0)." for thirdparty ".$soc->getNomUrl(0); $this->thirdparty_in_error[$soc->id] = "Error on default bank number IBAN/BIC for invoice ".$fact->getNomUrl(0)." for thirdparty ".$soc->getNomUrl(0); } } else { - dol_syslog(__METHOD__."::Check RIB Failed to read company", LOG_WARNING); + dol_syslog(__METHOD__."::Check BAN Failed to read company", LOG_WARNING); } } else { - dol_syslog(__METHOD__."::Check RIB Failed to read invoice", LOG_WARNING); + dol_syslog(__METHOD__."::Check BAN Failed to read invoice", LOG_WARNING); } } } else { - dol_syslog(__METHOD__."::Check RIB No invoice to process", LOG_WARNING); + dol_syslog(__METHOD__."::Check BAN No invoice to process", LOG_WARNING); } } $ok = 0; // Withdraw invoices in factures_prev array - $out = count($factures_prev)." invoices will be withdrawn."; + $out = count($factures_prev)." invoices will be included."; //print $out."\n"; dol_syslog($out); @@ -975,14 +1013,14 @@ class BonPrelevement extends CommonObject { /* * We are in real mode. - * We create withdraw receipt and build withdraw into disk + * We create order and build file into disk */ $this->db->begin(); $now = dol_now(); /* - * Traitements + * Process order generation */ if (!$error) { @@ -994,7 +1032,7 @@ class BonPrelevement extends CommonObject $sql .= " AND entity = ".$conf->entity; $sql .= " ORDER BY ref DESC LIMIT 1"; - dol_syslog(get_class($this)."::Create sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) @@ -1002,18 +1040,23 @@ class BonPrelevement extends CommonObject $row = $this->db->fetch_row($resql); $ref = "T".$ref.str_pad(dol_substr("00".intval($row[0]) + 1, 0, 2), 2, "0", STR_PAD_LEFT); - $dir = $conf->prelevement->dir_output.'/receipts'; + if ($type != 'bank-transfer') { + $dir = $conf->prelevement->dir_output.'/receipts'; + } else { + $dir = $conf->paymentbybanktransfer->dir_output.'/receipts'; + } if (!is_dir($dir)) dol_mkdir($dir); $this->filename = $dir.'/'.$ref.'.xml'; // Create withdraw receipt in database $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons ("; - $sql .= " ref, entity, datec"; + $sql .= " ref, entity, datec, type"; $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($ref)."'"; $sql .= ", ".$conf->entity; $sql .= ", '".$this->db->idate($now)."'"; + $sql .= ", '".($type == 'bank-transfer' ? 'bank-transfer' : 'debit-order')."'"; $sql .= ")"; $resql = $this->db->query($sql); @@ -1051,7 +1094,9 @@ class BonPrelevement extends CommonObject /* * Add standing order * - * + * $fac[0] : invoice_id + * $fac[1] : ??? + * $fac[2] : third party id * $fac[3] : banque * $fac[4] : guichet * $fac[5] : number @@ -1060,7 +1105,8 @@ class BonPrelevement extends CommonObject * $fac[8] : client nom * $fac[2] : client id */ - $ri = $this->AddFacture($fac[0], $fac[2], $fac[8], $fac[7], $fac[3], $fac[4], $fac[5], $fac[6]); + + $ri = $this->AddFacture($fac[0], $fac[2], $fac[8], $fac[7], $fac[3], $fac[4], $fac[5], $fac[6], $type); if ($ri <> 0) { $error++; @@ -1073,13 +1119,12 @@ class BonPrelevement extends CommonObject $sql .= ", fk_prelevement_bons = ".$this->id; $sql .= " WHERE rowid = ".$fac[1]; - dol_syslog(__METHOD__."::Update Orders::Sql=".$sql, LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $error++; - dol_syslog(__METHOD__."::Update Orders::Error=".$this->db->error(), LOG_ERR); + dol_syslog(__METHOD__."::Update Error=".$this->db->error(), LOG_ERR); } } } @@ -1088,11 +1133,10 @@ class BonPrelevement extends CommonObject if (!$error) { /* - * Create direct debit order in a XML file + * Create file of direct debit order or credit transfer into a XML file */ - dol_syslog(__METHOD__."::Init withdraw receipt for ".count($factures_prev)." invoices", LOG_DEBUG); - + dol_syslog(__METHOD__."::Init direct debit file for ".count($factures_prev)." invoices", LOG_DEBUG); if (count($factures_prev) > 0) { @@ -1119,7 +1163,7 @@ class BonPrelevement extends CommonObject $this->context['factures_prev'] = $factures_prev; // Generation of SEPA file $this->filename - $this->generate($format, $executiondate); + $result = $this->generate($format, $executiondate); } dol_syslog(__METHOD__."::End withdraw receipt, file ".$this->filename, LOG_DEBUG); } @@ -1142,8 +1186,13 @@ class BonPrelevement extends CommonObject if (!$error && !$notrigger) { + $triggername = 'DIRECT_DEBIT_ORDER_CREATE'; + if ($type != 'bank-transfer') { + $triggername = 'CREDIT_TRANSFER_ORDER_CREATE'; + } + // Call trigger - $result = $this->call_trigger('DIRECT_DEBIT_ORDER_CREATE', $user); + $result = $this->call_trigger($triggername, $user); if ($result < 0) $error++; // End call triggers } @@ -1412,9 +1461,9 @@ class BonPrelevement extends CommonObject * - Others countries: Warning message * File is generated with name this->filename * - * @param string $format FRST, RCUR or ALL - * @param string $executiondate Date to execute transfer - * @return int 0 if OK, <0 if KO + * @param string $format FRST, RCUR or ALL + * @param string $executiondate Date to execute transfer + * @return int >=0 if OK, <0 if KO */ public function generate($format = 'ALL', $executiondate = '') { @@ -1461,7 +1510,7 @@ class BonPrelevement extends CommonObject $this->total = 0; /* - * section Debiteur (sepa Debiteurs bloc lines) + * Section Debitor (sepa Debiteurs bloc lines) */ $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; @@ -1586,13 +1635,15 @@ class BonPrelevement extends CommonObject $langs->load('withdrawals'); // TODO Add here code to generate a generic file - fputs($this->file, $langs->trans('WithdrawalFileNotCapable', $mysoc->country_code)); + fputs($this->file, $langs->transnoentitiesnoconv('WithdrawalFileNotCapable', $mysoc->country_code)); } fclose($this->file); - if (!empty($conf->global->MAIN_UMASK)) + if (!empty($conf->global->MAIN_UMASK)) { @chmod($this->file, octdec($conf->global->MAIN_UMASK)); - return $result; + } + + return $result; } diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 01a5ae5e942..80055b20d72 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -1,11 +1,11 @@ - * Copyright (C) 2010-2015 Laurent Destailleur + * Copyright (C) 2010-2020 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2010-2012 Juanjo Menent * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2018 Frédéric France - * Copyright (C) 2019 Markus Welters + * Copyright (C) 2019 Markus Welters * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ /** * \file htdocs/compta/prelevement/create.php * \ingroup prelevement - * \brief Prelevement creation page + * \brief Page to create a direct debit order or a credit transfer order */ require '../../main.inc.php'; @@ -77,11 +77,17 @@ if (empty($reshook)) } if ($action == 'create') { - // $conf->global->PRELEVEMENT_CODE_BANQUE and $conf->global->PRELEVEMENT_CODE_GUICHET should be empty + $delayindays = 0; + if ($type != 'bank-transfer') { + $conf->global->PRELEVEMENT_ADDDAYS; + } else { + $conf->global->PAYMENTBYBANKTRANSFER_ADDDAYS; + } $bprev = new BonPrelevement($db); - $executiondate = dol_mktime(0, 0, 0, GETPOST('remonth'), (GETPOST('reday') + $conf->global->PRELEVEMENT_ADDDAYS), GETPOST('reyear')); + $executiondate = dol_mktime(0, 0, 0, GETPOST('remonth', 'int'), (GETPOST('reday', 'int') + $delayindays), GETPOST('reyear', 'int')); - $result = $bprev->create($conf->global->PRELEVEMENT_CODE_BANQUE, $conf->global->PRELEVEMENT_CODE_GUICHET, $mode, $format, $executiondate); + // $conf->global->PRELEVEMENT_CODE_BANQUE and $conf->global->PRELEVEMENT_CODE_GUICHET should be empty (we don't use them anymore) + $result = $bprev->create($conf->global->PRELEVEMENT_CODE_BANQUE, $conf->global->PRELEVEMENT_CODE_GUICHET, $mode, $format, $executiondate, 0, $type); if ($result < 0) { setEventMessages($bprev->error, $bprev->errors, 'errors'); @@ -114,7 +120,11 @@ if (empty($reshook)) $form = new Form($db); $thirdpartystatic = new Societe($db); -$invoicestatic = new Facture($db); +if ($type != 'bank-transfer') { + $invoicestatic = new Facture($db); +} else { + $invoicestatic = new FactureFournisseur($db); +} $bprev = new BonPrelevement($db); llxHeader('', $langs->trans("NewStandingOrder")); @@ -177,6 +187,7 @@ print '
'."\n"; print '
'; print ''; +print ''; if ($nb) { if ($pricetowithdraw) { print $langs->trans('ExecutionDate').' '; @@ -184,8 +195,13 @@ if ($nb) { if ($mysoc->isInEEC()) { $title = $langs->trans("CreateForSepa"); + if ($type == 'bank-transfer') { + $title = $langs->trans("CreateSepaFileForPaymentByBankTransfer"); + } - print ''; + if ($type != 'bank-transfer') { + print ''; + } print ''; } else { $title = $langs->trans("CreateAll"); @@ -257,8 +273,10 @@ if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS)) { $sql .= " AND f.fk_statut = ".Facture::STATUS_VALIDATED; } -$sql .= " AND f.total_ttc > 0"; +//$sql .= " AND pfd.amount > 0"; +$sql .= " AND f.total_ttc > 0"; // Avoid credit notes $sql .= " AND pfd.traite = 0"; +$sql .= " AND pfd.ext_payment_id IS NULL"; if ($type == 'bank-transfer') { $sql .= " AND pfd.fk_facture_fourn = f.rowid"; } else { @@ -304,9 +322,14 @@ if ($resql) } print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, '', '', '', $num, $nbtotalofrecords, 'bill', 0, '', '', $limit); + $tradinvoice = "Invoice"; + if ($type == 'bank-transfer') { + $tradinvoice = "SupplierInvoice"; + } + print ''; print ''; - print ''; + print ''; print ''; print ''; print ''; @@ -350,7 +373,9 @@ if ($resql) print ''; // Amount print '
'.$langs->trans("Invoice").''.$langs->trans($tradinvoice).''.$langs->trans("ThirdParty").''.$langs->trans("RIB").''.$langs->trans("RUM").''; print $thirdpartystatic->display_rib('rum'); $format = $thirdpartystatic->display_rib('format'); - if ($format) print ' ('.$format.')'; + if ($type != 'bank-transfer') { + if ($format) print ' ('.$format.')'; + } print ''; diff --git a/htdocs/compta/prelevement/index.php b/htdocs/compta/prelevement/index.php index eaec6d92f16..ef451146f55 100644 --- a/htdocs/compta/prelevement/index.php +++ b/htdocs/compta/prelevement/index.php @@ -22,7 +22,7 @@ /** * \file htdocs/compta/prelevement/index.php * \ingroup prelevement - * \brief Prelevement index page + * \brief Home page for direct debit orders */ @@ -94,7 +94,7 @@ print '

'; */ $sql = "SELECT f.ref, f.rowid, f.total_ttc, f.fk_statut, f.paye, f.type,"; $sql .= " pfd.date_demande, pfd.amount,"; -$sql .= " s.nom as name, s.rowid as socid"; +$sql .= " s.nom as name, s.email, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -106,7 +106,9 @@ if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS)) { $sql .= " AND f.fk_statut = ".Facture::STATUS_VALIDATED; } -$sql .= " AND pfd.traite = 0 AND pfd.fk_facture = f.rowid"; +$sql .= " AND pfd.traite = 0"; +$sql .= " AND pfd.ext_payment_id IS NULL"; +$sql .= " AND pfd.fk_facture = f.rowid"; if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; if ($socid) $sql .= " AND f.fk_soc = ".$socid; @@ -133,14 +135,15 @@ if ($resql) $invoicestatic->type = $obj->type; $alreadypayed = $invoicestatic->getSommePaiement(); + $thirdpartystatic->id = $obj->socid; + $thirdpartystatic->name = $obj->name; + $thirdpartystatic->email = $obj->email; print ''; print $invoicestatic->getNomUrl(1, 'withdraw'); print ''; print ''; - $thirdpartystatic->id = $obj->socid; - $thirdpartystatic->name = $obj->name; print $thirdpartystatic->getNomUrl(1, 'customer'); print ''; @@ -175,8 +178,9 @@ print '
'; /* - * Withdraw receipts + * Direct debit orders */ + $limit = 5; $sql = "SELECT p.rowid, p.ref, p.amount, p.datec, p.statut"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; @@ -193,7 +197,8 @@ if ($result) print"\n\n"; print '
'; print ''; - print ''; + print ''; + print ''; print ''; print ''; print ''; @@ -221,7 +226,7 @@ if ($result) $i++; } } else { - print ''; + print ''; } print "
'.$langs->trans("LastWithdrawalReceipt", $limit).'
'.$langs->trans("LastWithdrawalReceipt", $limit).''.$langs->trans("Date").''.$langs->trans("Amount").''.$langs->trans("Status").'
'.$langs->trans("None").'
'.$langs->trans("None").'

"; diff --git a/htdocs/compta/sociales/list.php b/htdocs/compta/sociales/list.php index 9d210c23d85..8ccd8aa35aa 100644 --- a/htdocs/compta/sociales/list.php +++ b/htdocs/compta/sociales/list.php @@ -152,6 +152,7 @@ if ($search_typeid) { $sql .= " AND cs.fk_type=".$db->escape($search_typeid); } $sql .= " GROUP BY cs.rowid, cs.fk_type, cs.amount, cs.date_ech, cs.libelle, cs.paye, cs.periode, c.libelle"; +if (!empty($conf->projet->enabled)) $sql .= ", p.rowid, p.ref, p.title"; $sql .= $db->order($sortfield, $sortorder); $totalnboflines = 0; diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 40e6849d494..77fbea3c36a 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1153,8 +1153,6 @@ if (!$error && $massaction == 'validate' && $permissiontoadd) $result = $objecttmp->fetch($toselectid); if ($result > 0) { - //if (in_array($objecttmp->element, array('societe','member'))) $result = $objecttmp->delete($objecttmp->id, $user, 1); - //else $result = $objecttmp->validate($user); if ($result == 0) { diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index 7167097672b..9d96d11f64d 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -90,7 +90,7 @@ class box_services_contracts extends ModeleBoxes $sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,"; $sql .= " c.rowid, c.ref, c.statut as contract_status, c.ref_customer, c.ref_supplier,"; - $sql .= " cd.rowid as cdid, cd.label, cd.description, cd.tms as datem, cd.statut, cd.product_type as type,"; + $sql .= " cd.rowid as cdid, cd.label, cd.description, cd.tms as datem, cd.statut, cd.product_type as type, cd.date_fin_validite as date_line,"; $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as plabel, p.fk_product_type as ptype, p.entity, p.tobuy, p.tosell"; $sql .= " FROM (".MAIN_DB_PREFIX."societe as s"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."contrat as c ON s.rowid = c.fk_soc"; @@ -113,6 +113,8 @@ class box_services_contracts extends ModeleBoxes while ($i < $num) { + $late = ''; + $objp = $this->db->fetch_object($result); $datem = $this->db->jdate($objp->datem); @@ -124,11 +126,11 @@ class box_services_contracts extends ModeleBoxes $contractlinestatic->product_id = $objp->product_id; $contractlinestatic->product_ref = $objp->product_ref; - $contractstatic->statut = $objp->contract_status; $contractstatic->id = $objp->rowid; $contractstatic->ref = $objp->ref; $contractstatic->ref_customer = $objp->ref_customer; $contractstatic->ref_supplier = $objp->ref_supplier; + $contractstatic->statut = $objp->contract_status; $thirdpartytmp->name = $objp->name; $thirdpartytmp->id = $objp->socid; @@ -140,6 +142,9 @@ class box_services_contracts extends ModeleBoxes $thirdpartytmp->code_compta = $objp->code_compta; $thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur; + $dateline = $this->db->jdate($objp->date_line); + if ($contractstatic->statut == Contrat::STATUS_VALIDATED && $objp->statut == ContratLigne::STATUS_OPEN && ($dateline + $conf->contrat->services->expires->warning_delay) < $now) $late = img_warning($langs->trans("Late")); + // Multilangs if (!empty($conf->global->MAIN_MULTILANGS) && $objp->product_id > 0) // if option multilang is on { @@ -214,6 +219,7 @@ class box_services_contracts extends ModeleBoxes $this->info_box_contents[$i][] = array( 'td' => '', 'text' => dol_print_date($datem, 'day'), + 'text2'=> $late, ); $this->info_box_contents[$i][] = array( diff --git a/htdocs/core/boxes/box_shipments.php b/htdocs/core/boxes/box_shipments.php index 8908f52640c..61942d03f45 100644 --- a/htdocs/core/boxes/box_shipments.php +++ b/htdocs/core/boxes/box_shipments.php @@ -103,10 +103,10 @@ class box_shipments extends ModeleBoxes $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON e.rowid = el.fk_target AND el.targettype = 'shipping' AND el.sourcetype IN ('commande')"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON el.fk_source = c.rowid AND el.sourcetype IN ('commande') AND el.targettype = 'shipping'"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = e.fk_soc"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON e.fk_soc = sc.fk_soc"; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON e.fk_soc = sc.fk_soc"; $sql .= " WHERE e.entity = ".$conf->entity; if (!empty($conf->global->ORDER_BOX_LAST_SHIPMENTS_VALIDATED_ONLY)) $sql .= " AND e.fk_statut = 1"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql .= " AND sc.fk_user = ".$user->id; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND sc.fk_user = ".$user->id; else $sql .= " ORDER BY e.date_delivery, e.ref DESC "; $sql .= $this->db->plimit($max, 0); diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index c37ece437d4..cb7ce67d923 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -687,6 +687,160 @@ abstract class CommonInvoice extends CommonObject return $datelim; } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Create a withdrawal request for a direct debit order or a credit transfer order. + * Use the remain to pay excluding all existing open direct debit requests. + * + * @param User $fuser User asking the direct debit transfer + * @param float $amount Amount we request direct debit for + * @param string $type 'direct-debit' or 'bank-transfer' + * @param string $sourcetype Source ('facture' or 'supplier_invoice') + * @return int <0 if KO, >0 if OK + */ + public function demande_prelevement($fuser, $amount = 0, $type = 'direct-debit', $sourcetype = 'facture') + { + // phpcs:enable + global $conf; + + $error = 0; + + dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); + + if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) + { + require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; + $bac = new CompanyBankAccount($this->db); + $bac->fetch(0, $this->socid); + + $sql = 'SELECT count(*)'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + if ($type == 'bank-transfer') { + $sql .= ' WHERE fk_facture_fourn = '.$this->id; + } else { + $sql .= ' WHERE fk_facture = '.$this->id; + } + $sql .= ' AND ext_payment_id IS NULL'; // To exclude record done for some online payments + $sql .= ' AND traite = 0'; + + dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $row = $this->db->fetch_row($resql); + if ($row[0] == 0) + { + $now = dol_now(); + + $totalpaye = $this->getSommePaiement(); + $totalcreditnotes = $this->getSumCreditNotesUsed(); + $totaldeposits = $this->getSumDepositsUsed(); + //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits; + + // We can also use bcadd to avoid pb with floating points + // For example print 239.2 - 229.3 - 9.9; does not return 0. + //$resteapayer=bcadd($this->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); + //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); + if (empty($amount)) $amount = price2num($this->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + + if (is_numeric($amount) && $amount != 0) + { + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande('; + if ($type == 'bank-transfer') { + $sql .= 'fk_facture_fourn, '; + } else { + $sql .= 'fk_facture, '; + } + $sql .= ' amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib, sourcetype, entity)'; + $sql .= ' VALUES ('.$this->id; + $sql .= ",'".price2num($amount)."'"; + $sql .= ",'".$this->db->idate($now)."'"; + $sql .= ",".$fuser->id; + $sql .= ",'".$this->db->escape($bac->code_banque)."'"; + $sql .= ",'".$this->db->escape($bac->code_guichet)."'"; + $sql .= ",'".$this->db->escape($bac->number)."'"; + $sql .= ",'".$this->db->escape($bac->cle_rib)."'"; + $sql .= ",'".$this->db->escape($sourcetype)."'"; + $sql .= ",".$conf->entity; + $sql .= ")"; + + dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) + { + $this->error = $this->db->lasterror(); + dol_syslog(get_class($this).'::demandeprelevement Erreur'); + $error++; + } + } + else + { + $this->error = 'WithdrawRequestErrorNilAmount'; + dol_syslog(get_class($this).'::demandeprelevement WithdrawRequestErrorNilAmount'); + $error++; + } + + if (!$error) + { + // Force payment mode of invoice to withdraw + $payment_mode_id = dol_getIdFromCode($this->db, 'PRE', 'c_paiement', 'code', 'id', 1); + if ($payment_mode_id > 0) + { + $result = $this->setPaymentMethods($payment_mode_id); + } + } + + if ($error) return -1; + return 1; + } + else + { + $this->error = "A request already exists"; + dol_syslog(get_class($this).'::demandeprelevement Impossible de creer une demande, demande deja en cours'); + return 0; + } + } + else + { + $this->error = $this->db->error(); + dol_syslog(get_class($this).'::demandeprelevement Erreur -2'); + return -2; + } + } + else + { + $this->error = "Status of invoice does not allow this"; + dol_syslog(get_class($this)."::demandeprelevement ".$this->error." $this->statut, $this->paye, $this->mode_reglement_id"); + return -3; + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Remove a direct debit request or a credit transfer request + * + * @param User $fuser User making delete + * @param int $did ID of request to delete + * @return int <0 if OK, >0 if KO + */ + public function demande_prelevement_delete($fuser, $did) + { + // phpcs:enable + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql .= ' WHERE rowid = '.$did; + $sql .= ' AND traite = 0'; + if ($this->db->query($sql)) + { + return 0; + } + else + { + $this->error = $this->db->lasterror(); + dol_syslog(get_class($this).'::demande_prelevement_delete Error '.$this->error); + return -1; + } + } } diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 551fe2b82c0..4df5c6add45 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -1144,7 +1144,7 @@ class DolGraph foreach ($legends as $val) // Loop on each serie { if ($i > 0) $this->stringtoshow .= ', '; - $this->stringtoshow .= "'".$val."'"; + $this->stringtoshow .= "'".dol_escape_js(dol_trunc($val, 32))."'"; $i++; } @@ -1207,7 +1207,7 @@ class DolGraph foreach ($legends as $val) // Loop on each serie { if ($i > 0) $this->stringtoshow .= ', '; - $this->stringtoshow .= "'".$val."'"; + $this->stringtoshow .= "'".dol_escape_js(dol_trunc($val, 32))."'"; $i++; } diff --git a/htdocs/core/class/evalmath.class.php b/htdocs/core/class/evalmath.class.php index b0fcc963eba..7e02aa57032 100644 --- a/htdocs/core/class/evalmath.class.php +++ b/htdocs/core/class/evalmath.class.php @@ -194,7 +194,7 @@ class EvalMath * * @return string Output */ - private function vars() + public function vars() { $output = $this->v; unset($output['pi']); @@ -270,10 +270,11 @@ class EvalMath // =============== } elseif ($op == ')' and $expecting_op) { // ready to close a parenthesis? while (($o2 = $stack->pop()) != '(') { // pop off the stack back to the last ( - if (is_null($o2)) + if (is_null($o2)) { return $this->trigger(5, "unexpected ')'", ")"); - else + } else { $output[] = $o2; + } } if (preg_match("/^([a-z]\w*)\($/", $stack->last(2), $matches)) { // did we just close a function? $fnn = $matches[1]; // get the function name @@ -293,10 +294,11 @@ class EvalMath // =============== } elseif ($op == ',' and $expecting_op) { // did we just finish a function argument? while (($o2 = $stack->pop()) != '(') { - if (is_null($o2)) + if (is_null($o2)) { return $this->trigger(5, "unexpected ','", ","); // oops, never had a ( - else + } else { $output[] = $o2; // pop the argument expression stuff and push onto the output + } } // make sure there was a function if (!preg_match("/^([a-z]\w*)\($/", $stack->last(2), $matches)) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index e1a834a42ca..caf43f94342 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -2091,6 +2091,10 @@ class ExtraFields $value_arr = GETPOST("options_".$key, 'alpha'); $value_key = price2num($value_arr); } + elseif (in_array($key_type, array('html'))) + { + $value_key = GETPOST("options_".$key, 'alpha'); + } else { $value_key = GETPOST("options_".$key); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index c38e69eaa50..9c4e2526249 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4264,7 +4264,7 @@ class Form elseif ($input['type'] == 'select') { $more .= '
'; - if (!empty($input['label'])) $more .= $input['label'].'
'; + if (!empty($input['label'])) $more .= $input['label'].'
'; $more .= $this->selectarray($input['name'], $input['values'], $input['default'], 1, 0, 0, $moreattr, 0, 0, 0, '', $morecss); $more .= '
'."\n"; } @@ -5482,7 +5482,7 @@ class Form * @param int $d 1=Show days, month, years * @param int $addnowlink Add a link "Now", 1 with server time, 2 with local computer time * @param int $disabled Disable input fields - * @param int $fullday When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59 + * @param int $fullday When a checkbox with id #fullday is cheked, hours are set with 00:00 (if value if 'fulldaystart') or 23:59 (if value is 'fulldayend') * @param string $addplusone Add a link "+1 hour". Value must be name of another selectDate field. * @param datetime $adddateof Add a link "Date of ..." using the following date. See also $labeladddateof for the label used. * @param string $openinghours Specify hour start and hour end for the select ex 8,20 @@ -5784,10 +5784,17 @@ class Form } elseif ($addnowlink == 2) { + /* Disabled because the output does not use the string format defined by FormatDateShort key to forge the value into #prefix. + * This break application for foreign languages. $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(d.toLocaleDateString(\''.str_replace('_', '-', $langs->defaultlang).'\'));'; $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(d.getDate().pad());'; $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(parseInt(d.getMonth().pad()) + 1);'; $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(d.getFullYear());'; + */ + $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date(dol_now(), 'day', 'tzuser').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date(dol_now(), '%d', 'tzuser').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date(dol_now(), '%m', 'tzuser').'\');'; + $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date(dol_now(), '%Y', 'tzuser').'\');'; } /*if ($usecalendar == "eldy") { diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php index a6d774090aa..953064e6b4c 100644 --- a/htdocs/core/class/menubase.class.php +++ b/htdocs/core/class/menubase.class.php @@ -656,7 +656,7 @@ class Menubase // Define $right $perms = true; - if ($menu['perms']) + if (isset($menu['perms'])) { $tmpcond = $menu['perms']; if ($leftmenu == 'all') $tmpcond = preg_replace('/\$leftmenu\s*==\s*["\'a-zA-Z_]+/', '1==1', $tmpcond); // Force part of condition to true @@ -666,7 +666,7 @@ class Menubase // Define $enabled $enabled = true; - if ($menu['enabled']) + if (isset($menu['enabled'])) { $tmpcond = $menu['enabled']; if ($leftmenu == 'all') $tmpcond = preg_replace('/\$leftmenu\s*==\s*["\'a-zA-Z_]+/', '1==1', $tmpcond); // Force part of condition to true diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index 51e375c5279..09a1f7f2949 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -428,7 +428,7 @@ class SMTPs $host = preg_replace('@ssl://@i', '', $host); // Remove prefix $host = preg_replace('@tls://@i', '', $host); // Remove prefix - if ($usetls) $host = 'tls://'.$host; + if ($usetls && ! empty($conf->global->MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO)) $host = 'tls://'.$host; $hosth = $host; @@ -565,6 +565,8 @@ class SMTPs $host = preg_replace('@ssl://@i', '', $host); // Remove prefix $host = preg_replace('@tls://@i', '', $host); // Remove prefix + if ($usetls && ! empty($conf->global->MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO)) $host = 'tls://'.$host; + $hosth = $host; if (!empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 7c0d680662d..9c023a05478 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -806,7 +806,7 @@ class DoliDBMysqli extends DoliDB $sql .= $field_desc['type']; if (preg_match("/^[^\s]/i", $field_desc['value'])) { - if (!in_array($field_desc['type'], array('date', 'datetime'))) + if (!in_array($field_desc['type'], array('date', 'datetime')) && $field_desc['value']) { $sql .= "(".$field_desc['value'].")"; } @@ -853,7 +853,7 @@ class DoliDBMysqli extends DoliDB // phpcs:enable $sql = "ALTER TABLE ".$table; $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type']; - if ($field_desc['type'] == 'double' || $field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') { + if (in_array($field_desc['type'], array('double', 'tinyint', 'int', 'varchar')) && $field_desc['value']) { $sql .= "(".$field_desc['value'].")"; } if ($field_desc['null'] == 'not null' || $field_desc['null'] == 'NOT NULL') diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index bf9b468d4a8..6b71366c46c 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -1126,11 +1126,12 @@ class DoliDBPgsql extends DoliDB // ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment'); $sql = "ALTER TABLE ".$table." ADD ".$field_name." "; $sql .= $field_desc['type']; - if (preg_match("/^[^\s]/i", $field_desc['value'])) - if (!in_array($field_desc['type'], array('int', 'date', 'datetime'))) - { - $sql .= "(".$field_desc['value'].")"; - } + if (preg_match("/^[^\s]/i", $field_desc['value'])) { + if (!in_array($field_desc['type'], array('int', 'date', 'datetime')) && $field_desc['value']) + { + $sql .= "(".$field_desc['value'].")"; + } + } if (preg_match("/^[^\s]/i", $field_desc['attribute'])) $sql .= " ".$field_desc['attribute']; if (preg_match("/^[^\s]/i", $field_desc['null'])) @@ -1167,7 +1168,7 @@ class DoliDBPgsql extends DoliDB // phpcs:enable $sql = "ALTER TABLE ".$table; $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type']; - if ($field_desc['type'] == 'double' || $field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') { + if (in_array($field_desc['type'], array('double', 'tinyint', 'int', 'varchar')) && $field_desc['value']) { $sql .= "(".$field_desc['value'].")"; } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 8328a330b7d..e102e0e155d 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1465,7 +1465,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = '', $noprin $sql2 .= " WHERE mc.email = '".$db->escape($objcon->email)."'"; // Search is done on email. $sql2 .= " AND mc.statut = 1"; $sql2 .= " AND u.rowid = m.fk_user_valid"; - $sql2 .= " AND mc.fk_mailing=m.rowid"; + $sql2 .= " AND mc.fk_mailing = m.rowid"; } if (!empty($sql) && !empty($sql2)) { diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php index 3b41f2620b4..201d74a9ff9 100644 --- a/htdocs/core/lib/fourn.lib.php +++ b/htdocs/core/lib/fourn.lib.php @@ -53,6 +53,28 @@ function facturefourn_prepare_head($object) $h++; } + //if ($fac->mode_reglement_code == 'PRE') + if (!empty($conf->paymentbybanktransfer->enabled)) + { + $nbStandingOrders = 0; + $sql = "SELECT COUNT(pfd.rowid) as nb"; + $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd"; + $sql .= " WHERE pfd.fk_facture_fourn = ".$object->id; + $sql .= " AND pfd.ext_payment_id IS NULL"; + $resql = $db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + if ($obj) $nbStandingOrders = $obj->nb; + } + else dol_print_error($db); + $head[$h][0] = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$object->id.'&type=bank-transfer'; + $head[$h][1] = $langs->trans('BankTransfer'); + if ($nbStandingOrders > 0) $head[$h][1] .= ''.$nbStandingOrders.''; + $head[$h][2] = 'standingorders'; + $h++; + } + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab @@ -211,8 +233,6 @@ function supplierorder_admin_prepare_head() $head[$h][2] = 'supplierorderdet'; $h++; - - $head[$h][0] = DOL_URL_ROOT.'/admin/supplierinvoice_extrafields.php'; $head[$h][1] = $langs->trans("ExtraFieldsSupplierInvoices"); $head[$h][2] = 'supplierinvoice'; diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index f081fc94120..077176c6ff9 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -55,7 +55,6 @@ function facture_prepare_head($object) $h++; } - //if ($fac->mode_reglement_code == 'PRE') if (!empty($conf->prelevement->enabled)) { $nbStandingOrders = 0; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index a4f1a30bd4d..72713393025 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -223,58 +223,39 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f // Check read permission from module $readok = 1; $nbko = 0; - foreach ($featuresarray as $feature) // first we check nb of test ko - { + foreach ($featuresarray as $feature) { // first we check nb of test ko $featureforlistofmodule = $feature; if ($featureforlistofmodule == 'produit') $featureforlistofmodule = 'product'; - if (!empty($user->socid) && !empty($conf->global->MAIN_MODULES_FOR_EXTERNAL) && !in_array($featureforlistofmodule, $listofmodules)) // If limits on modules for external users, module must be into list of modules for external users - { + if (!empty($user->socid) && !empty($conf->global->MAIN_MODULES_FOR_EXTERNAL) && !in_array($featureforlistofmodule, $listofmodules)) { // If limits on modules for external users, module must be into list of modules for external users $readok = 0; $nbko++; continue; } - if ($feature == 'societe') - { + if ($feature == 'societe') { if (!$user->rights->societe->lire && !$user->rights->fournisseur->lire) { $readok = 0; $nbko++; } - } - elseif ($feature == 'contact') - { + } elseif ($feature == 'contact') { if (!$user->rights->societe->contact->lire) { $readok = 0; $nbko++; } - } - elseif ($feature == 'produit|service') - { + } elseif ($feature == 'produit|service') { if (!$user->rights->produit->lire && !$user->rights->service->lire) { $readok = 0; $nbko++; } - } - elseif ($feature == 'prelevement') - { + } elseif ($feature == 'prelevement') { if (!$user->rights->prelevement->bons->lire) { $readok = 0; $nbko++; } - } - elseif ($feature == 'cheque') - { + } elseif ($feature == 'cheque') { if (!$user->rights->banque->cheque) { $readok = 0; $nbko++; } - } - elseif ($feature == 'projet') - { + } elseif ($feature == 'projet') { if (!$user->rights->projet->lire && !$user->rights->projet->all->lire) { $readok = 0; $nbko++; } - } - elseif (!empty($feature2)) // This is for permissions on 2 levels - { + } elseif (!empty($feature2)) { // This is for permissions on 2 levels $tmpreadok = 1; - foreach ($feature2 as $subfeature) - { + foreach ($feature2 as $subfeature) { if ($subfeature == 'user' && $user->id == $objectid) continue; // A user can always read its own card if (!empty($subfeature) && empty($user->rights->$feature->$subfeature->lire) && empty($user->rights->$feature->$subfeature->read)) { $tmpreadok = 0; } elseif (empty($subfeature) && empty($user->rights->$feature->lire) && empty($user->rights->$feature->read)) { $tmpreadok = 0; } else { $tmpreadok = 1; break; } // Break is to bypass second test if the first is ok } - if (!$tmpreadok) // We found a test on feature that is ko - { + if (!$tmpreadok) { // We found a test on feature that is ko $readok = 0; // All tests are ko (we manage here the and, the or will be managed later using $nbko). $nbko++; } - } - elseif (!empty($feature) && ($feature != 'user' && $feature != 'usergroup')) // This is permissions on 1 level - { + } elseif (!empty($feature) && ($feature != 'user' && $feature != 'usergroup')) { // This is permissions on 1 level if (empty($user->rights->$feature->lire) && empty($user->rights->$feature->read) && empty($user->rights->$feature->run)) { $readok = 0; $nbko++; } @@ -296,34 +277,25 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f { foreach ($featuresarray as $feature) { - if ($feature == 'contact') - { + if ($feature == 'contact') { if (!$user->rights->societe->contact->creer) { $createok = 0; $nbko++; } - } - elseif ($feature == 'produit|service') - { + } elseif ($feature == 'produit|service') { if (!$user->rights->produit->creer && !$user->rights->service->creer) { $createok = 0; $nbko++; } - } - elseif ($feature == 'prelevement') - { + } elseif ($feature == 'prelevement') { if (!$user->rights->prelevement->bons->creer) { $createok = 0; $nbko++; } - } - elseif ($feature == 'commande_fournisseur') - { + } elseif ($feature == 'commande_fournisseur') { if (!$user->rights->fournisseur->commande->creer) { $createok = 0; $nbko++; } - } - elseif ($feature == 'banque') - { + } elseif ($feature == 'banque') { if (!$user->rights->banque->modifier) { $createok = 0; $nbko++; } - } - elseif ($feature == 'cheque') - { + } elseif ($feature == 'cheque') { if (!$user->rights->banque->cheque) { $createok = 0; $nbko++; } + } elseif ($feature == 'import') { + if (!$user->rights->import->run) { $createok = 0; $nbko++; } + } elseif ($feature == 'ecm') { + if (!$user->rights->ecm->upload) { $createok = 0; $nbko++; } } - elseif (!empty($feature2)) // This is for permissions on one level - { - foreach ($feature2 as $subfeature) - { + elseif (!empty($feature2)) { // This is for permissions on one level + foreach ($feature2 as $subfeature) { if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->creer) continue; // User can edit its own card if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->password) continue; // User can edit its own password @@ -338,10 +310,8 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f break; } } - } - elseif (!empty($feature)) // This is for permissions on 2 levels ('creer' or 'write') - { - //print '
feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; + } elseif (!empty($feature)) { // This is for permissions on 2 levels ('creer' or 'write') + //print '
feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; exit; if (empty($user->rights->$feature->creer) && empty($user->rights->$feature->write) && empty($user->rights->$feature->create)) { diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index cc47218e2db..0bfa4cfd2db 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -49,7 +49,6 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = $mainmenu = (empty($_SESSION["mainmenu"]) ? '' : $_SESSION["mainmenu"]); $leftmenu = (empty($_SESSION["leftmenu"]) ? '' : $_SESSION["leftmenu"]); - $id = 'mainmenu'; $listofmodulesforexternal = explode(',', $conf->global->MAIN_MODULES_FOR_EXTERNAL); @@ -457,6 +456,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = $num = count($newTabMenu); for ($i = 0; $i < $num; $i++) { + //var_dump($type_user.' '.$newTabMenu[$i]['url'].' '.$showmode.' '.$newTabMenu[$i]['perms']); $idsel = (empty($newTabMenu[$i]['mainmenu']) ? 'none' : $newTabMenu[$i]['mainmenu']); $showmode = isVisibleToUserType($type_user, $newTabMenu[$i], $listofmodulesforexternal); @@ -1491,7 +1491,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM // Direct debit order if (!empty($conf->prelevement->enabled)) { - $newmenu->add("/compta/prelevement/index.php?leftmenu=withdraw&mainmenu=bank", $langs->trans("StandingOrders"), 0, $user->rights->prelevement->bons->lire, '', $mainmenu, 'withdraw'); + $newmenu->add("/compta/prelevement/index.php?leftmenu=withdraw&mainmenu=bank", $langs->trans("PaymentByDirectDebit"), 0, $user->rights->prelevement->bons->lire, '', $mainmenu, 'withdraw'); if ($usemenuhider || empty($leftmenu) || $leftmenu == "withdraw") { $newmenu->add("/compta/prelevement/create.php?mainmenu=bank", $langs->trans("NewStandingOrder"), 1, $user->rights->prelevement->bons->creer); diff --git a/htdocs/core/modules/modAsset.class.php b/htdocs/core/modules/modAsset.class.php index c11cf34d257..ebceca2960e 100644 --- a/htdocs/core/modules/modAsset.class.php +++ b/htdocs/core/modules/modAsset.class.php @@ -102,9 +102,7 @@ class modAsset extends DolibarrModules // Example: $this->const=array(0=>array('ASSETS_MYNEWCONST1','chaine','myvalue','This is a constant to add',1), // 1=>array('ASSETS_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1) // ); - $this->const = array( - //1=>array('ASSET_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1) - ); + $this->const = array(); if (!isset($conf->asset) || !isset($conf->asset->enabled)) diff --git a/htdocs/core/modules/modDebugBar.class.php b/htdocs/core/modules/modDebugBar.class.php index bf2bc640c44..f89f3659285 100644 --- a/htdocs/core/modules/modDebugBar.class.php +++ b/htdocs/core/modules/modDebugBar.class.php @@ -54,7 +54,7 @@ class modDebugBar extends DolibarrModules // Possible values for version are: 'development', 'experimental', 'dolibarr' or version $this->version = 'dolibarr'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); - $this->picto = 'technic'; + $this->picto = 'bug'; $this->module_parts = array('moduleforexternal' => 0); diff --git a/htdocs/core/modules/modECM.class.php b/htdocs/core/modules/modECM.class.php index 4d314644fb4..637cdb33739 100644 --- a/htdocs/core/modules/modECM.class.php +++ b/htdocs/core/modules/modECM.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2010 Laurent Destailleur + * Copyright (C) 2004-2020 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -97,21 +97,21 @@ class modECM extends DolibarrModules $r++; $this->rights[$r][0] = 2501; - $this->rights[$r][1] = 'Consulter/Télécharger les documents'; + $this->rights[$r][1] = 'Read or download documents'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'read'; $r++; $this->rights[$r][0] = 2503; - $this->rights[$r][1] = 'Soumettre ou supprimer des documents'; + $this->rights[$r][1] = 'Upload a document'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'upload'; $r++; $this->rights[$r][0] = 2515; - $this->rights[$r][1] = 'Administrer les rubriques de documents'; + $this->rights[$r][1] = 'Administer directories of documents'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'setup'; diff --git a/htdocs/core/modules/modSyslog.class.php b/htdocs/core/modules/modSyslog.class.php index 91e90d6540f..01079310e4b 100644 --- a/htdocs/core/modules/modSyslog.class.php +++ b/htdocs/core/modules/modSyslog.class.php @@ -58,7 +58,7 @@ class modSyslog extends DolibarrModules // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of image file used for this module. - $this->picto = 'technic'; + $this->picto = 'bug'; // Data directories to create when module is enabled $this->dirs = array(); diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 0fb1aff011d..2c54d4540b6 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -180,7 +180,7 @@ if ($nolinesbefore) { echo '