diff --git a/ChangeLog b/ChangeLog index 69005b0c492..d75938891f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,13 +11,55 @@ NEW: complete_head_from_modules() in ldap_prepare_head() WARNING: -Following changes may create regression for some external modules, but were necessary to make Dolibarr better: +Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: * The methode "cloture" on contact were renamed into "closeAll". +* The substitution key for reference of object is now __REF__ whatever is the object (it replaces __ORDERREF__, + __PROPALREF__, ...) +* Some REST API to access the dictionary (country, town, ...) were moved into a common API. - +***** ChangeLog for 6.0.1 compared to 6.0.* ***** +FIX: #7000 Dashboard link for late pending payment supplier invoices do not work +FIX: #7325 Default VAT rate when editing template invoices is 0% +FIX: #7330 +FIX: #7359 +FIX: #7367 +FIX: #7368 +FIX: #7391 +FIX: #7420 +FIX: Add some missing attributes in Adherent:makeSubstitution (type, phone… +FIX: Bad const name +FIX: Bad link to unpayed suppliers invoices +FIX: Better protection to no send email when we change limit +FIX: Calculation in the activity box +FIX: Clean bad parameters when inserting line of template invoice +FIX: dateSelector was not taken into account +FIX: hidden option MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN +FIX: journalization for bank journal should not rely on a label. +FIX: menu enty when url is external link +FIX: missing supplier qty and supplier discount in available fields for product export. +FIX: multicompany better accuracy in rounding and with revenue stamp. +FIX: Must use pdf format page as default for merging PDF. +FIX: PDF output was sharing 2 different currencies in same total +FIX: Position of signature on strato template +FIX: Protection to avoid to apply credit note discount > remain to pay +FIX: Remove warning when using log into syslog +FIX: Responsive +FIX: Security fixes (filter onload js, less verbose error message in +FIX: SEPA recording payment must save one payment in bank per customer +FIX: Several problem with the last event box on project/tasks +FIX: Sign of amount in origin currency on credit note created from lines +FIX: Some page of admin were not responsive +FIX: SQL injection +FIX: time.php crashed without project id in param +FIX: transfer of line extrafields from order to invoice +FIX: Upgrade missing on field +FIX: View of timespent for another user +FIX: ODT generation +FIX: CVE-2017-9840, CVE-2017-14238, CVE-2017-14239, CVE-2017-14240, CVE-2017-14241, + CVE-2017-14242 + ***** ChangeLog for 6.0.0 compared to 5.0.* ***** - NEW: Add experimental BlockeLog module (to log business events in a non reversible log file). NEW: Add a payment module for Stripe. NEW: Add module "Product variant" (like red, blue for the product shoes) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 80cc9b0856c..e0fa89d924d 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -366,7 +366,9 @@ if ($nboftargetok) { } else # For a maintenance release { - print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; + #print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; + print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. | grep -v "Merge branch" | grep -v "Merge pull" | grep "^ " | sed -e "s/^[0-9a-z]* *//" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; + } print "\n"; if (! $ret) diff --git a/dev/examples/code/create_user.php b/dev/examples/code/create_user.php index f745032f575..20173eb914a 100755 --- a/dev/examples/code/create_user.php +++ b/dev/examples/code/create_user.php @@ -60,14 +60,14 @@ $db->begin(); require_once(DOL_DOCUMENT_ROOT."/user/class/user.class.php"); -// Create invoice object +// Create user object $obj = new User($db); //$obj->initAsSpecimen(); $obj->login = 'ABCDEF'; $obj->nom = 'ABCDEF'; -// Create invoice +// Create user $idobject=$obj->create($user); if ($idobject > 0) { diff --git a/dev/examples/code/get_contracts.php b/dev/examples/code/get_contracts.php index 1262fe3eebd..fbe512300e8 100755 --- a/dev/examples/code/get_contracts.php +++ b/dev/examples/code/get_contracts.php @@ -67,7 +67,7 @@ $db->begin(); require_once(DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php"); -// Create invoice object +// Create contract object $obj = new Contrat($db); $obj->socid=$argv[1]; diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 5c4e836986e..fb48bc8094f 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -53,12 +53,10 @@ if (! $user->rights->accounting->chartofaccount) accessforbidden(); // Load variable for pagination $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'sortorder'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { - $page = 0; -} +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php index cf2b9080ee2..5c17f07183e 100644 --- a/htdocs/accountancy/admin/accountmodel.php +++ b/htdocs/accountancy/admin/accountmodel.php @@ -740,15 +740,6 @@ if ($id) print ''; print ""; - if ($tabname[$id] == MAIN_DB_PREFIX.'c_email_templates') - { - print '* '.$langs->trans("AvailableVariables").": "; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $tmp=FormMail::getAvailableSubstitKey('formemail'); - print implode(', ', $tmp); - print ''; - } - $colspan=count($fieldlist)+3; if ($id == 4) $colspan++; diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index 433448fa688..9a8a659db99 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2015 Alexandre Spangaro + * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2014 Florian Henry * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent @@ -37,10 +37,10 @@ $langs->load("bills"); $langs->load("admin"); $langs->load("accountancy"); -// Security check -if (empty($user->admin) && empty($user->rights->accounting->chartofaccount)) +// Security access +if (empty($user->rights->accounting->chartofaccount)) { - accessforbidden(); + accessforbidden(); } $action = GETPOST('action', 'alpha'); @@ -53,13 +53,6 @@ $main_option = array ( $model_option = array ( 'ACCOUNTING_EXPORT_SEPARATORCSV', 'ACCOUNTING_EXPORT_DATE' - /* - 'ACCOUNTING_EXPORT_PIECE', - 'ACCOUNTING_EXPORT_GLOBAL_ACCOUNT', - 'ACCOUNTING_EXPORT_LABEL', - 'ACCOUNTING_EXPORT_AMOUNT', - 'ACCOUNTING_EXPORT_DEVISE' - */ ); /* @@ -121,17 +114,13 @@ llxHeader(); $form = new Form($db); -$linkback = '' . $langs->trans("BackToModuleList") . ''; +// $linkback = '' . $langs->trans("BackToModuleList") . ''; print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'title_setup'); -$head = admin_accounting_prepare_head(); - print '
'; print ''; print ''; -dol_fiche_head($head, 'export', $langs->trans("Configuration"), -1, 'cron'); - $var = true; /* @@ -245,8 +234,6 @@ if ($num2) { print "\n"; } -dol_fiche_end(); - print '
'; print '
'; diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index b6aceb52ad4..bc078c062c6 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -37,10 +37,9 @@ $langs->load("compta"); $langs->load("bills"); $langs->load("admin"); $langs->load("accountancy"); -$langs->load("salaries"); -// Security check -if (empty($user->admin)) +// Security access +if (empty($user->rights->accounting->chartofaccount)) { accessforbidden(); } @@ -160,18 +159,13 @@ llxHeader(); $form = new Form($db); -$linkback = '' . $langs->trans("BackToModuleList") . ''; +//$linkback = '' . $langs->trans("BackToModuleList") . ''; print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'title_setup'); -$head = admin_accounting_prepare_head($accounting); - print '
'; print ''; print ''; -dol_fiche_head($head, 'general', $langs->trans("Configuration"), -1, 'cron'); - - // Default mode for calculating turnover (parameter ACCOUNTING_MODE) print ''; @@ -287,18 +281,11 @@ foreach ($list as $key) print '
'; - - - -dol_fiche_end(); - print '
'; print '
'; print '
'; -print '
'.$langs->trans("AccountancySetupDoneFromAccountancyMenu", $langs->transnoentitiesnoconv("MenuFinancial").'-'.$langs->transnoentitiesnoconv("MenuAccountancy")).'
'; - print '
'; print '
'; diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index c6d0d5cf40e..382d0697b6a 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -210,7 +210,7 @@ else { print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "t.label_operation", "", $options, "", $sortfield, $sortorder); print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="right"', $sortfield, $sortorder); print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="right"', $sortfield, $sortorder); - print_liste_field_titre("Solde", $_SERVER["PHP_SELF"], "", $options, "", 'align="right"', $sortfield, $sortorder); + print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $options, "", 'align="right"', $sortfield, $sortorder); print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder); print "\n"; @@ -280,4 +280,4 @@ else { llxFooter(); } -$db->close(); \ No newline at end of file +$db->close(); diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index ee17976ca30..c7ebb5ed5af 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -114,11 +114,11 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', } // Mass actions -$objectclass='Skeleton'; -$objectlabel='Skeleton'; -$permtoread = $user->rights->accounting->read; -$permtodelete = $user->rights->accounting->delete; -$uploaddir = $conf->accounting->dir_output; +$objectclass='ExpenseReport'; +$objectlabel='ExpenseReport'; +$permtoread = $user->rights->expensereport->read; +$permtodelete = $user->rights->expensereport->delete; +$uploaddir = $conf->expensereport->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; if ($massaction == 'ventil') { diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index bb67ec46468..0ef0a4e3dc3 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2001-2004 Rodolphe Quiedeville * Copyright (C) 2002-2003 Jean-Louis Bergamo * Copyright (C) 2004-2012 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2012 Marcos García * Copyright (C) 2012-2016 Philippe Grand * Copyright (C) 2015-2016 Alexandre Spangaro @@ -121,14 +121,22 @@ $hookmanager->initHooks(array('membercard','globalcard')); * Actions */ -if ($cancel) $action=''; - $parameters=array('id'=>$id, 'rowid'=>$id, 'objcanvas'=>$objcanvas); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); if (empty($reshook)) { + if ($cancel) + { + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + $action=''; + } + if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer)) { $error=0; @@ -230,6 +238,7 @@ if (empty($reshook)) } } + /* if ($action == 'confirm_sendinfo' && $confirm == 'yes') { if ($object->email) @@ -242,7 +251,7 @@ if (empty($reshook)) $langs->load("mails"); setEventMessages($langs->trans("MailSuccessfulySent", $from, $object->email), null, 'mesgs'); } - } + }*/ if ($action == 'update' && ! $cancel && $user->rights->adherent->creer) { @@ -715,10 +724,21 @@ if (empty($reshook)) } } + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + // Actions to build doc $upload_dir = $conf->adherent->dir_output; $permissioncreate=$user->rights->adherent->creer; include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + + // Actions to send emails + $trigger_name='MEMBER_SENTBYMAIL'; + $paramname='id'; + $mode='emailfrommember'; + $trackid='mem'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + } @@ -813,6 +833,7 @@ else print '
'; print ''; print ''; + if ($backtopage) print ''; dol_fiche_head(''); @@ -954,11 +975,18 @@ else dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; - print '
'; + print '
'; + print ''; + print '  '; + if (! empty($backtopage)) + { + print ''; + } + else + { + print ''; + } + print '
'; print "
\n"; } @@ -1225,7 +1253,7 @@ else print '
'; print ''; print '     '; - print ''; + print ''; print '
'; print ''; @@ -1344,10 +1372,10 @@ else } // Confirm send card by mail - if ($action == 'sendinfo') + /*if ($action == 'sendinfo') { print $form->formconfirm("card.php?rowid=".$id,$langs->trans("SendCardByMail"),$langs->trans("ConfirmSendCardByMail",$object->email),"confirm_sendinfo",'',0,1); - } + }*/ // Confirm terminate if ($action == 'resign') @@ -1590,6 +1618,31 @@ else if (empty($reshook)) { if ($action != 'valid' && $action != 'editlogin' && $action != 'editthirdparty') { + // Send + if ($object->statut == 1) { + print ''; + } + + // Send card by email + // TODO Remove this to replace with a template + /* + if ($user->rights->adherent->creer) + { + if ($object->statut >= 1) + { + if ($object->email) print '\n"; + else print '\n"; + } + else + { + print '
'.$langs->trans("SendCardByMail")."
"; + } + } + else + { + print '
'.$langs->trans("SendCardByMail")."
"; + }*/ + // Modify if ($user->rights->adherent->creer) { @@ -1626,24 +1679,6 @@ else } } - // Send card by email - if ($user->rights->adherent->creer) - { - if ($object->statut >= 1) - { - if ($object->email) print '\n"; - else print '\n"; - } - else - { - print '
'.$langs->trans("SendCardByMail")."
"; - } - } - else - { - print '
'.$langs->trans("SendCardByMail")."
"; - } - // Terminate if ($object->statut >= 1) { @@ -1720,52 +1755,65 @@ else } - - print '
'; - print ''; // ancre - - // Documents generes - $filename = dol_sanitizeFileName($object->ref); - //$filename = 'tmp_cards.php'; - //$filedir = $conf->adherent->dir_output . '/' . get_exdir($object->id, 2, 0, 0, $object, 'member') . dol_sanitizeFileName($object->ref); - $filedir = $conf->adherent->dir_output . '/' . get_exdir(0, 0, 0, 0, $object, 'member'); - $urlsource = $_SERVER['PHP_SELF'] . '?id=' . $object->id; - $genallowed = $user->rights->adherent->creer; - $delallowed = $user->rights->adherent->supprimer; - - print $formfile->showdocuments('member', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $object->default_lang, '', $object); - $somethingshown = $formfile->numoffiles; - - // Show links to link elements - //$linktoelem = $form->showLinkToObjectBlock($object, null, array('subscription')); - //$somethingshown = $form->showLinkedObjectBlock($object, ''); - - // Show links to link elements - /*$linktoelem = $form->showLinkToObjectBlock($object,array('order')); - if ($linktoelem) print ($somethingshown?'':'
').$linktoelem; - */ - - // Shon online payment link - $useonlinepayment = (! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)); - - if ($useonlinepayment) - { - print '
'; - - require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; - print showOnlinePaymentUrl('membersubscription', $object->ref); + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; } - print '
'; + if ($action != 'presend') + { + print '
'; + print ''; // ancre - // List of actions on element - /* Already in tab Agenda/Events - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'member', $socid, 1); - */ - print '
'; + // Documents generes + $filename = dol_sanitizeFileName($object->ref); + //$filename = 'tmp_cards.php'; + //$filedir = $conf->adherent->dir_output . '/' . get_exdir($object->id, 2, 0, 0, $object, 'member') . dol_sanitizeFileName($object->ref); + $filedir = $conf->adherent->dir_output . '/' . get_exdir(0, 0, 0, 0, $object, 'member'); + $urlsource = $_SERVER['PHP_SELF'] . '?id=' . $object->id; + $genallowed = $user->rights->adherent->creer; + $delallowed = $user->rights->adherent->supprimer; + print $formfile->showdocuments('member', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $object->default_lang, '', $object); + $somethingshown = $formfile->numoffiles; + + // Show links to link elements + //$linktoelem = $form->showLinkToObjectBlock($object, null, array('subscription')); + //$somethingshown = $form->showLinkedObjectBlock($object, ''); + + // Show links to link elements + /*$linktoelem = $form->showLinkToObjectBlock($object,array('order')); + if ($linktoelem) print ($somethingshown?'':'
').$linktoelem; + */ + + // Shon online payment link + $useonlinepayment = (! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)); + + if ($useonlinepayment) + { + print '
'; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + print showOnlinePaymentUrl('membersubscription', $object->ref); + } + + print '
'; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'member', $socid, 1, 'listactions', 10); + + print '
'; + } + + // Presend form + $modelmail='member'; + $defaulttopic='SendMemberRef'; + $diroutput = $conf->adherent->dir_output; + $trackid = 'mem'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } } diff --git a/htdocs/adherents/cartes/carte.php b/htdocs/adherents/cartes/carte.php index db4c631c0c9..63fd59f01e9 100644 --- a/htdocs/adherents/cartes/carte.php +++ b/htdocs/adherents/cartes/carte.php @@ -46,6 +46,10 @@ $mesg=''; $adherentstatic=new Adherent($db); +$extrafields = new ExtraFields($db); +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label('adherent'); + /* * Actions @@ -65,9 +69,14 @@ if ((! empty($foruserid) || ! empty($foruserlogin) || ! empty($mode)) && ! $mesg $sql.= " d.address, d.zip, d.town, d.country, d.birth, d.email, d.photo,"; $sql.= " t.libelle as type,"; $sql.= " c.code as country_code, c.label as country"; + // Add fields from extrafields + foreach ($extrafields->attribute_label as $key => $val) + $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid"; + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."adherent_extrafields as ef on (d.rowid = ef.fk_object)"; $sql.= " WHERE d.fk_adherent_type = t.rowid AND d.statut = 1"; + $sql.= " AND d.entity IN (".getEntity('adherent').")"; if (is_numeric($foruserid)) $sql.=" AND d.rowid=".$foruserid; if ($foruserlogin) $sql.=" AND d.login='".$db->escape($foruserlogin)."'"; $sql.= " ORDER BY d.rowid ASC"; @@ -84,9 +93,27 @@ if ((! empty($foruserid) || ! empty($foruserlogin) || ! empty($mode)) && ! $mesg if ($objp->country == '-') $objp->country=''; + $adherentstatic->id=$objp->rowid; $adherentstatic->lastname=$objp->lastname; $adherentstatic->firstname=$objp->firstname; + // format extrafiled so they can be parsed in function complete_substitutions_array + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + $adherentstatic->array_options = array(); + foreach($extrafields->attribute_label as $key => $val) + { + $tmpkey='options_'.$key; + if (!empty($objp->$tmpkey)) + { + $adherentstatic->array_options[$tmpkey] = $objp->$tmpkey; + } + //if (!empty($objp->$key)) + // $objp->array_options[$tmpkey] = $objp->$key; + //$objp->array_options[$tmpkey] = $extrafields->showOutputField($key, $objp->$tmpkey, '', 1); //$objp->$tmpkey; + } + } + // List of values to scan for a replacement $substitutionarray = array ( '%ID%'=>$objp->rowid, @@ -109,7 +136,7 @@ if ((! empty($foruserid) || ! empty($foruserlogin) || ! empty($mode)) && ! $mesg '%DOL_MAIN_URL_ROOT%'=>DOL_MAIN_URL_ROOT, '%SERVER%'=>"http://".$_SERVER["SERVER_NAME"]."/" ); - complete_substitutions_array($substitutionarray, $langs); + complete_substitutions_array($substitutionarray, $langs, $adherentstatic); // For business cards if (empty($mode) || $mode=='card' || $mode=='cardlogin') @@ -123,7 +150,7 @@ if ((! empty($foruserid) || ! empty($foruserlogin) || ! empty($mode)) && ! $mesg { $nb = $_Avery_Labels[$model]['NX'] * $_Avery_Labels[$model]['NY']; if ($nb <= 0) $nb=1; // Protection to avoid empty page - + for($j=0;$j<$nb;$j++) { $arrayofmembers[]=array( diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 85665280275..5eb757c0c5c 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -213,51 +213,23 @@ class Adherent extends CommonObject // Substitutions $substitutionarray=array( - '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT, - '__ID__'=>$msgishtml?dol_htmlentitiesbr($this->id):$this->id, - '__CIVILITY__'=>$this->getCivilityLabel(), - '__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname, - '__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname, - '__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs), - '__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe, - '__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address, - '__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip, - '__TOWN_'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town, - '__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country, - '__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email, - '__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday, - '__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo, - '__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login, - '__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass, - // For backward compatibility - '%DOL_MAIN_URL_ROOT%'=>DOL_MAIN_URL_ROOT, - '%ID%'=>$msgishtml?dol_htmlentitiesbr($this->id):$this->id, - '%CIVILITY%'=>$this->getCivilityLabel(), - '%FIRSTNAME%'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname, - '%LASTNAME%'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname, - '%FULLNAME%'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs), - '%COMPANY%'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe, - '%ADDRESS%'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address, - '%ZIP%'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip, - '%TOWN%'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town, - '%COUNTRY%'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country, - '%EMAIL%'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email, - '%BIRTH%'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday, - '%PHOTO%'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo, - '%LOGIN%'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login, - '%PASSWORD%'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass, - '%TYPE%'=>$msgishtml?dol_htmlentitiesbr($this->type):$this->type, - '%PHONE_PRO%'=>$msgishtml?dol_htmlentitiesbr($this->phone):$this->phone, - '%PHONE_PERSO%'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):$this->phone_perso, - '%PHONE_MOBILE%'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):$this->phone_mobile, - // For backward compatibility - '%INFOS%'=>$msgishtml?dol_htmlentitiesbr($infos):$infos, - '%SOCIETE%'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe, - '%PRENOM%'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname, - '%NOM%'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname, - '%CP%'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip, - '%VILLE%'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town, - '%PAYS%'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country, + '__CIVILITY__'=>$this->getCivilityLabel(), + '__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname, + '__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname, + '__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs), + '__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe, + '__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address, + '__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip, + '__TOWN__'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town, + '__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country, + '__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email, + '__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday, + '__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo, + '__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login, + '__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass, + '__PHONE__'=>$msgishtml?dol_htmlentitiesbr($this->phone):$this->phone, + '__PHONEPRO__'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):$this->phone_perso, + '__PHONEMOBILE__'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):$this->phone_mobile, ); complete_substitutions_array($substitutionarray, $langs, $this); @@ -447,33 +419,33 @@ class Adherent extends CommonObject $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " civility = ".(!is_null($this->civility_id)?$this->db->escape($this->civility_id):"null"); + $sql.= " civility = ".($this->civility_id>0?$this->db->escape($this->civility_id):"null"); $sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null"); - $sql.= ", lastname=" .($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); - $sql.= ", login=" .($this->login?"'".$this->db->escape($this->login)."'":"null"); - $sql.= ", societe=" .($this->societe?"'".$this->db->escape($this->societe)."'":"null"); - $sql.= ", fk_soc=" .($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); - $sql.= ", address=" .($this->address?"'".$this->db->escape($this->address)."'":"null"); - $sql.= ", zip=" .($this->zip?"'".$this->db->escape($this->zip)."'":"null"); - $sql.= ", town=" .($this->town?"'".$this->db->escape($this->town)."'":"null"); - $sql.= ", country=".($this->country_id>0?$this->db->escape($this->country_id):"null"); - $sql.= ", state_id=".($this->state_id>0?$this->db->escape($this->state_id):"null"); - $sql.= ", email='".$this->db->escape($this->email)."'"; - $sql.= ", skype='".$this->db->escape($this->skype)."'"; - $sql.= ", phone=" .($this->phone?"'".$this->db->escape($this->phone)."'":"null"); - $sql.= ", phone_perso=" .($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null"); - $sql.= ", phone_mobile=" .($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null"); - $sql.= ", note_private=" .($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); - $sql.= ", note_public=" .($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); - $sql.= ", photo=" .($this->photo?"'".$this->db->escape($this->photo)."'":"null"); - $sql.= ", public='".$this->db->escape($this->public)."'"; - $sql.= ", statut=" .$this->statut; - $sql.= ", fk_adherent_type=".$this->typeid; - $sql.= ", morphy='".$this->db->escape($this->morphy)."'"; - $sql.= ", birth=" .($this->birth?"'".$this->db->idate($this->birth)."'":"null"); - if ($this->datefin) $sql.= ", datefin='".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription - if ($this->datevalid) $sql.= ", datevalid='".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member - $sql.= ", fk_user_mod=".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest + $sql.= ", lastname = ".($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); + $sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null"); + $sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null"); + $sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null"); + $sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null"); + $sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null"); + $sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null"); + $sql.= ", country = ".($this->country_id>0?$this->db->escape($this->country_id):"null"); + $sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null"); + $sql.= ", email = '".$this->db->escape($this->email)."'"; + $sql.= ", skype = '".$this->db->escape($this->skype)."'"; + $sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null"); + $sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null"); + $sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null"); + $sql.= ", note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ", note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); + $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null"); + $sql.= ", public = '".$this->db->escape($this->public)."'"; + $sql.= ", statut = ".$this->statut; + $sql.= ", fk_adherent_type = ".$this->typeid; + $sql.= ", morphy = '".$this->db->escape($this->morphy)."'"; + $sql.= ", birth = ".($this->birth?"'".$this->db->idate($this->birth)."'":"null"); + if ($this->datefin) $sql.= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription + if ($this->datevalid) $sql.= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member + $sql.= ", fk_user_mod = ".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest $sql.= " WHERE rowid = ".$this->id; dol_syslog(get_class($this)."::update update member", LOG_DEBUG); @@ -714,15 +686,15 @@ class Adherent extends CommonObject * Fonction qui supprime l'adherent et les donnees associees * * @param int $rowid Id of member to delete - * @param User $user User object + * @param User $user User object * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @return int <0 if KO, 0=nothing to do, >0 if OK */ - function delete($rowid, $user, $notrigger=0) - { - global $conf, $langs; + function delete($rowid, $user, $notrigger=0) + { + global $conf, $langs; - $result = 0; + $result = 0; $error=0; $errorflag=0; @@ -739,84 +711,83 @@ class Adherent extends CommonObject // End call triggers } - // Remove category - $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-1; + // Remove category + $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-1; + } - } + // Remove subscription + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-2; + } + } - // Remove subscription - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-2; - } - } + // Remove linked user + if (! $error) + { + $ret=$this->setUserId(0); + if ($ret < 0) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-3; + } + } - // Remove linked user - if (! $error) - { - $ret=$this->setUserId(0); - if ($ret < 0) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-3; - } - } + // Removed extrafields + if (! $error) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->deleteExtraFields(); + if ($result < 0) + { + $error++; + $errorflag=-4; + dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); + } + } + } - // Removed extrafields - if (! $error) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->deleteExtraFields(); - if ($result < 0) - { - $error++; - $errorflag=-4; - dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR); - } - } - } + // Remove adherent + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag=-5; + } + } - // Remove adherent - if (! $error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid; - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - $this->error .= $this->db->lasterror(); - $errorflag=-5; - } - } - - if (! $error) - { - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return $errorflag; - } - } + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return $errorflag; + } + } /** @@ -1192,7 +1163,7 @@ class Adherent extends CommonObject // Load other properties $result=$this->fetch_subscriptions(); - return $result; + return $this->id; } else { diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index eec88a59c11..30c85618bfa 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2002 Rodolphe Quiedeville * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2009-2017 Regis Houssin * Copyright (C) 2016 Charlie Benke @@ -22,7 +22,6 @@ * \file htdocs/adherents/class/adherent_type.class.php * \ingroup member * \brief File of class to manage members types - * \author Rodolphe Quiedeville */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; @@ -62,228 +61,331 @@ class AdherentType extends CommonObject public $vote; /** @var bool Email sent during validation */ public $mail_valid; + /** @var array Array of members */ + public $members=array(); - /** + /** * Constructor * * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db = $db; - $this->statut = 1; - } + */ + function __construct($db) + { + $this->db = $db; + $this->statut = 1; + } - /** - * Fonction qui permet de creer le status de l'adherent - * - * @param User $user User making creation - * @return int >0 if OK, < 0 if KO - */ - function create($user) - { - global $conf; + /** + * Fonction qui permet de creer le status de l'adherent + * + * @param User $user User making creation + * @param int $notrigger 1=do not execute triggers, 0 otherwise + * @return int >0 if OK, < 0 if KO + */ + function create($user,$notrigger=0) + { + global $conf; - $this->statut=(int) $this->statut; - $this->label=(!empty($this->libelle)?trim($this->libelle):trim($this->label)); + $error=0; - $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent_type ("; - $sql.= "libelle"; - $sql.= ", entity"; - $sql.= ") VALUES ("; - $sql.= "'".$this->db->escape($this->label)."'"; - $sql.= ", ".$conf->entity; - $sql.= ")"; + $this->statut=(int) $this->statut; + $this->label=trim($this->label); - dol_syslog("Adherent_type::create", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent_type"); - return $this->update($user); - } - else - { - $this->error=$this->db->error().' sql='.$sql; - return -1; - } - } + $this->db->begin(); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent_type ("; + $sql.= "libelle"; + $sql.= ", entity"; + $sql.= ") VALUES ("; + $sql.= "'".$this->db->escape($this->label)."'"; + $sql.= ", ".$conf->entity; + $sql.= ")"; - /** - * Met a jour en base donnees du type - * - * @param User $user Object user making change - * @return int >0 if OK, < 0 if KO - */ - function update($user) - { - global $hookmanager,$conf; + dol_syslog("Adherent_type::create", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent_type"); - $error=0; + $result = $this->update($user,1); + if ($result < 0) + { + $this->db->rollback(); + return -3; + } - $this->label=(!empty($this->libelle)?trim($this->libelle):trim($this->label)); + if (! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_CREATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } - $sql = "UPDATE ".MAIN_DB_PREFIX."adherent_type "; - $sql.= "SET "; - $sql.= "statut = ".$this->statut.","; - $sql.= "libelle = '".$this->db->escape($this->label) ."',"; - $sql.= "subscription = '".$this->db->escape($this->subscription)."',"; - $sql.= "note = '".$this->db->escape($this->note)."',"; - $sql.= "vote = '".$this->db->escape($this->vote)."',"; - $sql.= "mail_valid = '".$this->db->escape($this->mail_valid)."'"; - $sql.= " WHERE rowid =".$this->id; + if (! $error) + { + $this->db->commit(); + return $this->id; + } + else + { + dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); + $this->db->rollback(); + return -2; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } - $result = $this->db->query($sql); - if ($result) - { - $action='update'; + /** + * Met a jour en base donnees du type + * + * @param User $user Object user making change + * @param int $notrigger 1=do not execute triggers, 0 otherwise + * @return int >0 if OK, < 0 if KO + */ + function update($user,$notrigger=0) + { + global $conf, $hookmanager; - // Actions on extra fields (by external module or standard code) - $hookmanager->initHooks(array('membertypedao')); - $parameters=array('membertype'=>$this->id); - $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (empty($reshook)) - { - if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used - { - $result=$this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - } - else if ($reshook < 0) $error++; + $error=0; + $this->label=trim($this->label); - return 1; - } - else - { - $this->error=$this->db->error().' sql='.$sql; - return -1; - } - } + $this->db->begin(); - /** - * Fonction qui permet de supprimer le status de l'adherent - * - * @param int $rowid Id of member type to delete - * @return int >0 if OK, 0 if not found, < 0 if KO - */ - function delete($rowid='') - { - if (empty($rowid)) $rowid=$this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."adherent_type "; + $sql.= "SET "; + $sql.= "statut = ".$this->statut.","; + $sql.= "libelle = '".$this->db->escape($this->label) ."',"; + $sql.= "subscription = '".$this->db->escape($this->subscription)."',"; + $sql.= "note = '".$this->db->escape($this->note)."',"; + $sql.= "vote = '".$this->db->escape($this->vote)."',"; + $sql.= "mail_valid = '".$this->db->escape($this->mail_valid)."'"; + $sql.= " WHERE rowid =".$this->id; - $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent_type WHERE rowid = ".$rowid; + $result = $this->db->query($sql); + if ($result) + { + $action='update'; - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->affected_rows($resql)) - { - return 1; - } - else - { - return 0; - } - } - else - { - print "Err : ".$this->db->error(); - return 0; - } - } + // Actions on extra fields (by external module or standard code) + $hookmanager->initHooks(array('membertypedao')); + $parameters=array('membertype'=>$this->id); + $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) + { + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used + { + $result=$this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + } + else if ($reshook < 0) $error++; - /** - * Fonction qui permet de recuperer le status de l'adherent - * - * @param int $rowid Id of member type to load - * @return int <0 if KO, >0 if OK - */ - function fetch($rowid) - { - $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; - $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; - $sql .= " WHERE d.rowid = ".$rowid; + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_MODIFY',$user); + if ($result < 0) { $error++; } + // End call triggers + } - dol_syslog("Adherent_type::fetch", LOG_DEBUG); + if (! $error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); + return -$error; + } + } + else + { + $this->error=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - $obj = $this->db->fetch_object($resql); + /** + * Fonction qui permet de supprimer le status de l'adherent + * + * @return int >0 if OK, 0 if not found, < 0 if KO + */ + function delete() + { + global $user; - $this->id = $obj->rowid; - $this->ref = $obj->rowid; - $this->label = $obj->label; - $this->libelle = $obj->label; // For backward compatibility - $this->statut = $obj->statut; - $this->subscription = $obj->subscription; - $this->mail_valid = $obj->mail_valid; - $this->note = $obj->note; - $this->vote = $obj->vote; - } - return 1; - } - else - { - $this->error=$this->db->lasterror(); - return -1; - } - } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent_type"; + $sql.= " WHERE rowid = ".$this->id; - /** - * Return list of members' type - * - * @return array List of types of members - */ - function liste_array() - { - global $conf,$langs; + $resql=$this->db->query($sql); + if ($resql) + { + // Call trigger + $result=$this->call_trigger('MEMBER_TYPE_DELETE',$user); + if ($result < 0) { $error++; $this->db->rollback(); return -2; } + // End call triggers - $adherenttypes = array(); + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + $this->error=$this->db->lasterror(); + return -1; + } + } - $sql = "SELECT rowid, libelle"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; - $sql.= " WHERE entity IN (".getEntity('adherent').")"; + /** + * Fonction qui permet de recuperer le status de l'adherent + * + * @param int $rowid Id of member type to load + * @return int <0 if KO, >0 if OK + */ + function fetch($rowid) + { + $sql = "SELECT d.rowid, d.libelle as label, d.statut, d.subscription, d.mail_valid, d.note, d.vote"; + $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as d"; + $sql .= " WHERE d.rowid = ".$rowid; - $resql=$this->db->query($sql); - if ($resql) - { - $nump = $this->db->num_rows($resql); + dol_syslog("Adherent_type::fetch", LOG_DEBUG); - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = $this->db->fetch_object($resql); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); - $adherenttypes[$obj->rowid] = $langs->trans($obj->libelle); - $i++; - } - } - } - else - { - print $this->db->error(); - } - return $adherenttypes; - } + $this->id = $obj->rowid; + $this->ref = $obj->rowid; + $this->label = $obj->label; + $this->statut = $obj->statut; + $this->subscription = $obj->subscription; + $this->mail_valid = $obj->mail_valid; + $this->note = $obj->note; + $this->vote = $obj->vote; + } + return 1; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } + + /** + * Return list of members' type + * + * @return array List of types of members + */ + function liste_array() + { + global $conf,$langs; + + $adherenttypes = array(); + + $sql = "SELECT rowid, libelle as label"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; + $sql.= " WHERE entity IN (".getEntity('adherent').")"; + + $resql=$this->db->query($sql); + if ($resql) + { + $nump = $this->db->num_rows($resql); + + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = $this->db->fetch_object($resql); + + $adherenttypes[$obj->rowid] = $langs->trans($obj->label); + $i++; + } + } + } + else + { + print $this->db->error(); + } + return $adherenttypes; + } + + /** + * Return array of Member objects for member type this->id (or all if this->id not defined) + * + * @param string $excludefilter Filter to exclude + * @param int $mode 0=Return array of member instance, 1=Return array of members id only + * @return mixed Array of members or -1 on error + */ + function listMembersForMemberType($excludefilter='', $mode=0) + { + global $conf, $user; + + $ret=array(); + + $sql = "SELECT a.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; + $sql.= " WHERE a.entity IN (".getEntity('member').")"; + $sql.= " AND a.fk_adherent_type = ".$this->id; + if (! empty($excludefilter)) $sql.=' AND ('.$excludefilter.')'; + + dol_syslog(get_class($this)."::listUsersForGroup", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + while ($obj = $this->db->fetch_object($resql)) + { + if (! array_key_exists($obj->rowid, $ret)) + { + if ($mode != 1) + { + $memberstatic=new Adherent($this->db); + $memberstatic->fetch($obj->rowid); + $ret[$obj->rowid]=$memberstatic; + } + else $ret[$obj->rowid]=$obj->rowid; + } + } + + $this->db->free($resql); + + $this->members=$ret; + + return $ret; + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + } /** * Return clicable name (with picto eventually) * * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param int $maxlen length max libelle + * @param int $maxlen length max label * @return string String with URL */ function getNomUrl($withpicto=0,$maxlen=0) @@ -291,7 +393,7 @@ class AdherentType extends CommonObject global $langs; $result=''; - $label=$langs->trans("ShowTypeCard",$this->libelle); + $label=$langs->trans("ShowTypeCard",$this->label); $link = ''; $linkend=''; @@ -300,75 +402,159 @@ class AdherentType extends CommonObject if ($withpicto) $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); if ($withpicto && $withpicto != 2) $result.=' '; - $result.=$link.($maxlen?dol_trunc($this->libelle,$maxlen):$this->libelle).$linkend; + $result.=$link.($maxlen?dol_trunc($this->label,$maxlen):$this->label).$linkend; return $result; } - /** * getLibStatut * * @return string Return status of a type of member */ - function getLibStatut() - { - return ''; - } + function getLibStatut() + { + return ''; + } - /** - * getMailOnValid - * - * @return string Return mail model - */ - function getMailOnValid() - { - global $conf; + /** + * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet + * + * @param array $info Info array loaded by _load_ldap_info + * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb) + * 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb) + * 2=Return key only (uid=qqq) + * @return string DN + */ + function _load_ldap_dn($info,$mode=0) + { + global $conf; + $dn=''; + if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS_TYPES."=".$info[$conf->global->LDAP_KEY_MEMBERS_TYPES].",".$conf->global->LDAP_MEMBER_TYPE_DN; + if ($mode==1) $dn=$conf->global->LDAP_MEMBER_TYPE_DN; + if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS_TYPES."=".$info[$conf->global->LDAP_KEY_MEMBERS_TYPES]; + return $dn; + } - if (! empty($this->mail_valid) && trim(dol_htmlentitiesbr_decode($this->mail_valid))) - { - return $this->mail_valid; - } - else - { - return $conf->global->ADHERENT_MAIL_VALID; - } - } - /** - * getMailOnSubscription - * - * @return string Return mail model - */ - function getMailOnSubscription() - { - global $conf; - // mail_subscription not defined so never used - if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription))) // Property not yet defined - { - return $this->mail_subscription; - } - else - { - return $conf->global->ADHERENT_MAIL_COTIS; - } - } + /** + * Initialize the info array (array of LDAP values) that will be used to call LDAP functions + * + * @return array Tableau info des attributs + */ + function _load_ldap_info() + { + global $conf,$langs; + + $info=array(); + + // Object classes + $info["objectclass"]=explode(',',$conf->global->LDAP_MEMBER_TYPE_OBJECT_CLASS); + + // Champs + if ($this->label && ! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME)) $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME] = $this->label; + if ($this->note && ! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION] = $this->note; + if (! empty($conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)) + { + $valueofldapfield=array(); + foreach($this->members as $key=>$val) // This is array of users for group into dolibarr database. + { + $member=new Adherent($this->db); + $member->fetch($val->id); + $info2 = $member->_load_ldap_info(); + $valueofldapfield[] = $member->_load_ldap_dn($info2); + } + $info[$conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield)?$valueofldapfield:''); + } + return $info; + } + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return void + */ + function initAsSpecimen() + { + global $conf, $user, $langs; + + // Initialise parametres + $this->id = 0; + $this->ref = 0; + $this->specimen=1; + + $this->label='MEMBERS TYPE SPECIMEN'; + $this->note='This is a note'; + $this->mail_valid='This is welcome email'; + $this->subscription=1; + $this->vote=0; + + $this->statut=1; + + // Members of this member type is just me + $this->members=array( + $user->id => $user + ); + } + + /** + * getMailOnValid + * + * @return string Return mail model + */ + function getMailOnValid() + { + global $conf; + + if (! empty($this->mail_valid) && trim(dol_htmlentitiesbr_decode($this->mail_valid))) + { + return $this->mail_valid; + } + else + { + return $conf->global->ADHERENT_MAIL_VALID; + } + } + + /** + * getMailOnSubscription + * + * @return string Return mail model + */ + function getMailOnSubscription() + { + global $conf; + + // mail_subscription not defined so never used + if (! empty($this->mail_subscription) && trim(dol_htmlentitiesbr_decode($this->mail_subscription))) // Property not yet defined + { + return $this->mail_subscription; + } + else + { + return $conf->global->ADHERENT_MAIL_COTIS; + } + } + + /** + * getMailOnResiliate + * + * @return string Return mail model + */ + function getMailOnResiliate() + { + global $conf; + + // NOTE mail_resiliate not defined so never used + if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate))) // Property not yet defined + { + return $this->mail_resiliate; + } + else + { + return $conf->global->ADHERENT_MAIL_RESIL; + } + } - /** - * getMailOnResiliate - * - * @return string Return mail model - */ - function getMailOnResiliate() - { - global $conf; - // NOTE mail_resiliate not defined so never used - if (! empty($this->mail_resiliate) && trim(dol_htmlentitiesbr_decode($this->mail_resiliate))) // Property not yet defined - { - return $this->mail_resiliate; - } - else - { - return $conf->global->ADHERENT_MAIL_RESIL; - } - } } diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index ff8064d80fb..c6adaf50142 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -272,7 +272,6 @@ class MembersTypes extends DolibarrApi $object = parent::_cleanObjectDatas($object); unset($object->cotisation); - unset($object->libelle); unset($object->array_options); unset($object->linkedObjectsIds); diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php index 2614a27d509..54779432a3b 100644 --- a/htdocs/adherents/index.php +++ b/htdocs/adherents/index.php @@ -59,7 +59,7 @@ $AdherentsResilies=array(); $AdherentType=array(); // Liste les adherents -$sql = "SELECT t.rowid, t.libelle, t.subscription,"; +$sql = "SELECT t.rowid, t.libelle as label, t.subscription,"; $sql.= " d.statut, count(d.rowid) as somme"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."adherent as d"; @@ -81,7 +81,7 @@ if ($result) $adhtype=new AdherentType($db); $adhtype->id=$objp->rowid; $adhtype->subscription=$objp->subscription; - $adhtype->libelle=$objp->libelle; + $adhtype->label=$objp->label; $AdherentType[$objp->rowid]=$adhtype; if ($objp->statut == -1) { $MemberToValidate[$objp->rowid]=$objp->somme; } @@ -273,7 +273,7 @@ $max=5; $sql = "SELECT a.rowid, a.statut, a.lastname, a.firstname, a.societe as company, a.fk_soc,"; $sql.= " a.tms as datem, datefin as date_end_subscription,"; -$sql.= " ta.rowid as typeid, ta.libelle, ta.subscription"; +$sql.= " ta.rowid as typeid, ta.libelle as label, ta.subscription"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a, ".MAIN_DB_PREFIX."adherent_type as ta"; $sql.= " WHERE a.entity IN (".getEntity('adherent').")"; $sql.= " AND a.fk_adherent_type = ta.rowid"; @@ -310,7 +310,7 @@ if ($resql) } $staticmember->ref=$staticmember->getFullName($langs); $statictype->id=$obj->typeid; - $statictype->libelle=$obj->libelle; + $statictype->label=$obj->label; print ''.$staticmember->getNomUrl(1,32).''; print ''.$statictype->getNomUrl(1,32).''; print ''.dol_print_date($db->jdate($obj->datem),'dayhour').''; diff --git a/htdocs/adherents/ldap.php b/htdocs/adherents/ldap.php index 38e90663c0f..65aea951d76 100644 --- a/htdocs/adherents/ldap.php +++ b/htdocs/adherents/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006 Regis Houssin +/* Copyright (C) 2006 Laurent Destailleur + * Copyright (C) 2006-2017 Regis Houssin * * 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 @@ -218,13 +218,11 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; - llxFooter(); - $db->close(); diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 3dc5439f47f..398d5b62adc 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -129,7 +129,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -315,7 +315,7 @@ if ($search_type > 0) { $membertype=new AdherentType($db); $result=$membertype->fetch(GETPOST("type",'int')); - $titre.=" (".$membertype->libelle.")"; + $titre.=" (".$membertype->label.")"; } $param=''; @@ -698,7 +698,7 @@ while ($i < min($num, $limit)) if (! empty($arrayfields['t.libelle']['checked'])) { $membertypestatic->id=$obj->type_id; - $membertypestatic->libelle=$obj->type; + $membertypestatic->label=$obj->type; print ''; print $membertypestatic->getNomUrl(1,32); print ''; diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index a0f36c409de..b59d8b7530d 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2001-2002 Rodolphe Quiedeville * Copyright (C) 2003 Jean-Louis Bergamo * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2017 Regis Houssin @@ -37,6 +37,7 @@ $langs->load("members"); $rowid = GETPOST('rowid','int'); $action = GETPOST('action','alpha'); $cancel = GETPOST('cancel','alpha'); +$backtopage = GETPOST('backtopage','alpha'); $search_lastname = GETPOST('search_lastname','alpha'); $search_login = GETPOST('search_login','alpha'); @@ -64,6 +65,8 @@ $mail_valid=GETPOST("mail_valid"); // Security check $result=restrictedArea($user,'adherent',$rowid,'adherent_type'); +$object = new AdherentType($db); + $extrafields = new ExtraFields($db); // fetch optionals attributes and labels @@ -87,73 +90,113 @@ $hookmanager->initHooks(array('membertypecard','globalcard')); * Actions */ +if ($cancel) { + + $action=''; + + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } +} + if ($action == 'add' && $user->rights->adherent->configurer) { - if (! $cancel) + $object->label = trim($label); + $object->subscription = (int) trim($subscription); + $object->note = trim($comment); + $object->mail_valid = trim($mail_valid); + $object->vote = (boolean) trim($vote); + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + if ($ret < 0) $error++; + + if (empty($object->label)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")), null, 'errors'); + } + else { + $sql = "SELECT libelle FROM ".MAIN_DB_PREFIX."adherent_type WHERE libelle='".$db->escape($object->label)."'"; + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + } + if ($num) { + $error++; + $langs->load("errors"); + setEventMessages($langs->trans("ErrorLabelAlreadyExists",$login), null, 'errors'); + } + } + + if (! $error) { - $object = new AdherentType($db); - - $object->label = trim($label); - $object->subscription = (int) trim($subscription); - $object->note = trim($comment); - $object->mail_valid = (boolean) trim($mail_valid); - $object->vote = (boolean) trim($vote); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - if ($ret < 0) $error++; - - if ($object->label) + $id=$object->create($user); + if ($id > 0) { - $id=$object->create($user); - if ($id > 0) - { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; - } - else - { - $mesg=$object->error; - $action = 'create'; - } + header("Location: ".$_SERVER["PHP_SELF"]); + exit; } else { - $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")); + setEventMessages($object->error, $object->errors, 'errors'); $action = 'create'; } } + else + { + $action = 'create'; + } } if ($action == 'update' && $user->rights->adherent->configurer) { - if (! $cancel) + $object->fetch($rowid); + + $object->oldcopy = clone $object; + + $object->label = trim($label); + $object->subscription = (int) trim($subscription); + $object->note = trim($comment); + $object->mail_valid = trim($mail_valid); + $object->vote = (boolean) trim($vote); + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + if ($ret < 0) $error++; + + $ret=$object->update($user); + + if ($ret >= 0 && ! count($object->errors)) { - $object = new AdherentType($db); - $object->id = $rowid; - $object->label = trim($label); - $object->subscription = (int) trim($subscription); - $object->note = trim($comment); - $object->mail_valid = (boolean) trim($mail_valid); - $object->vote = (boolean) trim($vote); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - if ($ret < 0) $error++; - - $object->update($user); - - header("Location: ".$_SERVER["PHP_SELF"]."?rowid=".$_POST["rowid"]); - exit; + setEventMessages($langs->trans("MemberTypeModified"), null, 'mesgs'); } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } + + header("Location: ".$_SERVER["PHP_SELF"]."?rowid=".$object->id); + exit; } -if ($action == 'delete' && $user->rights->adherent->configurer) +if ($action == 'confirm_delete' && $user->rights->adherent->configurer) { - $object = new AdherentType($db); - $object->delete($rowid); - header("Location: ".$_SERVER["PHP_SELF"]); - exit; + $object->fetch($rowid); + $res=$object->delete(); + + if ($res > 0) + { + setEventMessages($langs->trans("MemberTypeDeleted"), null, 'mesgs'); + header("Location: ".$_SERVER["PHP_SELF"]); + exit; + } + else + { + setEventMessages($langs->trans("MemberTypeCanNotBeDeleted"), null, 'errors'); + $action=''; + } } @@ -308,7 +351,15 @@ if ($rowid > 0) { $object = new AdherentType($db); $object->fetch($rowid); - $object->fetch_optionals($rowid,$extralabels); + $object->fetch_optionals($object->id,$extralabels); + + /* + * Confirmation suppression + */ + if ($action == 'delete') + { + print $form->formconfirm($_SERVER['PHP_SELF']."?rowid=".$object->id,$langs->trans("DeleteAMemberType"),$langs->trans("ConfirmDeleteMemberType",$object->label),"confirm_delete", '',0,1); + } $head = member_type_prepare_head($object); @@ -337,15 +388,14 @@ if ($rowid > 0) print ''.$langs->trans("WelcomeEMail").''; print nl2br($object->mail_valid).""; - // Other attributes - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; print ''; - print ''; + print ''; dol_fiche_end(); - /* * Buttons */ @@ -359,7 +409,7 @@ if ($rowid > 0) } // Add - print ''; + print ''; // Delete if ($user->rights->adherent->configurer) @@ -459,7 +509,7 @@ if ($rowid > 0) $titre.=" (".$membertype->label.")"; } - $param="&rowid=".$rowid; + $param="&rowid=".$object->id; if (! empty($status)) $param.="&status=".$status; if (! empty($search_lastname)) $param.="&search_lastname=".$search_lastname; if (! empty($search_firstname)) $param.="&search_firstname=".$search_firstname; @@ -473,7 +523,7 @@ if ($rowid > 0) } print '
'; - print ''; + print ''; print '
'; print_barre_liste('',$page,$_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords); @@ -593,12 +643,12 @@ if ($rowid > 0) print ''; if ($user->rights->adherent->creer) { - print ''.img_edit().''; + print ''.img_edit().''; } print ' '; if ($user->rights->adherent->supprimer) { - print ''.img_picto($langs->trans("Resiliate"),'disable.png').''; + print ''.img_picto($langs->trans("Resiliate"),'disable.png').''; } print ""; @@ -631,15 +681,14 @@ if ($rowid > 0) if ($action == 'edit') { $object = new AdherentType($db); - $object->id = $rowid; $object->fetch($rowid); - $object->fetch_optionals($rowid,$extralabels); + $object->fetch_optionals($object->id,$extralabels); $head = member_type_prepare_head($object); - print ''; + print ''; print ''; - print ''; + print ''; print ''; dol_fiche_head($head, 'card', $langs->trans("MemberType"), 0, 'group'); @@ -706,7 +755,7 @@ if ($rowid > 0) print '
'; print ''; print '     '; - print ''; + print ''; print '
'; print "
"; diff --git a/htdocs/adherents/type_ldap.php b/htdocs/adherents/type_ldap.php new file mode 100644 index 00000000000..d4de1a2afdb --- /dev/null +++ b/htdocs/adherents/type_ldap.php @@ -0,0 +1,191 @@ + + * Copyright (C) 2006-2017 Regis Houssin + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/adherents/type_ldap.php + * \ingroup ldap + * \brief Page fiche LDAP members types + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; + +$langs->load("members"); +$langs->load("admin"); +$langs->load("ldap"); + +$id = GETPOST('rowid', 'int'); +$action = GETPOST('action','alpha'); + +// Security check +$result=restrictedArea($user,'adherent',$id,'adherent_type'); + +$object = new AdherentType($db); +$object->fetch($id); + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('membertypeldapcard','globalcard')); + +/* + * Actions + */ + + +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + if ($action == 'dolibarr2ldap') + { + $ldap = new Ldap(); + $result = $ldap->connect_bind(); + + if ($result > 0) + { + $object->listMembersForMemberType(); + + $info = $object->_load_ldap_info(); + $dn = $object->_load_ldap_dn($info); + $olddn = $dn; // We can say that old dn = dn as we force synchro + + $result = $ldap->update($dn, $info, $user, $olddn); + } + + if ($result >= 0) { + setEventMessages($langs->trans("MemberTypeSynchronized"), null, 'mesgs'); + } + else { + setEventMessages($ldap->error, $ldap->errors, 'errors'); + } + } +} + +/* + * View + */ + +llxHeader(); + +$form = new Form($db); + +$head = member_type_prepare_head($object); + +dol_fiche_head($head, 'ldap', $langs->trans("MemberType"), -1, 'group'); + +$linkback = ''.$langs->trans("BackToList").''; + +dol_banner_tab($object, 'rowid', $linkback); + +print '
'; +print '
'; + +print ''; + +// LDAP DN +print '\n"; + +// LDAP Cle +print '\n"; + +// LDAP Server +print '\n"; +print '\n"; +print '\n"; +print '\n"; +print '\n"; + +print '
LDAP '.$langs->trans("LDAPMemberTypeDn").''.$conf->global->LDAP_MEMBER_TYPE_DN."
LDAP '.$langs->trans("LDAPNamingAttribute").''.$conf->global->LDAP_KEY_MEMBERS_TYPES."
LDAP '.$langs->trans("Type").''.$conf->global->LDAP_SERVER_TYPE."
LDAP '.$langs->trans("Version").''.$conf->global->LDAP_SERVER_PROTOCOLVERSION."
LDAP '.$langs->trans("LDAPPrimaryServer").''.$conf->global->LDAP_SERVER_HOST."
LDAP '.$langs->trans("LDAPSecondaryServer").''.$conf->global->LDAP_SERVER_HOST_SLAVE."
LDAP '.$langs->trans("LDAPServerPort").''.$conf->global->LDAP_SERVER_PORT."
'; + +print '
'; + +dol_fiche_end(); + +/* + * Barre d'actions + */ + +print '
'; + +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) +{ + print ''.$langs->trans("ForceSynchronize").''; +} + +print "
\n"; + +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == 1) print "
\n"; + + + +// Affichage attributs LDAP +print load_fiche_titre($langs->trans("LDAPInformationsForThisMemberType")); + +print ''; + +print ''; +print ''; +print ''; +print ''; + +// Lecture LDAP +$ldap=new Ldap(); +$result=$ldap->connect_bind(); +if ($result > 0) +{ + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info,1); + $search = "(".$object->_load_ldap_dn($info,2).")"; + $records = $ldap->getAttribute($dn,$search); + + //print_r($records); + + // Affichage arbre + if ((! is_numeric($records) || $records != 0) && (! isset($records['count']) || $records['count'] > 0)) + { + if (! is_array($records)) + { + print ''; + } + else + { + $result=show_ldap_content($records,0,$records['count'],true); + } + } + else + { + print ''; + } + + $ldap->unbind(); + $ldap->close(); +} +else +{ + setEventMessages($ldap->error, $ldap->errors, 'errors'); +} + +print '
'.$langs->trans("LDAPAttributes").''.$langs->trans("Value").'
'.$langs->trans("ErrorFailedToReadLDAP").'
'.$langs->trans("LDAPRecordNotFound").' (dn='.$dn.' - search='.$search.')
'; + +llxFooter(); +$db->close(); diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php index fa2c11849fb..50676e4c3af 100644 --- a/htdocs/admin/agenda.php +++ b/htdocs/admin/agenda.php @@ -165,6 +165,8 @@ if (! empty($triggers)) if ($module == 'shipping') $module = 'expedition_bon'; if ($module == 'member') $module = 'adherent'; if ($module == 'project') $module = 'projet'; + if ($module == 'proposal_supplier') $module = 'supplier_proposal'; + //print 'module='.$module.'
'; if (! empty($conf->$module->enabled)) { diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php index a5e37f620f7..a999db51857 100644 --- a/htdocs/admin/agenda_other.php +++ b/htdocs/admin/agenda_other.php @@ -373,11 +373,12 @@ $formactions->select_type_actions($conf->global->AGENDA_DEFAULT_FILTER_TYPE, "AG print ''."\n"; // AGENDA_DEFAULT_FILTER_STATUS +// TODO Remove to use the default generic feature print ''."\n"; print ''.$langs->trans("AGENDA_DEFAULT_FILTER_STATUS").''."\n"; print ' '."\n"; print ''."\n"; -$formactions->form_select_status_action('agenda', $conf->global->AGENDA_DEFAULT_FILTER_STATUS, 1, 'AGENDA_DEFAULT_FILTER_STATUS', 1, 2); +$formactions->form_select_status_action('agenda', $conf->global->AGENDA_DEFAULT_FILTER_STATUS, 1, 'AGENDA_DEFAULT_FILTER_STATUS', 1, 2, 'minwidth100'); print ''."\n"; // AGENDA_DEFAULT_VIEW diff --git a/htdocs/admin/defaultvalues.php b/htdocs/admin/defaultvalues.php index b758506f8b5..e4ba112511e 100644 --- a/htdocs/admin/defaultvalues.php +++ b/htdocs/admin/defaultvalues.php @@ -269,12 +269,12 @@ if ($mode != 'focus') { if ($mode != 'sortorder') { - $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object')); // Must match list into GETPOST - $substitutionarray['__(AnyTranslationKey)__']=$langs->trans("Translation"); + $substitutionarray=getCommonSubstitutionArray($langs, 2, array('object','objectamount')); // Must match list into GETPOST + unset($substitutionarray['__USER_SIGNATURE__']); $texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'
'; foreach($substitutionarray as $key => $val) { - $texthelp.=$key.'
'; + $texthelp.=$key.' -> '.$val.'
'; } $textvalue=$form->textwithpicto($langs->trans("Value"), $texthelp, 1, 'help', '', 0, 2, ''); // No tooltip on click, this also triggers the sort click } diff --git a/htdocs/admin/delais.php b/htdocs/admin/delais.php index d3ef125f2a7..37f66427225 100644 --- a/htdocs/admin/delais.php +++ b/htdocs/admin/delais.php @@ -137,7 +137,17 @@ if ($action == 'update') } } - dolibarr_set_const($db, "MAIN_DISABLE_METEO",$_POST["MAIN_DISABLE_METEO"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_DISABLE_METEO",$_POST["MAIN_DISABLE_METEO"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_USE_METEO_WITH_PERCENTAGE",GETPOST("MAIN_USE_METEO_WITH_PERCENTAGE"),'chaine',0,'',$conf->entity); + + // For update value with percentage + $plus=''; + if(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) $plus = '_PERCENTAGE'; + // Update values + for($i=0;$i<4;$i++) { + if(isset($_POST['MAIN_METEO'.$plus.'_LEVEL'.$i])) dolibarr_set_const($db, 'MAIN_METEO'.$plus.'_LEVEL'.$i, GETPOST('MAIN_METEO'.$plus.'_LEVEL'.$i, 'int'),'chaine',0,'',$conf->entity); + } + } @@ -196,13 +206,6 @@ if ($action == 'edit') print ''.$langs->trans("MAIN_DISABLE_METEO").'' .$form->selectyesno('MAIN_DISABLE_METEO',(empty($conf->global->MAIN_DISABLE_METEO)?0:1),1) . ''; print ''; - - print '
'; - - print '
'; - print '
'; - - print ''; } else { @@ -244,21 +247,30 @@ else print ''; - print '
'; - - // Boutons d'action - print '
'; - print ''.$langs->trans("Modify").''; - print '
'; - } print '
'; - // Show logo for weather print $langs->trans("DescWeather").'
'; +if($action == 'edit') { + + $str_mode_std = $langs->trans('MeteoStdModEnabled').' : '.$langs->trans('MeteoUseMod', $langs->trans('MeteoPercentageMod')); + $str_mode_percentage = $langs->trans('MeteoPercentageModEnabled').' : '.$langs->trans('MeteoUseMod', $langs->trans('MeteoStdMod')); + if(empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) $str_mode_enabled = $str_mode_std; + else $str_mode_enabled = $str_mode_percentage; + print ''.$str_mode_enabled.''; + print ''; + + print '

'; + +} else { + if(empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) print $langs->trans('MeteoStdModEnabled'); + else print $langs->trans('MeteoPercentageModEnabled'); + print '

'; +} + $offset=0; $cursor=10; // By default //if (! empty($conf->global->MAIN_METEO_OFFSET)) $offset=$conf->global->MAIN_METEO_OFFSET; @@ -267,36 +279,143 @@ $level0=$offset; if (! empty($conf->global->MAIN_METEO_LEVEL0)) $level $level1=$offset+1*$cursor; if (! empty($conf->global->MAIN_METEO_LEVEL1)) $level1=$conf->global->MAIN_METEO_LEVEL1; $level2=$offset+2*$cursor; if (! empty($conf->global->MAIN_METEO_LEVEL2)) $level2=$conf->global->MAIN_METEO_LEVEL2; $level3=$offset+3*$cursor; if (! empty($conf->global->MAIN_METEO_LEVEL3)) $level3=$conf->global->MAIN_METEO_LEVEL3; -$text=''; $options='height="60px"'; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; +$text=''; $options='class="valignmiddle" height="60px"'; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print '
'; -print img_weather($text,'weather-clear.png',$options); -print '= '.$level0.'         '; -print img_weather($text,'weather-few-clouds.png',$options); -print '<= '.$level1.'         '; -print img_weather($text,'weather-clouds.png',$options); -print '<= '.$level2.'
'; -print img_weather($text,'weather-many-clouds.png',$options); -print '<= '.$level3.'         '; -print img_weather($text,'weather-storm.png',$options); -print '> '.$level3.'                        
'; +if ($action == 'edit') { + print '
global->MAIN_USE_METEO_WITH_PERCENTAGE) ? '' : 'style="display:none;"').'>'; + + print '
'; + print '
'; + print img_weather($text,'weather-clear.png', $options); + print '= '; + print '
'; + print img_weather($text,'weather-few-clouds.png',$options); + print '<= '; + print '
'; + print img_weather($text,'weather-clouds.png',$options); + print '<= '; + print '
'; + print img_weather($text,'weather-many-clouds.png',$options); + print '<= '; + print '
'; + print '
'; + + print '
'; + + print '
global->MAIN_USE_METEO_WITH_PERCENTAGE) ? 'style="display:none;"' : '').'>'; + + print '
'; + print '
'; + print img_weather($text,'weather-clear.png',$options); + print '=  %'; + print '
'; + print img_weather($text,'weather-few-clouds.png',$options); + print '<=  %'; + print '
'; + print img_weather($text,'weather-clouds.png',$options); + print '<=  %'; + print '
'; + print img_weather($text,'weather-many-clouds.png',$options); + print '<=  %'; + print '
'; + print '
'; + + print '
'; + + ?> + + + + global->MAIN_USE_METEO_WITH_PERCENTAGE)) { + + print '
'; + print '
'; + print img_weather($text,'weather-clear.png',$options); + print '= '.$conf->global->MAIN_METEO_PERCENTAGE_LEVEL0.' %'; + print '
'; + print img_weather($text,'weather-few-clouds.png',$options); + print '<= '.$conf->global->MAIN_METEO_PERCENTAGE_LEVEL1.' %'; + print '
'; + print img_weather($text,'weather-clouds.png',$options); + print '<= '.$conf->global->MAIN_METEO_PERCENTAGE_LEVEL2.' %'; + print '
'; + print img_weather($text,'weather-many-clouds.png',$options); + print '<= '.$conf->global->MAIN_METEO_PERCENTAGE_LEVEL3.' %'; + print '
'; + print img_weather($text,'weather-storm.png',$options); + print '> '.$conf->global->MAIN_METEO_PERCENTAGE_LEVEL3.' %'; + print '
'; + print '
'; + + } else { + + print '
'; + print '
'; + print img_weather($text,'weather-clear.png',$options); + print '= '.$level0; + print '
'; + print img_weather($text,'weather-few-clouds.png',$options); + print '<= '.$level1; + print '
'; + print img_weather($text,'weather-clouds.png',$options); + print '<= '.$level2; + print '
'; + print img_weather($text,'weather-many-clouds.png',$options); + print '<= '.$level3; + print '
'; + print img_weather($text,'weather-storm.png',$options); + print '> '.$level3; + print '
'; + print '
'; + + } +} + +print ''; + +if($action == 'edit') { + + print '
'; + print '
'; + +} else { + + // Boutons d'action + print '
'; + +} + llxFooter(); $db->close(); diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 913f4611a0e..427eba96854 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -620,7 +620,8 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($value == 'localtax2' && empty($_POST['localtax2_type'])) continue; if ($value == 'color' && empty($_POST['color'])) continue; if ($value == 'formula' && empty($_POST['formula'])) continue; - if ((! isset($_POST[$value]) || $_POST[$value]=='') + if ($value == 'sortorder') continue; // For a column name 'sortorder', we use the field name 'position' + if ((! isset($_POST[$value]) || $_POST[$value]=='') && (! in_array($listfield[$f], array('decalage','module','accountancy_code','accountancy_code_sell','accountancy_code_buy')) // Fields that are not mandatory && (! ($id == 10 && $listfield[$f] == 'code')) // Code is mandatory fir table 10 ) @@ -735,7 +736,11 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) $_POST[$listfieldvalue[$i]] = $conf->entity; } if ($i) $sql.=","; - if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' + if ($listfieldvalue[$i] == 'sortorder') // For column name 'sortorder', we use the field name 'position' + { + $sql.="'".(int) $db->escape($_POST['position'])."'"; + } + elseif ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } @@ -784,7 +789,11 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) } if ($i) $sql.=","; $sql.= $field."="; - if ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' + if ($listfieldvalue[$i] == 'sortorder') // For column name 'sortorder', we use the field name 'position' + { + $sql.="'".(int) $db->escape($_POST['position'])."'"; + } + elseif ($_POST[$listfieldvalue[$i]] == '' && ! ($listfieldvalue[$i] == 'code' && $id == 10)) $sql.="null"; // For vat, we want/accept code = '' else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } @@ -1903,6 +1912,8 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') } else { + if ($fieldlist[$field]=='sortorder') $fieldlist[$field]='position'; + $classtd=''; $class=''; if ($fieldlist[$field]=='code') $classtd='width100'; if ($fieldlist[$field]=='affect') $class='maxwidth50'; diff --git a/htdocs/admin/dolistore/ajax/image.php b/htdocs/admin/dolistore/ajax/image.php index 6d63dd3e08b..14d05a036e8 100644 --- a/htdocs/admin/dolistore/ajax/image.php +++ b/htdocs/admin/dolistore/ajax/image.php @@ -64,4 +64,5 @@ try { if ($trace[0]['args'][0] == 404) die('Bad ID'); else if ($trace[0]['args'][0] == 401) die('Bad auth key'); else die('Can not access to '.$conf->global->MAIN_MODULE_DOLISTORE_API_SRV); -} \ No newline at end of file +} + diff --git a/htdocs/admin/dolistore/class/dolistore.class.php b/htdocs/admin/dolistore/class/dolistore.class.php index aff21ce58e8..f437dc66975 100644 --- a/htdocs/admin/dolistore/class/dolistore.class.php +++ b/htdocs/admin/dolistore/class/dolistore.class.php @@ -211,11 +211,11 @@ class Dolistore // add image or default ? if ($product->id_default_image != '') { - $image_url = DOL_URL_ROOT.'/dolistore/ajax/image.php?id_product='.$product->id.'&id_image='.$product->id_default_image; + $image_url = DOL_URL_ROOT.'/admin/dolistore/ajax/image.php?id_product='.$product->id.'&id_image='.$product->id_default_image; $images = ''. ''; } else { - $images = ''; + $images = ''; } // free or pay ? diff --git a/htdocs/admin/dolistore/class/init.php b/htdocs/admin/dolistore/class/init.php deleted file mode 100644 index 4a94e08002c..00000000000 --- a/htdocs/admin/dolistore/class/init.php +++ /dev/null @@ -1,72 +0,0 @@ -CRUD Tutorial - Customer's list - -* @copyright 2007-2013 PrestaShop SA -* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) -* International Registered Trademark & Property of PrestaShop SA -* PrestaShop Webservice Library -* @package PrestaShopWebservice -*/ -// Here we define constants /!\ You need to replace this parameters -//https://dolistorecatalogpublickey1234567@vmdevwww.dolistore.com/api/ -define('DEBUG', true); // Debug mode -define('PS_SHOP_PATH', 'https://www.dolistore.com/'); // Root path of your PrestaShop store -define('PS_WS_AUTH_KEY', 'dolistorecatalogpublickey1234567'); // Auth key (Get it in your Back Office) -require_once('./PSWebServiceLibrary.php'); -// Here we make the WebService Call -try -{ - $webService = new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG); - - // Here we set the option array for the Webservice : we want customers resources - $opt['resource'] = 'categories'; - $opt['id'] = '1'; - - // Call - $xml = $webService->get($opt); - // Here we get the elements from children of customers markup "customer" - $resources = $xml->categories->children(); -} -catch (PrestaShopWebserviceException $e) -{ - // Here we are dealing with errors - $trace = $e->getTrace(); - if ($trace[0]['args'][0] == 404) echo 'Bad ID'; - else if ($trace[0]['args'][0] == 401) echo 'Bad auth key'; - else echo 'Other error'; -} -// We set the Title -echo "

Categories's List

"; -echo ''; -// if $resources is set we can lists element in it otherwise do nothing cause there's an error -if (isset($resources)) -{ - echo ''; - foreach ($resources as $resource) - { - // Iterates on the found IDs - echo ''; - } -} -echo '
Id
'.$resource->attributes().'
'; -?> - \ No newline at end of file diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 56efe2b5d7d..2322ae7a057 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -82,8 +82,8 @@ if ($action == 'removebackgroundlogin' && ! empty($conf->global->MAIN_LOGIN_BACK if ($action == 'update') { - dolibarr_set_const($db, "MAIN_LANG_DEFAULT", $_POST["main_lang_default"],'chaine',0,'',$conf->entity); - dolibarr_set_const($db, "MAIN_MULTILANGS", $_POST["main_multilangs"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_LANG_DEFAULT", $_POST["MAIN_LANG_DEFAULT"],'chaine',0,'',$conf->entity); + dolibarr_set_const($db, "MAIN_MULTILANGS", $_POST["MAIN_MULTILANGS"],'chaine',0,'',$conf->entity); dolibarr_set_const($db, "MAIN_THEME", $_POST["main_theme"],'chaine',0,'',$conf->entity); @@ -230,15 +230,15 @@ if ($action == 'edit') // Edit print ''; // Default language - print ''.$langs->trans("DefaultLanguage").''; - print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'main_lang_default', 1, 0, 0, 0, 0, 'minwidth300'); + print ''.$langs->trans("DefaultLanguage").''; + print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, 0, 0, 0, 0, 'minwidth300'); print ''; print ' '; print ''; // Multilingual GUI - print ''.$langs->trans("EnableMultilangInterface").''; - print $form->selectyesno('main_multilangs',$conf->global->MAIN_MULTILANGS,1); + print ''.$langs->trans("EnableMultilangInterface").''; + print $form->selectyesno('MAIN_MULTILANGS',$conf->global->MAIN_MULTILANGS,1); print ''; print ' '; print ''; @@ -349,9 +349,8 @@ if ($action == 'edit') // Edit print ''; // Message of the day on home page - $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object')); + $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount')); complete_substitutions_array($substitutionarray, $langs); - $substitutionarray['__(AnyTranslationKey)__']=$langs->trans('TranslationKey'); print ''; $texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'
'; @@ -359,7 +358,7 @@ if ($action == 'edit') // Edit { $texthelp.=$key.'
'; } - print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, ''); + print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessageofday'); print ''; @@ -379,16 +378,15 @@ if ($action == 'edit') // Edit print ''; // Message on login page - $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','user')); + $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount','user')); complete_substitutions_array($substitutionarray, $langs); - $substitutionarray['__(AnyTranslationKey)__']=$langs->trans('TranslationKey'); print ''; $texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'
'; foreach($substitutionarray as $key => $val) { $texthelp.=$key.'
'; } - print $form->textwithpicto($langs->trans("MessageLogin"), $texthelp, 1, 'help', '', 0, 2, ''); + print $form->textwithpicto($langs->trans("MessageLogin"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessagelogin'); print ''; $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index d5720835f3c..f9b863e487e 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -68,6 +68,7 @@ if (empty($reshook)) if (! dolibarr_set_const($db, 'LDAP_SYNCHRO_ACTIVE',GETPOST("activesynchro"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_CONTACT_ACTIVE',GETPOST("activecontact"),'chaine',0,'',$conf->entity)) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_ACTIVE',GETPOST("activemembers"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_ACTIVE',GETPOST("activememberstypes"),'chaine',0,'',$conf->entity)) $error++; if (! $error) { @@ -135,7 +136,6 @@ print ''; // Synchro contact active if (! empty($conf->societe->enabled)) { - print ''.$langs->trans("LDAPDnContactActive").''; $arraylist=array(); $arraylist['0']=$langs->trans("No"); @@ -147,7 +147,6 @@ if (! empty($conf->societe->enabled)) // Synchro member active if (! empty($conf->adherent->enabled)) { - print ''.$langs->trans("LDAPDnMemberActive").''; $arraylist=array(); $arraylist['0']=$langs->trans("No"); @@ -157,6 +156,18 @@ if (! empty($conf->adherent->enabled)) print ''.$langs->trans("LDAPDnMemberActiveExample").''; } +// Synchro member type active +if (! empty($conf->adherent->enabled)) +{ + print ''.$langs->trans("LDAPDnMemberTypeActive").''; + $arraylist=array(); + $arraylist['0']=$langs->trans("No"); + $arraylist['1']=$langs->trans("DolibarrToLDAP"); + $arraylist['ldap2dolibarr']=$langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; + print $form->selectarray('activememberstypes',$arraylist,$conf->global->LDAP_MEMBER_TYPE_ACTIVE); + print ''.$langs->trans("LDAPDnMemberTypeActiveExample").''; +} + // Fields from hook $parameters=array(); $reshook=$hookmanager->executeHooks('addAdminLdapOptions',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index fc68d815439..d431a7aaf30 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -220,8 +220,9 @@ if (function_exists("ldap_connect")) $dn=$object->_load_ldap_dn($info); // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } $result1=$ldap->delete($dn); // To be sure to delete existing records $result2=$ldap->add($dn,$info,$user); // Now the test diff --git a/htdocs/admin/ldap_members_types.php b/htdocs/admin/ldap_members_types.php new file mode 100644 index 00000000000..47286dc98da --- /dev/null +++ b/htdocs/admin/ldap_members_types.php @@ -0,0 +1,252 @@ + + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2006-2011 Laurent Destailleur + * Copyright (C) 2011-2013 Juanjo Menent + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/ldap_members_types.php + * \ingroup ldap + * \brief Page to setup LDAP synchronization for members types + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; +require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php'; + +$langs->load("admin"); +$langs->load("errors"); + +if (!$user->admin) + accessforbidden(); + +$action = GETPOST('action','aZ09'); + + +/* + * Actions + */ + +if ($action == 'setvalue' && $user->admin) +{ + $error=0; + $db->begin(); + + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_DN',GETPOST("membertype"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_OBJECT_CLASS',GETPOST("objectclass"),'chaine',0,'',$conf->entity)) $error++; + + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_FULLNAME',GETPOST("fieldfullname"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_DESCRIPTION',GETPOST("fielddescription"),'chaine',0,'',$conf->entity)) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS',GETPOST("fieldmembertypemembers"),'chaine',0,'',$conf->entity)) $error++; + + // This one must be after the others + $valkey=''; + $key=GETPOST("key"); + if ($key) $valkey=$conf->global->$key; + if (! dolibarr_set_const($db, 'LDAP_KEY_MEMBERS_TYPES',$valkey,'chaine',0,'',$conf->entity)) $error++; + + if (! $error) + { + $db->commit(); + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + dol_print_error($db); + } +} + + + +/* + * View + */ + +llxHeader('',$langs->trans("LDAPSetup"),'EN:Module_LDAP_En|FR:Module_LDAP|ES:Módulo_LDAP'); +$linkback=''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans("LDAPSetup"),$linkback,'title_setup'); + +$head = ldap_prepare_head(); + +// Test si fonction LDAP actives +if (! function_exists("ldap_connect")) +{ + setEventMessages($langs->trans("LDAPFunctionsNotAvailableOnPHP"), null, 'errors'); +} + +dol_fiche_head($head, 'memberstypes', $langs->trans("LDAPSetup"), -1); + + +print $langs->trans("LDAPDescMembersTypes").'
'; +print '
'; + + +print '
'; +print ''; + +$form=new Form($db); + +print ''; +$var=true; + +print ''; +print ''; +print "\n"; + +// DN pour les types de membres + +print ''; +print ''; +print ''; + +// List of object class used to define attributes in structure + +print ''; +print ''; +print ''; + +print '
'.$langs->trans("LDAPSynchronizeMembersTypes").'
'.$langs->trans("LDAPMemberTypeDn").''; +print ''; +print ''.$langs->trans("LDAPMemberTypepDnExample").' 
'.$langs->trans("LDAPMemberTypeObjectClassList").''; +print ''; +print ''.$langs->trans("LDAPMemberTypeObjectClassListExample").' 
'; +print '
'; +print ''; +$var=true; + +print ''; +print ''; +print ''; +print ''; +print "\n"; + +// Filtre + +// Common name + +print ''; +print '"; +print ''; + +// Description + +print ''; +print '"; +print ''; + +// User group + +print ''; +print '"; +print ''; + +print '
'.$langs->trans("LDAPDolibarrMapping").''.$langs->trans("LDAPLdapMapping").''.$langs->trans("LDAPNamingAttribute").'
'.$langs->trans("LDAPFieldName").''; +print ''; +print ''.$langs->trans("LDAPFieldCommonNameExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBERS_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME)?' checked':'').">
'.$langs->trans("LDAPFieldDescription").''; +print ''; +print ''.$langs->trans("LDAPFieldDescriptionExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBER_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION)?' checked':'').">
'.$langs->trans("LDAPFieldGroupMembers").''; +print ''; +print ''.$langs->trans("LDAPFieldGroupMembersExample").'global->LDAP_KEY_MEMBERS_TYPES && $conf->global->LDAP_KEY_MEMBERS_TYPES==$conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)?' checked':'').">
'; + +print info_admin($langs->trans("LDAPDescValues")); + +dol_fiche_end(); + +print '
'; + +print '
'; + + +/* + * Test de la connexion + */ +if ($conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') +{ + $butlabel=$langs->trans("LDAPTestSynchroMemberType"); + $testlabel='testmembertype'; + $key=$conf->global->LDAP_KEY_MEMBERS_TYPES; + $dn=$conf->global->LDAP_MEMBER_TYPE_DN; + $objectclass=$conf->global->LDAP_MEMBER_TYPE_OBJECT_CLASS; + + show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass); +} + +if (function_exists("ldap_connect")) +{ + if ($_GET["action"] == 'testmembertype') + { + // Creation objet + $object=new AdherentType($db); + $object->initAsSpecimen(); + + // Test synchro + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPES'); + } + + $result1=$ldap->delete($dn); // To be sure to delete existing records + $result2=$ldap->add($dn,$info,$user); // Now the test + $result3=$ldap->delete($dn); // Clean what we did + + if ($result2 > 0) + { + print img_picto('','info').' '; + print ''.$langs->trans("LDAPSynchroOK").'
'; + } + else + { + print img_picto('','error').' '; + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ': '.$ldap->error; + print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; + } + + print "
\n"; + print "LDAP input file used for test:

\n"; + print nl2br($ldap->dump_content($dn,$info)); + print "\n
"; + } + else + { + print img_picto('','error').' '; + print ''.$langs->trans("LDAPSynchroKO"); + print ': '.$ldap->error; + print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; + } + } +} + +llxFooter(); +$db->close(); diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index c9b8120bd0f..755440a47fd 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -78,6 +78,9 @@ $offset = $listlimit * $page ; $pageprev = $page - 1; $pagenext = $page + 1; +if (empty($sortfield)) $sortfield='label, lang, position'; +if (empty($sortorder)) $sortorder='ASC'; + // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('emailtemplates')); @@ -87,7 +90,7 @@ $tabname[25]= MAIN_DB_PREFIX."c_email_templates"; // Criteria to sort dictionaries $tabsqlsort=array(); -$tabsqlsort[25]="label ASC"; +$tabsqlsort[25]="label ASC, lang ASC, position ASC"; // Nom des champs en resultat de select pour affichage du dictionnaire $tabfield=array(); @@ -122,17 +125,30 @@ $formmail=new FormMail($db); if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $tmp=FormMail::getAvailableSubstitKey('formemail'); - $tmp['__(AnyTranslationKey)__']='__(AnyTranslationKey)__'; - $helpsubstit = $langs->trans("AvailableVariables").':
'.implode('
', $tmp); - $helpsubstitforlines = $langs->trans("AvailableVariables").':
'.implode('
', $tmp); + $tmp['__(AnyTranslationKey)__']='Translation'; + $helpsubstit = $langs->trans("AvailableVariables").':
'; + $helpsubstitforlines = $langs->trans("AvailableVariables").':
'; + foreach($tmp as $key => $val) + { + $helpsubstit.=$key.' -> '.$val.'
'; + $helpsubstitforlines.=$key.' -> '.$val.'
'; + } } else { $tmp=FormMail::getAvailableSubstitKey('formemailwithlines'); - $tmp['__(AnyTranslationKey)__']='__(AnyTranslationKey)__'; - $helpsubstit = $langs->trans("AvailableVariables").':
'.implode('
', $tmp); + $tmp['__(AnyTranslationKey)__']='Translation'; + $helpsubstit = $langs->trans("AvailableVariables").':
'; + $helpsubstitforlines = $langs->trans("AvailableVariables").':
'; + foreach($tmp as $key => $val) + { + $helpsubstit.=$key.' -> '.$val.'
'; + } $tmp=FormMail::getAvailableSubstitKey('formemailforlines'); - $helpsubstitforlines = $langs->trans("AvailableVariables").':
'.implode('
', $tmp); + foreach($tmp as $key => $val) + { + $helpsubstitforlines.=$key.' -> '.$val.'
'; + } } @@ -159,8 +175,9 @@ if ($conf->supplier_proposal->enabled) $elementList['supplier_proposal_send']=$l if ($conf->fournisseur->enabled) $elementList['order_supplier_send']=$langs->trans('MailToSendSupplierOrder'); if ($conf->fournisseur->enabled) $elementList['invoice_supplier_send']=$langs->trans('MailToSendSupplierInvoice'); if ($conf->societe->enabled) $elementList['thirdparty']=$langs->trans('MailToThirdparty'); +if ($conf->adherent->enabled) $elementList['member']=$langs->trans('MailToMember'); if ($conf->contrat->enabled) $elementList['contract']=$langs->trans('MailToSendContract'); -$elementList['all']=$langs->trans('VisibleEverywhere'); +$elementList['all'] =$langs->trans('VisibleEverywhere'); $elementList['none']=$langs->trans('VisibleNowhere'); @@ -217,7 +234,7 @@ if (empty($reshook)) if ($value == 'content') $value='content-'.$rowid; if ($value == 'content_lines') $value='content_lines-'.$rowid; - if ((! isset($_POST[$value]) || $_POST[$value]=='' || $_POST[$value]=='-1') && $value != 'lang' && $value != 'fk_user') + if ((! isset($_POST[$value]) || $_POST[$value]=='' || $_POST[$value]=='-1') && $value != 'lang' && $value != 'fk_user' && $value != 'position') { $ok=0; $fieldnamekey=$listfield[$f]; @@ -270,16 +287,15 @@ if (empty($reshook)) $i=0; foreach ($listfieldinsert as $f => $value) { + //var_dump($i.' - '.$listfieldvalue[$i].' - '.$_POST[$listfieldvalue[$i]].' - '.$value); $keycode=$listfieldvalue[$i]; if ($value == 'lang') $keycode='langcode'; - - //var_dump($i.' - '.$listfieldvalue[$i].' - '.$_POST[$listfieldvalue[$i]].' - '.$value); if ($value == 'entity') $_POST[$keycode] = $conf->entity; if ($i) $sql.=","; if ($value == 'fk_user' && ! ($_POST[$keycode] > 0)) $_POST[$keycode]=''; if ($value == 'private' && ! is_numeric($_POST[$keycode])) $_POST[$keycode]='0'; if ($value == 'position' && ! is_numeric($_POST[$keycode])) $_POST[$keycode]='1'; - if ($_POST[$keycode] == '' || ($keycode == 'langcode' && empty($_POST[$keycode]))) $sql.="null"; // For vat, we want/accept code = '' + if ($_POST[$keycode] == '' && $keycode != 'langcode') $sql.="null"; // lang must be '' if not defined so the unique key that include lang will work else $sql.="'".$db->escape($_POST[$keycode])."'"; $i++; } @@ -469,7 +485,7 @@ if (! $user->admin) } if (empty($conf->global->MAIN_MULTILANGS)) { - $sql.= " AND (lang = '".$langs->defaultlang."' OR lang IS NULL)"; + $sql.= " AND (lang = '".$langs->defaultlang."' OR lang IS NULL OR lang = '')"; } if ($search_label) $sql.=natural_search('label', $search_label); if ($search_type_template != '' && $search_type_template != '-1') $sql.=natural_search('type_template', $search_type_template); @@ -520,7 +536,7 @@ foreach ($fieldlist as $field => $value) $valuetoshow=$langs->trans($valuetoshow); // try to translate $align="left"; if ($fieldlist[$field]=='fk_user') { $valuetoshow=$langs->trans("Owner");} - if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } + if ($fieldlist[$field]=='lang') { $valuetoshow=(empty($conf->global->MAIN_MULTILANGS) ? ' ' : $langs->trans("Language")); } if ($fieldlist[$field]=='type') { $valuetoshow=$langs->trans("Type"); } if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') { $valuetoshow=$langs->trans("Label"); } @@ -573,7 +589,7 @@ $errors = $hookmanager->errors; if (empty($reshook)) { - if ($tabname[$id] == MAIN_DB_PREFIX . 'c_email_templates' && $action == 'edit') { + if ($action == 'edit') { fieldList($fieldlist, $obj, $tabname[$id], 'hide'); } else { fieldList($fieldlist, $obj, $tabname[$id], 'add'); @@ -681,6 +697,10 @@ if ($resql) print ''; } elseif ($value == 'topic') print ''; + elseif ($value == 'type_template') + { + print ''.$form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100onsmartphone').''; + } elseif (! in_array($value, array('content', 'content_lines'))) print ''; } if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) print ''; @@ -829,6 +849,8 @@ if ($resql) if ($value == 'private') { $align="center"; + if ($valuetoshow) $valuetoshow=yn($valuetoshow); + else $valuetoshow=''; } if ($value == 'position') { @@ -1032,9 +1054,17 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $size='size="2" '; print ''; - if ($fieldlist[$field]=='private' && empty($user->admin)) + if ($fieldlist[$field]=='private') { - print ''; + if (empty($user->admin)) + { + print $form->selectyesno($fieldlist[$field], '1', 1); + } + else + { + //print ''; + print $form->selectyesno($fieldlist[$field], (isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), 1); + } } else { diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 6b7d839592c..06f7af5b8d6 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -254,7 +254,7 @@ if ($action == 'reset' && $user->admin) $form = new Form($db); -$morejs = array("/admin/dolistore/js/dolistore.js.php"); +//$morejs = array("/admin/dolistore/js/dolistore.js.php"); $morecss = array("/admin/dolistore/css/dolistore.css"); // Set dir where external modules are installed diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index 88a91feb083..52ac09074f3 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -78,23 +78,35 @@ if (preg_match('/del_(.*)/',$action,$reg)) if ($action == 'add_currency') { + $error=0; + $langs->loadCacheCurrencies(''); $code = GETPOST('code', 'alpha'); - $rate = GETPOST('rate', 'alpha'); + $rate = price2num(GETPOST('rate', 'alpha')); $currency = new MultiCurrency($db); $currency->code = $code; $currency->name = !empty($langs->cache_currencies[$code]['label']) ? $langs->cache_currencies[$code]['label'].' ('.$langs->getCurrencySymbol($code).')' : $code; - if ($currency->create($user) > 0) + if (empty($rate)) { - if ($currency->addRate($rate)) setEventMessages($langs->trans('RecordSaved'), array()); - else setEventMessages($langs->trans('ErrorAddRateFail'), array(), 'errors'); + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Rate")), null, 'errors'); + $error++; + } + if (! $error) + { + if ($currency->create($user) > 0) + { + if ($currency->addRate($rate)) setEventMessages($langs->trans('RecordSaved'), array()); + else setEventMessages($langs->trans('ErrorAddRateFail'), array(), 'errors'); + } + else setEventMessages($langs->trans('ErrorAddCurrencyFail'), $currency->errors, 'errors'); } - else setEventMessages($langs->trans('ErrorAddCurrencyFail'), $currency->errors, 'errors'); } elseif ($action == 'update_currency') { + $error = 0; + $submit = GETPOST('submit', 'alpha'); if ($submit == $langs->trans('Modify')) @@ -103,9 +115,17 @@ elseif ($action == 'update_currency') $rate = price2num(GETPOST('rate', 'alpha')); $currency = new MultiCurrency($db); - if ($currency->fetch($fk_multicurrency) > 0) + if (empty($rate)) { - $currency->updateRate($rate); + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Rate")), null, 'errors'); + $error++; + } + if (! $error) + { + if ($currency->fetch($fk_multicurrency) > 0) + { + $currency->updateRate($rate); + } } } elseif ($submit == $langs->trans('Delete')) @@ -279,7 +299,6 @@ if (!empty($conf->global->MAIN_MULTICURRENCY_ALLOW_SYNCHRONIZATION)) print ''; print ''; - print ''; print ''.$langs->transnoentitiesnoconv("multicurrency_alternateCurrencySource").''; print ' '; @@ -325,8 +344,7 @@ print ''; foreach ($TCurrency as &$currency) { - if($currency->code == $conf->currency) continue; - + if ($currency->code == $conf->currency) continue; print ''; print ''.$currency->code.' - '.$currency->name.''; diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index f7e18851306..a2f0a4b5346 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -45,6 +45,10 @@ if($action) { $db->begin(); + if ($action == 'STOCK_SUPPORTS_SERVICES') + { + $res = dolibarr_set_const($db, "STOCK_SUPPORTS_SERVICES", GETPOST('STOCK_SUPPORTS_SERVICES','alpha'),'chaine',0,'',$conf->entity); + } if ($action == 'STOCK_USERSTOCK_AUTOCREATE') { $res = dolibarr_set_const($db, "STOCK_USERSTOCK_AUTOCREATE", GETPOST('STOCK_USERSTOCK_AUTOCREATE','alpha'),'chaine',0,'',$conf->entity); @@ -164,8 +168,8 @@ $found=0; print ''; -print ''.$langs->trans("DeStockOnBill").''; -print ''; +print ''.$langs->trans("DeStockOnBill").''; +print ''; if (! empty($conf->facture->enabled)) { print "
"; @@ -184,8 +188,8 @@ $found++; print ''; -print ''.$langs->trans("DeStockOnValidateOrder").''; -print ''; +print ''.$langs->trans("DeStockOnValidateOrder").''; +print ''; if (! empty($conf->commande->enabled)) { print ""; @@ -206,8 +210,8 @@ $found++; //{ print ''; -print ''.$langs->trans("DeStockOnShipment").''; -print ''; +print ''.$langs->trans("DeStockOnShipment").''; +print ''; if (! empty($conf->expedition->enabled)) { print ""; @@ -226,8 +230,8 @@ $found++; print ''; -print ''.$langs->trans("DeStockOnShipmentOnClosing").''; -print ''; +print ''.$langs->trans("DeStockOnShipmentOnClosing").''; +print ''; if (! empty($conf->expedition->enabled)) { print ""; @@ -268,8 +272,8 @@ $found=0; print ''; -print ''.$langs->trans("ReStockOnBill").''; -print ''; +print ''.$langs->trans("ReStockOnBill").''; +print ''; if (! empty($conf->fournisseur->enabled)) { print ""; @@ -289,8 +293,8 @@ $found++; print ''; -print ''.$langs->trans("ReStockOnValidateOrder").''; -print ''; +print ''.$langs->trans("ReStockOnValidateOrder").''; +print ''; if (! empty($conf->fournisseur->enabled)) { print ""; @@ -309,8 +313,8 @@ $found++; print ''; -print ''.$langs->trans("ReStockOnDispatchOrder").''; -print ''; +print ''.$langs->trans("ReStockOnDispatchOrder").''; +print ''; if (! empty($conf->fournisseur->enabled)) { print ""; @@ -346,8 +350,8 @@ print ''."\n"; print ''; -print ''.$langs->trans("WarehouseAllowNegativeTransfer").''; -print ''; +print ''.$langs->trans("WarehouseAllowNegativeTransfer").''; +print ''; print ""; print ''; print ""; @@ -361,8 +365,8 @@ print "\n"; if($conf->invoice->enabled) { $var = !$var; print ''; - print ''.$langs->trans("StockMustBeEnoughForInvoice").''; - print ''; + print ''.$langs->trans("StockMustBeEnoughForInvoice").''; + print ''; print ""; print ''; print ""; @@ -376,8 +380,8 @@ if($conf->invoice->enabled) { if($conf->order->enabled) { $var = !$var; print ''; - print ''.$langs->trans("StockMustBeEnoughForOrder").''; - print ''; + print ''.$langs->trans("StockMustBeEnoughForOrder").''; + print ''; print ""; print ''; print ""; @@ -391,8 +395,8 @@ if($conf->order->enabled) { if($conf->expedition->enabled) { $var = !$var; print ''; - print ''.$langs->trans("StockMustBeEnoughForShipment").''; - print ''; + print ''.$langs->trans("StockMustBeEnoughForShipment").''; + print ''; print ""; print ''; print ""; @@ -404,6 +408,9 @@ if($conf->expedition->enabled) { } print ''; + +print '
'; + $virtualdiffersfromphysical=0; if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) @@ -411,7 +418,6 @@ if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) if ($virtualdiffersfromphysical) { - print '
'; print ''; print ''; print " \n"; @@ -419,8 +425,8 @@ if ($virtualdiffersfromphysical) print ''."\n"; $var = !$var; print ''; - print ''; - print ''; + print '\n"; print "\n"; print '
".$langs->trans("RuleForStockReplenishment")." ".img_help('help',$langs->trans("VirtualDiffersFromPhysical"))."
'.$langs->trans("UseVirtualStockByDefault").''; + print ''.$langs->trans("UseVirtualStockByDefault").''; print ""; print ''; print ""; @@ -430,9 +436,70 @@ if ($virtualdiffersfromphysical) print "
'; + print '
'; } +print ''; + +print ''; +print " \n"; +print " \n"; +print ''."\n"; + +print ''; +print ''; +print '\n"; +print "\n"; + +print ''; +print ''; +print '\n"; +print "\n"; + +print ''; +print ''; +print '\n"; +print "\n"; + +if (! empty($conf->fournisseur->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) { + + print ''; + print ''; + print '\n\n"; +} + +print '
".$langs->trans("Other")." 
'.$langs->trans("UserWarehouseAutoCreate").''; +print ""; +print ''; +print ""; +print $form->selectyesno("STOCK_USERSTOCK_AUTOCREATE",$conf->global->STOCK_USERSTOCK_AUTOCREATE,1); +print ''; +print ''; +print "
'; +print $form->textwithpicto($langs->trans("StockSupportServices"), $langs->trans("StockSupportServicesDesc")).''; +print "
"; +print ''; +print ""; +print $form->selectyesno("STOCK_SUPPORTS_SERVICES",$conf->global->STOCK_SUPPORTS_SERVICES,1); +print ''; +print '
'; +print "
'.$langs->trans("AllowAddLimitStockByWarehouse").''; +print "
"; +print ''; +print ""; +print $form->selectyesno("STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE",$conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE,1); +print ''; +print '
'; +print "
'.$langs->trans("UseDispatchStatus").''; + print "
"; + print ''; + print ""; + print $form->selectyesno("SUPPLIER_ORDER_USE_DISPATCH_STATUS",$conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS,1); + print ''; + print "
\n"; + print "
'; + print '
'; if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { @@ -484,54 +551,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) print ''; } -print ''; - -print ''; -print " \n"; -print " \n"; -print ''."\n"; - -if (! empty($conf->fournisseur->enabled) && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) { - - print ''; - print ''; - print '\n\n"; -} - -print ''; -print ''; -print '\n"; -print "\n"; - -print ''; -print ''; - -print '\n"; -print "\n"; - -print '
'; - /* I keep the option/feature, but hidden to end users for the moment. If feature is used by module, no need to have users see it. If not used by a module, I still need to understand in which case user may need this now we can set rule on product page. if ($conf->global->PRODUIT_SOUSPRODUITS) @@ -539,9 +558,8 @@ if ($conf->global->PRODUIT_SOUSPRODUITS) print ''; - print ''; - - print ''; + print '
".$langs->trans("Other")." 
'.$langs->trans("UseDispatchStatus").''; - print "
"; - print ''; - print ""; - print $form->selectyesno("SUPPLIER_ORDER_USE_DISPATCH_STATUS",$conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS,1); - print ''; - print "
\n"; - print "
'.$langs->trans("UserWarehouseAutoCreate").''; -print "
"; -print ''; -print ""; -print $form->selectyesno("STOCK_USERSTOCK_AUTOCREATE",$conf->global->STOCK_USERSTOCK_AUTOCREATE,1); -print ''; -print '
'; -print "
'.$langs->trans("AllowAddLimitStockByWarehouse").''; -print "
"; -print ''; -print ""; -print $form->selectyesno("STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE",$conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE,1); -print ''; -print '
'; -print "
'.$langs->trans("IndependantSubProductStock").''; + print ''.$langs->trans("IndependantSubProductStock").''; print "
"; print ''; print ""; @@ -553,8 +571,6 @@ if ($conf->global->PRODUIT_SOUSPRODUITS) } */ -print '
'; - llxFooter(); diff --git a/htdocs/admin/system/perf.php b/htdocs/admin/system/perf.php index 25079d8f185..3a8e1e42bf4 100644 --- a/htdocs/admin/system/perf.php +++ b/htdocs/admin/system/perf.php @@ -336,7 +336,7 @@ jQuery(document).ready(function() { var compjsphpstring; getjsphpurl = $.ajax({ type: "GET", - url: \''.DOL_URL_ROOT.'/core/js/datepicker.js.php\', + url: \''.DOL_URL_ROOT.'/core/js/lib_head.js.php\', cache: false, /* async: false, */ /* crossDomain: true,*/ diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index 218ab58467e..d912c2e40df 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -77,6 +77,8 @@ if ($action == 'setproductionmode') } } +dol_mkdir(DOL_DATA_ROOT.'/api/temp'); // May have been deleted by a purge + /* * View @@ -128,7 +130,7 @@ $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain // Show message $message=''; -$url=$urlwithroot.'/api/index.php/login?login=auserlogin&userpassword=thepassword[&reset=1]'; +$url=$urlwithroot.'/api/index.php/login?login=auserlogin&password=thepassword[&reset=1]'; $message.=$langs->trans("UrlToGetKeyToUseAPIs").':
'; $message.=img_picto('','object_globe.png').' '.$url; print $message; diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 40e00d01ffd..dcda8255e7c 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -48,7 +48,7 @@ class DolibarrApi */ function __construct($db, $cachedir='', $refreshCache=false) { - global $conf; + global $conf, $dolibarr_main_url_root; if (empty($cachedir)) $cachedir = $conf->api->dir_temp; Defaults::$cacheDirectory = $cachedir; @@ -56,7 +56,9 @@ class DolibarrApi $this->db = $db; $production_mode = ( empty($conf->global->API_PRODUCTION_MODE) ? false : true ); $this->r = new Restler($production_mode, $refreshCache); - + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + $this->r->setBaseUrls(DOL_MAIN_URL_ROOT, $urlwithroot); $this->r->setAPIVersion(1); } diff --git a/htdocs/api/class/api_dictionary.class.php b/htdocs/api/class/api_dictionary.class.php new file mode 100644 index 00000000000..b0d5bb00b0a --- /dev/null +++ b/htdocs/api/class/api_dictionary.class.php @@ -0,0 +1,519 @@ + + * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2017 Regis Houssin + * Copyright (C) 2017 Neil Orley + * + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +use Luracast\Restler\RestException; + +require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; + +/** + * API class for dictionaries + * + * @access protected + * @class DolibarrApiAccess {@requires user,external} + */ +class Dictionary extends DolibarrApi +{ + private $translations = null; + + /** + * Constructor + */ + function __construct() + { + global $db; + $this->db = $db; + } + + /** + * Get the list of payments types. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number {@min 0} + * @param int $active Payment type is active or not {@min 0} {@max 1} + * @param string $sqlfilters SQL criteria to filter with. Syntax example "(t.code:=:'CHQ')" + * + * @url GET payment/types + * + * @return array [List of payment types] + * + * @throws 400 RestException + * @throws 200 OK + */ + function getPaymentTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT id, code, type, libelle as label, module"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_paiement as t"; + $sql.= " WHERE t.active = ".$active; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(400, 'error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(400, $this->db->lasterror()); + } + + return $list; + } + + /** + * Get the list of countries. + * + * The names of the countries will be translated to the given language if + * the $lang parameter is provided. The value of $lang must be a language + * code supported by Dolibarr, for example 'en_US' or 'fr_FR'. + * The returned list is sorted by country ID. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $filter To filter the countries by name + * @param string $lang Code of the language the label of the countries must be translated to + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of countries + * + * @url GET countries + * + * @throws RestException + */ + function getListOfCountries($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '') + { + $list = array(); + + // Note: The filter is not applied in the SQL request because it must + // be applied to the translated names, not to the names in database. + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t"; + $sql.=" WHERE 1 = 1"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $obj = $this->db->fetch_object($result); + $country = new Ccountry($this->db); + if ($country->fetch($obj->rowid) > 0) { + // Translate the name of the country if needed + // and then apply the filter if there is one. + $this->translateLabel($country, $lang); + + if (empty($filter) || stripos($country->label, $filter) !== FALSE) { + $list[] = $this->_cleanObjectDatas($country); + } + } + } + } else { + throw new RestException(503, 'Error when retrieving list of countries : '.$country->error); + } + + return $list; + } + + /** + * Get country by ID. + * + * @param int $id ID of country + * @param string $lang Code of the language the name of the + * country must be translated to + * + * @url GET countries/{id} + * + * @throws RestException + */ + function getCountryByID($id, $lang = '') + { + $country = new Ccountry($this->db); + + if ($country->fetch($id) < 0) { + throw new RestException(503, 'Error when retrieving country : '.$country->error); + } + else if ($country->fetch($id) == 0) { + throw new RestException(404, 'country not found'); + } + + $this->translateLabel($country, $lang); + + return $this->_cleanObjectDatas($country); + } + + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) + { + $object = parent::_cleanObjectDatas($object); + + unset($object->error); + unset($object->errors); + + return $object; + } + + /** + * Translate the name of the country to the given language. + * + * @param Ccountry $country Country + * @param string $lang Code of the language the name of the + * country must be translated to + */ + private function translateLabel($country, $lang) + { + if (!empty($lang)) { + // Load the translations if this is a new language. + if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) { + global $conf; + $this->translations = new Translate('', $conf); + $this->translations->setDefaultLang($lang); + $this->translations->load('dict'); + } + if ($country->code) { + $key = 'Country'.$country->code; + $translation = $this->translations->trans($key); + if ($translation != $key) { + $country->label = html_entity_decode($translation); + } + } + } + } + + /** + * Get the list of events types. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $type To filter on type of event + * @param string $module To filter on module events + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of events types + * + * @url GET events + * + * @throws RestException + */ + function getListOfEvents($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT id, code, type, libelle as label, module"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t"; + $sql.= " WHERE t.active = 1"; + if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'"; + if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror()); + } + + return $list; + } + + + /** + * Get the list of extra fields. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param string $type Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...) + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%')" + * @return List of events types + * + * @url GET extrafields + * + * @throws RestException + */ + function getListOfExtrafields($sortfield = "t.pos", $sortorder = 'ASC', $type = '', $sqlfilters = '') + { + $list = array(); + + if ($type == 'thirdparty') $type='societe'; + if ($type == 'contact') $type='socpeople'; + + $sql = "SELECT t.rowid, t.name, t.label, t.type, t.size, t.elementtype, t.fieldunique, t.fieldrequired, t.param, t.pos, t.alwayseditable, t.perms, t.list, t.ishidden, t.fielddefault, t.fieldcomputed"; + $sql.= " FROM ".MAIN_DB_PREFIX."extrafields as t"; + $sql.= " WHERE t.entity IN (".getEntity('extrafields').")"; + if (! empty($type)) $sql.= " AND t.elementtype = '".$this->db->escape($type)."'"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql.= $this->db->order($sortfield, $sortorder); + + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + while ($tab = $this->db->fetch_object($resql)) + { + // New usage + $list[$tab->elementtype][$tab->name]['type']=$tab->type; + $list[$tab->elementtype][$tab->name]['label']=$tab->label; + $list[$tab->elementtype][$tab->name]['size']=$tab->size; + $list[$tab->elementtype][$tab->name]['elementtype']=$tab->elementtype; + $list[$tab->elementtype][$tab->name]['default']=$tab->fielddefault; + $list[$tab->elementtype][$tab->name]['computed']=$tab->fieldcomputed; + $list[$tab->elementtype][$tab->name]['unique']=$tab->fieldunique; + $list[$tab->elementtype][$tab->name]['required']=$tab->fieldrequired; + $list[$tab->elementtype][$tab->name]['param']=($tab->param ? unserialize($tab->param) : ''); + $list[$tab->elementtype][$tab->name]['pos']=$tab->pos; + $list[$tab->elementtype][$tab->name]['alwayseditable']=$tab->alwayseditable; + $list[$tab->elementtype][$tab->name]['perms']=$tab->perms; + $list[$tab->elementtype][$tab->name]['list']=$tab->list; + $list[$tab->elementtype][$tab->name]['ishidden']=$tab->ishidden; + } + } + } + else + { + throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror()); + } + + if (! count($list)) + { + throw new RestException(404, 'No extrafield found'); + } + + return $list; + } + + + /** + * Get the list of towns. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $zipcode To filter on zipcode + * @param string $town To filter on city name + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return List of towns + * + * @url GET towns + * + * @throws RestException + */ + function getListOfTowns($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown as t"; + $sql.= " WHERE t.active = 1"; + if ($zipcode) $sql.=" AND t.zip LIKE '%" . $this->db->escape($zipcode) . "%'"; + if ($town) $sql.=" AND t.town LIKE '%" . $this->db->escape($town) . "%'"; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of towns : '.$this->db->lasterror()); + } + + return $list; + } + + /** + * Get the list of payments terms. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number {@min 0} + * @param int $active Payment term is active or not {@min 0} {@max 1} + * @param string $sqlfilters SQL criteria to filter. Syntax example "(t.code:=:'CHQ')" + * + * @url GET payment/terms + * + * @return array List of payment terms + * + * @throws 400 RestException + * @throws 200 OK + */ + function getPaymentTerms($sortfield = "sortorder", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT rowid as id, code, sortorder, libelle as label, libelle_facture as descr, type_cdr, nbjour, decalage, module"; + $sql.= " FROM ".MAIN_DB_PREFIX."c_payment_term as t"; + $sql.= " WHERE t.active = ".$active; + // Add sql filters + if ($sqlfilters) + { + if (! DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(400, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql.= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(400, $this->db->lasterror()); + } + + return $list; + } + +} diff --git a/htdocs/api/class/api_dictionarycountries.class.php b/htdocs/api/class/api_dictionarycountries.class.php deleted file mode 100644 index 070be509a8a..00000000000 --- a/htdocs/api/class/api_dictionarycountries.class.php +++ /dev/null @@ -1,184 +0,0 @@ - - * Copyright (C) 2016 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; - -/** - * API class for countries - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryCountries extends DolibarrApi -{ - private $translations = null; - - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of countries. - * - * The names of the countries will be translated to the given language if - * the $lang parameter is provided. The value of $lang must be a language - * code supported by Dolibarr, for example 'en_US' or 'fr_FR'. - * The returned list is sorted by country ID. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Number of items per page - * @param int $page Page number (starting from zero) - * @param string $filter To filter the countries by name - * @param string $lang Code of the language the label of the countries must be translated to - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of countries - * - * @throws RestException - */ - function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $lang = '', $sqlfilters = '') - { - $list = array(); - - // Note: The filter is not applied in the SQL request because it must - // be applied to the translated names, not to the names in database. - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_country as t"; - $sql.=" WHERE 1 = 1"; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - $sql.= $this->db->order($sortfield, $sortorder); - - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit, $offset); - } - - $result = $this->db->query($sql); - - if ($result) { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - for ($i = 0; $i < $min; $i++) { - $obj = $this->db->fetch_object($result); - $country = new Ccountry($this->db); - if ($country->fetch($obj->rowid) > 0) { - // Translate the name of the country if needed - // and then apply the filter if there is one. - $this->translateLabel($country, $lang); - - if (empty($filter) || stripos($country->label, $filter) !== FALSE) { - $list[] = $this->_cleanObjectDatas($country); - } - } - } - } else { - throw new RestException(503, 'Error when retrieving list of countries : '.$country->error); - } - - return $list; - } - - /** - * Get country by ID. - * - * @param int $id ID of country - * @param string $lang Code of the language the name of the - * country must be translated to - * - * @throws RestException - */ - function get($id, $lang = '') - { - $country = new Ccountry($this->db); - - if ($country->fetch($id) < 0) { - throw new RestException(503, 'Error when retrieving country : '.$country->error); - } - else if ($country->fetch($id) == 0) { - throw new RestException(404, 'country not found'); - } - - $this->translateLabel($country, $lang); - - return $this->_cleanObjectDatas($country); - } - - /** - * Clean sensible object datas - * - * @param object $object Object to clean - * @return array Array of cleaned object properties - */ - function _cleanObjectDatas($object) - { - $object = parent::_cleanObjectDatas($object); - - unset($object->error); - unset($object->errors); - - return $object; - } - - /** - * Translate the name of the country to the given language. - * - * @param Ccountry $country Country - * @param string $lang Code of the language the name of the - * country must be translated to - */ - private function translateLabel($country, $lang) - { - if (!empty($lang)) { - // Load the translations if this is a new language. - if ($this->translations == null || $this->translations->getDefaultLang() !== $lang) { - global $conf; - $this->translations = new Translate('', $conf); - $this->translations->setDefaultLang($lang); - $this->translations->load('dict'); - } - if ($country->code) { - $key = 'Country'.$country->code; - $translation = $this->translations->trans($key); - if ($translation != $key) { - $country->label = html_entity_decode($translation); - } - } - } - } -} diff --git a/htdocs/api/class/api_dictionaryevents.class.php b/htdocs/api/class/api_dictionaryevents.class.php deleted file mode 100644 index 23d7e8e5dba..00000000000 --- a/htdocs/api/class/api_dictionaryevents.class.php +++ /dev/null @@ -1,100 +0,0 @@ - - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; - -/** - * API class for events type (content of the actioncomm dictionary) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryEvents extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of events types. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Number of items per page - * @param int $page Page number (starting from zero) - * @param string $type To filter on type of event - * @param string $module To filter on module events - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of events types - * - * @throws RestException - */ - function index($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '') - { - $list = array(); - - $sql = "SELECT id, code, type, libelle as label, module"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_actioncomm as t"; - $sql.= " WHERE t.active = 1"; - if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'"; - if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'"; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - - $sql.= $this->db->order($sortfield, $sortorder); - - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit, $offset); - } - - $result = $this->db->query($sql); - - if ($result) { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - for ($i = 0; $i < $min; $i++) { - $list[] = $this->db->fetch_object($result); - } - } else { - throw new RestException(503, 'Error when retrieving list of events types : '.$this->db->lasterror()); - } - - return $list; - } - -} diff --git a/htdocs/api/class/api_dictionaryextrafields.class.php b/htdocs/api/class/api_dictionaryextrafields.class.php deleted file mode 100644 index 69f574797c7..00000000000 --- a/htdocs/api/class/api_dictionaryextrafields.class.php +++ /dev/null @@ -1,112 +0,0 @@ - - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use Luracast\Restler\RestException; - -//require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; - -/** - * API class for extra fields (content of the extrafields) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryExtraFields extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of extra fields. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param string $type Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...) - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'SO-%')" - * @return List of events types - * - * @throws RestException - */ - function index($sortfield = "t.pos", $sortorder = 'ASC', $type = '', $sqlfilters = '') - { - $list = array(); - - if ($type == 'thirdparty') $type='societe'; - if ($type == 'contact') $type='socpeople'; - - $sql = "SELECT t.rowid, t.name, t.label, t.type, t.size, t.elementtype, t.fieldunique, t.fieldrequired, t.param, t.pos, t.alwayseditable, t.perms, t.list, t.ishidden, t.fielddefault, t.fieldcomputed"; - $sql.= " FROM ".MAIN_DB_PREFIX."extrafields as t"; - $sql.= " WHERE t.entity IN (".getEntity('extrafields').")"; - if (! empty($type)) $sql.= " AND t.elementtype = '".$this->db->escape($type)."'"; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - $sql.= $this->db->order($sortfield, $sortorder); - - $resql=$this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) - { - while ($tab = $this->db->fetch_object($resql)) - { - // New usage - $list[$tab->elementtype][$tab->name]['type']=$tab->type; - $list[$tab->elementtype][$tab->name]['label']=$tab->label; - $list[$tab->elementtype][$tab->name]['size']=$tab->size; - $list[$tab->elementtype][$tab->name]['elementtype']=$tab->elementtype; - $list[$tab->elementtype][$tab->name]['default']=$tab->fielddefault; - $list[$tab->elementtype][$tab->name]['computed']=$tab->fieldcomputed; - $list[$tab->elementtype][$tab->name]['unique']=$tab->fieldunique; - $list[$tab->elementtype][$tab->name]['required']=$tab->fieldrequired; - $list[$tab->elementtype][$tab->name]['param']=($tab->param ? unserialize($tab->param) : ''); - $list[$tab->elementtype][$tab->name]['pos']=$tab->pos; - $list[$tab->elementtype][$tab->name]['alwayseditable']=$tab->alwayseditable; - $list[$tab->elementtype][$tab->name]['perms']=$tab->perms; - $list[$tab->elementtype][$tab->name]['list']=$tab->list; - $list[$tab->elementtype][$tab->name]['ishidden']=$tab->ishidden; - } - } - } - else - { - throw new RestException(503, 'Error when retrieving list of extra fields : '.$this->db->lasterror()); - } - - if (! count($list)) - { - throw new RestException(404, 'No extrafield found'); - } - - return $list; - } - -} diff --git a/htdocs/api/class/api_dictionarytowns.class.php b/htdocs/api/class/api_dictionarytowns.class.php deleted file mode 100644 index 0ebcfbe0b17..00000000000 --- a/htdocs/api/class/api_dictionarytowns.class.php +++ /dev/null @@ -1,102 +0,0 @@ - - * Copyright (C) 2016 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php'; - -/** - * API class for towns (content of the ziptown dictionary) - * - * @access protected - * @class DolibarrApiAccess {@requires user,external} - */ -class DictionaryTowns extends DolibarrApi -{ - /** - * Constructor - */ - function __construct() - { - global $db; - $this->db = $db; - } - - /** - * Get the list of towns. - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Number of items per page - * @param int $page Page number (starting from zero) - * @param string $zipcode To filter on zipcode - * @param string $town To filter on city name - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return List of towns - * - * @throws RestException - */ - function index($sortfield = "zip,town", $sortorder = 'ASC', $limit = 100, $page = 0, $zipcode = '', $town = '', $sqlfilters = '') - { - $list = array(); - - $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country"; - $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown as t"; - $sql.= " WHERE t.active = 1"; - if ($zipcode) $sql.=" AND t.zip LIKE '%" . $this->db->escape($zipcode) . "%'"; - if ($town) $sql.=" AND t.town LIKE '%" . $this->db->escape($town) . "%'"; - // Add sql filters - if ($sqlfilters) - { - if (! DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - - $sql.= $this->db->order($sortfield, $sortorder); - - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit, $offset); - } - - $result = $this->db->query($sql); - - if ($result) { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - for ($i = 0; $i < $min; $i++) { - $list[] = $this->db->fetch_object($result); - } - } else { - throw new RestException(503, 'Error when retrieving list of towns : '.$this->db->lasterror()); - } - - return $list; - } - -} diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index e26486981fa..4d0efb63d62 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -22,6 +22,7 @@ use Luracast\Restler\Format\UploadFormat; require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; /** * API class for receive files @@ -54,13 +55,57 @@ class Documents extends DolibarrApi * * @param string $module_part Name of module or area concerned by file download ('facture', ...) * @param string $ref Reference of object (This will define subdir automatically) - * @param string $subdir Subdirectory (Only if ref not provided) + * @param string $subdir NOT YET AVAILABLE : Subdirectory (Only if ref not provided) * @return array List of documents * - * @throws RestException + * @throws 400 + * @throws 401 + * @throws 200 OK */ public function index($module_part, $ref='', $subdir='') { - return array('note'=>'FeatureNotYetAvailable'); + global $conf; + + if (empty($module_part)) { + throw new RestException(400, 'bad value for parameter modulepart'); + } + if (empty($ref) && empty($subdir)) { + throw new RestException(400, 'bad value for parameter ref or subdir'); + } + if (empty($ref)) { + throw new RestException(404, 'FeatureNotYetAvailable'); + } + if (!DolibarrApiAccess::$user->rights->ecm->read) { + throw new RestException(401); + } + + $original_file = str_replace("../","/", $ref.'/'.$ref.'.pdf'); + $refname=basename(dirname($original_file)."/"); + $entity=$conf->entity; + + $check_access = dol_check_secure_access_document($module_part,$original_file,$entity,DolibarrApiAccess::$user); + $accessallowed = $check_access['accessallowed']; + $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals']; + $original_file = $check_access['original_file']; + + if (preg_match('/\.\./',$original_file) || preg_match('/[<>|]/',$original_file)) + { + throw new RestException(401); + } + if (!$accessallowed) { + throw new RestException(401); + } + + + $filename = basename($original_file); + $original_file_osencoded=dol_osencode($original_file); // New file name encoded in OS encoding charset + + if (! file_exists($original_file_osencoded)) + { + throw new RestException(404, 'File not found'); + } + + $file_content=file_get_contents($original_file_osencoded); + return array('filename'=>$filename, 'content'=>base64_encode($file_content), 'encoding'=>'MIME base64 (base64_encode php function, http://php.net/manual/en/function.base64-encode.php)' ); } diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 7b1c81af59c..c8b92acd5fc 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -397,7 +397,7 @@ if ($action == 'update') $datep=dol_mktime($fulldayevent?'00':$aphour, $fulldayevent?'00':$apmin, 0, $_POST["apmonth"], $_POST["apday"], $_POST["apyear"]); $datef=dol_mktime($fulldayevent?'23':$p2hour, $fulldayevent?'59':$p2min, $fulldayevent?'59':'0', $_POST["p2month"], $_POST["p2day"], $_POST["p2year"]); - $object->fk_action = dol_getIdFromCode($db, GETPOST("actioncode"), 'c_actioncomm'); + $object->type_id = dol_getIdFromCode($db, GETPOST("actioncode"), 'c_actioncomm'); $object->label = GETPOST("label"); $object->datep = $datep; $object->datef = $datef; @@ -407,8 +407,6 @@ if ($action == 'update') $object->location = GETPOST('location'); $object->socid = GETPOST("socid"); $object->contactid = GETPOST("contactid",'int'); - //$object->societe->id = $_POST["socid"]; // deprecated - //$object->contact->id = $_POST["contactid"]; // deprecated $object->fk_project = GETPOST("projectid",'int'); $object->note = GETPOST("note"); $object->pnote = GETPOST("note"); @@ -773,9 +771,9 @@ if ($action == 'create') $events[]=array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1',1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled')); //For external user force the company to user company if (!empty($user->societe_id)) { - print $form->select_thirdparty_list($user->societe_id, 'socid', '', 1, 1, 0, $events); + print $form->select_company($user->societe_id, 'socid', '', 1, 1, 0, $events); } else { - print $form->select_thirdparty_list('', 'socid', '', 'SelectThirdParty', 1, 0, $events); + print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, $events); } } @@ -783,7 +781,7 @@ if ($action == 'create') // Related contact print ''.$langs->trans("ActionOnContact").''; - $form->select_contacts(GETPOST('socid','int'), GETPOST('contactid'), 'contactid', 1, '', '', 0, 'minwidth200'); + $form->selectcontacts(GETPOST('socid','int'), GETPOST('contactid'), 'contactid', 1, '', '', 0, 'minwidth200'); print ''; @@ -826,7 +824,7 @@ if ($action == 'create') // Description print ''.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('note',(GETPOST('note')?GETPOST('note'):$object->note),'',180,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_5,'90%'); + $doleditor=new DolEditor('note',(GETPOST('note','none')?GETPOST('note','none'):$object->note),'',180,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_5,'90%'); $doleditor->Create(); print ''; @@ -869,7 +867,7 @@ if ($id > 0) $datep=dol_mktime($fulldayevent?'00':$aphour, $fulldayevent?'00':$apmin, 0, $_POST["apmonth"], $_POST["apday"], $_POST["apyear"]); $datef=dol_mktime($fulldayevent?'23':$p2hour, $fulldayevent?'59':$p2min, $fulldayevent?'59':'0', $_POST["p2month"], $_POST["p2day"], $_POST["p2year"]); - $object->fk_action = dol_getIdFromCode($db, GETPOST("actioncode"), 'c_actioncomm'); + $object->type_id = dol_getIdFromCode($db, GETPOST("actioncode"), 'c_actioncomm'); $object->label = GETPOST("label"); $object->datep = $datep; $object->datef = $datef; @@ -879,8 +877,6 @@ if ($id > 0) $object->location = GETPOST('location'); $object->socid = GETPOST("socid"); $object->contactid = GETPOST("contactid",'int'); - //$object->societe->id = $_POST["socid"]; // deprecated - //$object->contact->id = $_POST["contactid"]; // deprecated $object->fk_project = GETPOST("projectid",'int'); $object->note = GETPOST("note"); @@ -1206,14 +1202,13 @@ if ($id > 0) // Link to other agenda views $out=''; - $out.=img_picto($langs->trans("ViewPerUser"),'object_calendarperuser','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewPerUser"),'object_calendarperuser','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewPerUser").''; - $out.='
    '; - $out.=img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewCal").''; - $out.=img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewWeek").''; - $out.=img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewDay").''; $linkback.=$out; diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 4d1f0d571e1..12c11f863f1 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -754,7 +754,7 @@ class ActionComm extends CommonObject $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm "; $sql.= " SET percent = '".$this->db->escape($this->percentage)."'"; - if ($this->fk_action > 0) $sql.= ", fk_action = '".$this->db->escape($this->fk_action)."'"; + if ($this->type_id > 0) $sql.= ", fk_action = '".$this->db->escape($this->type_id)."'"; $sql.= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'":"null"); $sql.= ", datep = ".(strval($this->datep)!='' ? "'".$this->db->idate($this->datep)."'" : 'null'); $sql.= ", datep2 = ".(strval($this->datef)!='' ? "'".$this->db->idate($this->datef)."'" : 'null'); @@ -851,7 +851,8 @@ class ActionComm extends CommonObject } /** - * Load all objects with filters + * Load all objects with filters. + * WARNING: This make a fetch on all records instead of making one request with a join. * * @param DoliDb $db Database handler * @param int $socid Filter by thirdparty @@ -906,59 +907,66 @@ class ActionComm extends CommonObject return $db->lasterror(); } } - + /** * Load indicators for dashboard (this->nbtodo and this->nbtodolate) * - * @param User $user Objet user + * @param User $user Objet user + * @param int $load_state_board Charge indicateurs this->nb de tableau de bord * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK */ - function load_board($user) + function load_board($user, $load_state_board=0) { - global $conf, $langs; - - $sql = "SELECT a.id, a.datep as dp"; - $sql.= " FROM (".MAIN_DB_PREFIX."actioncomm as a"; - $sql.= ")"; - if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; - $sql.= " WHERE a.percent >= 0 AND a.percent < 100"; - $sql.= " AND a.entity IN (".getEntity('agenda').")"; - if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= " AND (a.fk_soc IS NULL OR sc.fk_user = " .$user->id . ")"; - if ($user->societe_id) $sql.=" AND a.fk_soc = ".$user->societe_id; - if (! $user->rights->agenda->allactions->read) $sql.= " AND (a.fk_user_author = ".$user->id . " OR a.fk_user_action = ".$user->id . " OR a.fk_user_done = ".$user->id . ")"; - - $resql=$this->db->query($sql); - if ($resql) - { - $agenda_static = new ActionComm($this->db); - - $response = new WorkboardResponse(); - $response->warning_delay = $conf->agenda->warning_delay/60/60/24; - $response->label = $langs->trans("ActionsToDo"); - $response->url = DOL_URL_ROOT.'/comm/action/listactions.php?status=todo&mainmenu=agenda'; - if ($user->rights->agenda->allactions->read) $response->url.='&filtert=-1'; - $response->img = img_object('',"action",'class="inline-block valigntextmiddle"'); - - // This assignment in condition is not a bug. It allows walking the results. - while ($obj=$this->db->fetch_object($resql)) - { - $response->nbtodo++; - - $agenda_static->datep = $this->db->jdate($obj->dp); - - if ($agenda_static->hasDelay()) { - $response->nbtodolate++; - } - } - - return $response; - } - else - { - $this->error=$this->db->error(); - return -1; - } + global $conf, $langs; + + if(empty($load_state_board)) $sql = "SELECT a.id, a.datep as dp"; + else { + $this->nb=array(); + $sql = "SELECT count(a.id) as nb"; + } + $sql.= " FROM (".MAIN_DB_PREFIX."actioncomm as a"; + $sql.= ")"; + if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; + $sql.= " WHERE 1"; + if(empty($load_state_board)) $sql.= " AND a.percent >= 0 AND a.percent < 100"; + $sql.= " AND a.entity IN (".getEntity('agenda').")"; + if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= " AND (a.fk_soc IS NULL OR sc.fk_user = " .$user->id . ")"; + if ($user->societe_id) $sql.=" AND a.fk_soc = ".$user->societe_id; + if (! $user->rights->agenda->allactions->read) $sql.= " AND (a.fk_user_author = ".$user->id . " OR a.fk_user_action = ".$user->id . " OR a.fk_user_done = ".$user->id . ")"; + + $resql=$this->db->query($sql); + if ($resql) + { + if(empty($load_state_board)) { + $agenda_static = new ActionComm($this->db); + $response = new WorkboardResponse(); + $response->warning_delay = $conf->agenda->warning_delay/60/60/24; + $response->label = $langs->trans("ActionsToDo"); + $response->url = DOL_URL_ROOT.'/comm/action/listactions.php?status=todo&mainmenu=agenda'; + if ($user->rights->agenda->allactions->read) $response->url.='&filtert=-1'; + $response->img = img_object('',"action",'class="inline-block valigntextmiddle"'); + } + // This assignment in condition is not a bug. It allows walking the results. + while ($obj=$this->db->fetch_object($resql)) + { + if(empty($load_state_board)) { + $response->nbtodo++; + $agenda_static->datep = $this->db->jdate($obj->dp); + if ($agenda_static->hasDelay()) $response->nbtodolate++; + } else $this->nb["actionscomm"]=$obj->nb; + } + + $this->db->free($resql); + if(empty($load_state_board)) return $response; + else return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } } diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php index 1e54db9d449..68a36844e39 100644 --- a/htdocs/comm/action/document.php +++ b/htdocs/comm/action/document.php @@ -128,14 +128,13 @@ if ($object->id > 0) // Link to other agenda views $out=''; - $out.=img_picto($langs->trans("ViewPerUser"),'object_calendarperuser','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewPerUser"),'object_calendarperuser','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewPerUser").''; - $out.='
    '; - $out.=img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewCal").''; - $out.=img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewWeek").''; - $out.=img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewDay").''; $linkback.=$out; diff --git a/htdocs/comm/action/info.php b/htdocs/comm/action/info.php index 7bee5550453..9bcf1d2b9cd 100644 --- a/htdocs/comm/action/info.php +++ b/htdocs/comm/action/info.php @@ -51,6 +51,8 @@ $result = restrictedArea($user, 'agenda', $id, 'actioncomm&societe', 'myactions| * View */ +$form=new Form($db); + $help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda'; llxHeader('',$langs->trans("Agenda"),$help_url); @@ -66,14 +68,13 @@ $linkback.= ''.$langs->trans("B // Link to other agenda views $out=''; -$out.=img_picto($langs->trans("ViewPerUser"),'object_calendarperuser','class="hideonsmartphone pictoactionview"'); +$out.='
  • '.img_picto($langs->trans("ViewPerUser"),'object_calendarperuser','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewPerUser").''; -$out.='
    '; -$out.=img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); +$out.='
  • '.img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewCal").''; -$out.=img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); +$out.='
  • '.img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewWeek").''; -$out.=img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); +$out.='
  • '.img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewDay").''; $linkback.=$out; diff --git a/htdocs/comm/mailing/advtargetemailing.php b/htdocs/comm/mailing/advtargetemailing.php index 39d1b7c8d8d..cfafdaa725b 100644 --- a/htdocs/comm/mailing/advtargetemailing.php +++ b/htdocs/comm/mailing/advtargetemailing.php @@ -45,13 +45,13 @@ if (! empty($conf->categorie->enabled)) { if (! $user->rights->mailing->lire || $user->societe_id > 0) accessforbidden(); -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { - $page = 0; -} -$offset = $conf->liste_limit * $page; +// Load variable for pagination +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index b2b7e9cf5cf..9f67db88bbb 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -57,24 +57,17 @@ $hookmanager->initHooks(array('mailingcard','globalcard')); // Array of possible substitutions (See also file mailing-send.php that should manage same substitutions) $object->substitutionarray=FormMail::getAvailableSubstitKey('emailing'); -$object->substitutionarray['__(AnyTranslationKey)__']=$langs->trans("Translation"); -$object->substitutionarrayfortest=array( - '__ID__' => 'TESTIdRecord', - //'__EMAIL__' => 'TESTEMail', // Done into "send" action - '__LASTNAME__' => 'TESTLastname', - '__FIRSTNAME__' => 'TESTFirstname', - '__MAILTOEMAIL__' => 'TESTMailtoEmail', - '__OTHER1__' => 'TESTOther1', - '__OTHER2__' => 'TESTOther2', - '__OTHER3__' => 'TESTOther3', - '__OTHER4__' => 'TESTOther4', - '__OTHER5__' => 'TESTOther5', - '__SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))?$user->signature:''), - '__CHECK_READ__' => 'TagCheckMail', - '__UNSUBSCRIBE__' => 'TagUnsubscribe' - //,'__PERSONALIZED__' => 'TESTPersonalized' // Not used yet -); + +// Set $object->substitutionarrayfortest +$signature = ((!empty($user->signature) && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))?$user->signature:''); + +$targetobject = null; // Not defined with mass emailing + +$parameters=array('mode'=>'emailing'); +$substitutionarray=FormMail::getAvailableSubstitKey('emailing', $targetobject); + +$object->substitutionarrayfortest = $substitutionarray; // List of sending methods $listofmethods=array(); @@ -205,24 +198,28 @@ if (empty($reshook)) $tmpfield=explode('=',$other[2],2); $other3=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); $tmpfield=explode('=',$other[3],2); $other4=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); + $signature = ((!empty($user->signature) && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))?$user->signature:''); - // Array of possible substitutions (See also fie mailing-send.php that should manage same substitutions) - $substitutionarray=array( - '__ID__' => $obj->source_id, - '__EMAIL__' => $obj->email, - '__LASTNAME__' => $obj->lastname, - '__FIRSTNAME__' => $obj->firstname, - '__MAILTOEMAIL__' => ''.$obj->email.'', - '__OTHER1__' => $other1, - '__OTHER2__' => $other2, - '__OTHER3__' => $other3, - '__OTHER4__' => $other4, - '__OTHER5__' => $other5, - '__SIGNATURE__' => $signature, // Signature is empty when ran from command line or taken from user in parameter) - '__CHECK_READ__' => '', - '__UNSUBSCRIBE__' => ''.$langs->trans("MailUnsubcribe").'' - ); + $targetobject = null; // Not defined with mass emailing + $parameters=array('mode'=>'emailing'); + $substitutionarray=getCommonSubstitutionArray($langs, 2, array('object','objectamount'), $targetobject); // Note: On mass emailing, this is null because be don't know object + + // Array of possible substitutions (See also file mailing-send.php that should manage same substitutions) + $substitutionarray['__ID__'] = $obj->source_id; + $substitutionarray['__EMAIL__'] = $obj->email; + $substitutionarray['__LASTNAME__'] = $obj->lastname; + $substitutionarray['__FIRSTNAME__'] = $obj->firstname; + $substitutionarray['__MAILTOEMAIL__'] = ''.$obj->email.''; + $substitutionarray['__OTHER1__'] = $other1; + $substitutionarray['__OTHER2__'] = $other2; + $substitutionarray['__OTHER3__'] = $other3; + $substitutionarray['__OTHER4__'] = $other4; + $substitutionarray['__OTHER5__'] = $other5; + $substitutionarray['__SIGNATURE__'] = $signature; // Signature is empty when ran from command line or taken from user in parameter) + $substitutionarray['__CHECK_READ__'] = ''; + $substitutionarray['__UNSUBSCRIBE__'] = ''.$langs->trans("MailUnsubcribe").''; + $onlinepaymentenabled = 0; if (! empty($conf->paypal->enabled)) $onlinepaymentenabled++; if (! empty($conf->paybox->enabled)) $onlinepaymentenabled++; @@ -230,18 +227,20 @@ if (empty($reshook)) if ($onlinepaymentenabled && ! empty($conf->global->PAYMENT_SECURITY_TOKEN)) { $substitutionarray['__SECUREKEYPAYMENT__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - - if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYMENT_MEMBER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYMENT_MEMBER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2); - - if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYMENT_ORDER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYMENT_ORDER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'order' . $obj->source_id, 2); - - if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYMENT_INVOICE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYMENT_INVOICE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'invoice' . $obj->source_id, 2); - - if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'contractline' . $obj->source_id, 2); + if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) + { + $substitutionarray['__SECUREKEYPAYMENT_MEMBER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); + $substitutionarray['__SECUREKEYPAYMENT_ORDER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); + $substitutionarray['__SECUREKEYPAYMENT_INVOICE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); + $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); + } + else + { + $substitutionarray['__SECUREKEYPAYMENT_MEMBER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2); + $substitutionarray['__SECUREKEYPAYMENT_ORDER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'order' . $obj->source_id, 2); + $substitutionarray['__SECUREKEYPAYMENT_INVOICE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'invoice' . $obj->source_id, 2); + $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'contractline' . $obj->source_id, 2); + } } /* For backward compatibility */ if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN)) @@ -261,6 +260,7 @@ if (empty($reshook)) else $substitutionarray['__SECUREKEYPAYPAL_CONTRACTLINE__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'contractline' . $obj->source_id, 2); } //$substitutionisok=true; + complete_substitutions_array($substitutionarray, $langs); $newsubject=make_substitutions($subject,$substitutionarray); $newmessage=make_substitutions($message,$substitutionarray); @@ -431,9 +431,12 @@ if (empty($reshook)) $msgishtml=-1; // Inconnu par defaut if (preg_match('/[\s\t]*/i',$object->body)) $msgishtml=1; - $object->substitutionarrayfortest['__EMAIL__'] = $object->sendto; // other are set at begin of page + // other are set at begin of page + $object->substitutionarrayfortest['__EMAIL__'] = $object->sendto; + $object->substitutionarrayfortest['__MAILTOEMAIL__'] = ''.$object->sendto.''; // Pratique les substitutions sur le sujet et message + complete_substitutions_array($object->substitutionarrayfortest, $langs); $tmpsujet=make_substitutions($object->sujet,$object->substitutionarrayfortest); $tmpbody=make_substitutions($object->body,$object->substitutionarrayfortest); @@ -1073,7 +1076,7 @@ else $formmail->substit=$object->substitutionarrayfortest; // Tableau des parametres complementaires du post $formmail->param["action"]="send"; - $formmail->param["models"]="body"; + $formmail->param["models"]='none'; $formmail->param["mailid"]=$object->id; $formmail->param["returnurl"]=$_SERVER['PHP_SELF']."?id=".$object->id; @@ -1224,7 +1227,6 @@ else // Print mail content print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto($langs->trans("AvailableVariables"), $htmltext, 1, 'help', '', 0, 2, 'emailsubstitionhelp'), 'title_generic'); - dol_fiche_head(null, '', '', -1); print ''; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 18add332294..a7540c69840 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -125,7 +125,15 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - if ($cancel) $action = ''; + if ($cancel) + { + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + $action=''; + } include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once @@ -350,8 +358,8 @@ if (empty($reshook)) $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->statut = Propal::STATUS_DRAFT; $object->fk_incoterms = GETPOST('incoterm_id', 'int'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); @@ -378,8 +386,8 @@ if (empty($reshook)) $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->fk_incoterms = GETPOST('incoterm_id', 'int'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); @@ -638,16 +646,10 @@ if (empty($reshook)) include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; - - /* - * Send mail - */ - // Actions to send emails $actiontypecode='AC_OTH_AUTO'; $trigger_name='PROPAL_SENTBYMAIL'; - $paramname='id'; - $mode='emailfromproposal'; + $autocopy='MAIN_MAIL_AUTOCOPY_PROPOSAL_TO'; $trackid='pro'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; @@ -977,7 +979,7 @@ if (empty($reshook)) $info_bits |= 0x01; // Clean parameters - $description = dol_htmlcleanlastbr(GETPOST('product_desc')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc','none')); // Define vat_rate $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); @@ -1528,13 +1530,7 @@ if ($action == 'create') } // Other attributes - $parameters = array(); - $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook) && ! empty($extrafields->attribute_label)) { - print $object->showOptionals($extrafields, 'edit'); - } - + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_add.tpl.php'; // Lines from source if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) @@ -2361,123 +2357,13 @@ if ($action == 'create') print ''; } - /* - * Action presend - */ - if ($action == 'presend') - { - $object->fetch_projet(); + // Presend form + $modelmail='propal_send'; + $defaulttopic='SendPropalRef'; + $diroutput = $conf->propal->dir_output; + $trackid = 'pro'.$object->id; - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - - if (!empty($newlang)) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); - $outputlangs->load('commercial'); - } - - // Build document if it not exists - if (! $file || ! is_readable($file)) { - $result = $object->generateDocument(GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) { - dol_print_error($db, $object->error, $object->errors); - exit(); - } - $fileparams = dol_most_recent_file($conf->propal->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - } - - print '
    '; - print '
    '; - print '
    '; - print load_fiche_titre($langs->trans('SendPropalByMail')); - - dol_fiche_head(''); - - // Create form object - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='pro'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'pro'.$object->id); - } - $formmail->withfrom = 1; - $liste = array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) - $liste [$key] = $value; - $formmail->withto = GETPOST("sendto") ? GETPOST("sendto") : $liste; - $formmail->withtocc = $liste; - $formmail->withtoccc = (! empty($conf->global->MAIN_EMAIL_USECCC) ? $conf->global->MAIN_EMAIL_USECCC : false); - if (empty($object->ref_client)) { - $formmail->withtopic = $outputlangs->trans('SendPropalRef', '__PROPREF__'); - } else if (! empty($object->ref_client)) { - $formmail->withtopic = $outputlangs->trans('SendPropalRef', '__PROPREF__ (__REFCLIENT__)'); - } - $formmail->withfile = 2; - $formmail->withbody = 1; - $formmail->withdeliveryreceipt = 1; - $formmail->withcancel = 1; - - // Tableau des substitutions - $formmail->setSubstitFromObject($object); - $formmail->substit['__PROPREF__'] = $object->ref; // For backward compatibility - - // Find the good contact adress - $custcontact = ''; - $contactarr = array(); - $contactarr = $object->liste_contact(- 1, 'external'); - - if (is_array($contactarr) && count($contactarr) > 0) { - foreach ($contactarr as $contact) { - if ($contact ['libelle'] == $langs->trans('TypeContact_propal_external_CUSTOMER')) { // TODO Use code and not label - $contactstatic = new Contact($db); - $contactstatic->fetch($contact ['id']); - $custcontact = $contactstatic->getFullName($langs, 1); - } - } - - if (! empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__'] = $custcontact; - } - } - - // Tableau des parametres complementaires - $formmail->param['action'] = 'send'; - $formmail->param['models'] = 'propal_send'; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['id'] = $object->id; - $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id; - // Init list of files - if (GETPOST("mode") == 'init') { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); - } - - print $formmail->get_form(); - - dol_fiche_end(); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } // End of page diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index ec89ad69fa4..a2e9cc6c36a 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1404,7 +1404,7 @@ class Propal extends CommonObject { $this->lines=array(); - $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; + $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; $sql.= ' d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,'; $sql.= ' d.fk_unit,'; $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,'; @@ -1443,6 +1443,8 @@ class Propal extends CommonObject $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; $line->subprice = $objp->subprice; $line->fk_remise_except = $objp->fk_remise_except; $line->remise_percent = $objp->remise_percent; @@ -3366,8 +3368,8 @@ class Propal extends CommonObject $this->lines = array(); $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,'; - $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.remise_percent, pt.subprice, pt.info_bits,'; - $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,'; + $sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.localtax1_type, pt.localtax2_type, pt.remise_percent, pt.subprice, pt.info_bits,'; + $sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.total_localtax1, pt.total_localtax2, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code,'; $sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,'; $sql.= ' pt.fk_unit,'; $sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,'; @@ -3411,11 +3413,17 @@ class Propal extends CommonObject $this->lines[$i]->vat_src_code = $obj->vat_src_code; $this->lines[$i]->tva_tx = $obj->tva_tx; + $this->lines[$i]->localtax1_tx = $obj->localtax1_tx; + $this->lines[$i]->localtax2_tx = $obj->localtax2_tx; + $this->lines[$i]->localtax1_type = $obj->localtax1_type; + $this->lines[$i]->localtax2_type = $obj->localtax2_type; $this->lines[$i]->info_bits = $obj->info_bits; $this->lines[$i]->total_ht = $obj->total_ht; $this->lines[$i]->total_tva = $obj->total_tva; $this->lines[$i]->total_ttc = $obj->total_ttc; - $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; + $this->lines[$i]->total_localtax1 = $obj->total_localtax1; + $this->lines[$i]->total_localtax2 = $obj->total_localtax2; + $this->lines[$i]->fk_fournprice = $obj->fk_fournprice; $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht); $this->lines[$i]->pa_ht = $marginInfos[0]; $this->lines[$i]->marge_tx = $marginInfos[1]; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index e0f1caafc81..0f2fd46c3f6 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -96,8 +96,8 @@ $pagenext = $page + 1; if (! $sortfield) $sortfield='p.ref'; if (! $sortorder) $sortorder='DESC'; -// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$contextpage='proposallist'; +// Initialize technical object to manage context to save list fields +$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'proposallist'; // Security check $module='propal'; @@ -158,7 +158,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -413,6 +413,7 @@ if ($resql) print ''; print ''; print ''; + print ''; print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, '', '', $limit); diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 04eb2583fb5..7a34d1a3a76 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -125,7 +125,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') if ($res > 0 && $newid1 > 0 && $newid2 > 0) { $db->commit(); - header("Location: ".$_SERVER["PHP_SELF"].'?id='.$id); // To avoid pb whith back + header("Location: ".$_SERVER["PHP_SELF"].'?id='.$id.($backtopage?'&backtopage='.urlencode($backtopage):'')); // To avoid pb whith back exit; } else @@ -275,13 +275,13 @@ if ($socid > 0) print '
    '; print ''; - + if ($user->rights->societe->creer) { print '
    '; - + print load_fiche_titre($langs->trans("NewGlobalDiscount"),'',''); - + print '
    '; print ''; print ''; @@ -292,8 +292,8 @@ if ($socid > 0) print $form->load_tva('tva_tx',GETPOST('tva_tx'),$mysoc,$object); print ''; print ''; - print ''; - + print ''; + print "
    '.$langs->trans("AmountHT").'
    '.$langs->trans("NoteReason").'
    "; } @@ -362,7 +362,7 @@ if ($socid > 0) while ($i < $num) { $obj = $db->fetch_object($resql); - + print ''; print ''.dol_print_date($db->jdate($obj->dc),'dayhour').''; if (preg_match('/\(CREDIT_NOTE\)/',$obj->description)) @@ -408,14 +408,14 @@ if ($socid > 0) if ($user->rights->societe->creer || $user->rights->facture->creer) { print ''; - print 'rowid.'">'.img_split($langs->trans("SplitDiscount")).''; + print 'rowid.($backtopage?'&backtopage='.urlencode($backtopage):'').'">'.img_split($langs->trans("SplitDiscount")).''; print '   '; - print 'rowid.'">'.img_delete($langs->trans("RemoveDiscount")).''; + print 'rowid.($backtopage?'&backtopage='.urlencode($backtopage):'').'">'.img_delete($langs->trans("RemoveDiscount")).''; print ''; } else print ' '; print ''; - + if ($_GET["action"]=='split' && GETPOST('remid') == $obj->rowid) { $showconfirminfo['rowid']=$obj->rowid; @@ -427,7 +427,7 @@ if ($socid > 0) else { print ''.$langs->trans("None").''; - } + } $db->free($resql); print ""; @@ -441,7 +441,7 @@ if ($socid > 0) array('type' => 'text', 'name' => 'amount_ttc_2', 'label' => $langs->trans("AmountTTC").' 2', 'value' => $amount2, 'size' => '5') ); $langs->load("dict"); - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.$showconfirminfo['rowid'], $langs->trans('SplitDiscount'), $langs->trans('ConfirmSplitDiscount',price($showconfirminfo['amount_ttc']),$langs->transnoentities("Currency".$conf->currency)), 'confirm_split', $formquestion, 0, 0); + print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.$showconfirminfo['rowid'].($backtopage?'&backtopage='.urlencode($backtopage):''), $langs->trans('SplitDiscount'), $langs->trans('ConfirmSplitDiscount',price($showconfirminfo['amount_ttc']),$langs->transnoentities("Currency".$conf->currency)), 'confirm_split', $formquestion, 0, 0); } } else @@ -590,7 +590,7 @@ if ($socid > 0) { print ''.$langs->trans("None").''; } - + print ""; } else diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 040b1e200d8..5da8423c0a2 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -118,16 +118,11 @@ if (empty($reshook)) { if ($cancel) { - if ($action != 'addlink' && $action != 'updateline') + if (! empty($backtopage)) { - $urltogo=$backtopage?$backtopage:dol_buildpath('/commande/list.php',1); - header("Location: ".$urltogo); + header("Location: ".$backtopage); exit; } - if ($id > 0 || ! empty($ref)) { - $ret = $object->fetch($id,$ref); - $object->fetch_thirdparty(); - } $action=''; } @@ -261,8 +256,8 @@ if (empty($reshook)) $db->begin(); $object->date_commande = $datecommande; - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->source = GETPOST('source_id'); $object->fk_project = GETPOST('projectid'); $object->ref_client = GETPOST('ref_client'); @@ -932,7 +927,7 @@ if (empty($reshook)) $date_end=''; $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description=dol_htmlcleanlastbr(GETPOST('product_desc')); + $description=dol_htmlcleanlastbr(GETPOST('product_desc','none')); $pu_ht=GETPOST('price_ht'); $vat_rate=(GETPOST('tva_tx')?GETPOST('tva_tx'):0); $pu_ht_devise = GETPOST('multicurrency_subprice'); @@ -1215,11 +1210,6 @@ if (empty($reshook)) } } - // Actions to build doc - $upload_dir = $conf->commande->dir_output; - $permissioncreate = $user->rights->commande->creer; - include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - if ($action == 'update_extras') { // Fill array 'array_options' with data from update form @@ -1256,13 +1246,18 @@ if (empty($reshook)) exit(); } - include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + // Actions to build doc + $upload_dir = $conf->commande->dir_output; + $permissioncreate = $user->rights->commande->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; // Actions to send emails $trigger_name='ORDER_SENTBYMAIL'; $paramname='id'; - $mode='emailfromorder'; + $autocopy='MAIN_MAIL_AUTOCOPY_ORDER_TO'; // used to know the automatic BCC to add $trackid='ord'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; @@ -2497,7 +2492,7 @@ if ($action == 'create' && $user->rights->commande->creer) if (! empty($conf->expedition->enabled)) { $numshipping = $object->nb_expedition(); - if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfProductsLines() > 0) { + if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES))) { if (($conf->expedition_bon->enabled && $user->rights->expedition->creer) || ($conf->livraison_bon->enabled && $user->rights->expedition->livraison->creer)) { if ($user->rights->expedition->creer) { print ''; @@ -2596,134 +2591,13 @@ if ($action == 'create' && $user->rights->commande->creer) print ''; } - /* - * Action presend - */ - if ($action == 'presend') - { - $object->fetch_projet(); + // Presend form + $modelmail='order_send'; + $defaulttopic='SendOrderRef'; + $diroutput = $conf->commande->dir_output; + $trackid = 'ord'.$object->id; - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - - if (!empty($newlang)) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); - $outputlangs->load('commercial'); - } - - // Show email form - - // By default if $action=='presend' - $titreform='SendOrderByMail'; - $topicmail=''; - if (empty($object->ref_client)) { - $topicmail = $outputlangs->trans('SendOrderRef', '__ORDERREF__'); - } else if (! empty($object->ref_client)) { - $topicmail = $outputlangs->trans('SendOrderRef', '__ORDERREF__ (__REFCLIENT__)'); - } - $action='send'; - $modelmail='order_send'; - - // Build document if it not exists - if (! $file || ! is_readable($file)) { - $result = $object->generateDocument(GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) { - dol_print_error($db, $object->error, $object->errors); - exit(); - } - $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - } - - print '
    '; - print '
    '; - print '
    '; - print load_fiche_titre($langs->trans($titreform)); - - dol_fiche_head(''); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='ord'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id); - } - $formmail->withfrom = 1; - $liste = array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) - $liste [$key] = $value; - $formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste; - $formmail->withtocc = $liste; - $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; - $formmail->withtopic = $topicmail; - $formmail->withfile = 2; - $formmail->withbody = 1; - $formmail->withdeliveryreceipt = 1; - $formmail->withcancel = 1; - // Tableau des substitutions - $formmail->setSubstitFromObject($object); - $formmail->substit ['__ORDERREF__'] = $object->ref; - - $custcontact = ''; - $contactarr = array(); - $contactarr = $object->liste_contact(- 1, 'external'); - - if (is_array($contactarr) && count($contactarr) > 0) - { - foreach ($contactarr as $contact) - { - if ($contact['libelle'] == $langs->trans('TypeContact_commande_external_CUSTOMER')) { // TODO Use code and not label - $contactstatic = new Contact($db); - $contactstatic->fetch($contact ['id']); - $custcontact = $contactstatic->getFullName($langs, 1); - } - } - - if (! empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__'] = $custcontact; - } - } - - // Tableau des parametres complementaires - $formmail->param['action'] = $action; - $formmail->param['models'] = $modelmail; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['orderid'] = $object->id; - $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id; - - // Init list of files - if (GETPOST("mode") == 'init') { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); - } - - // Show form - print $formmail->get_form(); - - dol_fiche_end(); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } } diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index af83b353101..fed61c1fc17 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -42,6 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $langs->loadLangs(array("orders",'sendings','deliveries','companies','compta','bills')); @@ -82,6 +83,7 @@ $result = restrictedArea($user, 'commande', $id,''); $diroutputmassaction=$conf->commande->dir_output . '/temp/massgeneration/'.$user->id; +// Load variable for pagination $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); $sortorder = GETPOST("sortorder",'alpha'); @@ -118,7 +120,8 @@ $checkedtypetiers=0; $arrayfields=array( 'c.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), 'c.ref_client'=>array('label'=>$langs->trans("RefCustomerOrder"), 'checked'=>1), - 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), + 'p.project_ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>0, 'enabled'=>1), + 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), 's.town'=>array('label'=>$langs->trans("Town"), 'checked'=>1), 's.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>1), 'state.nom'=>array('label'=>$langs->trans("StateShort"), 'checked'=>0), @@ -139,7 +142,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -186,6 +189,7 @@ if (empty($reshook)) $search_deliveryday=''; $search_deliverymonth=''; $search_deliveryyear=''; + $search_project_ref=''; $viewstatut=''; $billed=''; $toselect=''; @@ -203,7 +207,8 @@ if (empty($reshook)) $permtoread = $user->rights->commande->lire; $permtodelete = $user->rights->commande->supprimer; $uploaddir = $conf->commande->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + $trigger_name='ORDER_SENTBYMAIL'; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; // TODO Move this into mass action include if ($massaction == 'confirm_createbills') { @@ -438,6 +443,7 @@ $formother = new FormOther($db); $formfile = new FormFile($db); $companystatic = new Societe($db); $formcompany=new FormCompany($db); +$projectstatic=new Project($db); $title=$langs->trans("Orders"); $help_url="EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_Pedidos_de_clientes"; @@ -450,7 +456,8 @@ $sql.= " typent.code as typent_code,"; $sql.= " state.code_departement as state_code, state.nom as state_name,"; $sql.= ' c.rowid, c.ref, c.total_ht, c.tva as total_tva, c.total_ttc, c.ref_client,'; $sql.= ' c.date_valid, c.date_commande, c.note_private, c.date_livraison as date_delivery, c.fk_statut, c.facture as billed,'; -$sql.= ' c.date_creation as date_creation, c.tms as date_update'; +$sql.= ' c.date_creation as date_creation, c.tms as date_update,'; +$sql.= " p.rowid as project_id, p.ref as project_ref"; // Add fields from extrafields foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); // Add fields from hooks @@ -465,6 +472,7 @@ $sql.= ', '.MAIN_DB_PREFIX.'commande as c'; if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."commande_extrafields as ef on (c.rowid = ef.fk_object)"; if ($sall || $search_product_category > 0) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'commandedet as pd ON c.rowid=pd.fk_commande'; if ($search_product_category > 0) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=pd.fk_product'; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = c.fk_projet"; // We'll need this table joined to the select in order to filter by sale if ($search_sale > 0 || (! $user->rights->societe->client->voir && ! $socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; if ($search_user > 0) @@ -539,6 +547,7 @@ if ($search_company) $sql .= natural_search('s.nom', $search_company); if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; if ($search_user > 0) $sql.= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='commande' AND tc.source='internal' AND ec.element_id = c.rowid AND ec.fk_socpeople = ".$search_user; if ($search_total_ht != '') $sql.= natural_search('c.total_ht', $search_total_ht, 1); +if ($search_project_ref != '') $sql.= natural_search("p.ref",$search_project_ref); // Add where from extra fields foreach ($search_array_options as $key => $val) { @@ -626,7 +635,8 @@ if ($resql) if ($search_total_ht != '') $param.='&search_total_ht='.$search_total_ht; if ($search_total_vat != '') $param.='&search_total_vat='.$search_total_vat; if ($search_total_ttc != '') $param.='&search_total_ttc='.$search_total_ttc; - if ($show_files) $param.='&show_files=' .$show_files; + if ($search_project_ref >= 0) $param.="&search_project_ref=".$search_project_ref; + if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; if ($billed != '') $param.='&billed='.$billed; // Add $param from extra fields @@ -670,6 +680,7 @@ if ($resql) include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_form.tpl.php'; } + if ($massaction == 'createbills') { //var_dump($_REQUEST); @@ -787,6 +798,11 @@ if ($resql) print ''; print ''; } + // Project ref + if (! empty($arrayfields['p.project_ref']['checked'])) + { + print ''; + } // Thirpdarty if (! empty($arrayfields['s.nom']['checked'])) { @@ -930,6 +946,7 @@ if ($resql) print ''; if (! empty($arrayfields['c.ref']['checked'])) print_liste_field_titre($arrayfields['c.ref']['label'],$_SERVER["PHP_SELF"],'c.ref','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['c.ref_client']['checked'])) print_liste_field_titre($arrayfields['c.ref_client']['label'],$_SERVER["PHP_SELF"],'c.ref_client','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['p.project_ref']['checked'])) print_liste_field_titre($arrayfields['p.project_ref']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,'',$sortfield,$sortorder); if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],'s.nom','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); @@ -979,27 +996,35 @@ if ($resql) { $obj = $db->fetch_object($resql); - print ''; - $notshippable=0; $warning = 0; $text_info=''; $text_warning=''; $nbprod=0; + $companystatic->id=$obj->socid; + $companystatic->code_client = $obj->code_client; + $companystatic->name=$obj->name; + $companystatic->client=$obj->client; + $companystatic->email=$obj->email; + + $generic_commande->id=$obj->rowid; + $generic_commande->ref=$obj->ref; + $generic_commande->statut = $obj->fk_statut; + $generic_commande->date_commande = $db->jdate($obj->date_commande); + $generic_commande->date_livraison = $db->jdate($obj->date_delivery); + $generic_commande->ref_client = $obj->ref_client; + $generic_commande->total_ht = $obj->total_ht; + $generic_commande->total_tva = $obj->total_tva; + $generic_commande->total_ttc = $obj->total_ttc; + + print ''; + // Ref if (! empty($arrayfields['c.ref']['checked'])) { print ''; - $generic_commande->id=$obj->rowid; - $generic_commande->ref=$obj->ref; - $generic_commande->statut = $obj->fk_statut; - $generic_commande->date_commande = $db->jdate($obj->date_commande); - $generic_commande->date_livraison = $db->jdate($obj->date_delivery); - $generic_commande->ref_client = $obj->ref_client; - $generic_commande->total_ht = $obj->total_ht; - $generic_commande->total_tva = $obj->total_tva; - $generic_commande->total_ttc = $obj->total_ttc; + $generic_commande->lines=array(); $generic_commande->getLinesArray(); @@ -1144,11 +1169,16 @@ if ($resql) if (! $i) $totalarray['nbfield']++; } - $companystatic->id=$obj->socid; - $companystatic->code_client = $obj->code_client; - $companystatic->name=$obj->name; - $companystatic->client=$obj->client; - $companystatic->email=$obj->email; + // Project + if (! empty($arrayfields['p.project_ref']['checked'])) + { + $projectstatic->id=$obj->project_id; + $projectstatic->ref=$obj->project_ref; + print ''; + if ($obj->project_id > 0) print $projectstatic->getNomUrl(1); + print ''; + if (! $i) $totalarray['nbfield']++; + } // Third party if (! empty($arrayfields['s.nom']['checked'])) diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index cd4d659d743..a04d9cf0f2e 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -104,9 +104,9 @@ if (! $sortfield) $sortfield='b.datev, b.dateo, b.rowid'; $mode_balance_ok=false; //if (($sortfield == 'b.datev' || $sortfield == 'b.datev, b.dateo, b.rowid')) // TODO Manage balance when account not selected -if (($sortfield == 'b.datev' || $sortfield == 'b.datev, b.dateo, b.rowid')) +if (($sortfield == 'b.datev' || $sortfield == 'b.datev,b.dateo,b.rowid')) { - $sortfield = 'b.datev, b.dateo, b.rowid'; + $sortfield = 'b.datev,b.dateo,b.rowid'; if ($id > 0 || ! empty($ref) || $account > 0) $mode_balance_ok = true; } if (strtolower($sortorder) == 'desc') $mode_balance_ok = false; @@ -151,7 +151,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -743,7 +743,7 @@ if ($resql) // Title $bankcateg=new BankCateg($db); - $morehtml='
    '; + $morehtml='
    '; $morehtml.= ' "; // ' Page '; $morehtml.=''; $morehtml.='/'.$nbtotalofpages.' '; @@ -887,7 +887,7 @@ if ($resql) if (! empty($arrayfields['b.rowid']['checked'])) print_liste_field_titre($arrayfields['b.rowid']['label'],$_SERVER['PHP_SELF'],'b.rowid','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['description']['checked'])) print_liste_field_titre($arrayfields['description']['label'],$_SERVER['PHP_SELF'],'','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.dateo']['checked'])) print_liste_field_titre($arrayfields['b.dateo']['label'],$_SERVER['PHP_SELF'],'b.dateo','',$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev, b.dateo, b.rowid','',$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['b.datev']['checked'])) print_liste_field_titre($arrayfields['b.datev']['label'],$_SERVER['PHP_SELF'],'b.datev,b.dateo,b.rowid','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['type']['checked'])) print_liste_field_titre($arrayfields['type']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['b.num_chq']['checked'])) print_liste_field_titre($arrayfields['b.num_chq']['label'],$_SERVER['PHP_SELF'],'b.num_chq','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['bu.label']['checked'])) print_liste_field_titre($arrayfields['bu.label']['label'],$_SERVER['PHP_SELF'],'bu.label','',$param,'',$sortfield,$sortorder); @@ -1065,7 +1065,7 @@ if ($resql) $bankstatic->id=$banklinestatic->fk_account; $bankstatic->label=$banklinestatic->bank_account_ref; print ' ('.$langs->trans("TransferFrom").' '; - print $bankstatic->getNomUrl(1,'transactions'); + print $bankstatic->getNomUrl(1); print ' '.$langs->trans("toward").' '; $bankstatic->id=$objp->bankid; $bankstatic->label=$objp->bankref; @@ -1082,7 +1082,7 @@ if ($resql) $banklinestatic->fetch($links[$key]['url_id']); $bankstatic->id=$banklinestatic->fk_account; $bankstatic->label=$banklinestatic->bank_account_ref; - print $bankstatic->getNomUrl(1,'transactions'); + print $bankstatic->getNomUrl(1); print ')'; } //var_dump($links); diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 7c94e03e339..b32d4ea938e 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -145,7 +145,7 @@ if ($action == 'add') if ($id > 0) { // Category association - $categories = GETPOST('categories'); + $categories = GETPOST('categories', 'array'); $object->setCategories($categories); $_GET["id"]=$id; // Force chargement page en mode visu @@ -239,7 +239,7 @@ if ($action == 'update') if ($result >= 0) { // Category association - $categories = GETPOST('categories'); + $categories = GETPOST('categories', 'array'); $object->setCategories($categories); $_GET["id"]=$_POST["id"]; // Force chargement page en mode visu diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index a25447da224..53e84b036d4 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -925,7 +925,8 @@ class Account extends CommonObject } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; + $this->errors[]=$this->error; return -1; } } @@ -1150,7 +1151,7 @@ class Account extends CommonObject return $solde; } } - + /** * Load indicators for dashboard (this->nbtodo and this->nbtodolate) * @@ -1160,50 +1161,88 @@ class Account extends CommonObject */ function load_board(User $user, $filteraccountid = 0) { - global $conf, $langs; - - if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe - - $sql = "SELECT b.rowid, b.datev as datefin"; - $sql.= " FROM ".MAIN_DB_PREFIX."bank as b,"; - $sql.= " ".MAIN_DB_PREFIX."bank_account as ba"; - $sql.= " WHERE b.rappro=0"; - $sql.= " AND b.fk_account = ba.rowid"; - $sql.= " AND ba.entity IN (".getEntity('bank_account').")"; - $sql.= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable - $sql.= " AND clos = 0"; - if ($filteraccountid) $sql.=" AND ba.rowid = ".$filteraccountid; - - $resql=$this->db->query($sql); - if ($resql) - { - $langs->load("banks"); - $now=dol_now(); - - require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php'; - - $response = new WorkboardResponse(); - $response->warning_delay=$conf->bank->rappro->warning_delay/60/60/24; - $response->label=$langs->trans("TransactionsToConciliate"); - $response->url=DOL_URL_ROOT.'/compta/bank/index.php?leftmenu=bank&mainmenu=bank'; - $response->img=img_object('',"payment"); - - while ($obj=$this->db->fetch_object($resql)) - { - $response->nbtodo++; - if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) { - $response->nbtodolate++; - } - } - - return $response; - } - else - { - dol_print_error($this->db); - $this->error=$this->db->error(); - return -1; - } + global $conf, $langs; + + if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe + + $sql = "SELECT b.rowid, b.datev as datefin"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank as b,"; + $sql.= " ".MAIN_DB_PREFIX."bank_account as ba"; + $sql.= " WHERE b.rappro=0"; + $sql.= " AND b.fk_account = ba.rowid"; + $sql.= " AND ba.entity IN (".getEntity('bank_account').")"; + $sql.= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable + $sql.= " AND clos = 0"; + if ($filteraccountid) $sql.=" AND ba.rowid = ".$filteraccountid; + + $resql=$this->db->query($sql); + if ($resql) + { + $langs->load("banks"); + $now=dol_now(); + + require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php'; + + $response = new WorkboardResponse(); + $response->warning_delay=$conf->bank->rappro->warning_delay/60/60/24; + $response->label=$langs->trans("TransactionsToConciliate"); + $response->url=DOL_URL_ROOT.'/compta/bank/index.php?leftmenu=bank&mainmenu=bank'; + $response->img=img_object('',"payment"); + + while ($obj=$this->db->fetch_object($resql)) + { + $response->nbtodo++; + if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) { + $response->nbtodolate++; + } + } + + return $response; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } + + /** + * Charge indicateurs this->nb de tableau de bord + * @param int $filteraccountid To get info for a particular account id + * @return int <0 if ko, >0 if ok + */ + function load_state_board($filteraccountid = 0) + { + global $user; + + if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe + + $sql = "SELECT count(b.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank as b,"; + $sql.= " ".MAIN_DB_PREFIX."bank_account as ba"; + $sql.= " WHERE b.fk_account = ba.rowid"; + $sql.= " AND ba.entity IN (".getEntity('bank_account').")"; + $sql.= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable + $sql.= " AND clos = 0"; + if ($filteraccountid) $sql.=" AND ba.rowid = ".$filteraccountid; + + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["banklines"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } } @@ -1255,6 +1294,7 @@ class Account extends CommonObject $label = '' . $langs->trans("ShowAccount") . ''; $label .= '
    ' . $langs->trans('BankAccount') . ': ' . $this->label; $label .= '
    ' . $langs->trans('AccountNumber') . ': ' . $this->number; + $label .= '
    ' . $langs->trans("AccountCurrency") . ': ' . $this->currency_code; if (! empty($conf->accounting->enabled)) { include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 80bf9d6f50c..31c777740ac 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -46,7 +46,7 @@ $toselect = GETPOST('toselect', 'array'); $search_ref=GETPOST('search_ref','alpha'); $search_label=GETPOST('search_label','alpha'); $search_number=GETPOST('search_number','alpha'); -$statut=GETPOST('statut')?GETPOST('statut', 'alpha'):'opened'; // 'all' or ''='opened' +$search_status=GETPOST('search_status')?GETPOST('search_status', 'alpha'):'opened'; // 'all' or ''='opened' $optioncss = GETPOST('optioncss','alpha'); // Security check @@ -92,7 +92,8 @@ $arrayfields=array( 'b.account_number'=>array('label'=>$langs->trans("AccountAccounting"), 'checked'=>$conf->accountancy->enabled), 'b.fk_accountancy_journal'=>array('label'=>$langs->trans("AccountancyJournal"), 'checked'=>$conf->accountancy->enabled), 'toreconcile'=>array('label'=>$langs->trans("TransactionsToConciliate"), 'checked'=>1), - 'b.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 'b.currency_code'=>array('label'=>$langs->trans("Currency"), 'checked'=>0), + 'b.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'b.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), 'b.clos'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), 'balance'=>array('label'=>$langs->trans("Balance"), 'checked'=>1, 'position'=>1010), @@ -102,7 +103,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -121,13 +122,12 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; // Purge search criteria -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { - $statut = 'all'; $search_ref=''; $search_label=''; $search_number=''; - $search_statut=''; + $search_status=''; } @@ -143,7 +143,7 @@ $title=$langs->trans('BankAccounts'); // Load array of financial accounts (opened by default) $accounts = array(); -$sql = "SELECT rowid, label, courant, rappro, account_number, fk_accountancy_journal, datec as date_creation, tms as date_update"; +$sql = "SELECT rowid, label, courant, rappro, account_number, fk_accountancy_journal, currency_code, datec as date_creation, tms as date_update"; // Add fields from extrafields foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); // Add fields from hooks @@ -153,8 +153,8 @@ $sql.=$hookmanager->resPrint; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account as b"; if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."bankcacount_extrafields as ef on (c.rowid = ef.fk_object)"; $sql.= " WHERE entity IN (".getEntity('bank_account').")"; -if ($statut == 'opened') $sql.= " AND clos = 0"; -if ($statut == 'closed') $sql.= " AND clos = 1"; +if ($search_status == 'opened') $sql.= " AND clos = 0"; +if ($search_status == 'closed') $sql.= " AND clos = 1"; if ($search_ref != '') $sql.=natural_search('b.ref', $search_ref); if ($search_label != '') $sql.=natural_search('b.label', $search_label); if ($search_number != '') $sql.=natural_search('b.number', $search_number); @@ -222,7 +222,7 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; if ($search_ref != '') $param.='&search_ref='.$search_ref; if ($search_label != '') $param.='&search_label='.$search_label; if ($search_number != '') $param.='&search_number='.$search_number; -if ($statut != '') $param.='&statut='.$statut; +if ($search_status != '') $param.='&search_status='.$search_status; if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields @@ -338,6 +338,12 @@ if (! empty($arrayfields['toreconcile']['checked'])) print ''; print ''; } +// Currency +if (! empty($arrayfields['b.currency_code']['checked'])) +{ + print ''; + print ''; +} // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { @@ -377,7 +383,7 @@ if (! empty($arrayfields['b.tms']['checked'])) print ''; print ''; } -// Statut +// Status if (! empty($arrayfields['b.clos']['checked'])) { print ''; @@ -385,7 +391,7 @@ if (! empty($arrayfields['b.clos']['checked'])) 'opened'=>$langs->trans("Opened"), 'closed'=>$langs->trans("Closed") ); - print $form->selectarray("statut", $array, $statut, 1); + print $form->selectarray("search_status", $array, $search_status, 1); print ''; } // Balance @@ -408,6 +414,7 @@ if (! empty($arrayfields['accountype']['checked'])) print_liste_field_titr if (! empty($arrayfields['b.number']['checked'])) print_liste_field_titre($arrayfields['b.number']['label'],$_SERVER["PHP_SELF"],'b.number','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.account_number']['checked'])) print_liste_field_titre($arrayfields['b.account_number']['label'],$_SERVER["PHP_SELF"],'b.account_number','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['b.fk_accountancy_journal']['checked'])) print_liste_field_titre($arrayfields['b.fk_accountancy_journal']['label'],$_SERVER["PHP_SELF"],'b.fk_accountancy_journal','',$param,'',$sortfield,$sortorder); +if (! empty($arrayfields['b.currency_code']['checked'])) print_liste_field_titre($arrayfields['b.currency_code']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['toreconcile']['checked'])) print_liste_field_titre($arrayfields['toreconcile']['label'],$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -443,19 +450,19 @@ foreach ($accounts as $key=>$type) $found++; - $acc = new Account($db); - $acc->fetch($key); + $obj = new Account($db); + $obj->fetch($key); $var = !$var; - $solde = $acc->solde(1); + $solde = $obj->solde(1); - if (! empty($lastcurrencycode) && $lastcurrencycode != $acc->currency_code) + if (! empty($lastcurrencycode) && $lastcurrencycode != $obj->currency_code) { $lastcurrencycode='various'; // We found several different currencies } if ($lastcurrencycode != 'various') { - $lastcurrencycode=$acc->currency_code; + $lastcurrencycode=$obj->currency_code; } print ''; @@ -463,14 +470,14 @@ foreach ($accounts as $key=>$type) // Ref if (! empty($arrayfields['b.ref']['checked'])) { - print ''.$acc->getNomUrl(1).''; + print ''.$obj->getNomUrl(1).''; if (! $i) $totalarray['nbfield']++; } // Label if (! empty($arrayfields['b.label']['checked'])) { - print ''.$acc->label.''; + print ''.$obj->label.''; if (! $i) $totalarray['nbfield']++; } @@ -478,7 +485,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['accountype']['checked'])) { print ''; - print $acc->type_lib[$acc->type]; + print $obj->type_lib[$obj->type]; print ''; if (! $i) $totalarray['nbfield']++; } @@ -486,7 +493,7 @@ foreach ($accounts as $key=>$type) // Number if (! empty($arrayfields['b.number']['checked'])) { - print ''.$acc->number.''; + print ''.$obj->number.''; if (! $i) $totalarray['nbfield']++; } @@ -497,12 +504,12 @@ foreach ($accounts as $key=>$type) if (! empty($conf->accounting->enabled)) { $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('',$acc->account_number); + $accountingaccount->fetch('',$obj->account_number); print $accountingaccount->getNomUrl(0,1,1,'',1); } else { - print $acc->account_number; + print $obj->account_number; } print ''; if (! $i) $totalarray['nbfield']++; @@ -515,7 +522,7 @@ foreach ($accounts as $key=>$type) if (! empty($conf->accounting->enabled)) { $accountingjournal = new AccountingJournal($db); - $accountingjournal->fetch($acc->fk_accountancy_journal); + $accountingjournal->fetch($obj->fk_accountancy_journal); print $accountingjournal->getNomUrl(0,1,1,'',1); } else @@ -526,15 +533,24 @@ foreach ($accounts as $key=>$type) if (! $i) $totalarray['nbfield']++; } + // Currency + if (! empty($arrayfields['b.currency_code']['checked'])) + { + print ''; + print $obj->currency_code; + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Transactions to reconcile if (! empty($arrayfields['toreconcile']['checked'])) { print ''; - if ($acc->rappro) + if ($obj->rappro) { - $result=$acc->load_board($user,$acc->id); + $result=$obj->load_board($user,$obj->id); if ($result<0) { - setEventMessages($acc->error, $acc->errors, 'errors'); + setEventMessages($obj->error, $obj->errors, 'errors'); } else { print $result->nbtodo; if ($result->nbtodolate) print '   ('.$result->nbtodolate.img_warning($langs->trans("Late")).')'; @@ -571,7 +587,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['b.datec']['checked'])) { print ''; - print dol_print_date($acc->date_creation, 'dayhour'); + print dol_print_date($obj->date_creation, 'dayhour'); print ''; if (! $i) $totalarray['nbfield']++; } @@ -579,15 +595,15 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['b.tms']['checked'])) { print ''; - print dol_print_date($acc->date_update, 'dayhour'); + print dol_print_date($obj->date_update, 'dayhour'); print ''; if (! $i) $totalarray['nbfield']++; } - // Statut + // Status if (! empty($arrayfields['b.clos']['checked'])) { - print ''.$acc->getLibStatut(5).''; + print ''.$obj->getLibStatut(5).''; if (! $i) $totalarray['nbfield']++; } @@ -595,7 +611,7 @@ foreach ($accounts as $key=>$type) if (! empty($arrayfields['balance']['checked'])) { print ''; - print ''.price($solde, 0, $langs, 0, 0, -1, $acc->currency_code).''; + print ''.price($solde, 0, $langs, 0, 0, -1, $obj->currency_code).''; print ''; if (! $i) $totalarray['nbfield']++; if (! $i) $totalarray['totalbalancefield']=$totalarray['nbfield']; @@ -615,7 +631,7 @@ foreach ($accounts as $key=>$type) print ''; - $total[$acc->currency_code] += $solde; + $total[$obj->currency_code] += $solde; $i++; } diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php index 1f3ca1cde8e..7696427b059 100644 --- a/htdocs/compta/bank/transfer.php +++ b/htdocs/compta/bank/transfer.php @@ -30,8 +30,7 @@ require('../../main.inc.php'); require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; -$langs->load("banks"); -$langs->load("categories"); +$langs->loadLangs(array("banks", "categories", "multicurrency")); if (! $user->rights->banque->transfer) accessforbidden(); @@ -44,14 +43,14 @@ $error = 0; * Actions */ -if ($action == 'add_confirm') +if ($action == 'add') { $langs->load("errors"); $dateo = dol_mktime(12,0,0,GETPOST('remonth','int'),GETPOST('reday','int'),GETPOST('reyear','int')); $label = GETPOST('label','alpha'); $amount= GETPOST('amount'); - $amount_to= GETPOST('amount_to'); + $amountto= GETPOST('amountto'); if (! $label) { @@ -83,7 +82,17 @@ if ($action == 'add_confirm') $accountto=new Account($db); $accountto->fetch(GETPOST('account_to','int')); - if ($accountto->id != $accountfrom->id) + if ($accountto->currency_code == $accountfrom->currency_code) { + $amountto=$amount; + } else { + if (! $amountto) + { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AmountTo")), null, 'errors'); + } + } + + if (($accountto->id != $accountfrom->id) && empty($error)) { $db->begin(); @@ -103,8 +112,7 @@ if ($action == 'add_confirm') if (! $error) $bank_line_id_from = $accountfrom->addline($dateo, $typefrom, $label, -1*price2num($amount), '', '', $user); if (! ($bank_line_id_from > 0)) $error++; - if ((! $error) && ($accountto->currency_code == $accountfrom->currency_code)) $bank_line_id_to = $accountto->addline($dateo, $typeto, $label, price2num($amount), '', '', $user); - if ((! $error) && ($accountto->currency_code != $accountfrom->currency_code)) $bank_line_id_to = $accountto->addline($dateo, $typeto, $label, price2num($amount_to), '', '', $user); + if (! $error) $bank_line_id_to = $accountto->addline($dateo, $typeto, $label, price2num($amountto), '', '', $user); if (! ($bank_line_id_to > 0)) $error++; if (! $error) $result=$accountfrom->add_url_line($bank_line_id_from, $bank_line_id_to, DOL_URL_ROOT.'/compta/bank/ligne.php?rowid=', '(banktransfert)', 'banktransfert'); @@ -114,7 +122,7 @@ if ($action == 'add_confirm') if (! $error) { - $mesgs = $langs->trans("TransferFromToDone","id."\">".$accountfrom->label."","id."\">".$accountto->label."",$amount,$langs->transnoentities("Currency".$conf->currency)); + $mesgs = $langs->trans("TransferFromToDone",''.$accountfrom->label."",''.$accountto->label."",$amount,$langs->transnoentities("Currency".$conf->currency)); setEventMessages($mesgs, null, 'mesgs'); $db->commit(); } @@ -139,6 +147,58 @@ if ($action == 'add_confirm') */ llxHeader(); +print ' '; $form=new Form($db); @@ -146,9 +206,8 @@ $account_from=''; $account_to=''; $label=''; $amount=''; -$amount_to=''; -if ($error) +if($error) { $account_from = GETPOST('account_from','int'); $account_to = GETPOST('account_to','int'); @@ -164,21 +223,21 @@ print "

    "; print ''; print ''; -print ''; +print ''; print ''; print ''; -print ''; -print ''; +print ''; +print ''; print ''; $var=false; print '"; print "\n"; print "\n"; print ''; print ''; +print ''; + print "
    '.$langs->trans("TransferFrom").''.$langs->trans("TransferTo").''.$langs->trans("Date").''.$langs->trans("Description").''.$langs->trans("Amount").''.$langs->trans("TransferFrom").''.$langs->trans("TransferTo").''.$langs->trans("Date").''.$langs->trans("Description").''.$langs->trans("Amount").'
    '; -$form->select_comptes($account_from,'account_from',0,'',1); +$form->select_comptes($account_from, 'account_from', 0, '', 1, '', empty($conf->multicurrency->enabled)?0:1); print "\n"; -$form->select_comptes($account_to,'account_to',0,'',1); +$form->select_comptes($account_to, 'account_to', 0, '', 1, '', empty($conf->multicurrency->enabled)?0:1); print ""; @@ -186,6 +245,8 @@ $form->select_date((! empty($dateo)?$dateo:''),'','','','','add'); print "
    "; print '
    '; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 1e387bcd3fa..940ada5e04b 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -132,7 +132,15 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - if ($cancel) $action=''; + if ($cancel) + { + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + $action=''; + } include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once @@ -378,7 +386,9 @@ if (empty($reshook)) else if ($action == "setabsolutediscount" && $user->rights->facture->creer) { - // POST[remise_id] ou POST[remise_id_for_payment] + // POST[remise_id] or POST[remise_id_for_payment] + + // We use the credit to reduce amount of invoice if (! empty($_POST["remise_id"])) { $ret = $object->fetch($id); if ($ret > 0) { @@ -390,14 +400,28 @@ if (empty($reshook)) dol_print_error($db, $object->error); } } - if (! empty($_POST["remise_id_for_payment"])) { + // We use the credit to reduce remain to pay + if (! empty($_POST["remise_id_for_payment"])) + { require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php'; $discount = new DiscountAbsolute($db); $discount->fetch($_POST["remise_id_for_payment"]); - $result = $discount->link_to_invoice(0, $id); - if ($result < 0) { - setEventMessages($discount->error, $discount->errors, 'errors'); + //var_dump($object->getRemainToPay(0)); + //var_dump($discount->amount_ttc);exit; + if ($discount->amount_ttc > $object->getRemainToPay(0)) + { + // TODO Split the discount in 2 automatically + $error++; + setEventMessages($langs->trans("ErrorDiscountLargerThanRemainToPaySplitItBefore"), null, 'errors'); + } + + if (! $error) + { + $result = $discount->link_to_invoice(0, $id); + if ($result < 0) { + setEventMessages($discount->error, $discount->errors, 'errors'); + } } } @@ -580,27 +604,30 @@ if (empty($reshook)) $ventilExportCompta = $object->getVentilExportCompta(); // On verifie si aucun paiement n'a ete effectue - if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) + if ($ventilExportCompta == 0) { - $result=$object->set_draft($user, $idwarehouse); - if ($result<0) setEventMessages($object->error, $object->errors, 'errors'); - - - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_EDITED) || ($resteapayer == $object->total_ttc && empty($object->paye))) { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model=$object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records + $result=$object->set_draft($user, $idwarehouse); + if ($result<0) setEventMessages($object->error, $object->errors, 'errors'); - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model=$object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } } } } @@ -882,13 +909,18 @@ if (empty($reshook)) $line->fk_facture = $object->id; $line->fk_parent_line = $fk_parent_line; - $line->subprice =-$line->subprice; // invert price for object + $line->subprice = -$line->subprice; // invert price for object $line->pa_ht = $line->pa_ht; // we choosed to have buy/cost price always positive, so no revert of sign here - $line->total_ht=-$line->total_ht; - $line->total_tva=-$line->total_tva; - $line->total_ttc=-$line->total_ttc; - $line->total_localtax1=-$line->total_localtax1; - $line->total_localtax2=-$line->total_localtax2; + $line->total_ht = -$line->total_ht; + $line->total_tva = -$line->total_tva; + $line->total_ttc = -$line->total_ttc; + $line->total_localtax1 = -$line->total_localtax1; + $line->total_localtax2 = -$line->total_localtax2; + + $line->multicurrency_subprice = -$line->multicurrency_subprice; + $line->multicurrency_total_ht = -$line->multicurrency_total_ht; + $line->multicurrency_total_tva = -$line->multicurrency_total_tva; + $line->multicurrency_total_ttc = -$line->multicurrency_total_ttc; $result = $line->insert(0, 1); // When creating credit note with same lines than source, we must ignore error if discount alreayd linked @@ -1385,6 +1417,7 @@ if (empty($reshook)) { $line->origin = $object->origin; $line->origin_id = $line->id; + $line->fetch_optionals($line->id); } } @@ -1406,7 +1439,21 @@ if (empty($reshook)) $object->situation_counter = $object->situation_counter + 1; $id = $object->createFromCurrent($user); - if ($id <= 0) $mesg = $object->error; + if ($id <= 0) + { + $mesg = $object->error; + } + else + { + $nextSituationInvoice = new Facture($db); + $nextSituationInvoice->fetch($id); + // create extrafields with data from create form + $extralabels = $extrafields->fetch_name_optionals_label($nextSituationInvoice->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $nextSituationInvoice); + if ($ret > 0) { + $nextSituationInvoice->insertExtraFields(); + } + } } } @@ -1772,7 +1819,7 @@ if (empty($reshook)) $date_end = ''; $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description = dol_htmlcleanlastbr(GETPOST('product_desc') ? GETPOST('product_desc') : GETPOST('desc')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc','none') ? GETPOST('product_desc','none') : GETPOST('desc','none')); $pu_ht = GETPOST('price_ht'); $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); $qty = GETPOST('qty'); @@ -1957,20 +2004,17 @@ if (empty($reshook)) exit(); } - - /* - * Send mail - */ + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to send emails if (empty($id)) $id=$facid; $trigger_name='BILL_SENTBYMAIL'; $paramname='id'; - $mode='emailfrominvoice'; + $autocopy='MAIN_MAIL_AUTOCOPY_INVOICE_TO'; $trackid='inv'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; - // Actions to build doc $upload_dir = $conf->facture->dir_output; $permissioncreate=$user->rights->facture->creer; @@ -2003,8 +2047,6 @@ if (empty($reshook)) $action = 'edit_extras'; } - include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; - if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) { if ($action == 'addcontact') { $result = $object->fetch($id); @@ -2526,8 +2568,8 @@ if ($action == 'create') print $desc; print '
    '; - print '    0 ? 'checked':'').' /> "; - print '
        0 ? 'checked':'').' /> "; + print '    0 ? 'checked':'').' /> "; + print '
        0 ? 'checked':'').' /> "; print '
    '; print '
    '; @@ -3221,6 +3263,7 @@ else if ($id > 0 || ! empty($ref)) $addrelativediscount = '' . $langs->trans("EditRelativeDiscounts") . ''; $addabsolutediscount = '' . $langs->trans("EditGlobalDiscounts") . ''; $addcreditnote = '' . $langs->trans("AddCreditNote") . ''; + $viewabsolutediscount = '' . $langs->trans("ViewAvailableGlobalDiscounts") . ''; print '' . $langs->trans('Discounts'); print ''; @@ -3230,7 +3273,7 @@ else if ($id > 0 || ! empty($ref)) print $langs->trans("CompanyHasNoRelativeDiscount"); // print ' ('.$addrelativediscount.')'; - // Is there commercial discount or down payment available ? + // Is there is commercial discount or down payment available ? if ($absolute_discount > 0) { print '. '; if ($object->statut > 0 || $object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) { @@ -3255,7 +3298,7 @@ else if ($id > 0 || ! empty($ref)) } else { if ($absolute_creditnote > 0) // If not, link will be added later { - if ($object->statut == 0 && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) + if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) print ' (' . $addabsolutediscount . ')
    '; else print '. '; @@ -3266,7 +3309,7 @@ else if ($id > 0 || ! empty($ref)) if ($absolute_creditnote > 0) { // If validated, we show link "add credit note to payment" - if ($object->statut != 1 || $object->type == Facture::TYPE_CREDIT_NOTE) { + if ($object->statut != Facture::STATUS_VALIDATED || $object->type == Facture::TYPE_CREDIT_NOTE) { if ($object->statut == 0 && $object->type != Facture::TYPE_DEPOSIT) { $text = $langs->trans("CompanyHasCreditNote", price($absolute_creditnote), $langs->transnoentities("Currency" . $conf->currency)); print $form->textwithpicto($text, $langs->trans("CreditNoteDepositUse")); @@ -3277,13 +3320,13 @@ else if ($id > 0 || ! empty($ref)) // There is credit notes discounts available if (! $absolute_discount) print '
    '; // $form->form_remise_dispo($_SERVER["PHP_SELF"].'?facid='.$object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, $resteapayer); - $more=' ('.$addcreditnote.')'; + $more=' ('.$addcreditnote. (($addcreditnote && $viewabsolutediscount) ? ' - ' : '') . $viewabsolutediscount . ')'; $form->form_remise_dispo($_SERVER["PHP_SELF"] . '?facid=' . $object->id, 0, 'remise_id_for_payment', $soc->id, $absolute_creditnote, $filtercreditnote, 0, $more); // We allow credit note even if amount is higher } } if (! $absolute_discount && ! $absolute_creditnote) { print $langs->trans("CompanyHasNoAbsoluteDiscount"); - if ($object->statut == 0 && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) + if ($object->statut == Facture::STATUS_DRAFT && $object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT) print ' (' . $addabsolutediscount . ')
    '; else print '. '; @@ -4075,28 +4118,35 @@ else if ($id > 0 || ! empty($ref)) $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { // Editer une facture deja validee, sans paiement effectue et pas exporte en compta - if ($object->statut == 1) + if ($object->statut == Facture::STATUS_VALIDATED) { // On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees $ventilExportCompta = $object->getVentilExportCompta(); - if ($resteapayer == $object->total_ttc && empty($object->paye) && $ventilExportCompta == 0) + if ($ventilExportCompta == 0) { - if (! $objectidnext && $object->is_last_in_cycle()) + if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_EDITED) || ($resteapayer == $object->total_ttc && empty($object->paye))) { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate))) + if (! $objectidnext && $object->is_last_in_cycle()) { - print ''; + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate))) + { + print ''; + } else { + print '
    ' . $langs->trans('Modify') . '
    '; + } + } else if (!$object->is_last_in_cycle()) { + print '
    ' . $langs->trans('Modify') . '
    '; } else { - print '
    ' . $langs->trans('Modify') . '
    '; + print '
    ' . $langs->trans('Modify') . '
    '; } - } else if (!$object->is_last_in_cycle()) { - print '
    ' . $langs->trans('Modify') . '
    '; - } else { - print '
    ' . $langs->trans('Modify') . '
    '; } } + else + { + print '
    ' . $langs->trans('Modify') . '
    '; + } } $discount = new DiscountAbsolute($db); @@ -4118,7 +4168,7 @@ else if ($id > 0 || ! empty($ref)) } // Validate - if ($object->statut == 0 && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { + if ($object->statut == Facture::STATUS_DRAFT && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->validate))) { @@ -4335,143 +4385,15 @@ else if ($id > 0 || ! empty($ref)) print ''; } - else - { - /* - * Action presend (or prerelance) - */ - $object->fetch_projet(); - // By default if $action=='presend' - $titreform = 'SendBillByMail'; - $topicmail = 'SendBillRef'; - $modelmail = 'facture_send'; + // Presend form + $modelmail='facture_send'; + $defaulttopic='SendBillRef'; + $diroutput = $conf->facture->dir_output; + $trackid = 'inv'.$object->id; - if ($action == 'prerelance') // For backward compatibility - { - $titrefrom = 'SendReminderBillByMail'; - $topicmail = 'SendReminderBillRef'; - $modelmail = 'facture_relance'; - $action = 'relance'; - } else - $action = 'send'; - - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - - if (!empty($newlang)) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); - $outputlangs->load('bills'); - } - - // Build document if it not exists - if (! $file || ! is_readable($file)) { - $result = $object->generateDocument(GETPOST('model','alpha') ? GETPOST('model','alpha') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) { - dol_print_error($db, $object->error, $object->errors); - exit(); - } - $fileparams = dol_most_recent_file($conf->facture->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - } - - print '
    '; - print '
    '; - print '
    '; - print load_fiche_titre($langs->trans($titreform)); - - // Cree l'objet formulaire mail - dol_fiche_head(); - - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype','alpha')?GETPOST('fromtype','alpha'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='inv'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'inv'.$object->id); - } - $formmail->withfrom = 1; - $liste = array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) { - $liste [$key] = $value; - } - $formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste; // List suggested for send to - $formmail->withtocc = $liste; // List suggested for CC - $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; - if (empty($object->ref_client)) { - $formmail->withtopic = $outputlangs->transnoentities($topicmail, '__REF__'); - } else if (! empty($object->ref_client)) { - $formmail->withtopic = $outputlangs->transnoentities($topicmail, '__REF__ (__REFCLIENT__)'); - } - - $formmail->withfile = 2; - $formmail->withbody = 1; - $formmail->withdeliveryreceipt = 1; - $formmail->withcancel = 1; - // Tableau des substitutions - $formmail->setSubstitFromObject($object, $outputlangs); - $formmail->substit['__INVREF__'] = $object->ref; - - // Find the good contact adress - $custcontact = ''; - $contactarr = array(); - $contactarr = $object->liste_contact(- 1, 'external'); - - if (is_array($contactarr) && count($contactarr) > 0) { - foreach ($contactarr as $contact) { - if ($contact['libelle'] == $langs->trans('TypeContact_facture_external_BILLING')) { // TODO Use code and not label - - require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; - - $contactstatic = new Contact($db); - $contactstatic->fetch($contact ['id']); - $custcontact = $contactstatic->getFullName($langs, 1); - } - } - - if (! empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__'] = $custcontact; - } - } - - // Tableau des parametres complementaires du post - $formmail->param['action'] = $action; - $formmail->param['models'] = $modelmail; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['facid'] = $object->id; - $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id; - - // Init list of files - if (GETPOST("mode") == 'init') { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); - } - - print $formmail->get_form(); - - dol_fiche_end(); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } llxFooter(); diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index f841fc80050..e28d19b95b2 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -192,7 +192,7 @@ class Invoices extends DolibarrApi foreach($request_data as $field => $value) { $this->invoice->$field = $value; } - if(! array_keys($request_data,'date')) { + if(! array_key_exists('date', $request_data)) { $this->invoice->date = dol_now(); } /* We keep lines as an array @@ -276,6 +276,107 @@ class Invoices extends DolibarrApi ); } + /** + * Get lines of a given invoice + * + * @param int $id Id of invoice + * + * @url GET {id}/lines + * + * @return array + */ + function getLines($id) { + if(! DolibarrApiAccess::$user->rights->facture->lire) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Invoice not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $this->invoice->getLinesArray(); + $result = array(); + foreach ($this->invoice->lines as $line) { + array_push($result,$this->_cleanObjectDatas($line)); + } + return $result; + } + + /** + * Add a line to a given invoice + * + * Exemple of POST query : { "desc": "Desc", "subprice": "1.00000000", "qty": "1", "tva_tx": "20.000", "localtax1_tx": "0.000", "localtax2_tx": "0.000", "fk_product": "1", "remise_percent": "0", "date_start": "", "date_end": "", "fk_code_ventilation": 0, "info_bits": "0", "fk_remise_except": null, "product_type": "1", "rang": "-1", "special_code": "0", "fk_parent_line": null, "fk_fournprice": null, "pa_ht": "0.00000000", "label": "", "array_options": [], "situation_percent": "100", "fk_prev_id": null, "fk_unit": null } + * + * @param int $id Id of invoice + * @param array $request_data Invoiceline data + * + * @url POST {id}/lines + * + * @return int + */ + function postLine($id, $request_data = NULL) { + if(! DolibarrApiAccess::$user->rights->facture->creer) { + throw new RestException(401); + } + + $result = $this->invoice->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Invoice not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $request_data = (object) $request_data; + + // Reset fk_parent_line for no child products and special product + if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) { + $request_data->fk_parent_line = 0; + } + + $updateRes = $this->invoice->addline( + $request_data->desc, + $request_data->subprice, + $request_data->qty, + $request_data->tva_tx, + $request_data->localtax1_tx, + $request_data->localtax2_tx, + $request_data->fk_product, + $request_data->remise_percent, + $request_data->date_start, + $request_data->date_end, + $request_data->fk_code_ventilation, + $request_data->info_bits, + $request_data->fk_remise_except, + 'HT', + 0, + $request_data->product_type, + $request_data->rang, + $request_data->special_code, + 'facture', + $id, + $request_data->fk_parent_line, + $request_data->fk_fournprice, + $request_data->pa_ht, + $request_data->label, + $request_data->array_options, + $request_data->situation_percent, + $request_data->fk_prev_id, + $request_data->fk_unit + ); + + if ($updateRes > 0) { + return $this->get($id)->line->rowid; + + } + throw new RestException(400, 'Unable to insert the new line. Check your inputs.'); + } + /** * Validate an order * diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index b12f848323d..7c6e0567c24 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -152,8 +152,8 @@ class FactureRec extends CommonInvoice $sql.= ", '".$this->db->escape($user->id)."'"; $sql.= ", ".(! empty($facsrc->fk_project)?"'".$facsrc->fk_project."'":"null"); $sql.= ", ".(! empty($facsrc->fk_account)?"'".$facsrc->fk_account."'":"null"); - $sql.= ", '".$this->db->escape($facsrc->cond_reglement_id)."'"; - $sql.= ", '".$this->db->escape($facsrc->mode_reglement_id)."'"; + $sql.= ", ".($facsrc->cond_reglement_id > 0 ? $this->db->escape($facsrc->cond_reglement_id) : "null"); + $sql.= ", ".($facsrc->mode_reglement_id > 0 ? $this->db->escape($facsrc->mode_reglement_id) : "null"); $sql.= ", ".$this->usenewprice; $sql.= ", ".$this->frequency; $sql.= ", '".$this->db->escape($this->unit_frequency)."'"; @@ -329,7 +329,6 @@ class FactureRec extends CommonInvoice if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1; - // Retreive all extrafield for thirdparty // fetch optionals attributes and labels require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); @@ -447,7 +446,6 @@ class FactureRec extends CommonInvoice $line->price = $objp->price; $line->remise = $objp->remise; - // Retreive all extrafield for thirdparty // fetch optionals attributes and labels require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); @@ -715,6 +713,9 @@ class FactureRec extends CommonInvoice dol_syslog(get_class($this)."::updateline facid=".$facid." rowid=$rowid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,txlocaltax1=$txlocaltax1,txlocaltax2=$txlocaltax2,fk_product=$fk_product,remise_percent=$remise_percent,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + // Clean parameters + if (empty($remise_percent)) $remise_percent = 0; + // Check parameters if ($type < 0) return -1; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index ef1ca35bde3..b22816f1473 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -293,8 +293,8 @@ class Facture extends CommonInvoice // Fields coming from GUI (priority on template). TODO Value of template should be used as default value on GUI so we can use here always value from GUI $this->fk_project = GETPOST('projectid','int') > 0 ? GETPOST('projectid','int') : $_facrec->fk_project; - $this->note_public = GETPOST('note_public') ? GETPOST('note_public') : $_facrec->note_public; - $this->note_private = GETPOST('note_private') ? GETPOST('note_private') : $_facrec->note_private; + $this->note_public = GETPOST('note_public','none') ? GETPOST('note_public','none') : $_facrec->note_public; + $this->note_private = GETPOST('note_private','none') ? GETPOST('note_private','none') : $_facrec->note_private; $this->modelpdf = GETPOST('model') ? GETPOST('model') : $_facrec->modelpdf; $this->cond_reglement_id = GETPOST('cond_reglement_id') > 0 ? GETPOST('cond_reglement_id') : $_facrec->cond_reglement_id; $this->mode_reglement_id = GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $_facrec->mode_reglement_id; @@ -1051,6 +1051,30 @@ class Facture extends CommonInvoice else return -1; } + /** + * Return link to download file from a direct external access + * + * @param int $withpicto Add download picto into link + * @return string HTML link to file + */ + function getDirectExternalLink($withpicto=0) + { + global $dolibarr_main_url_root; + + // Define $urlwithroot + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + // TODO Read into ecmfile table to get entry and hash exists (PS: If not found, add it) + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($this->db); + //$result = $ecmfile->get(); + + $hashp='todo'; + return ''.$this->ref.''; + } + /** * Return clicable link of object (with eventually picto) * @@ -1577,7 +1601,7 @@ class Facture extends CommonInvoice $facligne->desc=$remise->description; // Description ligne $facligne->vat_src_code=$remise->vat_src_code; $facligne->tva_tx=$remise->tva_tx; - $facligne->subprice=-$remise->amount_ht; + $facligne->subprice = -$remise->amount_ht; $facligne->fk_product=0; // Id produit predefini $facligne->qty=1; $facligne->remise_percent=0; @@ -1600,6 +1624,11 @@ class Facture extends CommonInvoice $facligne->total_tva = -$remise->amount_tva; $facligne->total_ttc = -$remise->amount_ttc; + $facligne->multicurrency_subprice = -$remise->multicurrency_subprice; + $facligne->multicurrency_total_ht = -$remise->multicurrency_total_ht; + $facligne->multicurrency_total_tva = -$remise->multicurrency_total_tva; + $facligne->multicurrency_total_ttc = -$remise->multicurrency_total_ttc; + $lineid=$facligne->insert(); if ($lineid > 0) { @@ -1708,7 +1737,7 @@ class Facture extends CommonInvoice * @param User $user User making the deletion. * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @param int $idwarehouse Id warehouse to use for stock change. - * @return int <0 if KO, >0 if OK + * @return int <0 if KO, 0=Refused, >0 if OK */ function delete($user, $notrigger=0, $idwarehouse=-1) { @@ -1719,9 +1748,13 @@ class Facture extends CommonInvoice dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); - // TODO Test if there is at least one payment. If yes, refuse to delete. + // Test to avoid invoice deletion (allowed if draft) + $test = $this->is_erasable(); + + if ($test <= 0) return $test; $error=0; + $this->db->begin(); if (! $error && ! $notrigger) @@ -3327,9 +3360,9 @@ class Facture extends CommonInvoice /** * Return if an invoice can be deleted * Rule is: - * If hidden option INVOICE_CAN_ALWAYS_BE_REMOVED is on, we can - * If invoice has a definitive ref, is last, without payment and not dipatched into accountancy -> yes end of rule * If invoice is draft and ha a temporary ref -> yes + * If hidden option INVOICE_CAN_ALWAYS_BE_REMOVED is on, we can. If hidden option INVOICE_CAN_NEVER_BE_REMOVED is on, we can't. + * If invoice has a definitive ref, is last, without payment and not dipatched into accountancy -> yes end of rule * * @return int <0 if KO, 0=no, 1=yes */ @@ -3337,30 +3370,36 @@ class Facture extends CommonInvoice { global $conf; + // on verifie si la facture est en numerotation provisoire + $facref = substr($this->ref, 1, 4); + + if ($this->statut == self::STATUS_DRAFT && $facref == 'PROV') // If draft invoice and ref not yet defined + { + return 1; + } + if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED)) return 1; if (! empty($conf->global->INVOICE_CAN_NEVER_BE_REMOVED)) return 0; - // on verifie si la facture est en numerotation provisoire - $facref = substr($this->ref, 1, 4); + // TODO Test if there is at least one payment. If yes, refuse to delete. + // ... // If not a draft invoice and not temporary invoice if ($facref != 'PROV') { $maxfacnumber = $this->getNextNumRef($this->thirdparty,'last'); $ventilExportCompta = $this->getVentilExportCompta(); + // If there is no invoice into the reset range and not already dispatched, we can delete if ($maxfacnumber == '' && $ventilExportCompta == 0) return 1; // If invoice to delete is last one and not already dispatched, we can delete if ($maxfacnumber == $this->ref && $ventilExportCompta == 0) return 1; + if ($this->situation_cycle_ref) { $last = $this->is_last_in_cycle(); return $last; } } - else if ($this->statut == self::STATUS_DRAFT && $facref == 'PROV') // Si facture brouillon et provisoire - { - return 1; - } return 0; } diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 2e7a46f3067..80912bffbad 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -70,13 +70,17 @@ $search_societe=GETPOST('search_societe'); $search_montant_ht=GETPOST('search_montant_ht'); $search_montant_vat=GETPOST('search_montant_vat'); $search_montant_ttc=GETPOST('search_montant_ttc'); +$search_payment_mode=GETPOST('search_payment_mode'); +$search_payment_term=GETPOST('search_payment_term'); $day=GETPOST('day'); $year=GETPOST('year'); $month=GETPOST('month'); $day_date_when=GETPOST('day_date_when'); $year_date_when=GETPOST('year_date_when'); $month_date_when=GETPOST('month_date_when'); -$search_frequency=GETPOST('search_frequency'); +$search_recurring=GETPOST('search_recurring','int'); +$search_frequency=GETPOST('search_frequency','alpha'); +$search_unit_frequency=GETPOST('search_unit_frequency','alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); @@ -111,29 +115,6 @@ $permissionnote = $user->rights->facture->creer; // Used by the include of actio $permissiondellink=$user->rights->facture->creer; // Used by the include of actions_dellink.inc.php $permissiontoedit = $user->rights->facture->creer; // Used by the include of actions_lineupdonw.inc.php -$arrayfields=array( - 'f.titre'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), - 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), - 'f.total'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1), - 'f.tva'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>1), - 'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>1), - 'f.frequency'=>array('label'=>$langs->trans("RecurringInvoiceTemplate"), 'checked'=>1), - 'f.nb_gen_done'=>array('label'=>$langs->trans("NbOfGenerationDone"), 'checked'=>1), - 'f.date_last_gen'=>array('label'=>$langs->trans("DateLastGeneration"), 'checked'=>1), - 'f.date_when'=>array('label'=>$langs->trans("NextDateToExecution"), 'checked'=>1), - 'status'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>100), - 'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), - 'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), -); -// Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); - } -} - /* * Actions @@ -168,13 +149,17 @@ if (empty($reshook)) $search_montant_ht=''; $search_montant_vat=''; $search_montant_ttc=''; + $search_montant_mode=''; + $search_montant_term=''; $day=''; $year=''; $month=''; $day_date_when=''; $year_date_when=''; $month_date_when=''; + $search_recurring=''; $search_frequency=''; + $search_unit_frequency=''; $search_array_options=array(); } @@ -224,8 +209,8 @@ if (empty($reshook)) if (! $error) { $object->titre = GETPOST('titre', 'alpha'); - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->usenewprice = GETPOST('usenewprice'); $object->frequency = $frequency; @@ -375,7 +360,7 @@ if (empty($reshook)) // For triggers $line->id = $lineid; - if ($line->delete() > 0) + if ($line->delete($user) > 0) { $result=$object->update_price(1); @@ -738,7 +723,7 @@ if (empty($reshook)) $date_end = ''; //$date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); //$date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - $description = dol_htmlcleanlastbr(GETPOST('product_desc') ? GETPOST('product_desc') : GETPOST('desc')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc','none') ? GETPOST('product_desc','none') : GETPOST('desc','none')); $pu_ht = GETPOST('price_ht'); $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); $qty = GETPOST('qty'); @@ -980,14 +965,17 @@ if ($action == 'create') print ''.$langs->trans("Customer").''.$object->thirdparty->getNomUrl(1,'customer').''; print ''; - $note_public=GETPOST('note_public')?GETPOST('note_public'):$object->note_public; - $note_private=GETPOST('note_private')?GETPOST('note_private'):$object->note_private; + $note_public=GETPOST('note_public','none')?GETPOST('note_public','none'):$object->note_public; + $note_private=GETPOST('note_private','none')?GETPOST('note_private','none'):$object->note_private; // Help of substitution key $substitutionarray=array( - '__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($object->total_ht).')', - '__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($object->total_ttc).')', - '__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, -1, 'm'),'%m').')', + //'__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($object->total_ht).')', + //'__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($object->total_ttc).')', + '__AMOUNT_EXCL_TAX__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($object->total_ht).')', + '__AMOUNT_VAT__' => $langs->trans("AmountVAT").' ('.$langs->trans("Example").': '.price($object->total_tva).')', + '__AMOUNT__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($object->total_ttc).')', + '__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, -1, 'm'),'%m').')', '__INVOICE_MONTH__' => $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($object->date,'%m').')', '__INVOICE_NEXT_MONTH__' => $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, 1, 'm'),'%m').')', '__INVOICE_PREVIOUS_MONTH_TEXT__' => $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($object->date, -1, 'm'),'%B').')', @@ -1042,7 +1030,7 @@ if ($action == 'create') // Payment mode print "".$langs->trans("PaymentMode").""; - $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'none'); + $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'none', '', 1); print ""; // Project @@ -1077,7 +1065,7 @@ if ($action == 'create') print ''; - // Frequency + // Frequency + unit print '"; @@ -1181,7 +1169,7 @@ else // Recurring invoice content - $linkback = '' . $langs->trans("BackToList") . ''; + $linkback = '' . $langs->trans("BackToList") . ''; $morehtmlref=''; if ($action != 'editref') $morehtmlref.=$form->editfieldkey($object->ref, 'ref', $object->ref, $object, $user->rights->facture->creer, '', '', 0, 2); @@ -1307,8 +1295,11 @@ else $dateexample=dol_now(); if (! empty($object->frequency) && ! empty($object->date_when)) $dateexample=$object->date_when; $substitutionarray=array( - '__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($object->total_ht).')', - '__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($object->total_ttc).')', + //'__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($object->total_ht).')', + //'__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($object->total_ttc).')', + '__AMOUNT_EXCL_TAX__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($object->total_ht).')', + '__AMOUNT_VAT__' => $langs->trans("AmountVAT").' ('.$langs->trans("Example").': '.price($object->total_tva).')', + '__AMOUNT__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($object->total_ttc).')', '__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'),'%m').')', '__INVOICE_MONTH__' => $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample,'%m').')', '__INVOICE_NEXT_MONTH__' => $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'),'%m').')', @@ -1549,8 +1540,6 @@ else { if ($action != 'editline') { - $var = true; - // Add free products/services $object->formAddObjectLine(0, $mysoc, $object->thirdparty); // No date selector for template invoice @@ -1620,382 +1609,6 @@ else print ''; } - else - { - /* - * List mode - */ - $sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre, f.total, f.tva as total_vat, f.total_ttc, f.frequency, f.unit_frequency,"; - $sql.= " f.nb_gen_done, f.nb_gen_max, f.date_last_gen, f.date_when,"; - $sql.= " f.datec, f.tms"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f"; - if (! $user->rights->societe->client->voir && ! $socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql.= " WHERE f.fk_soc = s.rowid"; - $sql.= ' AND f.entity IN ('.getEntity('facture').')'; - if (! $user->rights->societe->client->voir && ! $socid) { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; - } - if ($search_ref) $sql .= natural_search('f.titre', $search_ref); - if ($search_societe) $sql .= natural_search('s.nom', $search_societe); - if ($search_montant_ht != '') $sql.= natural_search('f.total', $search_montant_ht, 1); - if ($search_montant_vat != '') $sql.= natural_search('f.tva', $search_montant_vat, 1); - if ($search_montant_ttc != '') $sql.= natural_search('f.total_ttc', $search_montant_ttc, 1); - if ($search_frequency > 0) $sql.= natural_search('f.frequency', $search_frequency); - if ($search_frequency == '1') $sql.= ' AND f.frequency > 0'; - if ($search_frequency == '0') $sql.= ' AND (f.frequency IS NULL or f.frequency = 0)'; - - if ($month > 0) - { - if ($year > 0 && empty($day)) - $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'"; - else if ($year > 0 && ! empty($day)) - $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; - else - $sql.= " AND date_format(f.date_last_gen, '%m') = '".$month."'"; - } - else if ($year > 0) - { - $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; - } - if ($month_date_when > 0) - { - if ($year_date_when > 0 && empty($day_date_when)) - $sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($year_date_when,$month_date_when,false))."' AND '".$db->idate(dol_get_last_day($year_date_when,$month_date_when,false))."'"; - else if ($year_date_when > 0 && ! empty($day_date_when)) - $sql.= " AND f.date_date_when_reglement BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_date_when, $day_date_when, $year_date_when))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_date_when, $day_date_when, $year_date_when))."'"; - else - $sql.= " AND date_format(f.date_when, '%m') = '".$month_date_when."'"; - } - else if ($year_date_when > 0) - { - $sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($year_date_when,1,false))."' AND '".$db->idate(dol_get_last_day($year_date_when,12,false))."'"; - } - - $nbtotalofrecords = ''; - if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) - { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); - } - - $sql.= $db->order($sortfield, $sortorder); - $sql.= $db->plimit($limit+1,$offset); - - $resql = $db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - - $param=''; - if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; - if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; - if ($socid) $param.='&socid='.$socid; - if ($day) $param.='&day='.$day; - if ($month) $param.='&month='.$month; - if ($year) $param.='&year=' .$year; - if ($day_date_when) $param.='&day_date_when='.$day_date_when; - if ($month_date_when) $param.='&month_date_when='.$month_date_when; - if ($year_date_when) $param.='&year_date_when=' .$year_date_when; - if ($search_ref) $param.='&search_ref=' .$search_ref; - if ($search_societe) $param.='&search_societe=' .$search_societe; - if ($search_montant_ht != '') $param.='&search_montant_ht='.$search_montant_ht; - if ($search_montant_vat != '') $param.='&search_montant_vat='.$search_montant_vat; - if ($search_montant_ttc != '') $param.='&search_montant_ttc='.$search_montant_ttc; - if ($search_frequency > 0) $param.='&search_frequency=' .$search_frequency; - if ($option) $param.="&option=".$option; - if ($optioncss != '') $param.='&optioncss='.$optioncss; - // Add $param from extra fields - foreach ($search_array_options as $key => $val) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); - } - - $massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); - - $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; - $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields - //$selectedfields.=$form->showCheckAddButtons('checkforselect', 1); - - print ''."\n"; - if ($optioncss != '') print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - print_barre_liste($langs->trans("RepeatableInvoices"),$page,$_SERVER['PHP_SELF'],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords,'title_accountancy.png',0,'','', $limit); - - print $langs->trans("ToCreateAPredefinedInvoice", $langs->transnoentitiesnoconv("ChangeIntoRepeatableInvoice")).'

    '; - - $i = 0; - - print '
    '; - print '
    '.$form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency')).""; print " ".$form->selectarray('unit_frequency', array('d'=>$langs->trans('Day'), 'm'=>$langs->trans('Month'), 'y'=>$langs->trans('Year')), (GETPOST('unit_frequency')?GETPOST('unit_frequency'):'m')); print "
    '."\n"; - - // Filters lines - print ''; - // Ref - if (! empty($arrayfields['f.titre']['checked'])) - { - print ''; - } - // Thirpdarty - if (! empty($arrayfields['s.nom']['checked'])) - { - print ''; - } - if (! empty($arrayfields['f.total']['checked'])) - { - // Amount - print ''; - } - if (! empty($arrayfields['f.tva']['checked'])) - { - // Amount - print ''; - } - if (! empty($arrayfields['f.total_ttc']['checked'])) - { - // Amount - print ''; - } - if (! empty($arrayfields['f.frequency']['checked'])) - { - // Recurring or not - print ''; - } - if (! empty($arrayfields['f.nb_gen_done']['checked'])) - { - // Nb generation - print ''; - } - // Date invoice - if (! empty($arrayfields['f.date_last_gen']['checked'])) - { - print ''; - } - // Date due - if (! empty($arrayfields['f.date_when']['checked'])) - { - print ''; - } - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } - // Fields from hook - $parameters=array('arrayfields'=>$arrayfields); - $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Date creation - if (! empty($arrayfields['f.datec']['checked'])) - { - print ''; - } - // Date modification - if (! empty($arrayfields['f.tms']['checked'])) - { - print ''; - } - // Status - if (! empty($arrayfields['status']['checked'])) - { - print ''; - } - // Action column - print ''; - print "\n"; - - - print ''; - if (! empty($arrayfields['f.titre']['checked'])) print_liste_field_titre($arrayfields['f.titre']['label'],$_SERVER['PHP_SELF'],"f.titre","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER['PHP_SELF'],"s.nom","",$param,"",$sortfield,$sortorder); - if (! empty($arrayfields['f.total']['checked'])) print_liste_field_titre($arrayfields['f.total']['label'],$_SERVER['PHP_SELF'],"f.total","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tva']['checked'])) print_liste_field_titre($arrayfields['f.tva']['label'],$_SERVER['PHP_SELF'],"f.tva","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); - if (! empty($arrayfields['f.frequency']['checked'])) print_liste_field_titre($arrayfields['f.frequency']['label'],$_SERVER['PHP_SELF'],"f.frequency","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.nb_gen_done']['checked'])) print_liste_field_titre($arrayfields['f.nb_gen_done']['label'],$_SERVER['PHP_SELF'],"f.nb_gen_done","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.date_last_gen']['checked'])) print_liste_field_titre($arrayfields['f.date_last_gen']['label'],$_SERVER['PHP_SELF'],"f.date_last_gen","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.date_when']['checked'])) print_liste_field_titre($arrayfields['f.date_when']['label'],$_SERVER['PHP_SELF'],"f.date_when","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER['PHP_SELF'],"f.datec","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER['PHP_SELF'],"f.tms","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['status']['checked'])) print_liste_field_titre($arrayfields['status']['label'],$_SERVER['PHP_SELF'],"","",$param,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ')."\n"; - print "\n"; - - - if ($num > 0) - { - $var=true; - while ($i < min($num,$limit)) - { - $objp = $db->fetch_object($resql); - - $companystatic->id=$objp->socid; - $companystatic->name=$objp->name; - - $invoicerectmp->id=$objp->id; - $invoicerectmp->frequency=$objp->frequency; - $invoicerectmp->suspend=$objp->suspend; - $invoicerectmp->unit_frequency=$objp->unit_frequency; - - print ''; - - if (! empty($arrayfields['f.titre']['checked'])) - { - print '\n"; - } - if (! empty($arrayfields['s.nom']['checked'])) - { - print ''; - } - if (! empty($arrayfields['f.total']['checked'])) - { - print ''."\n"; - } - if (! empty($arrayfields['f.tva']['checked'])) - { - print ''."\n"; - } - if (! empty($arrayfields['f.total_ttc']['checked'])) - { - print ''."\n"; - } - if (! empty($arrayfields['f.frequency']['checked'])) - { - print ''; - } - if (! empty($arrayfields['f.nb_gen_done']['checked'])) - { - print ''; - } - if (! empty($arrayfields['f.date_last_gen']['checked'])) - { - print ''; - } - if (! empty($arrayfields['f.date_when']['checked'])) - { - print ''; - } - if (! empty($arrayfields['f.datec']['checked'])) - { - print ''; - } - if (! empty($arrayfields['f.tms']['checked'])) - { - print ''; - } - if (! empty($arrayfields['status']['checked'])) - { - print ''; - } - // Action column - print '"; - print "\n"; - $i++; - } - } - else - { - $colspan=1; - foreach($arrayfields as $key => $val) { if (! empty($val['checked'])) $colspan++; } - print ''; - } - - print "
    '; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print $form->selectyesno('search_frequency', $search_frequency, 1, false, 1); - print ''; - print ''; - if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; - print ''; - $formother->select_year($year?$year:-1,'year',1, 20, 5); - print ''; - if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; - print ''; - $formother->select_year($year_date_when?$year_date_when:-1,'year_date_when',1, 20, 5); - print ''; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print ''; - print ''; - print ''; - print ''; - $searchpicto=$form->showFilterAndCheckAddButtons(0, 'checkforselect', 1); - print $searchpicto; - print '
    '.img_object($langs->trans("ShowBill"),"bill").' '.$objp->titre; - print "'.$companystatic->getNomUrl(1,'customer').''.price($objp->total).''.price($objp->total_vat).''.price($objp->total_ttc).''.yn($objp->frequency?1:0).''; - print ($objp->frequency ? $objp->nb_gen_done.($objp->nb_gen_max>0?' / '. $objp->nb_gen_max:'') : ''.$langs->trans('NA').''); - print ''; - print ($objp->frequency ? dol_print_date($db->jdate($objp->date_last_gen),'day') : ''.$langs->trans('NA').''); - print ''; - print ($objp->frequency ? dol_print_date($db->jdate($objp->date_when),'day') : ''.$langs->trans('NA').''); - print ''; - print dol_print_date($db->jdate($objp->datec),'dayhour'); - print ''; - print dol_print_date($db->jdate($objp->tms),'dayhour'); - print ''; - print $invoicerectmp->getLibStatut(3,0); - print ''; - if ($user->rights->facture->creer) - { - if (empty($objp->frequency) || $db->jdate($objp->date_when) <= $today) - { - print ''; - print $langs->trans("CreateBill").''; - } - else - { - print $langs->trans("DateIsNotEnough"); - } - } - else - { - print " "; - } - print "
    '.$langs->trans("NoRecordFound").'
    "; - print ""; - print ""; - - $db->free($resql); - } - else - { - dol_print_error($db); - } - } - } llxFooter(); diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php new file mode 100644 index 00000000000..f39fc7a3185 --- /dev/null +++ b/htdocs/compta/facture/invoicetemplate_list.php @@ -0,0 +1,700 @@ + + * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2015 Alexandre Spangaro + * Copyright (C) 2016 Meziane Sof + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/compta/facture/invoicetemplate_list.php + * \ingroup facture + * \brief Page to show list of template/recurring invoices + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +if (! empty($conf->projet->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; + //require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; +} +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; + +$langs->load('bills'); +$langs->load('compta'); +$langs->load('admin'); +$langs->load('other'); + +$action = GETPOST('action','alpha'); +$massaction = GETPOST('massaction','alpha'); +$show_files = GETPOST('show_files','int'); +$confirm = GETPOST('confirm','alpha'); +$cancel = GETPOST('cancel', 'alpha'); +$toselect = GETPOST('toselect', 'array'); +$contextpage= GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'invoicetemplatelist'; // To manage different context of search + +// Security check +$id=(GETPOST('facid','int')?GETPOST('facid','int'):GETPOST('id','int')); +$lineid=GETPOST('lineid','int'); +$ref=GETPOST('ref','alpha'); +if ($user->societe_id) $socid=$user->societe_id; +$objecttype = 'facture_rec'; +if ($action == "create" || $action == "add") $objecttype = ''; +$result = restrictedArea($user, 'facture', $id, $objecttype); +$projectid = GETPOST('projectid','int'); + +$search_ref=GETPOST('search_ref'); +$search_societe=GETPOST('search_societe'); +$search_montant_ht=GETPOST('search_montant_ht'); +$search_montant_vat=GETPOST('search_montant_vat'); +$search_montant_ttc=GETPOST('search_montant_ttc'); +$search_payment_mode=GETPOST('search_payment_mode'); +$search_payment_term=GETPOST('search_payment_term'); +$day=GETPOST('day'); +$year=GETPOST('year'); +$month=GETPOST('month'); +$day_date_when=GETPOST('day_date_when'); +$year_date_when=GETPOST('year_date_when'); +$month_date_when=GETPOST('month_date_when'); +$search_recurring=GETPOST('search_recurring','int'); +$search_frequency=GETPOST('search_frequency','alpha'); +$search_unit_frequency=GETPOST('search_unit_frequency','alpha'); + +$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +if (! $sortorder) $sortorder='DESC'; +if (! $sortfield) $sortfield='f.titre'; +$pageprev = $page - 1; +$pagenext = $page + 1; + +$object = new FactureRec($db); +if (($id > 0 || $ref) && $action != 'create' && $action != 'add') +{ + $ret = $object->fetch($id, $ref); + if (!$ret) + { + setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors'); + } +} + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('invoicereccard','globalcard')); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels = $extrafields->fetch_name_optionals_label('facture_rec'); +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_'); + +$permissionnote = $user->rights->facture->creer; // Used by the include of actions_setnotes.inc.php +$permissiondellink=$user->rights->facture->creer; // Used by the include of actions_dellink.inc.php +$permissiontoedit = $user->rights->facture->creer; // Used by the include of actions_lineupdonw.inc.php + +$arrayfields=array( + 'f.titre'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), + 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), + 'f.total'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1), + 'f.tva'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>1), + 'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>1), + 'f.fk_mode_reglement'=>array('label'=>$langs->trans("PaymentMode"), 'checked'=>0), + 'f.fk_cond_reglement'=>array('label'=>$langs->trans("PaymentTerm"), 'checked'=>0), + 'recurring'=>array('label'=>$langs->trans("RecurringInvoiceTemplate"), 'checked'=>1), + 'f.frequency'=>array('label'=>$langs->trans("Frequency"), 'checked'=>1), + 'f.unit_frequency'=>array('label'=>$langs->trans("FrequencyUnit"), 'checked'=>1), + 'f.nb_gen_done'=>array('label'=>$langs->trans("NbOfGenerationDone"), 'checked'=>1), + 'f.date_last_gen'=>array('label'=>$langs->trans("DateLastGeneration"), 'checked'=>1), + 'f.date_when'=>array('label'=>$langs->trans("NextDateToExecution"), 'checked'=>1), + 'status'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>100), + 'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), +); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + } +} + + +/* + * Actions + */ + +if (GETPOST('cancel','alpha')) { $action='list'; $massaction=''; } +if (! GETPOST('confirmmassaction','alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; } + +$parameters = array('socid' => $socid); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + if (GETPOST('cancel','alpha')) $action=''; + + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + // Do we click on purge search criteria ? + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers + { + $search_ref=''; + $search_societe=''; + $search_montant_ht=''; + $search_montant_vat=''; + $search_montant_ttc=''; + $search_payment_mode=''; + $search_payment_term=''; + $day=''; + $year=''; + $month=''; + $day_date_when=''; + $year_date_when=''; + $month_date_when=''; + $search_recurring=''; + $search_frequency=''; + $search_unit_frequency=''; + $search_array_options=array(); + } + + // Mass actions + /*$objectclass='MyObject'; + $objectlabel='MyObject'; + $permtoread = $user->rights->mymodule->read; + $permtodelete = $user->rights->mymodule->delete; + $uploaddir = $conf->mymodule->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';*/ + +} + + +/* + * View + */ + +llxHeader('',$langs->trans("RepeatableInvoices"),'ch-facture.html#s-fac-facture-rec'); + +$form = new Form($db); +$formother = new FormOther($db); +if (! empty($conf->projet->enabled)) { $formproject = new FormProjets($db); } +$companystatic = new Societe($db); +$invoicerectmp = new FactureRec($db); + +$now = dol_now(); +$tmparray=dol_getdate($now); +$today = dol_mktime(23,59,59,$tmparray['mon'],$tmparray['mday'],$tmparray['year']); // Today is last second of current day + + +/* + * List mode + */ +$sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre, f.total, f.tva as total_vat, f.total_ttc, f.frequency, f.unit_frequency,"; +$sql.= " f.nb_gen_done, f.nb_gen_max, f.date_last_gen, f.date_when,"; +$sql.= " f.datec, f.tms,"; +$sql.= " f.fk_cond_reglement, f.fk_mode_reglement"; +$sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture_rec as f"; +if (! $user->rights->societe->client->voir && ! $socid) { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +} +$sql.= " WHERE f.fk_soc = s.rowid"; +$sql.= ' AND f.entity IN ('.getEntity('facture').')'; +if (! $user->rights->societe->client->voir && ! $socid) { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; +} +if ($search_ref) $sql .= natural_search('f.titre', $search_ref); +if ($search_societe) $sql .= natural_search('s.nom', $search_societe); +if ($search_montant_ht != '') $sql .= natural_search('f.total', $search_montant_ht, 1); +if ($search_montant_vat != '') $sql .= natural_search('f.tva', $search_montant_vat, 1); +if ($search_montant_ttc != '') $sql .= natural_search('f.total_ttc', $search_montant_ttc, 1); +if (! empty($search_payment_mode) && $search_payment_mode != '-1') $sql .= natural_search('f.fk_mode_reglement', $search_payment_mode, 1); +if (! empty($search_payment_term) && $search_payment_term != '-1') $sql .= natural_search('f.fk_cond_reglement', $search_payment_term, 1); +if ($search_recurring == '1') $sql .= ' AND f.frequency > 0'; +if ($search_recurring == '0') $sql .= ' AND (f.frequency IS NULL or f.frequency = 0)'; +if ($search_frequency != '') $sql .= natural_search('f.frequency', $search_frequency, 1); +if ($search_unit_frequency != '') $sql .= natural_search('f.unit_frequency', $search_unit_frequency); + +if ($month > 0) +{ + if ($year > 0 && empty($day)) + $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_get_first_day($year,$month,false))."' AND '".$db->idate(dol_get_last_day($year,$month,false))."'"; + else if ($year > 0 && ! empty($day)) + $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; + else + $sql.= " AND date_format(f.date_last_gen, '%m') = '".$month."'"; +} +else if ($year > 0) +{ + $sql.= " AND f.date_last_gen BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; +} +if ($month_date_when > 0) +{ + if ($year_date_when > 0 && empty($day_date_when)) + $sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($year_date_when,$month_date_when,false))."' AND '".$db->idate(dol_get_last_day($year_date_when,$month_date_when,false))."'"; + else if ($year_date_when > 0 && ! empty($day_date_when)) + $sql.= " AND f.date_date_when_reglement BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month_date_when, $day_date_when, $year_date_when))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month_date_when, $day_date_when, $year_date_when))."'"; + else + $sql.= " AND date_format(f.date_when, '%m') = '".$month_date_when."'"; +} +else if ($year_date_when > 0) +{ + $sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($year_date_when,1,false))."' AND '".$db->idate(dol_get_last_day($year_date_when,12,false))."'"; +} + +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} + +$sql.= $db->order($sortfield, $sortorder); +$sql.= $db->plimit($limit+1,$offset); + +$resql = $db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + + $param=''; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage); + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit); + if ($socid) $param.='&socid='.urlencode($socid); + if ($day) $param.='&day='.urlencode($day); + if ($month) $param.='&month='.urlencode($month); + if ($year) $param.='&year=' .urlencode($year); + if ($day_date_when) $param.='&day_date_when='.urlencode($day_date_when); + if ($month_date_when) $param.='&month_date_when='.urlencode($month_date_when); + if ($year_date_when) $param.='&year_date_when=' .urlencode($year_date_when); + if ($search_ref) $param.='&search_ref=' .urlencode($search_ref); + if ($search_societe) $param.='&search_societe=' .urlencode($search_societe); + if ($search_montant_ht != '') $param.='&search_montant_ht=' .urlencode($search_montant_ht); + if ($search_montant_vat != '') $param.='&search_montant_vat='.urlencode($search_montant_vat); + if ($search_montant_ttc != '') $param.='&search_montant_ttc='.urlencode($search_montant_ttc); + if ($search_payment_mode != '') $param.='&search_payment_mode='.urlencode($search_payment_mode); + if ($search_payment_type != '') $param.='&search_payment_type='.urlencode($search_payment_type); + if ($search_recurring != '' && $search_recurrning != '-1') $param.='&search_recurring=' .urlencode($search_recurring); + if ($search_frequency > 0) $param.='&search_frequency=' .urlencode($search_frequency); + if ($search_unit_frequency > 0) $param.='&search_unit_frequency='.urlencode($search_unit_frequency); + if ($option) $param.="&option=".urlencode($option); + if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss); + // Add $param from extra fields + foreach ($search_array_options as $key => $val) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); + } + + $massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); + + $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; + $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + //$selectedfields.=$form->showCheckAddButtons('checkforselect', 1); + + print '
    '; + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + print_barre_liste($langs->trans("RepeatableInvoices"),$page,$_SERVER['PHP_SELF'],$param,$sortfield,$sortorder,'',$num,$nbtotalofrecords,'title_accountancy.png',0,'','', $limit); + + print $langs->trans("ToCreateAPredefinedInvoice", $langs->transnoentitiesnoconv("ChangeIntoRepeatableInvoice")).'

    '; + + $i = 0; + + print '
    '; + print ''."\n"; + + // Filters lines + print ''; + // Ref + if (! empty($arrayfields['f.titre']['checked'])) + { + print ''; + } + // Thirpdarty + if (! empty($arrayfields['s.nom']['checked'])) + { + print ''; + } + if (! empty($arrayfields['f.total']['checked'])) + { + // Amount net + print ''; + } + if (! empty($arrayfields['f.tva']['checked'])) + { + // Amount Vat + print ''; + } + if (! empty($arrayfields['f.total_ttc']['checked'])) + { + // Amount + print ''; + } + if (! empty($arrayfields['f.fk_cond_reglement']['checked'])) + { + // Payment term + print '"; + } + if (! empty($arrayfields['f.fk_mode_reglement']['checked'])) + { + // Payment mode + print ''; + } + if (! empty($arrayfields['recurring']['checked'])) + { + // Recurring or not + print ''; + } + if (! empty($arrayfields['f.frequency']['checked'])) + { + // Recurring or not + print ''; + } + if (! empty($arrayfields['f.unit_frequency']['checked'])) + { + // Frequency unit + print ''; + } + if (! empty($arrayfields['f.nb_gen_done']['checked'])) + { + // Nb generation + print ''; + } + // Date invoice + if (! empty($arrayfields['f.date_last_gen']['checked'])) + { + print ''; + } + // Date due + if (! empty($arrayfields['f.date_when']['checked'])) + { + print ''; + } + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields); + $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Date creation + if (! empty($arrayfields['f.datec']['checked'])) + { + print ''; + } + // Date modification + if (! empty($arrayfields['f.tms']['checked'])) + { + print ''; + } + // Status + if (! empty($arrayfields['status']['checked'])) + { + print ''; + } + // Action column + print ''; + print "\n"; + + + print ''; + if (! empty($arrayfields['f.titre']['checked'])) print_liste_field_titre($arrayfields['f.titre']['label'],$_SERVER['PHP_SELF'],"f.titre","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER['PHP_SELF'],"s.nom","",$param,"",$sortfield,$sortorder); + if (! empty($arrayfields['f.total']['checked'])) print_liste_field_titre($arrayfields['f.total']['label'],$_SERVER['PHP_SELF'],"f.total","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tva']['checked'])) print_liste_field_titre($arrayfields['f.tva']['label'],$_SERVER['PHP_SELF'],"f.tva","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'],$_SERVER['PHP_SELF'],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_cond_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_cond_reglement']['label'],$_SERVER['PHP_SELF'],"f.fk_cond_reglement","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'],$_SERVER['PHP_SELF'],"f.fk_mode_reglement","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['recurring']['checked'])) print_liste_field_titre($arrayfields['recurring']['label'],$_SERVER['PHP_SELF'],"recurring","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.frequency']['checked'])) print_liste_field_titre($arrayfields['f.frequency']['label'],$_SERVER['PHP_SELF'],"f.frequency","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.unit_frequency']['checked'])) print_liste_field_titre($arrayfields['f.unit_frequency']['label'],$_SERVER['PHP_SELF'],"f.unit_frequency","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.nb_gen_done']['checked'])) print_liste_field_titre($arrayfields['f.nb_gen_done']['label'],$_SERVER['PHP_SELF'],"f.nb_gen_done","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.date_last_gen']['checked'])) print_liste_field_titre($arrayfields['f.date_last_gen']['label'],$_SERVER['PHP_SELF'],"f.date_last_gen","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.date_when']['checked'])) print_liste_field_titre($arrayfields['f.date_when']['label'],$_SERVER['PHP_SELF'],"f.date_when","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER['PHP_SELF'],"f.datec","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER['PHP_SELF'],"f.tms","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['status']['checked'])) print_liste_field_titre($arrayfields['status']['label'],$_SERVER['PHP_SELF'],"","",$param,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'nomaxwidthsearch ')."\n"; + print "\n"; + + if ($num > 0) + { + $i=0; + $totalarray=array(); + while ($i < min($num,$limit)) + { + $objp = $db->fetch_object($resql); + if (empty($objp)) break; + + $companystatic->id=$objp->socid; + $companystatic->name=$objp->name; + + $invoicerectmp->id=$objp->id; + $invoicerectmp->frequency=$objp->frequency; + $invoicerectmp->suspend=$objp->suspend; + $invoicerectmp->unit_frequency=$objp->unit_frequency; + + print ''; + + if (! empty($arrayfields['f.titre']['checked'])) + { + print '\n"; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['s.nom']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.total']['checked'])) + { + print ''."\n"; + if (! $i) $totalarray['nbfield']++; + if (! $i) $totalarray['pos'][$totalarray['nbfield']]='f.total'; + $totalarray['val']['f.total'] += $objp->total; + } + if (! empty($arrayfields['f.tva']['checked'])) + { + print ''."\n"; + if (! $i) $totalarray['nbfield']++; + if (! $i) $totalarray['pos'][$totalarray['nbfield']]='f.tva'; + $totalarray['val']['f.tva'] += $objp->total_vat; + } + if (! empty($arrayfields['f.total_ttc']['checked'])) + { + print ''."\n"; + if (! $i) $totalarray['nbfield']++; + if (! $i) $totalarray['pos'][$totalarray['nbfield']]='f.total_ttc'; + $totalarray['val']['f.total_ttc'] += $objp->total_ttc; + } + // Payment term + if (! empty($arrayfields['f.fk_cond_reglement']['checked'])) + { + print ''."\n"; + if (! $i) $totalarray['nbfield']++; + } + // Payment mode + if (! empty($arrayfields['f.fk_mode_reglement']['checked'])) + { + print ''."\n"; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['recurring']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.frequency']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.unit_frequency']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.nb_gen_done']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.date_last_gen']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.date_when']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.datec']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.tms']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['status']['checked'])) + { + print ''; + if (! $i) $totalarray['nbfield']++; + } + // Action column + print '"; + + print "\n"; + + $i++; + } + } + else + { + $colspan=1; + foreach($arrayfields as $key => $val) { if (! empty($val['checked'])) $colspan++; } + print ''; + } + + //var_dump($totalarray); + // Show total line + if (isset($totalarray['pos'])) + { + print ''; + $i=0; + while ($i < $totalarray['nbfield']) + { + $i++; + if (! empty($totalarray['pos'][$i])) print ''; + else + { + if ($i == 1) + { + if ($num < $limit) print ''; + else print ''; + } + else print ''; + } + } + print ''; + } + + print "
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print $form->select_conditions_paiements($search_payment_term, 'search_payment_term', -1, 1, 1, 'maxwidth100'); + print "'; + print $form->select_types_paiements($search_payment_mode, 'search_payment_mode', '', 0, 1, 1, 0, 1, 'maxwidth100'); + print ''; + print $form->selectyesno('search_recurring', $search_recurring, 1, false, 1); + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; + $formother->select_year($year?$year:-1,'year',1, 20, 5); + print ''; + if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; + print ''; + $formother->select_year($year_date_when?$year_date_when:-1,'year_date_when',1, 20, 5); + print ''; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + print ''; + print ''; + print ''; + print ''; + $searchpicto=$form->showFilterAndCheckAddButtons(0, 'checkforselect', 1); + print $searchpicto; + print '
    '.img_object($langs->trans("ShowBill"),"bill").' '.$objp->titre; + print "'.$companystatic->getNomUrl(1,'customer').''.price($objp->total).''.price($objp->total_vat).''.price($objp->total_ttc).''; + print $form->form_conditions_reglement('', $objp->fk_cond_reglement, 'none'); + print ''; + print $form->form_modes_reglement('', $objp->fk_mode_reglement, 'none'); + print ''.yn($objp->frequency?1:0).''.($objp->frequency > 0 ? $objp->frequency : '').''.($objp->frequency > 0 ? $objp->unit_frequency : '').''; + print ($objp->frequency ? $objp->nb_gen_done.($objp->nb_gen_max>0?' / '. $objp->nb_gen_max:'') : ''.$langs->trans('NA').''); + print ''; + print ($objp->frequency ? dol_print_date($db->jdate($objp->date_last_gen),'day') : ''.$langs->trans('NA').''); + print ''; + print ($objp->frequency ? dol_print_date($db->jdate($objp->date_when),'day') : ''.$langs->trans('NA').''); + print ''; + print dol_print_date($db->jdate($objp->datec),'dayhour'); + print ''; + print dol_print_date($db->jdate($objp->tms),'dayhour'); + print ''; + print $invoicerectmp->getLibStatut(3,0); + print ''; + if ($user->rights->facture->creer) + { + if (empty($objp->frequency) || $db->jdate($objp->date_when) <= $today) + { + print ''; + print $langs->trans("CreateBill").''; + } + else + { + print $langs->trans("DateIsNotEnough"); + } + } + else + { + print " "; + } + if (! $i) $totalarray['nbfield']++; + print "
    '.$langs->trans("NoRecordFound").'
    '.price($totalarray['val'][$totalarray['pos'][$i]]).''.$langs->trans("Total").''.$langs->trans("Totalforthispage").'
    "; + print "
    "; + print "
    "; + + $db->free($resql); +} +else +{ + dol_print_error($db); +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 46f8c76ae58..be81fe48a0c 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -95,8 +95,10 @@ $month_lim = GETPOST('month_lim','int'); $year_lim = GETPOST('year_lim','int'); $option = GETPOST('option'); -if ($option == 'late') $filter = 'paye:0'; -$filtre = GETPOST('filtre'); +if ($option == 'late') { + $search_status = '1'; +} +$filtre = GETPOST('filtre','alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); @@ -110,8 +112,8 @@ if (! $sortfield) $sortfield='f.datef'; $pageprev = $page - 1; $pagenext = $page + 1; -// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$contextpage='invoicelist'; +// Initialize technical object to manage context to save list fields +$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'invoicelist'; // Security check $fieldid = (! empty($ref)?'facnumber':'rowid'); @@ -172,7 +174,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -387,7 +389,7 @@ if ($search_user > 0) $sql.= ' WHERE f.fk_soc = s.rowid'; $sql.= ' AND f.entity IN ('.getEntity('facture').')'; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; -if ($search_product_category > 0) $sql.=" AND cp.fk_categorie = ".$search_product_category; +if ($search_product_category > 0) $sql.=" AND cp.fk_categorie = ".$db->escape($search_product_category); if ($socid > 0) $sql.= ' AND s.rowid = '.$socid; if ($userid) { @@ -400,7 +402,7 @@ if ($filtre) foreach ($aFilter as $filter) { $filt = explode(':', $filter); - $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); + $sql .= ' AND ' . $db->escape(trim($filt[0])) . ' = ' . $db->escape(trim($filt[1])); } } if ($search_ref) $sql .= natural_search('f.facnumber', $search_ref); @@ -434,7 +436,7 @@ if ($search_status != '' && $search_status >= 0) if ($search_status == '2') $sql.=" AND f.fk_statut = 2"; // payed Not that some corrupted data may contains f.fk_statut = 1 AND f.paye = 1 (it means payed too but should not happend. If yes, reopen and reclassify billed) if ($search_status == '3') $sql.=" AND f.fk_statut = 3"; // abandonned } -if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$search_paymentmode; +if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$db->escape($search_paymentmode); if ($month > 0) { if ($year > 0 && empty($day)) @@ -462,7 +464,6 @@ else if ($year_lim > 0) $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($year_lim,1,false))."' AND '".$db->idate(dol_get_last_day($year_lim,12,false))."'"; } if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->client->warning_delay)."'"; -if ($filter == 'paye:0') $sql.= " AND f.fk_statut = 1"; if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; if ($search_user > 0) { @@ -494,7 +495,7 @@ if (! $sall) $sql.= ' f.datef, f.date_lim_reglement,'; $sql.= ' f.paye, f.fk_statut,'; $sql.= ' f.datec, f.tms,'; - $sql.= ' s.rowid, s.nom, s.town, s.zip, s.fk_pays, s.code_client, s.client, typent.code,'; + $sql.= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.code_client, s.client, typent.code,'; $sql.= ' state.code_departement, state.nom'; foreach ($extrafields->attribute_label as $key => $val) //prevent error with sql_mode=only_full_group_by @@ -606,6 +607,7 @@ if ($resql) print ''; print ''; print ''; + print ''; print_barre_liste($langs->trans('BillsCustomers').' '.($socid?' '.$soc->name:''), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy.png', 0, '', '', $limit); diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 523d5256816..da38e9fb47a 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -60,7 +60,7 @@ if ($action == 'setnote' && $user->rights->facture->paiement) $db->begin(); $object->fetch($id); - $result = $object->update_note(GETPOST('note')); + $result = $object->update_note(GETPOST('note','none')); if ($result > 0) { $db->commit(); diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php index 808d2cbb00b..8f5f51f36e9 100644 --- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php +++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php @@ -478,20 +478,20 @@ class RemiseCheque extends CommonObject return ""; } } - - + + /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * - * @param User $user Objet user - * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Objet user + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK */ function load_board($user) { global $conf, $langs; - + if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe - + $sql = "SELECT b.rowid, b.datev as datefin"; $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; $sql.= ", ".MAIN_DB_PREFIX."bank_account as ba"; @@ -500,28 +500,28 @@ class RemiseCheque extends CommonObject $sql.= " AND b.fk_type = 'CHQ'"; $sql.= " AND b.fk_bordereau = 0"; $sql.= " AND b.amount > 0"; - + $resql=$this->db->query($sql); if ($resql) { $langs->load("banks"); $now=dol_now(); - + $response = new WorkboardResponse(); $response->warning_delay=$conf->bank->cheque->warning_delay/60/60/24; $response->label=$langs->trans("BankChecksToReceipt"); $response->url=DOL_URL_ROOT.'/compta/paiement/cheque/index.php?leftmenu=checks&mainmenu=bank'; $response->img=img_object('',"payment"); - + while ($obj=$this->db->fetch_object($resql)) { $response->nbtodo++; - + if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->cheque->warning_delay)) { $response->nbtodolate++; } } - + return $response; } else @@ -531,6 +531,45 @@ class RemiseCheque extends CommonObject return -1; } } + + + /** + * Charge indicateurs this->nb de tableau de bord + * + * @return int <0 if ko, >0 if ok + */ + function load_state_board() + { + global $user; + + if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe + + $sql = "SELECT count(b.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; + $sql.= ", ".MAIN_DB_PREFIX."bank_account as ba"; + $sql.= " WHERE b.fk_account = ba.rowid"; + $sql.= " AND ba.entity IN (".getEntity('bank_account').")"; + $sql.= " AND b.fk_type = 'CHQ'"; + $sql.= " AND b.amount > 0"; + + $resql=$this->db->query($sql); + if ($resql) + { + + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["cheques"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } /** diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 0278d97d724..a3d50d58143 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -953,6 +953,7 @@ class BonPrelevement extends CommonObject { $prev_id = $this->db->last_insert_id(MAIN_DB_PREFIX."prelevement_bons"); $this->id = $prev_id; + $this->ref = $ref; } else { diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 6743ea3098b..09102ec1309 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -80,7 +80,7 @@ if ($action == 'create') } else { - setEventMessages($langs->trans("DirectDebitOrderCreated"), null); + setEventMessages($langs->trans("DirectDebitOrderCreated", $bprev->getNomUrl(1)), null); } } diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index f7e41bdc997..60215005446 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -145,9 +145,9 @@ if ($prev_id > 0 || $ref) // List of invoices -$sql = "SELECT pf.rowid"; -$sql.= ",f.rowid as facid, f.facnumber as ref, f.total_ttc"; -$sql.= ", s.rowid as socid, s.nom as name, pl.statut"; +$sql = "SELECT pf.rowid,"; +$sql.= " f.rowid as facid, f.facnumber as ref, f.total_ttc,"; +$sql.= " s.rowid as socid, s.nom as name, pl.statut, pl.amount as amount_requested"; $sql.= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql.= ", ".MAIN_DB_PREFIX."prelevement_lignes as pl"; $sql.= ", ".MAIN_DB_PREFIX."prelevement_facture as pf"; @@ -202,14 +202,14 @@ if ($result) print ''; print_liste_field_titre("Bill",$_SERVER["PHP_SELF"],"p.ref",'',$param,'',$sortfield,$sortorder); print_liste_field_titre("ThirdParty",$_SERVER["PHP_SELF"],"s.nom",'',$param,'',$sortfield,$sortorder); - print_liste_field_titre("Amount",$_SERVER["PHP_SELF"],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre("AmountInvoice",$_SERVER["PHP_SELF"],"f.total_ttc","",$param,'align="right"',$sortfield,$sortorder); + print_liste_field_titre("AmountRequested",$_SERVER["PHP_SELF"],"pl.amount_requested","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre("StatusDebitCredit",$_SERVER["PHP_SELF"],"","",$param,'align="center"',$sortfield,$sortorder); print_liste_field_titre(''); print "\n"; - $var=false; - - $total = 0; + $totalinvoices = 0; + $totalamount_requested = 0; while ($i < min($num, $limit)) { @@ -231,9 +231,12 @@ if ($result) print $thirdpartytmp->getNomUrl(1); print "\n"; - // Amount + // Amount of invoice print ''.price($obj->total_ttc)."\n"; + // Amount requested + print ''.price($obj->amount_requested)."\n"; + // Status of requests print ''; @@ -256,7 +259,8 @@ if ($result) print "\n"; - $total += $obj->total_ttc; + $totalinvoices += $obj->total_ttc; + $totalamount_requested += $obj->amount_requested; $i++; } @@ -267,8 +271,11 @@ if ($result) print ''.$langs->trans("Total").''; print ' '; print ''; - if ($total != $object->amount) print img_warning("AmountOfFileDiffersFromSumOfInvoices"); - print price($total); + //if ($totalinvoices != $object->amount) print img_warning("AmountOfFileDiffersFromSumOfInvoices"); // It is normal to have total that differs. For an amount of invoice of 100, request to pay may be 50 only. + if ($totalamount_requested != $object->amount) print img_warning("AmountOfFileDiffersFromSumOfInvoices"); + print "\n"; + print ''; + print price($totalamount_requested); print "\n"; print ' '; print ' '; diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php index 2b8b6a6fe5b..47d4c027185 100644 --- a/htdocs/compta/salaries/card.php +++ b/htdocs/compta/salaries/card.php @@ -214,6 +214,12 @@ if ($action == 'create') $pastmonthyear--; } + $datespmonth = GETPOST('datespmonth', 'int'); + $datespday = GETPOST('datespday', 'int'); + $datespyear = GETPOST('datespyear', 'int'); + $dateepmonth = GETPOST('dateepmonth', 'int'); + $dateepday = GETPOST('dateepday', 'int'); + $dateepyear = GETPOST('dateepyear', 'int'); $datesp=dol_mktime(0, 0, 0, $datespmonth, $datespday, $datespyear); $dateep=dol_mktime(23, 59, 59, $dateepmonth, $dateepday, $dateepyear); @@ -253,7 +259,7 @@ if ($action == 'create') // Label print ''; print fieldLabel('Label','label',1).''; - print 'trans("SalaryPayment")).'">'; + print 'trans("SalaryPayment")).'">'; print ''; // Date start period diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 7dffd99f8bf..ac3c52ae8f5 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -224,7 +224,7 @@ if (empty($reshook)) $action = 'create'; } else { // Categories association - $contcats = GETPOST( 'contcats', 'array' ); + $contcats = GETPOST( 'contcats', 'array'); $object->setCategories($contcats); } } @@ -383,7 +383,7 @@ if (empty($reshook)) $db->query( $sql ); // Then we add the associated categories - $categories = GETPOST( 'contcats', 'array' ); + $categories = GETPOST( 'contcats', 'array'); $object->setCategories($categories); $object->old_lastname=''; @@ -396,6 +396,15 @@ if (empty($reshook)) $action = 'edit'; } } + + if (! $error && empty($errors)) + { + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + } } } @@ -541,7 +550,7 @@ else { print ''; print ''; - print $objsoc->getNomUrl(1); + print $objsoc->getNomUrl(1, 'contact'); print ''; print ''; print ''; @@ -1063,7 +1072,7 @@ else $objsoc->fetch($object->socid); // Thirdparty $morehtmlref.=$langs->trans('ThirdParty') . ' : '; - if ($objsoc->id > 0) $morehtmlref.=$objsoc->getNomUrl(1); + if ($objsoc->id > 0) $morehtmlref.=$objsoc->getNomUrl(1, 'contact'); else $morehtmlref.=$langs->trans("ContactNotLinkedToCompany"); } $morehtmlref.=''; diff --git a/htdocs/contact/ldap.php b/htdocs/contact/ldap.php index 16c00bf92cb..759831f7d57 100644 --- a/htdocs/contact/ldap.php +++ b/htdocs/contact/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2012 Regis Houssin + * Copyright (C) 2006-2017 Regis Houssin * * 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 @@ -91,7 +91,7 @@ $head = contact_prepare_head($object); dol_fiche_head($head, 'ldap', $title, -1, 'contact'); dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', ''); - + print '
    '; print '
    '; @@ -196,15 +196,11 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; - - - llxFooter(); - $db->close(); diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index ebf7bc611f9..05fcf3e0916 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -160,7 +160,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 0e8722d20b8..46fa2b3ca87 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -676,7 +676,7 @@ if (empty($reshook)) $fk_unit = GETPOST('unit', 'alpha'); - $objectline->description=GETPOST('product_desc'); + $objectline->description=GETPOST('product_desc','none'); $objectline->price_ht=GETPOST('elprice'); $objectline->subprice=GETPOST('elprice'); $objectline->qty=GETPOST('elqty'); @@ -918,51 +918,17 @@ if (empty($reshook)) } } - // Generation doc (depuis lien ou depuis cartouche doc) - else if ($action == 'builddoc' && $user->rights->contrat->creer) { - if (GETPOST('model')) { - $object->setDocModel($user, GETPOST('model')); - } - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - $action=''; - } - } - - // Remove file in doc form - else if ($action == 'remove_file' && $user->rights->contrat->creer) { - if ($object->id > 0) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $langs->load("other"); - $upload_dir = $conf->contrat->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); - else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors'); - } - } - - /* - * Send mail - */ + // Actions to build doc + $upload_dir = $conf->contrat->dir_output; + $permissioncreate = $user->rights->contrat->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; // Actions to send emails $trigger_name='CONTRACT_SENTBYMAIL'; $paramname='id'; $mode='emailfromcontract'; - $trackid='cont'.$object->id; + $trackid='con'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; @@ -2164,136 +2130,13 @@ else print '
    '; } - /* - * Action presend - */ - if ($action == 'presend') - { - $object->fetch_projet(); - - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->contrat->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - - if (!empty($newlang)) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); - $outputlangs->load('commercial'); - } - - // Build document if it not exists - if (! $file || ! is_readable($file)) { - $result = $object->generateDocument(GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) { - dol_print_error($db, $object->error, $object->errors); - exit(); - } - $fileparams = dol_most_recent_file($conf->contrat->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - } - - print '
    '; - print '
    '; - print '
    '; - print load_fiche_titre($langs->trans('SendByMail')); - - dol_fiche_head(''); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='cont'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id); - } - $formmail->withfrom = 1; - $liste = array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) - $liste [$key] = $value; - $formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste; - $formmail->withtocc = $liste; - $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; - if (empty($object->ref_client)) { - $formmail->withtopic = $outputlangs->trans('SendContractRef', '__CONTRACTREF__'); - } else if (! empty($object->ref_client)) { - $formmail->withtopic = $outputlangs->trans('SendContractRef', '__CONTRACTREF__ (__REFCLIENT__)'); - } - $formmail->withfile = 2; - $formmail->withbody = 1; - $formmail->withdeliveryreceipt = 1; - $formmail->withcancel = 1; - // Array of substitutions - $formmail->withsubstit='AvailableVariables'; - $formmail->setSubstitFromObject($object); - $datenextexpiration=''; - foreach($object->lines as $line) - { - if ($line->statut != 4) continue; - if ($line->date_fin_prevue > $datenextexpiration) $datenextexpiration = $line->date_fin_prevue; - } - $formmail->substit['__CONTRACT_NEXT_EXPIRATION_DATE__'] = dol_print_date($datenextexpiration, 'dayrfc'); - $formmail->substit['__CONTRACT_NEXT_EXPIRATION_DATETIME__'] = dol_print_date($datenextexpiration, 'standard'); - $formmail->substit['__PERSONALIZED__']=''; - $formmail->substit['__CONTACTCIVNAME__']=''; - - $custcontact = ''; - $contactarr = array(); - $contactarr = $object->liste_contact(- 1, 'external'); - - if (is_array($contactarr) && count($contactarr) > 0) - { - foreach ($contactarr as $contact) - { - if ($contact['libelle'] == $langs->trans('TypeContact_contract_external_CUSTOMER')) { // TODO Use code and not label - $contactstatic = new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact = $contactstatic->getFullName($langs, 1); - } - } - - if (! empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__'] = $custcontact; - } - } - - // Tableau des parametres complementaires - $formmail->param['action'] = 'send'; - $formmail->param['models'] = 'contract_send'; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['contractid'] = $object->id; - $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id; - - // Init list of files - if (GETPOST("mode") == 'init') { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); - } - - // Show form - print $formmail->get_form(); - - dol_fiche_end(); - } + // Presend form + $modelmail='contract'; + $defaulttopic='SendContractRef'; + $diroutput = $conf->contrat->dir_output; + $trackid = 'con'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } } diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 6e9fc443e03..61cd62bd338 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -538,11 +538,13 @@ class Contrat extends CommonObject /** * Load a contract from database * - * @param int $id Id of contract to load - * @param string $ref Ref - * @return int <0 if KO, id of contract if OK + * @param int $id Id of contract to load + * @param string $ref Ref + * @param string $ref_customer Customer ref + * @param string $ref_supplier Supplier ref + * @return int <0 if KO, 0 if not found, Id of contract if OK */ - function fetch($id,$ref='') + function fetch($id, $ref='', $ref_customer='', $ref_supplier='') { $sql = "SELECT rowid, statut, ref, fk_soc, mise_en_service as datemise,"; $sql.= " ref_supplier, ref_customer,"; @@ -553,12 +555,20 @@ class Contrat extends CommonObject $sql.= " fk_commercial_signature, fk_commercial_suivi,"; $sql.= " note_private, note_public, model_pdf, extraparams"; $sql.= " FROM ".MAIN_DB_PREFIX."contrat"; + if (! $id) $sql.=" WHERE entity IN (".getEntity('contract', 0).")"; + else $sql.= " WHERE rowid=".$id; + if ($ref_customer) + { + $sql.= " AND ref_customer = '".$this->db->escape($ref_customer)."'"; + } + if ($ref_supplier) + { + $sql.= " AND ref_supplier = '".$this->db->escape($ref_supplier)."'"; + } if ($ref) { - $sql.= " WHERE ref='".$this->db->escape($ref)."'"; - $sql.= " AND entity IN (".getEntity('contract', 0).")"; + $sql.= " AND ref='".$this->db->escape($ref)."'"; } - else $sql.= " WHERE rowid=".$id; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql = $this->db->query($sql); @@ -628,7 +638,7 @@ class Contrat extends CommonObject { dol_syslog(get_class($this)."::Fetch Erreur contrat non trouve"); $this->error="Contract not found"; - return -2; + return 0; } } else @@ -780,7 +790,7 @@ class Contrat extends CommonObject } // Selectionne les lignes contrat liees a aucun produit - $sql = "SELECT d.rowid, d.fk_contrat, d.statut, d.qty, d.description, d.price_ht, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.rowid, d.remise_percent, d.subprice,"; + $sql = "SELECT d.rowid, d.fk_contrat, d.statut, d.qty, d.description, d.price_ht, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.rowid, d.remise_percent, d.subprice,"; $sql.= " d.total_ht,"; $sql.= " d.total_tva,"; $sql.= " d.total_localtax1,"; @@ -818,6 +828,8 @@ class Contrat extends CommonObject $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; + $line->localtax1_type = $objp->localtax1_type; + $line->localtax2_type = $objp->localtax2_type; $line->subprice = $objp->subprice; $line->remise_percent = $objp->remise_percent; $line->price_ht = $objp->price_ht; @@ -924,7 +936,7 @@ class Contrat extends CommonObject $sql.= " fk_commercial_signature, fk_commercial_suivi, fk_projet,"; $sql.= " ref, entity, note_private, note_public, ref_customer, ref_supplier, ref_ext)"; $sql.= " VALUES ('".$this->db->idate($now)."',".$this->socid.",".$user->id; - $sql.= ", '".$this->db->idate($this->date_contrat)."'"; + $sql.= ", ".(dol_strlen($this->date_contrat)!=0 ? "'".$this->db->idate($this->date_contrat)."'" : "NULL"); $sql.= ",".($this->commercial_signature_id>0?$this->commercial_signature_id:"NULL"); $sql.= ",".($this->commercial_suivi_id>0?$this->commercial_suivi_id:"NULL"); $sql.= ",".($this->fk_project>0?$this->fk_project:"NULL"); @@ -2701,6 +2713,8 @@ class ContratLigne extends CommonObjectLine $sql.= " t.vat_src_code,"; $sql.= " t.localtax1_tx,"; $sql.= " t.localtax2_tx,"; + $sql.= " t.localtax1_type,"; + $sql.= " t.localtax2_type,"; $sql.= " t.qty,"; $sql.= " t.remise_percent,"; $sql.= " t.remise,"; @@ -2754,6 +2768,8 @@ class ContratLigne extends CommonObjectLine $this->vat_src_code = $obj->vat_src_code; $this->localtax1_tx = $obj->localtax1_tx; $this->localtax2_tx = $obj->localtax2_tx; + $this->localtax1_type = $obj->localtax1_type; + $this->localtax2_type = $obj->localtax2_type; $this->qty = $obj->qty; $this->remise_percent = $obj->remise_percent; $this->remise = $obj->remise; @@ -2834,6 +2850,7 @@ class ContratLigne extends CommonObjectLine if (empty($this->total_ttc)) $this->total_ttc = 0; if (empty($this->localtax1_tx)) $this->localtax1_tx = 0; if (empty($this->localtax2_tx)) $this->localtax2_tx = 0; + if (empty($this->remise_percent)) $this->remise_percent = 0; // Check parameters // Put here code to add control on parameters values diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 76b710bc5c8..64f2b6b94f2 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2014 Juanjo Menent @@ -47,12 +47,14 @@ $confirm=GETPOST('confirm','alpha'); $toselect = GETPOST('toselect', 'array'); $search_name=GETPOST('search_name'); +$search_email=GETPOST('search_email'); $search_town=GETPOST('search_town','alpha'); $search_zip=GETPOST('search_zip','alpha'); $search_state=trim(GETPOST("search_state")); $search_country=GETPOST("search_country",'int'); $search_type_thirdparty=GETPOST("search_type_thirdparty",'int'); $search_contract=GETPOST('search_contract'); +$search_ref_customer=GETPOST('search_ref_customer','alpha'); $search_ref_supplier=GETPOST('search_ref_supplier','alpha'); $sall=GETPOST('sall', 'alphanohtml'); $search_status=GETPOST('search_status'); @@ -115,7 +117,8 @@ $arrayfields=array( 'c.ref_customer'=>array('label'=>$langs->trans("RefCustomer"), 'checked'=>1), 'c.ref_supplier'=>array('label'=>$langs->trans("RefSupplier"), 'checked'=>1), 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), - 's.town'=>array('label'=>$langs->trans("Town"), 'checked'=>0), + 's.email'=>array('label'=>$langs->trans("ThirdPartyEmail"), 'checked'=>0), + 's.town'=>array('label'=>$langs->trans("Town"), 'checked'=>0), 's.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>0), 'state.nom'=>array('label'=>$langs->trans("StateShort"), 'checked'=>0), 'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0), @@ -130,7 +133,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -155,12 +158,14 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', $month=''; $year=''; $search_name=""; - $search_town=''; + $search_email=""; + $search_town=''; $search_zip=""; $search_state=""; $search_type=''; $search_country=''; $search_contract=""; + $search_ref_customer=""; $search_ref_supplier=""; $search_user=''; $search_sale=''; @@ -197,7 +202,7 @@ llxHeader('', $langs->trans("Contracts")); $sql = 'SELECT'; $sql.= " c.rowid, c.ref, c.datec as date_creation, c.tms as date_update, c.date_contrat, c.statut, c.ref_customer, c.ref_supplier, c.note_private, c.note_public,"; -$sql.= ' s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s.code_client,'; +$sql.= ' s.rowid as socid, s.nom as name, s.email, s.town, s.zip, s.fk_pays, s.client, s.code_client,'; $sql.= " typent.code as typent_code,"; $sql.= " state.code_departement as state_code, state.nom as state_name,"; $sql.= ' SUM('.$db->ifsql("cd.statut=0",1,0).') as nb_initial,'; @@ -244,7 +249,9 @@ else if ($year > 0) $sql.= " AND c.date_contrat BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; } if ($search_name) $sql .= natural_search('s.nom', $search_name); +if ($search_email) $sql .= natural_search('s.email', $search_name); if ($search_contract) $sql .= natural_search(array('c.rowid', 'c.ref'), $search_contract); +if (!empty($search_ref_customer)) $sql .= natural_search(array('c.ref_customer'), $search_ref_customer); if (!empty($search_ref_supplier)) $sql .= natural_search(array('c.ref_supplier'), $search_ref_supplier); if ($search_sale > 0) { @@ -272,14 +279,11 @@ $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // No $sql.=$hookmanager->resPrint; $sql.= " GROUP BY c.rowid, c.ref, c.datec, c.tms, c.date_contrat, c.statut, c.ref_customer, c.ref_supplier, c.note_private, c.note_public,"; -$sql.= ' s.rowid, s.nom, s.town, s.zip, s.fk_pays, s.client, s.code_client,'; +$sql.= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.code_client,'; $sql.= " typent.code,"; $sql.= " state.code_departement, state.nom"; -// Add where from extra fields -foreach ($extrafields->attribute_label as $key => $val) -{ - $sql .= ', ef.'.$key; -} +// Add fields from extrafields +foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key : ''); // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook @@ -324,6 +328,7 @@ if ($resql) if ($sall != '') $param.='&sall='.$sall; if ($search_contract != '') $param.='&search_contract='.$search_contract; if ($search_name != '') $param.='&search_name='.$search_name; + if ($search_email != '') $param.='&search_email='.$search_email; if ($search_ref_supplier != '') $param.='&search_ref_supplier='.$search_ref_supplier; if ($search_sale != '') $param.='&search_sale=' .$search_sale; if ($show_files) $param.='&show_files=' .$show_files; @@ -431,13 +436,13 @@ if ($resql) if (! empty($arrayfields['c.ref_customer']['checked'])) { print ''; - print ''; + print ''; print ''; } if (! empty($arrayfields['c.ref_supplier']['checked'])) { print ''; - print ''; + print ''; print ''; } if (! empty($arrayfields['s.nom']['checked'])) @@ -446,6 +451,12 @@ if ($resql) print ''; print ''; } + if (! empty($arrayfields['s.email']['checked'])) + { + print ''; + print ''; + print ''; + } // Town if (! empty($arrayfields['s.town']['checked'])) print ''; // Zip @@ -542,7 +553,8 @@ if ($resql) if (! empty($arrayfields['c.ref_customer']['checked'])) print_liste_field_titre($arrayfields['c.ref_customer']['label'], $_SERVER["PHP_SELF"], "c.ref_customer","","$param",'',$sortfield,$sortorder); if (! empty($arrayfields['c.ref_supplier']['checked'])) print_liste_field_titre($arrayfields['c.ref_supplier']['label'], $_SERVER["PHP_SELF"], "c.ref_supplier","","$param",'',$sortfield,$sortorder); if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom","","$param",'',$sortfield,$sortorder); - if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.email']['checked'])) print_liste_field_titre($arrayfields['s.email']['label'], $_SERVER["PHP_SELF"], "s.email","","$param",'',$sortfield,$sortorder); + if (! empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],'s.town','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],'s.zip','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder); if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder); @@ -621,6 +633,10 @@ if ($resql) { print ''.img_object($langs->trans("ShowCompany"),"company").' '.$obj->name.''; } + if (! empty($arrayfields['s.email']['checked'])) + { + print ''.$obj->email.''; + } // Town if (! empty($arrayfields['s.town']['checked'])) { diff --git a/htdocs/contrat/services.php b/htdocs/contrat/services.php index e5a5c21c00b..945b5b8b983 100644 --- a/htdocs/contrat/services.php +++ b/htdocs/contrat/services.php @@ -115,6 +115,11 @@ $companystatic=new Societe($db); $arrayfields=array( 'c.ref'=>array('label'=>$langs->trans("Contract"), 'checked'=>1, 'position'=>80), 'p.description'=>array('label'=>$langs->trans("Service"), 'checked'=>1, 'position'=>80), + 'cd.qty'=>array('label'=>$langs->trans("Qty"), 'checked'=>0, 'position'=>100), + 'cd.total_ht'=>array('label'=>$langs->trans("TotalHT"), 'checked'=>0, 'position'=>100), + 'cd.total_tva'=>array('label'=>$langs->trans("TotalVAT"), 'checked'=>0, 'position'=>100), + 'cd.tva_tx'=>array('label'=>$langs->trans("VAT"), 'checked'=>0, 'position'=>100), + 'cd.subprice'=>array('label'=>$langs->trans("PriceUHT"), 'checked'=>0, 'position'=>100), 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1, 'position'=>100), 'cd.date_ouverture_prevue'=>array('label'=>$langs->trans("DateStartPlannedShort"), 'checked'=>(($mode == "" || $mode == -1) || $mode == "0")), 'cd.date_ouverture'=>array('label'=>$langs->trans("DateStartRealShort"), 'checked'=>(($mode == "" || $mode == -1) || $mode > 0)), @@ -129,7 +134,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -199,7 +204,11 @@ if (!$user->rights->societe->client->voir && !$socid) $sql .= " sc.fk_soc, sc.fk $sql.= " cd.date_ouverture_prevue,"; $sql.= " cd.date_ouverture,"; $sql.= " cd.date_fin_validite,"; -$sql.= " cd.date_cloture,"; +$sql.= " cd.qty,"; +$sql.= " cd.total_ht,"; +$sql.= " cd.total_tva,"; +$sql.= " cd.tva_tx,"; +$sql.= " cd.subprice,"; //$sql.= " cd.date_c as date_creation,"; $sql.= " cd.tms as date_update"; // Add fields from extrafields @@ -285,7 +294,7 @@ if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && llxHeader(null, $langs->trans("Services")); $param=''; -if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; +if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage); if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; if ($search_contract) $param.='&search_contract='.urlencode($search_contract); if ($search_name) $param.='&search_name='.urlencode($search_name); @@ -326,6 +335,7 @@ print ''; print ''; print ''; print ''; +print ''; $title=$langs->trans("ListOfServices"); if ($mode == "0") $title=$langs->trans("ListOfInactiveServices"); // Must use == "0" @@ -376,6 +386,11 @@ print ''; if (! empty($arrayfields['c.ref']['checked'])) print_liste_field_titre($arrayfields['c.ref']['label'],$_SERVER["PHP_SELF"],"c.ref","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['p.description']['checked'])) print_liste_field_titre($arrayfields['p.description']['label'],$_SERVER["PHP_SELF"],"p.description","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['cd.qty']['checked'])) print_liste_field_titre($arrayfields['cd.qty']['label'],$_SERVER["PHP_SELF"],"cd.qty","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.total_ht']['checked'])) print_liste_field_titre($arrayfields['cd.total_ht']['label'],$_SERVER["PHP_SELF"],"cd.total_ht","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.total_tva']['checked'])) print_liste_field_titre($arrayfields['cd.total_tva']['label'],$_SERVER["PHP_SELF"],"cd.total_tva","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.tva_tx']['checked'])) print_liste_field_titre($arrayfields['cd.tva_tx']['label'],$_SERVER["PHP_SELF"],"cd.tva_tx","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); +if (! empty($arrayfields['cd.subprice']['checked'])) print_liste_field_titre($arrayfields['cd.subprice']['label'],$_SERVER["PHP_SELF"],"cd.subprice","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); if (! empty($arrayfields['cd.date_ouverture_prevue']['checked'])) print_liste_field_titre($arrayfields['cd.date_ouverture_prevue']['label'],$_SERVER["PHP_SELF"],"cd.date_ouverture_prevue","",$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['cd.date_ouverture']['checked'])) print_liste_field_titre($arrayfields['cd.date_ouverture']['label'],$_SERVER["PHP_SELF"],"cd.date_ouverture","",$param,'align="center"',$sortfield,$sortorder); @@ -421,6 +436,32 @@ if (! empty($arrayfields['p.description']['checked'])) print ''; print ''; } +// detail lines +if (! empty($arrayfields['cd.qty']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.total_ht']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.total_tva']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.tva_tx']['checked'])) +{ + print ''; +} +if (! empty($arrayfields['cd.subprice']['checked'])) +{ + print ''; +} // Third party if (! empty($arrayfields['s.nom']['checked'])) { @@ -428,6 +469,8 @@ if (! empty($arrayfields['s.nom']['checked'])) print ''; print ''; } + + if (! empty($arrayfields['cd.date_ouverture_prevue']['checked'])) { print ''; } + if (! empty($arrayfields['cd.qty']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.total_ht']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.total_tva']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.tva_tx']['checked'])) + { + print ''; + } + if (! empty($arrayfields['cd.subprice']['checked'])) + { + print ''; + } + + // Third party if (! empty($arrayfields['s.nom']['checked'])) { diff --git a/htdocs/core/actions_extrafields.inc.php b/htdocs/core/actions_extrafields.inc.php index 433288606ec..b6e70059da3 100644 --- a/htdocs/core/actions_extrafields.inc.php +++ b/htdocs/core/actions_extrafields.inc.php @@ -159,6 +159,7 @@ if ($action == 'add') $params['options'][$key] = $value; } } + $result=$extrafields->addExtraField( GETPOST('attrname', 'alpha'), GETPOST('label', 'alpha'), @@ -172,7 +173,7 @@ if ($action == 'add') $params, (GETPOST('alwayseditable', 'alpha')?1:0), (GETPOST('perms', 'alpha')?GETPOST('perms', 'alpha'):''), - (GETPOST('list', 'alpha')?1:0), + GETPOST('list', 'alpha'), // Same as visible -1=not visible by default in list, 1=visible, 0=not visible in list (GETPOST('ishidden', 'alpha')?1:0), GETPOST('computed_value','alpha'), (GETPOST('entitycurrentorall', 'alpha')?0:''), @@ -334,7 +335,7 @@ if ($action == 'update') $params, (GETPOST('alwayseditable', 'alpha')?1:0), (GETPOST('perms', 'alpha')?GETPOST('perms', 'alpha'):''), - (GETPOST('list', 'alpha')?1:0), + GETPOST('list', 'alpha'), // Same as visible -1=not visible by default in list, 1=visible, 0=not visible in list (GETPOST('ishidden', 'alpha')?1:0), GETPOST('default_value','alpha'), GETPOST('computed_value','alpha'), diff --git a/htdocs/core/actions_fetchobject.inc.php b/htdocs/core/actions_fetchobject.inc.php index 7c25fbe7981..6a2d7196d0f 100644 --- a/htdocs/core/actions_fetchobject.inc.php +++ b/htdocs/core/actions_fetchobject.inc.php @@ -28,7 +28,7 @@ // $cancel must be defined // $id or $ref must be defined (object is loaded in this file with fetch) -if (($id > 0 || (! empty($ref) && ! in_array($action, array('create', 'createtask', 'add')))) && empty($cancel)) +if (($id > 0 || (! empty($ref) && ! in_array($action, array('create', 'createtask', 'add')))) && (empty($cancel) || $id > 0)) { $ret = $object->fetch($id, $ref); if ($ret > 0) diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 4c3fe6af317..67fde5dbd48 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -64,36 +64,63 @@ if (! $error && $massaction == 'confirm_presend') $langs->load("mails"); include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - if (!$error && !isset($user->email)) - { - $error++; - setEventMessages($langs->trans("NoSenderEmailDefined"), null, 'warnings'); - } + $listofobjectid=array(); + $listofobjectthirdparties=array(); + $listofobjectref=array(); if (! $error) { $thirdparty=new Societe($db); + if ($objecttmp->element == 'expensereport') $thirdparty=new User($db); + $objecttmp=new $objectclass($db); - $listofobjectid=array(); - $listofobjectthirdparties=array(); - $listofobjectref=array(); foreach($toselect as $toselectid) { - $objecttmp=new $objectclass($db); // must create new instance because instance is saved into $listofobjectref array for future use + $objecttmp=new $objectclass($db); // we must create new instance because instance is saved into $listofobjectref array for future use $result=$objecttmp->fetch($toselectid); if ($result > 0) { $listofobjectid[$toselectid]=$toselectid; $thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid; if ($objecttmp->element == 'societe') $thirdpartyid=$objecttmp->id; + if ($objecttmp->element == 'expensereport') $thirdpartyid=$objecttmp->fk_user_author; $listofobjectthirdparties[$thirdpartyid]=$thirdpartyid; $listofobjectref[$thirdpartyid][$toselectid]=$objecttmp; } } - //var_dump($listofobjectthirdparties);exit; + } + // Check mandatory parameters + if (empty($user->email)) + { + $error++; + setEventMessages($langs->trans("NoSenderEmailDefined"), null, 'warnings'); + $massaction='presend'; + } - // Loop on each thirdparty + $receiver=$_POST['receiver']; + if (! is_array($receiver)) + { + if (empty($receiver) || $receiver == '-1') $receiver=array(); + else $receiver=array($receiver); + } + if (! trim($_POST['sendto']) && count($receiver) == 0 && count($listofobjectthirdparties) == 1) // if only one recipient, receiver is mandatory + { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Recipient")), null, 'warnings'); + $massaction='presend'; + } + + if (! GETPOST('subject','none')) + { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("MailTopic")), null, 'warnings'); + $massaction='presend'; + } + + // Loop on each recipient/thirdparty + if (! $error) + { foreach ($listofobjectthirdparties as $thirdpartyid) { $result = $thirdparty->fetch($thirdpartyid); @@ -109,12 +136,6 @@ if (! $error && $massaction == 'confirm_presend') $sendtoid = array(); // Define $sendto - $receiver=$_POST['receiver']; - if (! is_array($receiver)) - { - if ($receiver == '-1') $receiver=array(); - else $receiver=array($receiver); - } $tmparray=array(); if (trim($_POST['sendto'])) { @@ -126,11 +147,11 @@ if (! $error && $massaction == 'confirm_presend') foreach($receiver as $key=>$val) { // Recipient was provided from combo list - if ($val == 'thirdparty') // Id of third party + if ($val == 'thirdparty') // Id of third party or user { $tmparray[] = $thirdparty->name.' <'.$thirdparty->email.'>'; } - elseif ($val) // Id du contact + elseif ($val && method_exists($thirdparty, 'contact_get_property')) // Id of contact { $tmparray[] = $thirdparty->contact_get_property((int) $val,'email'); $sendtoid[] = $val; @@ -203,8 +224,17 @@ if (! $error && $massaction == 'confirm_presend') // Test recipient if (empty($sendto)) // For the case, no recipient were set (multi thirdparties send) { - $object->fetch_thirdparty(); - $sendto = $object->thirdparty->email; + if ($object->element == 'expensereport') + { + $fuser = new User($db); + $fuser->fetch($object->fk_user_author); + $sendto = $fuser->email; + } + else + { + $object->fetch_thirdparty(); + $sendto = $object->thirdparty->email; + } } if (empty($sendto)) @@ -292,100 +322,129 @@ if (! $error && $massaction == 'confirm_presend') if ($objectclass == 'CommandeFournisseur') $sendtocc = (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO)?'':$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO); if ($objectclass == 'FactureFournisseur') $sendtocc = (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO)?'':$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO); - $objecttmp=new $objectclass($db); - $objecttmp->thirdparty = $thirdparty; - - // Make substitution in email content - $substitutionarray=getCommonSubstitutionArray($langs, 0, null, $objecttmp); - $substitutionarray['__ID__'] = join(', ',array_keys($listofqualifiedid)); - $substitutionarray['__EMAIL__'] = $thirdparty->email; - $substitutionarray['__CHECK_READ__'] = ''; - $substitutionarray['__REF__'] = join(', ',$listofqualifiedref); - - $parameters=array('mode'=>'formemail'); - complete_substitutions_array($substitutionarray, $langs, $objecttmp, $parameters); - - $subject=make_substitutions($subject, $substitutionarray); - $message=make_substitutions($message, $substitutionarray); - - $filepath = $attachedfiles['paths']; - $filename = $attachedfiles['names']; - $mimetype = $attachedfiles['mimes']; - - //var_dump($filepath); - - // Send mail (substitutionarray must be done just before this) - require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'); - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1); - if ($mailfile->error) + // $listofqualifiedid is array with key = object id of qualified objects for the current thirdparty + $oneemailperrecipient=(GETPOST('oneemailperrecipient')=='on'?1:0); + $looparray=array(); + if (! $oneemailperrecipient) { - $resaction.='
    '.$mailfile->error.'
    '; + $looparray = $listofqualifiedid; } else { - $result=$mailfile->sendfile(); - if ($result) - { - $resaction.=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)).'
    '; // Must not contain " - - $error=0; - - // Insert logs into agenda - foreach($listofqualifiedid as $objid => $object) - { - /*if ($objectclass == 'Propale') $actiontypecode='AC_PROP'; - if ($objectclass == 'Commande') $actiontypecode='AC_COM'; - if ($objectclass == 'Facture') $actiontypecode='AC_FAC'; - if ($objectclass == 'Supplier_Proposal') $actiontypecode='AC_SUP_PRO'; - if ($objectclass == 'CommandeFournisseur') $actiontypecode='AC_SUP_ORD'; - if ($objectclass == 'FactureFournisseur') $actiontypecode='AC_SUP_INV';*/ - - $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; - if ($message) - { - if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); - $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); - $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); - $actionmsg = dol_concatdesc($actionmsg, $message); - } - $actionmsg2=''; - - // Initialisation donnees - $object->sendtoid = 0; - $object->actionmsg = $actionmsg; // Long text - $object->actionmsg2 = $actionmsg2; // Short text - $object->fk_element = $objid; - $object->elementtype = $object->element; - - // Appel des triggers - include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php"); - $interface=new Interfaces($db); - $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf); - if ($result < 0) { $error++; $errors=$interface->errors; } - // Fin appel triggers - - if ($error) - { - setEventMessages($db->lasterror(), $errors, 'errors'); - dol_syslog("Error in trigger BILL_SENTBYMAIL ".$db->lasterror(), LOG_ERR); - } - $nbsent++; - } - } - else - { - $langs->load("other"); - if ($mailfile->error) - { - $resaction.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); - $resaction.='
    '.$mailfile->error.'
    '; - } - else - { - $resaction.='
    No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS
    '; - } - } + $objectforloop=new $objectclass($db); + $objectforloop->thirdparty = $thirdparty; + $looparray[0]=$objectforloop; } + //var_dump($looparray);exit; + + foreach ($looparray as $objecttmp) // $objecttmp is a real object or an empty if we choose to send one email per thirdparty instead of per record + { + // Make substitution in email content + $substitutionarray=getCommonSubstitutionArray($langs, 0, null, $objecttmp); + $substitutionarray['__ID__'] = ($oneemailperrecipient ? join(', ',array_keys($listofqualifiedid)) : $objecttmp->id); + $substitutionarray['__REF__'] = ($oneemailperrecipient ? join(', ',$listofqualifiedref) : $objecttmp->ref); + $substitutionarray['__EMAIL__'] = $thirdparty->email; + $substitutionarray['__CHECK_READ__'] = ''; + + $parameters=array('mode'=>'formemail'); + complete_substitutions_array($substitutionarray, $langs, $objecttmp, $parameters); + + $subject=make_substitutions($subject, $substitutionarray); + $message=make_substitutions($message, $substitutionarray); + + $filepath = $attachedfiles['paths']; + $filename = $attachedfiles['names']; + $mimetype = $attachedfiles['mimes']; + + //var_dump($filepath); + + // Send mail (substitutionarray must be done just before this) + require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'); + $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1); + if ($mailfile->error) + { + $resaction.='
    '.$mailfile->error.'
    '; + } + else + { + $result=$mailfile->sendfile(); + if ($result) + { + $resaction.=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)).'
    '; // Must not contain " + + $error=0; + + // Insert logs into agenda + foreach($listofqualifiedid as $objid => $object) + { + /*if ($objectclass == 'Propale') $actiontypecode='AC_PROP'; + if ($objectclass == 'Commande') $actiontypecode='AC_COM'; + if ($objectclass == 'Facture') $actiontypecode='AC_FAC'; + if ($objectclass == 'Supplier_Proposal') $actiontypecode='AC_SUP_PRO'; + if ($objectclass == 'CommandeFournisseur') $actiontypecode='AC_SUP_ORD'; + if ($objectclass == 'FactureFournisseur') $actiontypecode='AC_SUP_INV';*/ + + $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; + if ($message) + { + if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject); + $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); + $actionmsg = dol_concatdesc($actionmsg, $message); + } + $actionmsg2=''; + + // Initialisation donnees + $object->sendtoid = 0; + $object->actionmsg = $actionmsg; // Long text + $object->actionmsg2 = $actionmsg2; // Short text + $object->fk_element = $objid; + $object->elementtype = $object->element; + + $triggername = strtoupper(get_class($object)) .'_SENTBYMAIL'; + if ($triggername == 'SOCIETE_SENTBYMAIL') $triggername = 'COMPANY_SENTBYEMAIL'; + if ($triggername == 'CONTRAT_SENTBYMAIL') $triggername = 'CONTRACT_SENTBYEMAIL'; + if ($triggername == 'COMMANDE_SENTBYMAIL') $triggername = 'ORDER_SENTBYEMAIL'; + if ($triggername == 'FACTURE_SENTBYMAIL') $triggername = 'BILL_SENTBYEMAIL'; + if ($triggername == 'EXPEDITION_SENTBYMAIL') $triggername = 'SHIPPING_SENTBYEMAIL'; + if ($triggername == 'COMMANDEFOURNISSEUR_SENTBYMAIL') $triggername = 'ORDER_SUPPLIER_SENTBYMAIL'; + if ($triggername == 'FACTUREFOURNISSEUR_SENTBYMAIL') $triggername = 'BILL_SUPPLIER_SENTBYEMAIL'; + if ($triggername == 'SUPPLIERPROPOSAL_SENTBYMAIL') $triggername = 'PROPOSAL_SUPPLIER_SENTBYEMAIL'; + + if (! empty($trigger_name)) + { + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php"); + $interface=new Interfaces($db); + $result=$interface->run_triggers($trigger_name, $object, $user, $langs, $conf); + if ($result < 0) { $error++; $errors=$interface->errors; } + // Fin appel triggers + + if ($error) + { + setEventMessages($db->lasterror(), $errors, 'errors'); + dol_syslog("Error in trigger ".$trigger_name.' '.$db->lasterror(), LOG_ERR); + } + } + + $nbsent++; + } + } + else + { + $langs->load("other"); + if ($mailfile->error) + { + $resaction.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); + $resaction.='
    '.$mailfile->error.'
    '; + } + else + { + $resaction.='
    No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS
    '; + } + } + } + } } } @@ -407,10 +466,10 @@ if (! $error && $massaction == 'confirm_presend') //setEventMessages($langs->trans("EMailSentToNRecipients", 0), null, 'warnings'); // May be object has no generated PDF file setEventMessages($resaction, null, 'warnings'); } - } - $action='list'; - $massaction=''; + $action='list'; + $massaction=''; + } } if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_search')) @@ -481,7 +540,7 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se $filename=preg_replace('/\s/','_',$filename); // Save merged file - if ($filter=='paye:0') + if (in_array($object->element, array('facture', 'facture_fournisseur')) && $search_status == Facture::STATUS_VALIDATED) { if ($option=='late') $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))).'_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Late"))); else $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))); @@ -553,7 +612,7 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se $filename=preg_replace('/\s/','_',$filename); // Save merged file - if ($filter=='paye:0') + if (in_array($object->element, array('facture', 'facture_fournisseur')) && $search_status == Facture::STATUS_VALIDATED) { if ($option=='late') $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))).'_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Late"))); else $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))); @@ -592,7 +651,7 @@ if ($action == 'remove_file') $action=''; } -// Validate records +// Validate records if (! $error && $massaction == 'validate' && $permtocreate) { if ($object->element == 'invoice_supplier' && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)) @@ -664,8 +723,19 @@ if (! $error && $massaction == 'delete' && $permtodelete) $result=$objecttmp->fetch($toselectid); if ($result > 0) { + // Refuse deletion for some status ? + /* + if ($objectclass == 'Facture' && $objecttmp->status == Facture::STATUS_DRAFT) + { + $langs->load("errors"); + $nbignored++; + $resaction.='
    '.$langs->trans('ErrorOnlyDraftStatusCanBeDeletedInMassAction',$object->ref).'

    '; + continue; + }*/ + if (in_array($objecttmp->element, array('societe','member'))) $result = $objecttmp->delete($objecttmp->id, $user, 1); else $result = $objecttmp->delete($user); + if ($result <= 0) { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 18c951c7763..4439f0034ce 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -18,13 +18,13 @@ /** * \file htdocs/core/actions_sendmails.inc.php -* \brief Code for actions on sending mails from object page -*/ + * \brief Code for actions on sending mails from object page + */ // $mysoc must be defined // $id must be defined // $paramname must be defined -// $mode must be defined +// $mode must be defined (used to know the automatic BCC to add) // $trigger_name must be set (can be '') // $actiontypecode can be set // $object and $uobject may be defined @@ -113,13 +113,18 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO $result=$object->fetch($id); $sendtosocid=0; // Thirdparty on object - if (method_exists($object,"fetch_thirdparty") && $object->element != 'societe') + if (method_exists($object,"fetch_thirdparty") && ! in_array($object->element, array('societe','member'))) { $result=$object->fetch_thirdparty(); if ($object->element == 'user' && $result == 0) $result=1; // Even if not found, we consider ok $thirdparty=$object->thirdparty; $sendtosocid=$thirdparty->id; } + else if ($object->element == 'member') + { + $thirdparty=$object; + if ($thirdparty->id > 0) $sendtosocid=$thirdparty->id; + } else if ($object->element == 'societe') { $thirdparty=$object; @@ -268,12 +273,12 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO $message=preg_replace('/()/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $message); $sendtobcc= GETPOST('sendtoccc'); - if ($mode == 'emailfromproposal') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO)); - if ($mode == 'emailfromorder') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO)); - if ($mode == 'emailfrominvoice') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO)); - if ($mode == 'emailfromsupplierproposal') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO)); - if ($mode == 'emailfromsupplierorder') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO)); - if ($mode == 'emailfromsupplierinvoice') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO)); + // Autocomplete the $sendtobcc + // $autocopy can be MAIN_MAIL_AUTOCOPY_PROPOSAL_TO, MAIN_MAIL_AUTOCOPY_ORDER_TO, MAIN_MAIL_AUTOCOPY_INVOICE_TO, MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO... + if (! empty($autocopy)) + { + $sendtobcc .= (empty($conf->global->$autocopy) ? '' : (($sendtobcc?", ":"").$conf->global->$autocopy)); + } $deliveryreceipt = $_POST['deliveryreceipt']; @@ -348,18 +353,6 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO $substitutionarray=getCommonSubstitutionArray($langs, 0, null, $object); $substitutionarray['__EMAIL__'] = $sendto; $substitutionarray['__CHECK_READ__'] = (is_object($object) && is_object($object->thirdparty))?'':''; - // Add specific substitution for contracts - if (is_object($object) && $object->element == 'contrat' && is_array($object->lines)) - { - $datenextexpiration=''; - foreach($object->lines as $line) - { - if ($line->statut != 4) continue; - if ($line->date_fin_prevue > $datenextexpiration) $datenextexpiration = $line->date_fin_prevue; - } - $substitutionarray['__CONTRACT_NEXT_EXPIRATION_DATE__'] = dol_print_date($datenextexpiration, 'dayrfc'); - $substitutionarray['__CONTRACT_NEXT_EXPIRATION_DATETIME__'] = dol_print_date($datenextexpiration, 'standard'); - } $parameters=array('mode'=>'formemail'); complete_substitutions_array($substitutionarray, $langs, $object, $parameters); @@ -367,6 +360,12 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO $subject=make_substitutions($subject, $substitutionarray); $message=make_substitutions($message, $substitutionarray); + if (method_exists($object, 'makeSubstitution')) + { + $subject = $object->makeSubstitution($subject); + $message = $object->makeSubstitution($message); + } + // Send mail (substitutionarray must be done just before this) if (empty($sendcontext)) $sendcontext = 'standard'; $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1,'','',$trackid,'', $sendcontext); @@ -482,7 +481,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO else { $langs->load("other"); - setEventMessages($langs->trans('ErrorFailedToReadEntity',$object->element), null, 'errors'); + setEventMessages($langs->trans('ErrorFailedToReadObject',$object->element), null, 'errors'); dol_syslog('Failed to read data of object id='.$object->id.' element='.$object->element); $action = 'presend'; } diff --git a/htdocs/core/actions_setnotes.inc.php b/htdocs/core/actions_setnotes.inc.php index 39f63683575..50b35392644 100644 --- a/htdocs/core/actions_setnotes.inc.php +++ b/htdocs/core/actions_setnotes.inc.php @@ -32,7 +32,7 @@ if ($action == 'setnote_public' && ! empty($permissionnote) && ! GETPOST('cancel { if (empty($action) || ! is_object($object) || empty($id)) dol_print_error('','Include of actions_setnotes.inc.php was done but required variable was not set before'); if (empty($object->id)) $object->fetch($id); // Fetch may not be already done - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public', 'none'), ENT_QUOTES),'_public'); if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); } // Set public note @@ -40,6 +40,6 @@ else if ($action == 'setnote_private' && ! empty($permissionnote) && ! GETPOST(' { if (empty($action) || ! is_object($object) || empty($id)) dol_print_error('','Include of actions_setnotes.inc.php was done but required variable was not set before'); if (empty($object->id)) $object->fetch($id); // Fetch may not be already done - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private', 'none'), ENT_QUOTES),'_private'); if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); } diff --git a/htdocs/core/ajax/getaccountcurrency.php b/htdocs/core/ajax/getaccountcurrency.php new file mode 100644 index 00000000000..40e52672c0e --- /dev/null +++ b/htdocs/core/ajax/getaccountcurrency.php @@ -0,0 +1,60 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/core/ajax/vatrates.php + * \brief File to load vat rates combobox + */ + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Disables token renewal +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); + +require '../../main.inc.php'; + +$id = GETPOST('id','int'); + +/* + * View + */ + +top_httphead(); + +//print ''."\n"; + +// Load original field value +if (! empty($id)) +{ + require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + $account=new Account($db); + $result = $account->fetch($id); + if ($result<0) { + $return['value'] = ''; + $return['num'] = $result; + $return['error'] = $account->errors[0]; + } else { + $return['value'] = $account->currency_code; + $return['num'] = $result; + $return['error'] = ''; + } + + echo json_encode($return); +} + diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 02b1d1880c8..d3059daba53 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -77,7 +77,6 @@ class box_activity extends ModeleBoxes include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $totalMnt = 0; $totalnb = 0; $line = 0; $cachetime = 3600; @@ -95,8 +94,6 @@ class box_activity extends ModeleBoxes // compute the year limit to show $tmpdate= dol_time_plus_duree(dol_now(), -1*$nbofperiod, "m"); - $cumuldata = array(); - // list the summary of the propals if (! empty($conf->propal->enabled) && $user->rights->propale->lire) @@ -146,11 +143,10 @@ class box_activity extends ModeleBoxes $data = dol_readcachefile($cachedir, $filename); } - $cumuldata=array_merge($cumuldata, $data); if (! empty($data)) { $j=0; - while ($line < count($cumuldata)) + while ($j < count($data)) { $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', @@ -176,7 +172,6 @@ class box_activity extends ModeleBoxes 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); - $totalMnt += $data[$j]->Mnttot; $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', 'text' => $propalstatic->LibStatut($data[$j]->fk_statut,3), @@ -231,10 +226,9 @@ class box_activity extends ModeleBoxes $data = dol_readcachefile($cachedir, $filename); } - $cumuldata=array_merge($cumuldata, $data); if (! empty($data)) { $j=0; - while ($line < count($cumuldata)) { + while ($j < count($data)) { $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', 'url' => DOL_URL_ROOT."/commande/list.php?mainmenu=commercial&leftmenu=orders&viewstatut=".$data[$j]->fk_statut, @@ -259,7 +253,6 @@ class box_activity extends ModeleBoxes 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); - $totalMnt += $data[$j]->Mnttot; $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', 'text' => $commandestatic->LibStatut($data[$j]->fk_statut,0,3), @@ -290,11 +283,11 @@ class box_activity extends ModeleBoxes $sql.= " FROM (".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= ")"; - $sql.= " WHERE f.entity = ".$conf->entity; + $sql.= " WHERE f.entity IN (".getEntity('facture').')'; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; $sql.= " AND f.fk_soc = s.rowid"; - $sql.= " AND f.datef >= '".$db->idate($tmpdate)."' AND paye=1"; + $sql.= " AND f.datef >= '".$db->idate($tmpdate)."' AND f.paye=1"; $sql.= " GROUP BY f.fk_statut"; $sql.= " ORDER BY f.fk_statut DESC"; @@ -317,10 +310,9 @@ class box_activity extends ModeleBoxes $data = dol_readcachefile($cachedir, $filename); } - $cumuldata=array_merge($cumuldata, $data); if (! empty($data)) { $j=0; - while ($line < count($cumuldata)) { + while ($j < count($data)) { $billurl="search_status=2&paye=1&year=".$data[$j]->annee; $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', @@ -347,10 +339,8 @@ class box_activity extends ModeleBoxes ); // We add only for the current year - if ($data[$j]->annee == date("Y")) { - $totalnb += $data[$j]->nb; - $totalMnt += $data[$j]->Mnttot; - } + $totalnb += $data[$j]->nb; + $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', 'text' => $facturestatic->LibStatut(1,$data[$j]->fk_statut,3), @@ -371,12 +361,13 @@ class box_activity extends ModeleBoxes $refresh = dol_cache_refresh($cachedir, $filename, $cachetime); + $data = array(); if ($refresh) { $sql = "SELECT f.fk_statut, SUM(f.total_ttc) as Mnttot, COUNT(*) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f"; - $sql.= " WHERE f.entity = ".$conf->entity; + $sql.= " WHERE f.entity IN (".getEntity('facture').')'; $sql.= " AND f.fk_soc = s.rowid"; - $sql.= " AND paye=0"; + $sql.= " AND f.datef >= '".$db->idate($tmpdate)."' AND f.paye=0"; $sql.= " GROUP BY f.fk_statut"; $sql.= " ORDER BY f.fk_statut DESC"; @@ -399,11 +390,11 @@ class box_activity extends ModeleBoxes $data = dol_readcachefile($cachedir, $filename); } - $cumuldata=array_merge($cumuldata, $data); if (! empty($data)) { - $j=0; + $alreadypaid=-1; - while ($line < count($cumuldata)) { + $j=0; + while ($j < count($data)) { $billurl="search_status=".$data[$j]->fk_statut."&paye=0"; $this->info_box_contents[$line][0] = array( 'td' => 'align="left" width="16"', @@ -428,10 +419,9 @@ class box_activity extends ModeleBoxes 'td' => 'class="right"', 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), ); - $totalMnt += $objp->Mnttot; $this->info_box_contents[$line][4] = array( 'td' => 'align="right" width="18"', - 'text' => $facturestatic->LibStatut(0,$data[$j]->fk_statut,3), + 'text' => $facturestatic->LibStatut(0,$data[$j]->fk_statut,3, $alreadypaid), ); $line++; $j++; @@ -441,16 +431,11 @@ class box_activity extends ModeleBoxes 'td' => 'align="center"', 'text'=>$langs->trans("NoRecordedInvoices"), ); - } else { - $this->info_box_contents[0][0] = array( - 'td' => '', - 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), - ); } } // Add the sum in the bottom of the boxes - $this->info_box_contents[$line][0] = array('tr' => 'class="liste_total"'); + $this->info_box_contents[$line][0] = array('tr' => 'class="liste_total_wrap"'); $this->info_box_contents[$line][1] = array('td' => 'align="left" class="liste_total" ', 'text' => $langs->trans("Total")." ".$textHead); $this->info_box_contents[$line][2] = array('td' => 'align="right" class="liste_total" ', 'text' => $totalnb); $this->info_box_contents[$line][3] = array('td' => 'align="right" class="liste_total" ', 'text' => ''); diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index 1795f7c6f2f..0cc4e68682b 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -2,6 +2,7 @@ /* Copyright (C) 2003 Rodolphe Quiedeville * Copyright (C) 2005-2017 Laurent Destailleur * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2017 Nicolas Zabouri * * 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 @@ -91,7 +92,7 @@ class box_services_contracts extends ModeleBoxes $sql.= " INNER JOIN ".MAIN_DB_PREFIX."contrat as c ON s.rowid = c.fk_soc"; $sql.= " INNER JOIN ".MAIN_DB_PREFIX."contratdet as cd ON c.rowid = cd.fk_contrat"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= "INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; $sql.= ")"; $sql.= " WHERE c.entity = ".$conf->entity; if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 9c496964942..93b8fa3d9d2 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -286,7 +286,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" if (isset($contents[$i])) { // TR - if (isset($contents[$i][0]['tr'])) $out.= ''; + if (isset($contents[$i][0]['tr'])) $out.= ''; else $out.= ''; // Loop on each TD diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 535200ab95a..937634de5d4 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -418,6 +418,21 @@ abstract class CommonDocGenerator $resarray[$array_key.'_total_discount_ht'] = ''; } + // Fetch project information if there is a project assigned to this object + if ($object->element != "project" && ! empty($object->fk_project) && $object->fk_project > 0) + { + if (! is_object($object->project)) + { + $object->fetch_projet(); + } + + $resarray[$array_key.'_project_ref'] = $object->project->ref; + $resarray[$array_key.'_project_title'] = $object->project->title; + $resarray[$array_key.'_project_description'] = $object->project->description; + $resarray[$array_key.'_project_date_start'] = dol_print_date($object->project->date_start, 'day'); + $resarray[$array_key.'_project_date_end'] = dol_print_date($object->project->date_end, 'day'); + } + // Add vat by rates if (is_array($object->lines) && count($object->lines)>0) { diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 4b6d70b1366..6bbde52cb58 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -51,7 +51,7 @@ abstract class CommonInvoice extends CommonObject const TYPE_DEPOSIT = 3; /** - * Proforma invoice. + * Proforma invoice. * @deprectad Remove this. A "proforma invoice" is an order with a look of invoice, not an invoice ! */ const TYPE_PROFORMA = 4; @@ -89,7 +89,7 @@ abstract class CommonInvoice extends CommonObject */ const STATUS_ABANDONED = 3; - + /** * Return remain amount to pay. Property ->id and ->total_ttc must be set. * This does not include open direct debit requests. @@ -141,7 +141,7 @@ abstract class CommonInvoice extends CommonObject return -1; } } - + /** * Return amount (with tax) of all deposits invoices used by invoice. * Should always be empty, except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is on (not recommended). @@ -154,11 +154,11 @@ abstract class CommonInvoice extends CommonObject if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') { // TODO - return 0; + return 0; } - + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - + $discountstatic=new DiscountAbsolute($this->db); $result=$discountstatic->getSumDepositsUsed($this, $multicurrency); if ($result >= 0) @@ -185,9 +185,9 @@ abstract class CommonInvoice extends CommonObject // TODO return 0; } - + require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; - + $discountstatic=new DiscountAbsolute($this->db); $result=$discountstatic->getSumCreditNotesUsed($this, $multicurrency); if ($result >= 0) @@ -200,7 +200,7 @@ abstract class CommonInvoice extends CommonObject return -1; } } - + /** * Renvoie tableau des ids de facture avoir issus de la facture * @@ -309,7 +309,7 @@ abstract class CommonInvoice extends CommonObject * @param int $paye Status field paye * @param int $status Id status * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=short label + picto, 6=long label + picto - * @param integer $alreadypaid 0=No payment already done, >0=Some payments were already done (we recommand to put here amount payed if you have it, 1 otherwise) + * @param integer $alreadypaid 0=No payment already done, >0=Some payments were already done (we recommand to put here amount payed if you have it, -1 otherwise) * @param int $type Type invoice * @return string Libelle du statut */ @@ -418,7 +418,7 @@ abstract class CommonInvoice extends CommonObject if ($status == 0) return ''.$langs->trans('Bill'.$prefix.'StatusDraft').' '.img_picto($langs->trans('BillStatusDraft'),'statut0'); if (($status == 3 || $status == 2) && $alreadypaid <= 0) return ''.$langs->trans('Bill'.$prefix.'StatusCanceled').' '.img_picto($langs->trans('BillStatusCanceled'),'statut5'); if (($status == 3 || $status == 2) && $alreadypaid > 0) return ''.$langs->trans('Bill'.$prefix.'StatusClosedPaidPartially').' '.img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut7'); - if ($alreadypaid <= 0) + if ($alreadypaid <= 0) { if ($type == self::TYPE_CREDIT_NOTE) return ''.$langs->trans('Bill'.$prefix.'StatusNotRefunded').' '.img_picto($langs->trans('StatusNotRefunded'),'statut1'); return ''.$langs->trans('Bill'.$prefix.'StatusNotPaid').' '.img_picto($langs->trans('BillStatusNotPaid'),'statut1'); @@ -497,13 +497,13 @@ abstract class CommonInvoice extends CommonObject } elseif($cdr_type == 2 && !empty($cdr_nbjour)) // Application de la règle, le N du mois courant ou suivant { - + $date_piece = dol_mktime(0,0,0,date('m', $this->date),date('d', $this->date),date('Y', $this->date)); // Sans les heures minutes et secondes $date_lim_current = dol_mktime(0,0,0,date('m', $this->date),$cdr_nbjour,date('Y', $this->date)); // Sans les heures minutes et secondes $date_lim_next = strtotime(date('Y-m-d', $date_lim_current).' +1month'); - + $diff = $date_piece - $date_lim_current; - + if($diff < 0) $datelim = $date_lim_current; else $datelim = $date_lim_next; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 54a907a3c0f..ac2c1482682 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1563,22 +1563,22 @@ abstract class CommonObject switch ($this->element) { case 'propal': - $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'commande': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'facture': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit, $line->multicurrency_subprice); break; case 'supplier_proposal': - $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->multicurrency_subprice); + $this->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, ($line->description?$line->description:$line->desc), 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, $line->skip_update_total, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->multicurrency_subprice); break; case 'order_supplier': - $this->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; case 'invoice_supplier': - $this->updateline($line->id, $line->desc, $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + $this->updateline($line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->qty, 0, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, false, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); break; default: dol_syslog(get_class($this).'::setMulticurrencyRate no updateline defined', LOG_DEBUG); @@ -4594,23 +4594,28 @@ abstract class CommonObject }else { $colspan='3'; } + switch($mode) { case "view": $value=$this->array_options["options_".$key]; break; case "edit": - if (isset($_POST["options_" . $key])) { - if (is_array($_POST["options_" . $key])) { - // $_POST["options"] is an array but following code expects a comma separated string - $value = implode(",", $_POST["options_" . $key]); + // GETPOST("options_" . $key) can be 'abc' or array(0=>'abc') + $getposttemp = GETPOST('options_'.$key, 'none'); // GETPOST can get value from GET, POST or setup of default values. + if (isset($getposttemp)) { + if (is_array($getposttemp)) { + // $getposttemp is an array but following code expects a comma separated string + $value = implode(",", $getposttemp); } else { - $value = $_POST["options_" . $key]; + $value = $getposttemp; } } else { - $value = $this->array_options["options_" . $key]; + $value = $this->array_options["options_" . $key]; // No GET, no POST, no default value, so we take value of object. } break; } + //var_dump($value); + if ($extrafields->attribute_type[$key] == 'separate') { $out .= $extrafields->showSeparator($key); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index ad224fec97d..e0e032d7e25 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -254,13 +254,13 @@ class Conf if (! isset($this->global->LDAP_KEY_GROUPS)) $this->global->LDAP_KEY_GROUPS=$this->global->LDAP_FIELD_FULLNAME; if (! isset($this->global->LDAP_KEY_CONTACTS)) $this->global->LDAP_KEY_CONTACTS=$this->global->LDAP_FIELD_FULLNAME; if (! isset($this->global->LDAP_KEY_MEMBERS)) $this->global->LDAP_KEY_MEMBERS=$this->global->LDAP_FIELD_FULLNAME; + if (! isset($this->global->LDAP_KEY_MEMBERS_TYPES)) $this->global->LDAP_KEY_MEMBERS_TYPES=$this->global->LDAP_FIELD_FULLNAME; // Load translation object with current language if (empty($this->global->MAIN_LANG_DEFAULT)) $this->global->MAIN_LANG_DEFAULT="en_US"; - // By default, we repeat info on all tabs - if (! isset($this->global->MAIN_REPEATCONTACTONEACHTAB)) $this->global->MAIN_REPEATCONTACTONEACHTAB=1; - if (! isset($this->global->MAIN_REPEATADDRESSONEACHTAB)) $this->global->MAIN_REPEATADDRESSONEACHTAB=1; + //if (! isset($this->global->MAIN_REPEATCONTACTONEACHTAB)) $this->global->MAIN_REPEATCONTACTONEACHTAB=1; + //if (! isset($this->global->MAIN_REPEATADDRESSONEACHTAB)) $this->global->MAIN_REPEATADDRESSONEACHTAB=1; $rootfordata = DOL_DATA_ROOT; $rootforuser = DOL_DATA_ROOT; @@ -287,15 +287,18 @@ class Conf { foreach($this->modules_parts['dir'] as $module => $dirs) { - foreach($dirs as $type => $name) + if (! empty($this->$module->enabled)) { - $subdir=($type=='temp'?'/temp':''); - // For multicompany sharings - $varname = 'multidir_'.$type; - $this->$module->$varname = array($this->entity => $rootfordata."/".$name.$subdir); - // For backward compatibility - $varname = 'dir_'.$type; - $this->$module->$varname = $rootfordata."/".$name.$subdir; + foreach($dirs as $type => $name) + { + $subdir=($type=='temp'?'/temp':''); + // For multicompany sharings + $varname = 'multidir_'.$type; + $this->$module->$varname = array($this->entity => $rootfordata."/".$name.$subdir); + // For backward compatibility + $varname = 'dir_'.$type; + $this->$module->$varname = $rootfordata."/".$name.$subdir; + } } } } diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 16cb219f718..d4432435704 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -78,6 +78,7 @@ class DiscountAbsolute $sql = "SELECT sr.rowid, sr.fk_soc,"; $sql.= " sr.fk_user,"; $sql.= " sr.amount_ht, sr.amount_tva, sr.amount_ttc, sr.tva_tx,"; + $sql.= " sr.multicurrency_amount_ht, sr.multicurrency_amount_tva, sr.multicurrency_amount_ttc,"; $sql.= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.description,"; $sql.= " sr.datec,"; $sql.= " f.facnumber as ref_facture_source"; @@ -97,9 +98,15 @@ class DiscountAbsolute $this->id = $obj->rowid; $this->fk_soc = $obj->fk_soc; + $this->amount_ht = $obj->amount_ht; $this->amount_tva = $obj->amount_tva; $this->amount_ttc = $obj->amount_ttc; + + $this->multicurrency_amount_ht = $obj->multicurrency_amount_ht; + $this->multicurrency_amount_tva = $obj->multicurrency_amount_tva; + $this->multicurrency_amount_ttc = $obj->multicurrency_amount_ttc; + $this->tva_tx = $obj->tva_tx; $this->fk_user = $obj->fk_user; $this->fk_facture_line = $obj->fk_facture_line; diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 12d958b6ebb..c8779b388c0 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -8,6 +8,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Charles-Fr BENKE * Copyright (C) 2016 Raphaël Doursenaud + * Copyright (C) 2017 Nicolas ZABOURI * * 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 @@ -139,14 +140,14 @@ class ExtraFields * @param array|string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check - * @param int $list Into list view by default + * @param int $list Into list view by default (-1, 0 or 1) * @param int $ishidden Is hidden extrafield (warning, do not rely on this. If your module need a hidden data, it must use its own table) * @param string $computed Computed value * @param string $entity Entity of extrafields * @param string $langfile Language file * @return int <=0 if KO, >0 if OK */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=0, $ishidden=0, $computed='', $entity='', $langfile='') + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $computed='', $entity='', $langfile='') { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -278,7 +279,7 @@ class ExtraFields * @param array|string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check - * @param int $list Into list view by default + * @param int $list Into list view by default (-1, 0 or 1) * @param int $ishidden Is hidden extrafield (warning, do not rely on this. If your module need a hidden data, it must use its own table) * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value @@ -286,7 +287,7 @@ class ExtraFields * @param string $langfile Language file * @return int <=0 if KO, >0 if OK */ - private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=0, $ishidden=0, $default='', $computed='',$entity='', $langfile='') + private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $default='', $computed='',$entity='', $langfile='') { global $conf,$user; @@ -892,13 +893,13 @@ class ExtraFields if (! is_object($form)) $form=new Form($this->db); // TODO Must also support $moreparam - $out = $form->select_date($value, $keysuffix.'options_'.$key.$keyprefix, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); + $out = $form->select_date($value, $keysuffix.'options_'.$key.$keyprefix, $showtime, $showtime, $required, '', 1, ($keysuffix != 'search_' ? 1 : 0), 1, 0, 1); } elseif (in_array($type,array('int'))) { $tmp=explode(',',$size); $newsize=$tmp[0]; - $out=''; + $out=''; } elseif ($type == 'varchar') { @@ -1322,7 +1323,8 @@ class ExtraFields } elseif ($type == 'password') { - $out=''; + // If prefix is 'search_', field is used as a filter, we use a common text field. + $out=''; } if (!empty($hidden)) { $out=''; @@ -1708,7 +1710,7 @@ class ExtraFields if (! empty($onlykey) && $key != $onlykey) continue; $key_type = $this->attribute_type[$key]; - if($this->attribute_required[$key] && !GETPOST("options_$key",2)) + if ($this->attribute_required[$key] && empty($_POST["options_".$key])) // Check if empty without GETPOST, value can be alpha, int, array, etc... { $nofillrequired++; $error_field_required[] = $value; @@ -1721,7 +1723,7 @@ class ExtraFields } else if (in_array($key_type,array('checkbox','chkbxlst'))) { - $value_arr=GETPOST("options_".$key); + $value_arr=GETPOST("options_".$key, 'array'); // check if an array if (!empty($value_arr)) { $value_key=implode($value_arr,','); }else { @@ -1740,7 +1742,7 @@ class ExtraFields $object->array_options["options_".$key]=$value_key; } - if($nofillrequired) { + if ($nofillrequired) { $langs->load('errors'); setEventMessages($langs->trans('ErrorFieldsRequired').' : '.implode(', ',$error_field_required), null, 'errors'); return -1; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index e37932ea635..f33ab83ee29 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -544,7 +544,7 @@ class Form $disabled=0; $ret='
    '; - $ret.=''; // Complete list with data from external modules. THe module can use $_SERVER['PHP_SELF'] to know on which page we are, or use the $parameters['currentcontext'] completed by executeHooks. $parameters=array(); @@ -561,7 +561,7 @@ class Form $ret.=''; // Warning: if you set submit button to disabled, post using 'Enter' will no more work. - $ret.=''; + $ret.=''; $ret.='
    '; if (! empty($conf->use_javascript_ajax)) @@ -1256,6 +1256,7 @@ class Form * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param bool $options_only Return options only (for ajax treatment) * @return int <0 if KO, Nb of contact in list if OK + * @deprected You can use selectcontacts directly (warning order of param was changed) */ function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false) { @@ -1264,7 +1265,8 @@ class Form } /** - * Return list of all contacts (for a third party or all) + * Return HTML code of the SELECT of list of all contacts (for a third party or all). + * This also set the number of contacts found into $this->num * * @param int $socid Id ot third party or 0 for all * @param string $selected Id contact pre-selectionne @@ -2987,13 +2989,15 @@ class Form * Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want. * See instead to force the default value by the caller. * - * @param int $selected Id of payment term to preselect by default - * @param string $htmlname Nom de la zone select - * @param int $filtertype Not used - * @param int $addempty Add an empty entry + * @param int $selected Id of payment term to preselect by default + * @param string $htmlname Nom de la zone select + * @param int $filtertype Not used + * @param int $addempty Add an empty entry + * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info + * @param string $morecss Add more CSS on select tag * @return void */ - function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0) + function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0, $noinfoadmin=0, $morecss='') { global $langs, $user, $conf; @@ -3004,7 +3008,7 @@ class Form // Set default value if not already set by caller if (empty($selected) && ! empty($conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID)) $selected = $conf->global->MAIN_DEFAULT_PAYMENT_TERM_ID; - print ''; if ($addempty) print ''; foreach($this->cache_conditions_paiements as $id => $arrayconditions) { @@ -3020,7 +3024,7 @@ class Form print ''; } print ''; - if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); + if ($user->admin && empty($noinfoadmin)) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); } @@ -3035,7 +3039,7 @@ class Form * @param int $noadmininfo 0=Add admin info, 1=Disable admin info * @param int $maxlength Max length of label * @param int $active Active or not, -1 = all - * @param string $morecss Add more css + * @param string $morecss Add more CSS on select tag * @return void */ function select_types_paiements($selected='', $htmlname='paiementtype', $filtertype='', $format=0, $empty=0, $noadmininfo=0, $maxlength=0, $active=1, $morecss='') @@ -3275,7 +3279,7 @@ class Form $return= ''; + $retstring.=''; } else return 'BadValueForParameterTypeHour'; if ($typehour!='text') $retstring.=' '.$langs->trans('HourShort'); - else $retstring.=':'; + else $retstring.=':'; // Minutes if ($minunderhours) $retstring.='
    '; - else $retstring.=" "; + else $retstring.=' '; if ($typehour=='select' || $typehour=='textselect') { @@ -5065,7 +5071,7 @@ class Form } elseif ($typehour=='text' ) { - $retstring.=''; + $retstring.=''; } if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); @@ -5213,15 +5219,16 @@ class Form */ static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0) { - global $langs; + global $conf, $langs; global $delayedhtmlcontent; - $tmpplugin='select2'; + // TODO Use an internal dolibarr component instead of select2 + if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && ! defined('REQUIRE_JQUERY_MULTISELECT')) return ''; $out=''; - // TODO Use an internal dolibarr component instead of select2 - $outdelayed=' + $tmpplugin='select2'; + $outdelayed="\n".' '; + print ''; print '
    '; + $tableCell.=' onkeyup="updateTotal('.$idw.',\''.$modeinput.'\')"'; + $tableCell.=' onblur="regexEvent(this,event,\''.$modeinput.'\'); updateTotal('.$idw.',\''.$modeinput.'\')" />'; + $tableCell.=''; print $tableCell; } @@ -996,8 +1017,8 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $var); - else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $var); + if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); + else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable); } $level--; } @@ -1151,7 +1172,6 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $sql2.= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_amount, p.dateo, p.datee"; $sql2.= " ORDER BY p.title, p.ref"; - $var=true; $resql = $db->query($sql2); if ($resql) { diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 581c324674a..c02fbbbb220 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -252,7 +252,8 @@ function restrictedArea($user, $features, $objectid=0, $tableandshare='', $featu { //print '
    feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; if (empty($user->rights->$feature->creer) - && empty($user->rights->$feature->write)) { $createok=0; $nbko++; } + && empty($user->rights->$feature->write) + && empty($user->rights->$feature->create)) { $createok=0; $nbko++; } } } diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index 3876dc0e2cd..4d79b87122e 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -184,7 +184,7 @@ function dol_loginfunction($langs,$conf,$mysoc) // Set cookie for timeout management $prefix=dol_getprefix(); $sessiontimeout='DOLSESSTIMEOUT_'.$prefix; - if (! empty($conf->global->MAIN_SESSION_TIMEOUT)) setcookie($sessiontimeout, $conf->global->MAIN_SESSION_TIMEOUT, 0, "/", '', 0); + if (! empty($conf->global->MAIN_SESSION_TIMEOUT)) setcookie($sessiontimeout, $conf->global->MAIN_SESSION_TIMEOUT, 0, "/", null, false, true); if (GETPOST('urlfrom','alpha')) $_SESSION["urlfrom"]=GETPOST('urlfrom','alpha'); else unset($_SESSION["urlfrom"]); diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 47ec0741127..6a02f67c6d4 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -175,7 +175,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1700__+MAX_llx_menu__, 'billing', 'customer_bills', 6__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills', 'BillsCustomers', 0, 'bills', '$user->rights->facture->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1701__+MAX_llx_menu__, 'billing', '', 1700__+MAX_llx_menu__, '/compta/facture/card.php?action=create&leftmenu=customers_bills', 'NewBill', 1, 'bills', '$user->rights->facture->creer', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1705__+MAX_llx_menu__, 'billing', '', 1700__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills', 'List', 1, 'bills', '$user->rights->facture->lire', '', 2, 4, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1702__+MAX_llx_menu__, 'billing', '', 1700__+MAX_llx_menu__, '/compta/facture/fiche-rec.php?leftmenu=customers_bills', 'ListOfTemplates', 1, 'bills', '$user->rights->facture->lire', '', 2, 5, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1702__+MAX_llx_menu__, 'billing', '', 1700__+MAX_llx_menu__, '/compta/facture/invoicetemplate_list.php?leftmenu=customers_bills', 'ListOfTemplates', 1, 'bills', '$user->rights->facture->lire', '', 2, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1720__+MAX_llx_menu__, 'billing', '', 1705__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills&search_status=0', 'BillShortStatusDraft', 2, 'bills', '$user->rights->facture->lire', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->facture->enabled', __HANDLER__, 'left', 1721__+MAX_llx_menu__, 'billing', '', 1705__+MAX_llx_menu__, '/compta/facture/list.php?leftmenu=customers_bills&search_status=1', 'BillShortStatusNotPaid', 2, 'bills', '$user->rights->facture->lire', '', 2, 2, __ENTITY__); @@ -217,18 +217,21 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left -- Setup insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2451__+MAX_llx_menu__, 'accountancy', 'accountancy_admin', 2400__+MAX_llx_menu__, '/accountancy/index.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'Setup', 1, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 1, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2454__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_journal', 2451__+MAX_llx_menu__, '/accountancy/admin/journals_list.php?id=35&mainmenu=accountancy&leftmenu=accountancy_admin', 'AccountingJournals', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 10, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2455__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_chartmodel', 2451__+MAX_llx_menu__, '/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'Pcg_version', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 20, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2456__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_chart', 2451__+MAX_llx_menu__, '/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'Chartofaccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 30, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2457__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_chart_group', 2451__+MAX_llx_menu__, '/accountancy/admin/categories_list.php?id=32&mainmenu=accountancy&leftmenu=accountancy_admin', 'AccountingCategory', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 40, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2453__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_general', 2451__+MAX_llx_menu__, '/accountancy/admin/index.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'General', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 10, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2454__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_journal', 2451__+MAX_llx_menu__, '/accountancy/admin/journals_list.php?id=35&mainmenu=accountancy&leftmenu=accountancy_admin', 'AccountingJournals', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 20, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2455__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_chartmodel', 2451__+MAX_llx_menu__, '/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'Pcg_version', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 30, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2456__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_chart', 2451__+MAX_llx_menu__, '/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'Chartofaccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 40, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2457__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_chart_group', 2451__+MAX_llx_menu__, '/accountancy/admin/categories_list.php?id=32&mainmenu=accountancy&leftmenu=accountancy_admin', 'AccountingCategory', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 41, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2458__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_default', 2451__+MAX_llx_menu__, '/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuDefaultAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 50, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2459__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_vat', 2451__+MAX_llx_menu__, '/compta/bank/index.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuBankAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 52, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2459__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_vat', 2451__+MAX_llx_menu__, '/compta/bank/index.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuBankAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 51, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2460__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_vat', 2451__+MAX_llx_menu__, '/admin/dict.php?id=10&from=accountancy&search_country_id=__MYCOUNTRYID__&mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuVatAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 60, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2461__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_tax', 2451__+MAX_llx_menu__, '/admin/dict.php?id=7&from=accountancy&search_country_id=__MYCOUNTRYID__&mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuTaxAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 70, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $conf->expensereport->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2462__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_expensereport', 2451__+MAX_llx_menu__, '/admin/dict.php?id=17&from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuExpenseReportAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 80, __ENTITY__); - insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2463__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_product', 2451__+MAX_llx_menu__, '/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuProductsAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 90, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2460__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_vat', 2451__+MAX_llx_menu__, '/admin/dict.php?id=10&from=accountancy&search_country_id=__MYCOUNTRYID__&mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuVatAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 52, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2461__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_tax', 2451__+MAX_llx_menu__, '/admin/dict.php?id=7&from=accountancy&search_country_id=__MYCOUNTRYID__&mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuTaxAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 53, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $conf->expensereport->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2462__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_expensereport', 2451__+MAX_llx_menu__, '/admin/dict.php?id=17&from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuExpenseReportAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 54, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2463__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_product', 2451__+MAX_llx_menu__, '/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'MenuProductsAccounts', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 55, __ENTITY__); + + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin"', __HANDLER__, 'left', 2464__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_export', 2451__+MAX_llx_menu__, '/accountancy/admin/export.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'ExportOptions', 2, 'accountancy', '$user->rights->accounting->chartofaccount', '', 0, 60, __ENTITY__); -- Accounting period insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled && $leftmenu=="accountancy_admin" && $conf->global->MAIN_FEATURES_LEVEL > 0', __HANDLER__, 'left', 2450__+MAX_llx_menu__, 'accountancy', 'accountancy_admin_period', 2451__+MAX_llx_menu__, '/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin', 'FiscalPeriod', 1, 'admin', '', '', 2, 80, __ENTITY__); -- Binding diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 5fc0ab2c516..9119afc7696 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -73,6 +73,13 @@ function print_auguria_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$m $showmode=dol_auguria_showmenu($type_user,$newTabMenu[$i],$listofmodulesforexternal); if ($showmode == 1) { + // $menu_array[$i]['url'] can be a relative url, a full external url or a dynamic value like '$conf->global->APARAM) + if (preg_match('/^\$conf->global->([^\?]+)/', $newTabMenu[$i]['url'], $reg)) + { + $keyforsconst=$reg[1]; + $newTabMenu[$i]['url'] = $conf->global->$keyforsconst; + } + $url = $shorturl = $newTabMenu[$i]['url']; if (! preg_match("/^(http:\/\/|https:\/\/)/i",$newTabMenu[$i]['url'])) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 76eb879cd7b..013b6ea74ae 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -811,7 +811,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_paid&search_status=2",$langs->trans("BillShortStatusPaid"),2,$user->rights->facture->lire); $newmenu->add("/compta/facture/list.php?leftmenu=customers_bills_canceled&search_status=3",$langs->trans("BillShortStatusCanceled"),2,$user->rights->facture->lire); } - $newmenu->add("/compta/facture/fiche-rec.php",$langs->trans("ListOfTemplates"),1,$user->rights->facture->creer); // No need to see recurring invoices, if user has no permission to create invoice. + $newmenu->add("/compta/facture/invoicetemplate_list.php",$langs->trans("ListOfTemplates"),1,$user->rights->facture->creer); // No need to see recurring invoices, if user has no permission to create invoice. $newmenu->add("/compta/paiement/list.php",$langs->trans("Payments"),1,$user->rights->facture->lire); @@ -969,37 +969,30 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu // Chart of account $newmenu->add("/accountancy/index.php?leftmenu=accountancy_admin", $langs->trans("Setup"),1,$user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin', 1); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/journals_list.php?id=35&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingJournals"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_journal', 10); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/accountmodel.php?id=31&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Pcg_version"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chartmodel', 20); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Chartofaccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 30); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/categories_list.php?id=32&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingCategory"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 31); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDefaultAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 40); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/index.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("General"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_general', 10); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/journals_list.php?id=35&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingJournals"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_journal', 20); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/accountmodel.php?id=31&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Pcg_version"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chartmodel', 30); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Chartofaccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 40); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/categories_list.php?id=32&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingCategory"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 41); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDefaultAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 50); if (! empty($conf->banque->enabled)) { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/compta/bank/index.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuBankAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_bank', 42); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/compta/bank/index.php?mainmenu=accountancy&leftmenu=accountancy_admin&search_status=-1", $langs->trans("MenuBankAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_bank', 51); } if (! empty($conf->facture->enabled) || ! empty($conf->fournisseur->enabled)) { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=10&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuVatAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 50); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=10&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuVatAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 52); } if (! empty($conf->tax->enabled)) { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=7&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuTaxAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 50); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=7&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuTaxAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 53); } if (! empty($conf->expensereport->enabled)) { - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=17&from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuExpenseReportAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 50); + if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=17&from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuExpenseReportAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 54); } - /* not required yet, already supported by default account - if (! empty($conf->loan->enabled)) - { - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/loan.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuLoanAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_loan', 45); - } - if (! empty($conf->don->enabled)) - { - if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/don/admin/donation.php?from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDonationAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_donation', 47); - }*/ - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuProductsAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_product', 60); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuProductsAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_product', 55); + if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/export.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("ExportOptions"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_export', 60); // Fiscal year if ($conf->global->MAIN_FEATURES_LEVEL > 0) // Not yet used. In a future will lock some periods. @@ -1083,36 +1076,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } else dol_print_error($db); $db->free($resql); - - /* - $sql = "SELECT rowid, label, accountancy_journal"; - $sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; - $sql.= " WHERE entity = ".$conf->entity; - $sql.= " AND clos = 0"; - $sql.= " ORDER BY label"; - - $resql = $db->query($sql); - if ($resql) - { - $numr = $db->num_rows($resql); - $i = 0; - - if ($numr > 0) - while ($i < $numr) - { - $objp = $db->fetch_object($resql); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add('/accountancy/journal/bankjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal&id_account='.$objp->rowid,$langs->trans("Journal").' - '.dol_trunc($objp->label,10),2,$user->rights->accounting->comptarapport->lire); - $i++; - } - } - else dol_print_error($db); - $db->free($resql); - - // Add other journal - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/sellsjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("SellsJournal"),2,$user->rights->accounting->comptarapport->lire); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/purchasesjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("PurchasesJournal"),2,$user->rights->accounting->comptarapport->lire); - if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/journal/expensereportsjournal.php?mainmenu=accountancy&leftmenu=accountancy_journal",$langs->trans("ExpenseReportsJournal"),2,$user->rights->accounting->comptarapport->lire); - */ } // General Ledger @@ -1419,6 +1382,18 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/expensereport/list.php?search_status=2&leftmenu=expensereport&mainmenu=hrm", $langs->trans("ListToApprove"), 2, $user->rights->expensereport->approve); $newmenu->add("/expensereport/stats/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("Statistics"), 1, $user->rights->expensereport->lire); } + + if (! empty($conf->projet->enabled)) + { + if (empty($conf->global->PROJECT_HIDE_TASKS)) + { + $langs->load("projects"); + + $search_project_user = GETPOST('search_project_user','int'); + + $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire); + } + } } @@ -1623,6 +1598,13 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } } + // $menu_array[$i]['url'] can be a relative url, a full external url or a dynamic value like '$conf->global->APARAM) + if (preg_match('/^\$conf->global->([^\?]+)/', $menu_array[$i]['url'], $reg)) + { + $keyforsconst=$reg[1]; + $menu_array[$i]['url'] = $conf->global->$keyforsconst; + } + $url = $shorturl = $menu_array[$i]['url']; if (! preg_match("/^(http:\/\/|https:\/\/)/i",$menu_array[$i]['url'])) diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index 496d054d86c..3f8a7c092b8 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -35,12 +35,12 @@ class modAccounting extends DolibarrModules * Constructor. Define names, constants, directories, boxes, permissions * * @param DoliDB $db Database handler - */ + */ function __construct($db) { global $conf; - $this->db = $db; + $this->db = $db; $this->numero = 50400; $this->family = "financial"; @@ -60,7 +60,7 @@ class modAccounting extends DolibarrModules $this->dirs = array('/accounting/temp'); // Config pages - $this->config_page_url = array('index.php@accountancy'); + $this->config_page_url = array(); // Dependencies $this->depends = array("modFacture","modBanque","modTax"); // List of modules id that must be enabled if this module is enabled @@ -84,116 +84,57 @@ class modAccounting extends DolibarrModules "1", "With this constants on, bank account number is always required" ); - $this->const[1] = array( - "ACCOUNTING_EXPORT_SEPARATORCSV", - "string", - "," - ); - $this->const[2] = array( + $this->const[3] = array( "ACCOUNTING_ACCOUNT_SUSPENSE", "chaine", "471" ); - $this->const[3] = array( - "ACCOUNTING_SELL_JOURNAL", - "chaine", - "VTE" - ); $this->const[4] = array( - "ACCOUNTING_PURCHASE_JOURNAL", - "chaine", - "ACH" - ); - $this->const[5] = array( - "ACCOUNTING_SOCIAL_JOURNAL", - "chaine", - "SOC" - ); - $this->const[6] = array( - "ACCOUNTING_MISCELLANEOUS_JOURNAL", - "chaine", - "OD" - ); - $this->const[7] = array( "ACCOUNTING_ACCOUNT_TRANSFER_CASH", "chaine", "58" ); - $this->const[8] = array( + $this->const[5] = array( "CHARTOFACCOUNTS", "chaine", "2" ); - $this->const[9] = array( + $this->const[6] = array( "ACCOUNTING_EXPORT_MODELCSV", "chaine", "1" ); - $this->const[10] = array( + $this->const[7] = array( "ACCOUNTING_LENGTH_GACCOUNT", "chaine", "" ); - $this->const[11] = array( + $this->const[8] = array( "ACCOUNTING_LENGTH_AACCOUNT", "chaine", "" ); - $this->const[13] = array( + $this->const[9] = array( "ACCOUNTING_LIST_SORT_VENTILATION_TODO", "yesno", "1" ); - $this->const[14] = array( + $this->const[10] = array( "ACCOUNTING_LIST_SORT_VENTILATION_DONE", "yesno", "1" ); - /* - $this->const[15] = array ( - "ACCOUNTING_GROUPBYACCOUNT", - "yesno", - "1" - ); - */ - $this->const[16] = array ( + $this->const[11] = array ( "ACCOUNTING_EXPORT_DATE", "chaine", "%d%m%Y" ); - /* - $this->const[17] = array ( - "ACCOUNTING_EXPORT_PIECE", - "yesno", - "1" + $this->const[12] = array( + "ACCOUNTING_EXPORT_SEPARATORCSV", + "string", + "," ); - $this->const[18] = array ( - "ACCOUNTING_EXPORT_GLOBAL_ACCOUNT", - "yesno", - "1" - ); - $this->const[19] = array ( - "ACCOUNTING_EXPORT_LABEL", - "yesno", - "1" - ); - $this->const[20] = array ( - "ACCOUNTING_EXPORT_AMOUNT", - "yesno", - "1" - ); - $this->const[21] = array ( - "ACCOUNTING_EXPORT_DEVISE", - "yesno", - "1" - ); - */ - $this->const[22] = array( - "ACCOUNTING_EXPENSEREPORT_JOURNAL", - "chaine", - "ER" - ); - $this->const[23] = array( + $this->const[13] = array( "ACCOUNTING_EXPORT_FORMAT", "chaine", "csv" diff --git a/htdocs/core/modules/modApi.class.php b/htdocs/core/modules/modApi.class.php index fc1821fde53..34c8e62a03f 100644 --- a/htdocs/core/modules/modApi.class.php +++ b/htdocs/core/modules/modApi.class.php @@ -20,7 +20,7 @@ /** * \defgroup api Module Api * \brief Descriptor file for Api modulee - * \file htdocs/api/core/modules/modApi.class.php + * \file htdocs/core/modules/modApi.class.php * \ingroup api * \brief Description and activation file for module Api */ @@ -67,7 +67,7 @@ class modApi extends DolibarrModules // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' $this->picto='technic'; - + $this->module_parts = array(); // Data directories to create when module is enabled. diff --git a/htdocs/core/modules/modCashDesk.class.php b/htdocs/core/modules/modCashDesk.class.php index f153631dc20..33b44297628 100644 --- a/htdocs/core/modules/modCashDesk.class.php +++ b/htdocs/core/modules/modCashDesk.class.php @@ -70,7 +70,7 @@ class modCashDesk extends DolibarrModules $this->phpmin = array(4,1); // Minimum version of PHP required by module $this->need_dolibarr_version = array(2,4); // Minimum version of Dolibarr required by module $this->langfiles = array("cashdesk"); - //$this->warnings_activation = array('FR'=>'WarningNoteModulePOSForFrenchLaw'); // Warning to show when we activate module. array('always'='text') or array('FR'='text') + $this->warnings_activation = array('FR'=>'WarningNoteModulePOSForFrenchLaw'); // Warning to show when we activate module. array('always'='text') or array('FR'='text') //$this->warnings_activation_ext = array('FR'=>'WarningInstallationMayBecomeNotCompliantWithLaw'); // Warning to show when we activate an external module. array('always'='text') or array('FR'='text') // Constants diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index f51e69039e9..79541c10105 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -260,10 +260,12 @@ class modProduct extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('p'=>MAIN_DB_PREFIX.'product','extra'=>MAIN_DB_PREFIX.'product_extrafields'); $this->import_tables_creator_array[$r]=array('p'=>'fk_user_author'); // Fields to store import user id - $this->import_fields_array[$r]=array('p.ref'=>"Ref*",'p.label'=>"Label*",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.weight'=>"Weight",'p.duration'=>"Duration",'p.customcode'=>'CustomCode','p.price'=>"SellingPriceHT",'p.price_ttc'=>"SellingPriceTTC",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation'); + $this->import_fields_array[$r]=array('p.ref'=>"Ref*",'p.label'=>"Label*",'p.description'=>"Description",'p.url'=>"PublicUrl",'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode",'p.note'=>"Note",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.weight'=>"Weight",'p.duration'=>"Duration",'p.customcode'=>'CustomCode','p.price'=>"SellingPriceHT",'p.price_ttc'=>"SellingPriceTTC", 'p.tva_tx'=>'VATRate', 'p.tosell'=>"OnSell*",'p.tobuy'=>"OnBuy*",'p.fk_product_type'=>"Type*",'p.finished'=>'Nature','p.datec'=>'DateCreation'); if (! empty($conf->stock->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.seuil_stock_alerte'=>'StockLimit','p.desiredstock'=>'DesiredStock','p.pmp'=>'PMPValue')); if (! empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.cost_price'=>'CostPrice')); if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax1_tx'=>'LT1', 'p.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.localtax2_tx'=>'LT2', 'p.localtax2_type'=>'LT2Type')); if (! empty($conf->barcode->enabled)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('p.barcode'=>'BarCode')); if (! empty($conf->global->PRODUCT_USE_UNITS)) $this->import_fields_array[$r]['p.fk_unit'] = 'Unit'; // Add extra fields @@ -300,9 +302,12 @@ class modProduct extends DolibarrModules $this->import_fields_array[$r]=array('sp.fk_product'=>"ProductOrService*", 'sp.fk_soc'=>"Supplier*", 'sp.ref_fourn'=>'SupplierRef', 'sp.quantity'=>"QtyMin*", 'sp.tva_tx'=>'VATRate', 'sp.price'=>"PriceQtyMinHT*", - 'sp.unitprice'=>'UnitPriceHT*', // TODO Make this file not required and calculate it from price and qty + 'sp.unitprice'=>'UnitPriceHT*', // TODO Make this field not required and calculate it from price and qty 'sp.remise_percent'=>'DiscountQtyMin' ); + if (is_object($mysoc) && $mysoc->useNPR()) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.recuperableonly'=>'NPR')); + if (is_object($mysoc) && $mysoc->useLocalTax(1)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.localtax1_tx'=>'LT1', 'sp.localtax1_type'=>'LT1Type')); + if (is_object($mysoc) && $mysoc->useLocalTax(2)) $this->import_fields_array[$r]=array_merge($this->import_fields_array[$r],array('sp.localtax2_tx'=>'LT2', 'sp.localtax2_type'=>'LT2Type')); $this->import_convertvalue_array[$r]=array( 'sp.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty'), diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index da1223526db..54f0e418eb0 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -42,6 +42,7 @@ class pdf_paiement global $langs,$conf; $langs->load("bills"); $langs->load("compta"); + $langs->load("main"); $this->db = $db; $this->description = $langs->transnoentities("ListOfCustomerPayments"); @@ -77,6 +78,8 @@ class pdf_paiement $this->posxinvoiceamount-=10; $this->posxpaymentamount-=20; } + // which type of document will be generated: clients (client) or providers (fourn) invoices + $this->doc_type = "client"; } @@ -105,7 +108,6 @@ class pdf_paiement $this->month=$month; $this->year=$year; - $dir=$_dir.'/'.$year; if (! is_dir($dir)) @@ -120,7 +122,17 @@ class pdf_paiement $month = sprintf("%02d",$month); $year = sprintf("%04d",$year); + $file = $dir . "/payments-".$year."-".$month.".pdf"; + switch ($this->doc_type) { + case "client": + $file = $dir . "/payments-".$year."-".$month.".pdf"; + break; + case "fourn": + $file = $dir . "/supplier_payments-".$year."-".$month.".pdf"; + break; + } + // Add pdfgeneration hook if (! is_object($hookmanager)) @@ -148,7 +160,14 @@ class pdf_paiement // count number of lines of payment $sql = "SELECT p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p"; + switch ($this->doc_type) { + case "client": + $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p"; + break; + case "fourn": + $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p"; + break; + } $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; $sql.= " AND p.entity = " . $conf->entity; $result = $this->db->query($sql); @@ -158,35 +177,70 @@ class pdf_paiement } // number of bill - $sql = "SELECT p.datep as dp, f.facnumber"; - //$sql .= ", c.libelle as paiement_type, p.num_paiement"; - $sql.= ", c.code as paiement_code, p.num_paiement"; - $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; - $sql.= ", pf.amount as pf_amount"; - if (! empty($conf->banque->enabled)) - $sql.= ", ba.ref as bankaccount"; - $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."facture as f,"; - $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiement_facture as pf,"; - if (! empty($conf->banque->enabled)) - $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facture = f.rowid AND pf.fk_paiement = p.rowid"; - if (! empty($conf->banque->enabled)) - $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND p.fk_paiement = c.id "; - $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - } - if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; - $sql.= " ORDER BY p.datep ASC, pf.fk_paiement ASC"; + switch ($this->doc_type) { + case "client": + $sql = "SELECT p.datep as dp, f.facnumber"; + //$sql .= ", c.libelle as paiement_type, p.num_paiement"; + $sql.= ", c.code as paiement_code, p.num_paiement"; + $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; + $sql.= ", pf.amount as pf_amount"; + if (! empty($conf->banque->enabled)) + $sql.= ", ba.ref as bankaccount"; + $sql.= ", p.rowid as prowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."facture as f,"; + $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiement_facture as pf,"; + if (! empty($conf->banque->enabled)) + $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; + $sql.= " ".MAIN_DB_PREFIX."societe as s"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + } + $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facture = f.rowid AND pf.fk_paiement = p.rowid"; + if (! empty($conf->banque->enabled)) + $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND p.fk_paiement = c.id "; + $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + } + if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; + $sql.= " ORDER BY p.datep ASC, pf.fk_paiement ASC"; + break; + case "fourn": + $sql = "SELECT p.datep as dp, f.ref as facnumber"; + //$sql .= ", c.libelle as paiement_type, p.num_paiement"; + $sql.= ", c.code as paiement_code, p.num_paiement"; + $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; + $sql.= ", pf.amount as pf_amount"; + if (! empty($conf->banque->enabled)) + $sql.= ", ba.ref as bankaccount"; + $sql.= ", p.rowid as prowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p, ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; + if (! empty($conf->banque->enabled)) + $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; + $sql.= " ".MAIN_DB_PREFIX."societe as s"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + } + $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facturefourn = f.rowid AND pf.fk_paiementfourn = p.rowid"; + if (! empty($conf->banque->enabled)) + $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND p.fk_paiement = c.id "; + $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; + if (! $user->rights->societe->client->voir && ! $socid) + { + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + } + if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; + $sql.= " ORDER BY p.datep ASC, pf.fk_paiementfourn ASC"; + break; + } dol_syslog(get_class($this)."::write_file", LOG_DEBUG); $result = $this->db->query($sql); @@ -199,7 +253,7 @@ class pdf_paiement while ($i < $num) { $objp = $this->db->fetch_object($result); - + $lines[$i][0] = $objp->facnumber; $lines[$i][1] = dol_print_date($this->db->jdate($objp->dp),"day",false,$outputlangs,true); @@ -210,6 +264,7 @@ class pdf_paiement $lines[$i][6] = price($objp->pf_amount); $lines[$i][7] = $objp->prowid; $lines[$i][8] = $objp->bankaccount; + $lines[$i][9] = $objp->paiement_amount; $i++; } } @@ -275,9 +330,9 @@ class pdf_paiement if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); - + $this->result = array('fullpath'=>$file); - + return 1; } @@ -300,7 +355,14 @@ class pdf_paiement $default_font_size = pdf_getPDFFontSize($outputlangs); $title=$conf->global->MAIN_INFO_SOCIETE_NOM; - $title.=' - '.$outputlangs->transnoentities("ListOfCustomerPayments"); + switch($this->doc_type) { + case "client": + $title.=' - '.$outputlangs->transnoentities("ListOfCustomerPayments"); + break; + case "fourn": + $title.=' - '.$outputlangs->transnoentities("ListOfSupplierPayments"); + break; + } $title.=' - '.dol_print_date(dol_mktime(0,0,0,$this->month,1,$this->year),"%B %Y",false,$outputlangs,true); $pdf->SetFont('','B',$default_font_size + 1); $pdf->SetXY($this->marge_gauche,10); @@ -357,10 +419,13 @@ class pdf_paiement */ function Body(&$pdf, $page, $lines, $outputlangs) { + global $langs; $default_font_size = pdf_getPDFFontSize($outputlangs); $pdf->SetFont('','', $default_font_size - 1); $oldprowid = 0; + $total_page = 0; + $total = 0; $pdf->SetFillColor(220,220,220); $yp = 0; $numlines=count($lines); @@ -377,13 +442,17 @@ class pdf_paiement } if ($oldprowid <> $lines[$j][7]) { - if ($yp > $this->tab_height -10) + if ($yp > $this->tab_height -15) { + $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $langs->transnoentities('SubTotal')." : ".price($total_page), 0, 'R', 0); $page++; $pdf->AddPage(); $this->_pagehead($pdf, $page, 0, $outputlangs); $pdf->SetFont('','', $default_font_size - 1); $yp = 0; + $total += $total_page; + $total_page = 0; } $pdf->SetXY($this->posxdate - 1, $this->tab_top + 10 + $yp); @@ -398,11 +467,12 @@ class pdf_paiement $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][4], 0, 'R', 1); $yp = $yp + 5; + $total_page += $lines[$j][9]; } // Invoice number $pdf->SetXY($this->posxinvoice, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); + $pdf->MultiCell($this->posxinvoice - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); // BankAccount $pdf->SetXY($this->posxbankaccount, $this->tab_top + 10 + $yp); @@ -422,6 +492,9 @@ class pdf_paiement $oldprowid = $lines[$j][7]; } } + $total += $total_page; + $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); + $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $langs->transnoentities('Total')." : ".price($total), 0, 'R', 0); } } diff --git a/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php b/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php index 108b3bd6ce6..c7cb11ad31f 100644 --- a/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement_fourn.class.php @@ -23,12 +23,12 @@ */ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - +require_once DOL_DOCUMENT_ROOT.'/core/modules/rapport/pdf_paiement.class.php'; /** * Classe permettant de generer les rapports de paiement */ -class pdf_paiement_fourn +class pdf_paiement_fourn extends pdf_paiement { /** * Constructor @@ -37,389 +37,10 @@ class pdf_paiement_fourn */ function __construct($db) { - global $langs,$conf; - $langs->load("bills"); - $langs->load("compta"); - - $this->db = $db; - $this->description = $langs->transnoentities("ListOfCustomerPayments"); - - // Dimension page pour format A4 - $this->type = 'pdf'; - $formatarray=pdf_getFormat(); - $this->page_largeur = $formatarray['width']; - $this->page_hauteur = $formatarray['height']; - $this->format = array($this->page_largeur,$this->page_hauteur); - $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; - $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; - $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; - $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; - - $this->tab_top = 30; - - $this->line_height = 5; - $this->line_per_page = 40; - $this->tab_height = $this->page_hauteur - $this->marge_haute - $this->marge_basse - $this->tab_top - 5; // must be > $this->line_height * $this->line_per_page and < $this->page_hauteur - $this->marge_haute - $this->marge_basse - $this->tab_top - 5; - - $this->posxdate=$this->marge_gauche+2; - $this->posxpaymenttype=42; - $this->posxinvoice=82; - $this->posxbankaccount=110; - $this->posxinvoiceamount=132; - $this->posxpaymentamount=162; - if ($this->page_largeur < 210) // To work with US executive format - { - $this->line_per_page = 35; - $this->posxpaymenttype-=10; - $this->posxinvoice-=0; - $this->posxinvoiceamount-=10; - $this->posxpaymentamount-=20; + parent::__construct($db); + $this->doc_type = "fourn"; } } - /** - * Fonction generant la rapport sur le disque - * - * @param string $_dir repertoire - * @param int $month mois du rapport - * @param int $year annee du rapport - * @param string $outputlangs Lang output object - * @return int <0 if KO, >0 if OK - */ - function write_file($_dir, $month, $year, $outputlangs) - { - include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - - global $conf, $hookmanager, $langs, $user; - - $socid=0; - if ($user->societe_id) $socid=$user->societe_id; - - if (! is_object($outputlangs)) $outputlangs=$langs; - // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO - if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; - - $this->month=$month; - $this->year=$year; - - $dir=$_dir.'/'.$year; - - if (! is_dir($dir)) - { - $result=dol_mkdir($dir); - if ($result < 0) - { - $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); - return -1; - } - } - - $month = sprintf("%02d",$month); - $year = sprintf("%04d",$year); - $file = $dir . "/supplier_payments-".$year."-".$month.".pdf"; - - // Add pdfgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('pdfgeneration')); - $parameters=array('file'=>$file,'outputlangs'=>$outputlangs); - global $action; - $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks - - $pdf=pdf_getInstance($this->format); - $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance - - if (class_exists('TCPDF')) - { - $pdf->setPrintHeader(false); - $pdf->setPrintFooter(false); - } - $pdf->SetFont(pdf_getPDFFont($outputlangs)); - - $num=0; - $lines=array(); - - // count number of lines of payment - $sql = "SELECT p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p"; - $sql.= " WHERE p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - $sql.= " AND p.entity = " . $conf->entity; - $result = $this->db->query($sql); - if ($result) - { - $numpaiement = $this->db->num_rows($result); - } - - // number of bill - $sql = "SELECT p.datep as dp, f.ref"; - //$sql .= ", c.libelle as paiement_type, p.num_paiement"; - $sql.= ", c.code as paiement_code, p.num_paiement"; - $sql.= ", p.amount as paiement_amount, f.total_ttc as facture_amount"; - $sql.= ", pf.amount as pf_amount"; - if (! empty($conf->banque->enabled)) - $sql.= ", ba.ref as bankaccount"; - $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p, ".MAIN_DB_PREFIX."facture_fourn as f,"; - $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; - if (! empty($conf->banque->enabled)) - $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - } - $sql.= " WHERE f.fk_soc = s.rowid AND pf.fk_facturefourn = f.rowid AND pf.fk_paiementfourn = p.rowid"; - if (! empty($conf->banque->enabled)) - $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND p.fk_paiement = c.id "; - $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; - if (! $user->rights->societe->client->voir && ! $socid) - { - $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - } - if (! empty($socid)) $sql .= " AND s.rowid = ".$socid; - $sql.= " ORDER BY p.datep ASC, pf.fk_paiementfourn ASC"; - - dol_syslog(get_class($this)."::write_file", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - $var=True; - - while ($i < $num) - { - $objp = $this->db->fetch_object($result); - - - $lines[$i][0] = $objp->ref; - $lines[$i][1] = dol_print_date($this->db->jdate($objp->dp),"day",false,$outputlangs,true); - $lines[$i][2] = $langs->transnoentities("PaymentTypeShort".$objp->paiement_code); - $lines[$i][3] = $objp->num_paiement; - $lines[$i][4] = price($objp->paiement_amount); - $lines[$i][5] = price($objp->facture_amount); - $lines[$i][6] = price($objp->pf_amount); - $lines[$i][7] = $objp->prowid; - $lines[$i][8] = $objp->bankaccount; - $i++; - } - } - else - { - dol_print_error($this->db); - } - - $pages = intval(($num + $numpaiement) / $this->line_per_page); - - if ((($num + $numpaiement) % $this->line_per_page)>0) - { - $pages++; - } - - if ($pages == 0) - { - // force to build at least one page if report has no line - $pages = 1; - } - - $pdf->Open(); - $pagenb=0; - $pdf->SetDrawColor(128,128,128); - - $pdf->SetTitle($outputlangs->transnoentities("Payments")); - $pdf->SetSubject($outputlangs->transnoentities("Payments")); - $pdf->SetCreator("Dolibarr ".DOL_VERSION); - $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); - //$pdf->SetKeyWords(); - if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); - - $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right - $pdf->SetAutoPageBreak(1,0); - - // New page - $pdf->AddPage(); - $pagenb++; - $this->_pagehead($pdf, $pagenb, 1, $outputlangs); - $pdf->SetFont('','', 9); - $pdf->MultiCell(0, 3, ''); // Set interline to 3 - $pdf->SetTextColor(0,0,0); - - - $this->Body($pdf, 1, $lines, $outputlangs); - - if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); - - $pdf->Close(); - - $pdf->Output($file,'F'); - - // Add pdfgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('pdfgeneration')); - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); - global $action; - $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - - if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); - - $this->result = array('fullpath'=>$file); - - return 1; - } - - /** - * Show top header of page. - * - * @param PDF $pdf Object PDF - * @param int $page Object to show - * @param int $showaddress 0=no, 1=yes - * @param Translate $outputlangs Object lang for output - * @return void - */ - function _pagehead(&$pdf, $page, $showaddress, $outputlangs) - { - global $langs; - - // Do not add the BACKGROUND as this is a report - //pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); - - $default_font_size = pdf_getPDFFontSize($outputlangs); - - $title=$conf->global->MAIN_INFO_SOCIETE_NOM; - $title.=' - '.$outputlangs->transnoentities("ListOfSupplierPayments"); - $title.=' - '.dol_print_date(dol_mktime(0,0,0,$this->month,1,$this->year),"%B %Y",false,$outputlangs,true); - $pdf->SetFont('','B',$default_font_size + 1); - $pdf->SetXY($this->marge_gauche,10); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->marge_gauche, 2, $title, 0, 'C'); - - $pdf->SetFont('','',$default_font_size); - - $pdf->SetXY($this->posxdate, 16); - $pdf->MultiCell(80, 2, $outputlangs->transnoentities("DateBuild")." : ".dol_print_date(time(),"day",false,$outputlangs,true), 0, 'L'); - - $pdf->SetXY($this->posxdate+100, 16); - $pdf->MultiCell(80, 2, $outputlangs->transnoentities("Page")." : ".$page, 0, 'R'); - - - // Title line - $pdf->SetXY($this->posxdate, $this->tab_top+2); - $pdf->MultiCell($this->posxpaymenttype - $this->posxdate, 2, 'Date'); - - $pdf->line($this->posxpaymenttype - 1, $this->tab_top, $this->posxpaymenttype - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxpaymenttype, $this->tab_top+2); - $pdf->MultiCell($this->posxinvoice - $this->posxpaymenttype, 2, $outputlangs->transnoentities("PaymentMode"), 0, 'L'); - - $pdf->line($this->posxinvoice - 1, $this->tab_top, $this->posxinvoice - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxinvoice, $this->tab_top+2); - $pdf->MultiCell($this->posxbankaccount - $this->posxinvoice, 2, $outputlangs->transnoentities("Invoice"), 0, 'L'); - - $pdf->line($this->posxbankaccount - 1, $this->tab_top, $this->posxbankaccount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxbankaccount, $this->tab_top+2); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, 2, $outputlangs->transnoentities("Account"), 0, 'L'); - - - $pdf->line($this->posxinvoiceamount - 1, $this->tab_top, $this->posxinvoiceamount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top+2); - $pdf->MultiCell($this->posxpaymentamount - $this->posxinvoiceamount - 1, 2, $outputlangs->transnoentities("AmountInvoice"), 0, 'R'); - - $pdf->line($this->posxpaymentamount - 1, $this->tab_top, $this->posxpaymentamount - 1, $this->tab_top + $this->tab_height + 10); - $pdf->SetXY($this->posxpaymentamount, $this->tab_top+2); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount - 1, 2, $outputlangs->transnoentities("AmountPayment"), 0, 'R'); - - $pdf->line($this->marge_gauche, $this->tab_top + 10, $this->page_largeur - $this->marge_droite, $this->tab_top + 10); - - $pdf->Rect($this->marge_gauche, $this->tab_top, $this->page_largeur - $this->marge_gauche - $this->marge_droite, $this->tab_height + 10); - } - - - /** - * Output body - * - * @param PDF $pdf PDF object - * @param string $page Page - * @param array $lines Array of lines - * @param Translate $outputlangs Object langs - * @return void - */ - function Body(&$pdf, $page, $lines, $outputlangs) - { - $default_font_size = pdf_getPDFFontSize($outputlangs); - - $pdf->SetFont('','', $default_font_size - 1); - $oldprowid = 0; - $pdf->SetFillColor(220,220,220); - $yp = 0; - $numlines=count($lines); - for ($j = 0 ; $j < $numlines ; $j++) - { - $i = $j; - if ($yp > $this->tab_height -5) - { - $page++; - $pdf->AddPage(); - $this->_pagehead($pdf, $page, 0, $outputlangs); - $pdf->SetFont('','', $default_font_size - 1); - $yp = 0; - } - if ($oldprowid <> $lines[$j][7]) - { - if ($yp > $this->tab_height -10) - { - $page++; - $pdf->AddPage(); - $this->_pagehead($pdf, $page, 0, $outputlangs); - $pdf->SetFont('','', $default_font_size - 1); - $yp = 0; - } - - $pdf->SetXY($this->posxdate - 1, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymenttype - $this->posxdate + 1, $this->line_height, $lines[$j][1], 0, 'L', 1); - - $pdf->SetXY($this->posxpaymenttype, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxpaymenttype, $this->line_height, $lines[$j][2].' '.$lines[$j][3], 0, 'L', 1); - - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymentamount- $this->posxinvoiceamount, $this->line_height, '', 0, 'R', 1); - - $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][4], 0, 'R', 1); - $yp = $yp + 5; - } - - // Invoice number - $pdf->SetXY($this->posxinvoice, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxinvoiceamount - $this->posxbankaccount, $this->line_height, $lines[$j][0], 0, 'L', 0); - - // BankAccount - $pdf->SetXY($this->posxbankaccount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxbankaccount - $this->posxdate, $this->line_height, $lines[$j][8], 0, 'L', 0); - - // Invoice amount - $pdf->SetXY($this->posxinvoiceamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->posxpaymentamount- $this->posxinvoiceamount - 1, $this->line_height, $lines[$j][5], 0, 'R', 0); - - // Payment amount - $pdf->SetXY($this->posxpaymentamount, $this->tab_top + 10 + $yp); - $pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $lines[$j][6], 0, 'R', 0); - $yp = $yp + 5; - - if ($oldprowid <> $lines[$j][7]) - { - $oldprowid = $lines[$j][7]; - } - } - } -} - diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php index 494dddbdff3..61d39af045e 100644 --- a/htdocs/core/search_page.php +++ b/htdocs/core/search_page.php @@ -73,7 +73,7 @@ if ($conf->use_javascript_ajax && 1 == 2) // select2 is ko with jmobile { if (! is_object($form)) $form=new Form($db); $selected=-1; - $searchform.='

    '.$form->selectArrayAjax('searchselectcombo', DOL_URL_ROOT.'/core/ajax/selectsearchbox.php', $selected, 'data-role="none"', '', 0, 1, 'minwidth300', 1, $langs->trans("Search"), 0); + $searchform.='

    '.$form->selectArrayAjax('searchselectcombo', DOL_URL_ROOT.'/core/ajax/selectsearchbox.php', $selected, '', '', 0, 1, 'minwidth300', 1, $langs->trans("Search"), 0); } else { diff --git a/htdocs/core/tools.php b/htdocs/core/tools.php index 51378c9246a..8010f726c4f 100644 --- a/htdocs/core/tools.php +++ b/htdocs/core/tools.php @@ -49,7 +49,8 @@ print load_fiche_titre($text); print $langs->trans("ToolsDesc").'

    '; - +// Show logo +print '
    '; llxFooter(); diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index 6c5f563e106..e04f4e0cb92 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -26,6 +26,8 @@ * $elementtype */ +$langs->load("modulebuilder"); + ?> @@ -101,13 +103,13 @@ if (type == 'separate') { - required.removeAttr('checked').prop('disabled', true); alwayseditable.removeAttr('checked').prop('disabled', true); list.val('').prop('disabled', true); + required.removeAttr('checked').prop('disabled', true); alwayseditable.removeAttr('checked').prop('disabled', true); list.removeAttr('checked').prop('disabled', true); jQuery('#size, #default_value').val('').prop('disabled', true); } else { default_value.removeAttr('disabled'); - required.removeAttr('disabled'); alwayseditable.removeAttr('disabled'); list.val('').removeAttr('disabled'); + required.removeAttr('disabled'); alwayseditable.removeAttr('disabled'); list.removeAttr('disabled'); } } init_typeoffields(''); @@ -178,12 +180,9 @@ multicompany->enabled) { ?> -global->MAIN_FEATURES_LEVEL >= 2) { ?> - - +
    '; + print ''; + print ''; + print ''; + print ''; + print ''; @@ -576,6 +619,38 @@ while ($i < min($num,$limit)) print ''; + print $obj->qty; + print ''; + print price($obj->total_ht); + print ''; + print price($obj->total_tva); + print ''; + print price2num($obj->tva_tx).'%'; + print ''; + print price($obj->subprice); + print '
    '; @@ -772,8 +788,8 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $var); - else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $var); + if ($parent == 0) projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable); + else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable); } $level--; } @@ -787,7 +803,6 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr } - /** * Output a task line into a perday intput mode * @@ -801,10 +816,10 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr * @param string $tasksrole Array of roles user has on task * @param string $mine Show only task lines I am assigned to * @param int $restricteditformytask 0=No restriction, 1=Enable add time only if task is a task i am affected to - * @param boolean $var Var for css of lines + * @param array $isavailable Array with data that say if user is available for several days for morning and afternoon * @return $inc */ -function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask=1, $var=false) +function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, &$isavailable) { global $conf, $db, $user, $bc, $langs; global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic; @@ -840,7 +855,6 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ // Break on a new project if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) { - //$var = ! $var; $lastprojectid=$lines[$i]->fk_project; $projectstatic->id = $lines[$i]->fk_project; } @@ -955,13 +969,19 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ for ($idw = 0; $idw < 7; $idw++) { $tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd'); + + $cssonholiday=''; + if (! $isavailable[$tmpday]['morning'] && ! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayallday '; + elseif (! $isavailable[$tmpday]['morning']) $cssonholiday.='onholidaymorning '; + elseif (! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayafternoon '; + $tmparray=dol_getdate($tmpday); $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$tmpday][$lines[$i]->id]; $alreadyspent=''; if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); $alttitle=$langs->trans("AddHereTimeSpentForDay",$tmparray['day'],$tmparray['mon']); - $tableCell =''; + $tableCell =''; if ($alreadyspent) { $tableCell.=''; @@ -971,8 +991,9 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ } $tableCell.=''; - $tableCell.='
    trans("AllEntities"); ?>>
    trans("ByDefaultInList"); ?> -trans("FeatureNotYetSupported")); ?> ->
    textwithpicto($langs->trans("ByDefaultInList"), $langs->trans("VisibleDesc")); ?> +
    diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 85cfe510df8..def07fa432f 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -25,6 +25,8 @@ * $elementtype */ +$langs->load("modulebuilder"); + ?> @@ -96,13 +98,13 @@ if (type == 'separate') { - required.removeAttr('checked').prop('disabled', true); alwayseditable.removeAttr('checked').prop('disabled', true); list.val('').prop('disabled', true); + required.removeAttr('checked').prop('disabled', true); alwayseditable.removeAttr('checked').prop('disabled', true); list.removeAttr('checked').prop('disabled', true); jQuery('#size, #default_value').val('').prop('disabled', true); } else { default_value.removeAttr('disabled'); - required.removeAttr('disabled'); alwayseditable.removeAttr('disabled'); list.val('').removeAttr('disabled'); + required.removeAttr('disabled'); alwayseditable.removeAttr('disabled'); list.removeAttr('disabled'); } } init_typeoffields(jQuery("#type").val()); @@ -238,11 +240,8 @@ else trans("AllEntities"); ?>> -global->MAIN_FEATURES_LEVEL >= 2) { ?> -trans("ByDefaultInList"); ?> -trans("FeatureNotYetSupported")); ?> -> - +textwithpicto($langs->trans("ByDefaultInList"), $langs->trans("VisibleDesc")); ?> + diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php index f989ce448b5..30b4299a21e 100644 --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php @@ -22,6 +22,9 @@ * $extrafield * $elementtype */ + +$langs->load("modulebuilder"); + ?> @@ -48,6 +51,7 @@ print ''.$langs->trans("Unique").''; print ''.$langs->trans("ComputedFormula").''; print ''.$langs->trans("Required").''; print ''.$langs->trans("AlwaysEditable").''; +print ''.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).''; if (! empty($conf->global->MAIN_CAN_HIDE_EXTRAFIELDS)) print ''.$langs->trans("Hidden").''; if ($conf->multicompany->enabled) { print ''.$langs->trans("Entities").''; @@ -59,7 +63,7 @@ if (count($extrafields->attribute_type)) { foreach($extrafields->attribute_type as $key => $value) { - + print ''; print "".$extrafields->attribute_pos[$key]."\n"; print "".$extrafields->attribute_label[$key]."\n"; @@ -70,7 +74,8 @@ if (count($extrafields->attribute_type)) print ''.dol_trunc($extrafields->attribute_computed[$key], 20)."\n"; print ''.yn($extrafields->attribute_required[$key])."\n"; print ''.yn($extrafields->attribute_alwayseditable[$key])."\n"; - if (! empty($conf->global->MAIN_CAN_HIDE_EXTRAFIELDS)) print ''.yn($extrafields->attribute_hidden[$key])."\n"; // Add hidden option on not working feature. Why hide if user can't see it. + print ''.$extrafields->attribute_list[$key]."\n"; + if (! empty($conf->global->MAIN_CAN_HIDE_EXTRAFIELDS)) print ''.yn($extrafields->attribute_hidden[$key])."\n"; // Add hidden option on not working feature. Why hide if user can't see it. if ($conf->multicompany->enabled) { print ''.($extrafields->attribute_entityid[$key]==0?$langs->trans("All"):$extrafields->attribute_entitylabel[$key]).''; } @@ -83,7 +88,7 @@ else { $colspan=9; if (! empty($conf->global->MAIN_CAN_HIDE_EXTRAFIELDS)) $colspan++; - + print ''; print ''; print $langs->trans("None"); diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php new file mode 100644 index 00000000000..aa9353201cf --- /dev/null +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -0,0 +1,184 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + + +/* + * Code to ouput content when action is presend + * + * $trackid must be defined + * $modelmail + * $defaulttopic + * $diroutput + */ + +if ($action == 'presend') +{ + $langs->load("mails"); + + $titreform='SendMail'; + + $object->fetch_projet(); + + if (! in_array($object->element, array('societe', 'user'))) + { + $ref = dol_sanitizeFileName($object->ref); + include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + $fileparams = dol_most_recent_file($diroutput . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); + // + if ($object->element == 'invoice_supplier') + { + $fileparams = dol_most_recent_file($diroutput . '/' . get_exdir($object->id,2,0,0,$object,$object->element).$ref, preg_quote($ref,'/').'([^\-])+'); + } + + $file = $fileparams['fullname']; + } + + // Define output language + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) + { + $newlang = $_REQUEST['lang_id']; + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) + { + $newlang = $object->thirdparty->default_lang; + } + + if (!empty($newlang)) + { + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang($newlang); + $outputlangs->load('commercial'); + } + + $topicmail=''; + if (empty($object->ref_client)) { + $topicmail = $outputlangs->trans($defaulttopic, '__REF__'); + } else if (! empty($object->ref_client)) { + $topicmail = $outputlangs->trans($defaulttopic, '__REF__ (__REFCLIENT__)'); + } + + // Build document if it not exists + if (! in_array($object->element, array('societe', 'user'))) + { + if (! $file || ! is_readable($file)) { + if ($object->element != 'member') + { + $result = $object->generateDocument(GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) { + dol_print_error($db, $object->error, $object->errors); + exit(); + } + $fileparams = dol_most_recent_file($diroutput . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); + $file = $fileparams['fullname']; + } + } + } + + print '
    '; + print '
    '; + print '
    '; + print load_fiche_titre($langs->trans($titreform)); + + dol_fiche_head(''); + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); + $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); + + if ($formmail->fromtype === 'user') + { + $formmail->fromid = $user->id; + } + $formmail->trackid=$trackid; + if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set + { + include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $formmail->frommail=dolAddEmailTrackId($formmail->frommail, $trackid); + } + $formmail->withfrom = 1; + + $liste = array(); + if ($object->element == 'expensereport') + { + $fuser = new User($db); + $fuser->fetch($object->fk_user_author); + $liste['thirdparty'] = $fuser->getFullName($langs)." <".$fuser->email.">"; + } + elseif ($object->element == 'societe') + { + foreach ($object->thirdparty_and_contact_email_array(1) as $key => $value) { + $liste[$key] = $value; + } + } + elseif ($object->element == 'member') + { + $liste['thirdparty'] = $object->getFullName($langs)." <".$object->email.">"; + } + else + { + foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) { + $liste[$key] = $value; + } + } + + $formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste; + $formmail->withtocc = $liste; + $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; + $formmail->withtopic = $topicmail; + $formmail->withfile = 2; + $formmail->withbody = 1; + $formmail->withdeliveryreceipt = 1; + $formmail->withcancel = 1; + + // Make substitution in email content + $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object); + $substitutionarray['__CHECK_READ__'] = (is_object($object) && is_object($object->thirdparty)) ? '' : ''; + $substitutionarray['__PERSONALIZED__'] = ''; // deprecated + $substitutionarray['__CONTACTCIVNAME__'] = ''; + + $parameters = array( + 'mode' => 'formemail' + ); + complete_substitutions_array($substitutionarray, $outputlangs, $object, $parameters); + + // Tableau des substitutions + $formmail->substit = $substitutionarray; + + // Tableau des parametres complementaires + $formmail->param['action'] = 'send'; + $formmail->param['models'] = $modelmail; + $formmail->param['models_id']=GETPOST('modelmailselected','int'); + $formmail->param['id'] = $object->id; + $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id; + + // Init list of files + if (GETPOST("mode") == 'init') { + $formmail->clear_attached_files(); + $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); + } + + // Show form + print $formmail->get_form(); + + dol_fiche_end(); +} + diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index e613c479ee0..da1cb9658a0 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -79,7 +79,7 @@ $formfile->form_attach_new_file( ); $disablemove=1; -if ($modulepart == 'produit') $disablemove=0; +if ($modulepart == 'product' || $modulepart == 'produit') $disablemove=0; // Drag and drop for up and down allowed on product // List of document $formfile->list_of_documents( diff --git a/htdocs/core/tpl/extrafields_add.tpl.php b/htdocs/core/tpl/extrafields_add.tpl.php new file mode 100644 index 00000000000..a608cb2da6b --- /dev/null +++ b/htdocs/core/tpl/extrafields_add.tpl.php @@ -0,0 +1,40 @@ + + * Copyright (C) 2014 Juanjo Menent + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Need to have following variables defined: + * $object (invoice, order, ...) + * $action + * $conf + * $langs + * + * $parameters + * $cols + */ +?> + +executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (empty($reshook) && ! empty($extrafields->attribute_label)) { + print $object->showOptionals($extrafields, 'edit'); +} + +?> + \ No newline at end of file diff --git a/htdocs/core/tpl/extrafields_edit.tpl.php b/htdocs/core/tpl/extrafields_edit.tpl.php new file mode 100644 index 00000000000..aa0e30473f1 --- /dev/null +++ b/htdocs/core/tpl/extrafields_edit.tpl.php @@ -0,0 +1,40 @@ + + * Copyright (C) 2014 Juanjo Menent + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Need to have following variables defined: + * $object (invoice, order, ...) + * $action + * $conf + * $langs + * + * $parameters + * $cols + */ +?> + +executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (empty($reshook) && ! empty($extrafields->attribute_label)) { + print $object->showOptionals($extrafields, 'edit'); +} + +?> + \ No newline at end of file diff --git a/htdocs/core/tpl/massactions_form.tpl.php b/htdocs/core/tpl/massactions_form.tpl.php index 056a137a4b5..4087d988c3b 100644 --- a/htdocs/core/tpl/massactions_form.tpl.php +++ b/htdocs/core/tpl/massactions_form.tpl.php @@ -42,6 +42,8 @@ if (! GETPOST('cancel', 'alpha')) $thirdpartyid = ($objecttmp->fk_soc ? $objecttmp->fk_soc : $objecttmp->socid); if ($objecttmp->element == 'societe') $thirdpartyid = $objecttmp->id; + if ($objecttmp->element == 'expensereport') + $thirdpartyid = $objecttmp->fk_user_author; $listofselectedthirdparties[$thirdpartyid] = $thirdpartyid; $listofselectedref[$thirdpartyid][$toselectid] = $objecttmp->ref; } @@ -58,39 +60,47 @@ dol_fiche_head(null, '', ''); // Cree l'objet formulaire mail include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; $formmail = new FormMail($db); -$formmail->withform = - 1; +$formmail->withform = -1; $formmail->fromtype = (GETPOST('fromtype') ? GETPOST('fromtype') : (! empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE) ? $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE : 'user')); if ($formmail->fromtype === 'user') { $formmail->fromid = $user->id; } -if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1)) // If bit 1 is set -{ - $formmail->trackid = $trackid; -} +$formmail->trackid = $trackid; if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set { include DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; $formmail->frommail = dolAddEmailTrackId($formmail->frommail, $trackid); } $formmail->withfrom = 1; -$liste = $langs->trans("AllRecipientSelected", count($listofselectedthirdparties)); +$liste = $langs->trans("AllRecipientSelected", count($arrayofselected)); if (count($listofselectedthirdparties) == 1) // Only 1 different recipient selected, we can suggest contacts { $liste = array(); $thirdpartyid = array_shift($listofselectedthirdparties); - $soc = new Societe($db); - $soc->fetch($thirdpartyid); - foreach ($soc->thirdparty_and_contact_email_array(1) as $key => $value) { - $liste[$key] = $value; + if ($objecttmp->element == 'expensereport') + { + $fuser = new User($db); + $fuser->fetch($thirdpartyid); + $liste['thirdparty'] = $fuser->getFullName($langs)." <".$fuser->email.">"; + } + else + { + $soc = new Societe($db); + $soc->fetch($thirdpartyid); + foreach ($soc->thirdparty_and_contact_email_array(1) as $key => $value) { + $liste[$key] = $value; + } } $formmail->withtoreadonly = 0; } else { $formmail->withtoreadonly = 1; } -$formmail->withto = $liste; -$formmail->withtofree = 0; + +$formmail->withoptiononeemailperrecipient = empty($liste)?0:((GETPOST('oneemailperrecipient')=='on')?1:-1); +$formmail->withto = empty($liste)?(GETPOST('sendto','alpha')?GETPOST('sendto','alpha'):array()):$liste; +$formmail->withtofree = empty($liste)?1:0; $formmail->withtocc = 1; $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; $formmail->withtopic = $langs->transnoentities($topicmail, '__REF__', '__REFCLIENT__'); @@ -109,25 +119,11 @@ $formmail->withcancel = 1; $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $object); $substitutionarray['__EMAIL__'] = $sendto; $substitutionarray['__CHECK_READ__'] = (is_object($object) && is_object($object->thirdparty)) ? '' : ''; -$substitutionarray['__PERSONALIZED__'] = ''; +$substitutionarray['__PERSONALIZED__'] = ''; // deprecated $substitutionarray['__CONTACTCIVNAME__'] = ''; -// Add specific substitution for contracts -if (is_object($object) && $object->element == 'contrat' && is_array($object->lines)) -{ - $datenextexpiration = ''; - foreach ($object->lines as $line) - { - if ($line->statut != 4) - continue; - if ($line->date_fin_prevue > $datenextexpiration) - $datenextexpiration = $line->date_fin_prevue; - } - $substitutionarray['__CONTRACT_NEXT_EXPIRATION_DATE__'] = dol_print_date($datenextexpiration, 'dayrfc'); - $substitutionarray['__CONTRACT_NEXT_EXPIRATION_DATETIME__'] = dol_print_date($datenextexpiration, 'standard'); -} $parameters = array( -'mode' => 'formemail' + 'mode' => 'formemail' ); complete_substitutions_array($substitutionarray, $langs, $object, $parameters); diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index 45e7dc32697..0d1a0a79339 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -17,15 +17,15 @@ * along with this program. If not, see . */ -// $permission must be defined by caller. -// $cssclass must be defined by caller. For example cssclass='fieldtitle" +// $permissionnote must be defined by caller. For example $permissionnote=$user->rights->module->create +// $cssclass must be defined by caller. For example $cssclass='fieldtitle" $module = $object->element; $note_public = 'note_public'; $note_private = 'note_private'; $colwidth=(isset($colwidth)?$colwidth:(empty($cssclass)?'25':'')); - -$permission=(isset($permission)?$permission:(isset($user->rights->$module->creer)?$user->rights->$module->creer:0)); // If already defined by caller page +// Set $permission from the $permissionnote var defined on calling page +$permission=(isset($permissionnote)?$permissionnote:(isset($permission)?$permission:(isset($user->rights->$module->create)?$user->rights->$module->create:(isset($user->rights->$module->creer)?$user->rights->$module->creer:0)))); $moreparam=(isset($moreparam)?$moreparam:''); $value_public=$object->note_public; $value_private=$object->note_private; diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 9969740ff35..84b2413f396 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -317,7 +317,7 @@ else { product->enabled) || ! empty($conf->service->enabled)) { ?> - + "> diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 2f839e06281..de1649225ee 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -179,7 +179,7 @@ $coldisplay=-1; // We remove first td product->enabled) || ! empty($conf->service->enabled)) { ?> - + @@ -266,21 +266,21 @@ jQuery(document).ready(function() if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#price_ht").val() != '') { jQuery("#price_ttc").val(''); jQuery("#multicurrency_subprice").val(''); - } + } }); jQuery("#price_ttc").keyup(function(event) { // console.log(event.which); // discard event tag and arrows if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') { jQuery("#price_ht").val(''); jQuery("#multicurrency_subprice").val(''); - } + } }); jQuery("#multicurrency_subprice").keyup(function(event) { // console.log(event.which); // discard event tag and arrows if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') { jQuery("#price_ht").val(''); jQuery("#price_ttc").val(''); - } + } }); tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); + if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); if (price2num($line->total_localtax1)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); if (price2num($line->total_localtax2)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); if (empty($positiverates)) $positiverates='0'; diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index fa93db2503c..bfa0efad8e6 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -55,7 +55,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers // Proposals to order if ($action == 'PROPAL_CLOSE_SIGNED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_PROPAL_AUTOCREATE_ORDER)) { include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; @@ -74,7 +74,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers // Order to invoice if ($action == 'ORDER_CLOSE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_ORDER_AUTOCREATE_INVOICE)) { include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; @@ -90,12 +90,10 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - - // Order classify billed proposal if ($action == 'ORDER_CLASSIFY_BILLED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL)) { $object->fetchObjectLinked('','propal',$object->id,$object->element); @@ -106,8 +104,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['propal'] as $element) { @@ -119,11 +117,35 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - // classify billed order + // classify billed order & billed propososal if ($action == 'BILL_VALIDATE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); - + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); + + // First classify billed the order to allow the proposal classify process + if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER)) + { + $object->fetchObjectLinked('','commande',$object->id,$object->element); + if (! empty($object->linkedObjects)) + { + $totalonlinkedelements=0; + foreach($object->linkedObjects['commande'] as $element) + { + if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; + } + dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) + { + foreach($object->linkedObjects['commande'] as $element) + { + $ret=$element->classifyBilled($user); + } + } + } + return $ret; + } + + // Second classify billed the proposal. if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL)) { $object->fetchObjectLinked('','propal',$object->id,$object->element); @@ -134,8 +156,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['propal'] as $element) { @@ -145,34 +167,13 @@ class InterfaceWorkflowManager extends DolibarrTriggers } return $ret; } - - if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER)) - { - $object->fetchObjectLinked('','commande',$object->id,$object->element); - if (! empty($object->linkedObjects)) - { - $totalonlinkedelements=0; - foreach($object->linkedObjects['commande'] as $element) - { - if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; - } - dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) - { - foreach($object->linkedObjects['commande'] as $element) - { - $ret=$element->classifyBilled($user); - } - } - } - return $ret; - } + } // Invoice classify billed order if ($action == 'BILL_PAYED') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER)) { @@ -184,8 +185,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers { if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht; } - dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); - if ($totalonlinkedelements == $object->total_ht) + dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) { foreach($object->linkedObjects['commande'] as $element) { @@ -199,8 +200,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers if ($action=='SHIPPING_VALIDATE') { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG); - + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); if (! empty($conf->commande->enabled) && ! empty($conf->expedition->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING)) { @@ -234,6 +234,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } } + //Build array of quantity ordered by product if (is_array($order->lines) && count($order->lines)>0) { foreach($order->lines as $orderline) { diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index 0f9826ea0e0..ec1fa9465b5 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -349,7 +349,10 @@ class InterfaceActionsAuto extends DolibarrTriggers $langs->load("interventions"); if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionSentByEMail",$object->ref); - $object->actionmsg=$langs->transnoentities("InterventionSentByEMail",$object->ref); + if (empty($object->actionmsg)) + { + $object->actionmsg=$langs->transnoentities("InterventionSentByEMail",$object->ref); + } // Parameters $object->sendtoid defined by caller //$object->sendtoid=0; @@ -419,6 +422,54 @@ class InterfaceActionsAuto extends DolibarrTriggers // Parameters $object->sendtoid defined by caller //$object->sendtoid=0; } + elseif ($action == 'PROPOSAL_SUPPLIER_VALIDATE') + { + $langs->load("agenda"); + $langs->load("other"); + $langs->load("propal"); + + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalValidatedInDolibarr",($object->newref?$object->newref:$object->ref)); + $object->actionmsg=$langs->transnoentities("PropalValidatedInDolibarr",($object->newref?$object->newref:$object->ref)); + + $object->sendtoid=0; + } + elseif ($action == 'PROPOSAL_SUPPLIER_SENTBYMAIL') + { + $langs->load("agenda"); + $langs->load("other"); + $langs->load("propal"); + + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProposalSentByEMail",$object->ref); + if (empty($object->actionmsg)) + { + $object->actionmsg=$langs->transnoentities("ProposalSentByEMail",$object->ref); + } + + // Parameters $object->sendtoid defined by caller + //$object->sendtoid=0; + } + elseif ($action == 'PROPOSAL_SUPPLIER_CLOSE_SIGNED') + { + $langs->load("agenda"); + $langs->load("other"); + $langs->load("propal"); + + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedSignedInDolibarr",$object->ref); + $object->actionmsg=$langs->transnoentities("PropalClosedSignedInDolibarr",$object->ref); + + $object->sendtoid=0; + } + elseif ($action == 'PROPOSAL_SUPPLIER_CLOSE_REFUSED') + { + $langs->load("agenda"); + $langs->load("other"); + $langs->load("propal"); + + if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedRefusedInDolibarr",$object->ref); + $object->actionmsg=$langs->transnoentities("PropalClosedRefusedInDolibarr",$object->ref); + + $object->sendtoid=0; + } elseif ($action == 'ORDER_SUPPLIER_CREATE') { $langs->load("agenda"); diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php index 561ba330694..a906ec821ed 100644 --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php @@ -1,6 +1,7 @@ - * Copyright (C) 2014 Marcos García +/* Copyright (C) 2005-2012 Laurent Destailleur + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2014 Marcos García * * 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 @@ -49,553 +50,748 @@ class InterfaceLdapsynchro extends DolibarrTriggers * @return int <0 if KO, 0 if no triggered ran, >0 if OK */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) - { - if (empty($conf->ldap->enabled)) return 0; // Module not active, we do nothing + { + if (empty($conf->ldap->enabled)) return 0; // Module not active, we do nothing - if (! function_exists('ldap_connect')) - { - dol_syslog("Warning, module LDAP is enabled but LDAP functions not available in this PHP", LOG_WARNING); - return 0; - } + if (! function_exists('ldap_connect')) + { + dol_syslog("Warning, module LDAP is enabled but LDAP functions not available in this PHP", LOG_WARNING); + return 0; + } - // Users - if ($action == 'USER_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + $result=0; - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); + // Users + if ($action == 'USER_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); } - return $result; - } - } - elseif ($action == 'USER_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'USER_NEW_PASSWORD') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_NEW_PASSWORD') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'USER_ENABLEDISABLE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - } - elseif ($action == 'USER_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'USER_SETINGROUP') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - // Must edit $object->newgroupid - $usergroup=new UserGroup($this->db); - if ($object->newgroupid > 0) - { - $usergroup->fetch($object->newgroupid); + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_ENABLEDISABLE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + } + elseif ($action == 'USER_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $oldinfo=$usergroup->_load_ldap_info(); - $olddn=$usergroup->_load_ldap_dn($oldinfo); + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); - // Verify if entry exist - $container=$usergroup->_load_ldap_dn($oldinfo,1); - $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } + $result=$ldap->delete($dn); + } - $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) - $dn=$usergroup->_load_ldap_dn($info); + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_SETINGROUP') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - } - return $result; - } - } - elseif ($action == 'USER_REMOVEFROMGROUP') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + if ($result > 0) + { + // Must edit $object->newgroupid + $usergroup=new UserGroup($this->db); + if ($object->newgroupid > 0) + { + $usergroup->fetch($object->newgroupid); - // Must edit $object->newgroupid - $usergroup=new UserGroup($this->db); - if ($object->oldgroupid > 0) - { - $usergroup->fetch($object->oldgroupid); + $oldinfo=$usergroup->_load_ldap_info(); + $olddn=$usergroup->_load_ldap_dn($oldinfo); - $oldinfo=$usergroup->_load_ldap_info(); - $olddn=$usergroup->_load_ldap_dn($oldinfo); + // Verify if entry exist + $container=$usergroup->_load_ldap_dn($oldinfo,1); + $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } - // Verify if entry exist - $container=$usergroup->_load_ldap_dn($oldinfo,1); - $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } + $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$usergroup->_load_ldap_dn($info); - $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) - $dn=$usergroup->_load_ldap_dn($info); + $result=$ldap->update($dn,$info,$user,$olddn); + } + } - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - } - return $result; - } - } + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'USER_REMOVEFROMGROUP') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + // Must edit $object->newgroupid + $usergroup=new UserGroup($this->db); + if ($object->oldgroupid > 0) + { + $usergroup->fetch($object->oldgroupid); + + $oldinfo=$usergroup->_load_ldap_info(); + $olddn=$usergroup->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$usergroup->_load_ldap_dn($oldinfo,1); + $search = "(".$usergroup->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$usergroup->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$usergroup->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } // Groupes - elseif ($action == 'GROUP_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + elseif ($action == 'GROUP_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } + + $result=$ldap->add($dn,$info,$user); } - return $result; - } - } - elseif ($action == 'GROUP_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'GROUP_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - - // Contacts - elseif ($action == 'CONTACT_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'CONTACT_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } - elseif ($action == 'CONTACT_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) - { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } - } + } + elseif ($action == 'GROUP_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - // Members - elseif ($action == 'MEMBER_CREATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { - $ldap=new Ldap(); - $ldap->connect_bind(); - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->add($dn,$info,$user); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; - } - } - elseif ($action == 'MEMBER_VALIDATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'GROUP_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + // Contacts + elseif ($action == 'CONTACT_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'CONTACT_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'CONTACT_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_CONTACT_ACTIVE)) + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + // Members + elseif ($action == 'MEMBER_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $membertype=new AdherentType($this->db); + if ($object->typeid > 0) + { + $membertype->fetch($object->typeid); + $membertype->listMembersForMemberType(); + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$membertype->_load_ldap_dn($oldinfo,1); + $search = "(".$membertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_VALIDATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If status field is setup to be synchronized if (! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only status - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only status + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_SUBSCRIPTION') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + } + elseif ($action == 'MEMBER_SUBSCRIPTION') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If subscriptions fields are setup to be synchronized if ($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE - || $conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT - || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE - || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT - || $conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION) + || $conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT + || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE + || $conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT + || $conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only subscriptions - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only subscriptions + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_MODIFY') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { - $ldap=new Ldap(); - $ldap->connect_bind(); + } + elseif ($action == 'MEMBER_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); - if (empty($object->oldcopy) || ! is_object($object->oldcopy)) - { - dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); - $object->oldcopy = clone $object; - } - - $oldinfo=$object->oldcopy->_load_ldap_info(); - $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); - - // Verify if entry exist - $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); - $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; - $records=$ldap->search($container,$search); - if (count($records) && $records['count'] == 0) - { - $olddn = ''; - } - - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + /* + * Change member info + */ + $newmembertype=new AdherentType($this->db); + $newmembertype->fetch($object->typeid); + $newmembertype->listMembersForMemberType(); + + $oldinfo=$newmembertype->_load_ldap_info(); + $olddn=$newmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$newmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$newmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$newmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$newmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + + if ($object->oldcopy->typeid != $object->typeid) + { + /* + * Remove member in old member type + */ + $oldmembertype=new AdherentType($this->db); + $oldmembertype->fetch($object->oldcopy->typeid); + $oldmembertype->listMembersForMemberType(); + + $oldinfo=$oldmembertype->_load_ldap_info(); + $olddn=$oldmembertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$oldmembertype->_load_ldap_dn($oldinfo,1); + $search = "(".$oldmembertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$oldmembertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$oldmembertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } } - return $result; - } - } - elseif ($action == 'MEMBER_NEW_PASSWORD') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_NEW_PASSWORD') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If password field is setup to be synchronized if ($conf->global->LDAP_FIELD_PASSWORD || $conf->global->LDAP_FIELD_PASSWORD_CRYPTED) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only password - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only password + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } } - elseif ($action == 'MEMBER_RESILIATE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') - { + elseif ($action == 'MEMBER_RESILIATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') + { // If status field is setup to be synchronized if (! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We know olddn=dn as we change only status - - $result=$ldap->update($dn,$info,$user,$olddn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We know olddn=dn as we change only status + + $result=$ldap->update($dn,$info,$user,$olddn); } - return $result; + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; } } - } - elseif ($action == 'MEMBER_DELETE') - { - dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + } + elseif ($action == 'MEMBER_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (! empty($conf->global->LDAP_MEMBER_ACTIVE) && (string) $conf->global->LDAP_MEMBER_ACTIVE == '1') { $ldap=new Ldap(); - $ldap->connect_bind(); + $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - - $result=$ldap->delete($dn); - if ($result < 0) + if ($result > 0) { - $this->error="ErrorLDAP ".$ldap->error; - } - return $result; - } - } + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); - // If not found -/* - else - { - dol_syslog("Trigger '".$this->name."' for action '$action' was ran by ".__FILE__." but no handler found for this action."); - return -1; - } -*/ - return 0; - } + $result=$ldap->delete($dn); + + // For member type + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + if ($object->typeid > 0) + { + /* + * Remove member in member type + */ + $membertype=new AdherentType($this->db); + $membertype->fetch($object->typeid); + $membertype->listMembersForMemberType('a.rowid != ' . $object->id); // remove deleted member from the list + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$membertype->_load_ldap_dn($oldinfo,1); + $search = "(".$membertype->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $info=$membertype->_load_ldap_info(); // Contains all members, included the new one (insert already done before trigger call) + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + } + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + // Members types + elseif ($action == 'MEMBER_TYPE_CREATE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_MEMBERS_TYPE'); + } + + $result=$ldap->add($dn,$info,$user); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_TYPE_MODIFY') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + if (empty($object->oldcopy) || ! is_object($object->oldcopy)) + { + dol_syslog("Trigger ".$action." was called by a function that did not set previously the property ->oldcopy onto object", LOG_WARNING); + $object->oldcopy = clone $object; + } + + $object->oldcopy->listMembersForMemberType(); + + $oldinfo=$object->oldcopy->_load_ldap_info(); + $olddn=$object->oldcopy->_load_ldap_dn($oldinfo); + + // Verify if entry exist + $container=$object->oldcopy->_load_ldap_dn($oldinfo,1); + $search = "(".$object->oldcopy->_load_ldap_dn($oldinfo,2).")"; + $records=$ldap->search($container,$search); + if (count($records) && $records['count'] == 0) + { + $olddn = ''; + } + + $object->listMembersForMemberType(); + + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->update($dn,$info,$user,$olddn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + elseif ($action == 'MEMBER_TYPE_DELETE') + { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + if (! empty($conf->global->LDAP_MEMBER_TYPE_ACTIVE) && (string) $conf->global->LDAP_MEMBER_TYPE_ACTIVE == '1') + { + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); + + $result=$ldap->delete($dn); + } + + if ($result < 0) $this->error="ErrorLDAP ".$ldap->error; + } + } + + return $result; + } } diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index a1255954014..8e540c799fe 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -148,7 +148,7 @@ if ($action=='add') $object->params=GETPOST('params'); $object->md5params=GETPOST('md5params'); $object->module_name=GETPOST('module_name','alpha'); - $object->note=GETPOST('note'); + $object->note=GETPOST('note','none'); $object->datestart=dol_mktime(GETPOST('datestarthour','int'), GETPOST('datestartmin','int'), 0, GETPOST('datestartmonth','int'), GETPOST('datestartday','int'), GETPOST('datestartyear','int')); $object->dateend=dol_mktime(GETPOST('dateendhour','int'), GETPOST('dateendmin','int'), 0, GETPOST('dateendmonth','int'), GETPOST('dateendday','int'), GETPOST('dateendyear','int')); $object->datenextrun=dol_mktime(GETPOST('datenextrunhour','int'), GETPOST('datenextrunmin','int'), 0, GETPOST('datenextrunmonth','int'), GETPOST('datenextrunday','int'), GETPOST('datenextrunyear','int')); @@ -184,7 +184,7 @@ if ($action=='update') $object->params=GETPOST('params'); $object->md5params=GETPOST('md5params'); $object->module_name=GETPOST('module_name','alpha'); - $object->note=GETPOST('note'); + $object->note=GETPOST('note','none'); $object->datestart=dol_mktime(GETPOST('datestarthour','int'), GETPOST('datestartmin','int'), 0, GETPOST('datestartmonth','int'), GETPOST('datestartday','int'), GETPOST('datestartyear','int')); $object->dateend=dol_mktime(GETPOST('dateendhour','int'), GETPOST('dateendmin','int'), 0, GETPOST('dateendmonth','int'), GETPOST('dateendday','int'), GETPOST('dateendyear','int')); $object->datenextrun=dol_mktime(GETPOST('datenextrunhour','int'), GETPOST('datenextrunmin','int'), 0, GETPOST('datenextrunmonth','int'), GETPOST('datenextrunday','int'), GETPOST('datenextrunyear','int')); diff --git a/htdocs/document.php b/htdocs/document.php index d35021005e6..0b2db2323cd 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -25,7 +25,7 @@ * \file htdocs/document.php * \brief Wrapper to download data files * \remarks Call of this wrapper is made with URL: - * document.php?modulepart=repfichierconcerne&file=pathrelatifdufichier + * document.php?modulepart=repfichierconcerne&file=relativepathoffile * document.php?modulepart=logs&file=dolibarr.log */ @@ -59,24 +59,27 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $encoding = ''; $action=GETPOST('action','alpha'); -$original_file=GETPOST('file','alpha'); // Do not use urldecode here ($_GET are already decoded by PHP). +$original_file=GETPOST('file','alpha'); // Do not use urldecode here ($_GET are already decoded by PHP). +$hashp=GETPOST('hashp','aZ09'); $modulepart=GETPOST('modulepart','alpha'); $urlsource=GETPOST('urlsource','alpha'); $entity=GETPOST('entity','int')?GETPOST('entity','int'):$conf->entity; // Security check -if (empty($modulepart)) accessforbidden('Bad value for parameter modulepart'); +if (empty($modulepart)) accessforbidden('Bad link. Bad value for parameter modulepart',0,0,1); +if (empty($original_file) && empty($hashp)) accessforbidden('Bad link. Missing identification to find file (original_file or hashp)',0,0,1); if ($modulepart == 'fckeditor') $modulepart='medias'; // For backward compatibility $socid=0; if ($user->societe_id > 0) $socid = $user->societe_id; // For some module part, dir may be privates -if (in_array($modulepart,array('facture_paiement','unpaid'))) +if (in_array($modulepart, array('facture_paiement','unpaid'))) { if (! $user->rights->societe->client->voir || $socid) $original_file='private/'.$user->id.'/'.$original_file; // If user has no permission to see all, output dir is specific to user } + /* * Action */ @@ -99,6 +102,33 @@ if (preg_match('/\.(html|htm)$/i',$original_file)) $attachment = false; if (isset($_GET["attachment"])) $attachment = GETPOST("attachment",'alpha')?true:false; if (! empty($conf->global->MAIN_DISABLE_FORCE_SAVEAS)) $attachment=false; +// If we have a hash public (hashp), we guess the original_file. +if (! empty($hashp)) +{ + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; + $ecmfile=new EcmFiles($db); + $result = $ecmfile->fetch(0, '', '', '', $hashp); + if ($result > 0) + { + $tmp = explode('/', $ecmfile->filepath, 2); // $ecmfile->filepatch is relative to document directory + $moduleparttocheck = $tmp[0]; + if ($moduleparttocheck == $modulepart) + { + $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir + //var_dump($original_file); exit; + } + else + { + accessforbidden('Bad link. File owns to another module part.',0,0,1); + } + } + else + { + accessforbidden('Bad link. File was not found or sharing attribute removed recently.',0,0,1); + } +} + + // Security: Delete string ../ into $original_file $original_file = str_replace("../","/", $original_file); diff --git a/htdocs/don/card.php b/htdocs/don/card.php index 6f3ab42d7fc..02498009cd9 100644 --- a/htdocs/don/card.php +++ b/htdocs/don/card.php @@ -765,6 +765,10 @@ if (! empty($id) && $action != 'edit') print $formfile->showdocuments('donation',$filename,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf); + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, array('don')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + print '
    '; print '
    '; diff --git a/htdocs/don/tpl/linkedobjectblock.tpl.php b/htdocs/don/tpl/linkedobjectblock.tpl.php new file mode 100644 index 00000000000..fdf6ae71c2f --- /dev/null +++ b/htdocs/don/tpl/linkedobjectblock.tpl.php @@ -0,0 +1,74 @@ + + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2014 Marcos García + * Copyright (C) 2017 Charlene Benke + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +?> + + + +load("donations"); + +$total=0; $ilink=0; +$var=true; +foreach($linkedObjectBlock as $key => $objectlink) +{ + $ilink++; + + $trclass=($var?'pair':'impair'); + if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass.=' liste_sub_total'; +?> + + trans("Donation"); ?> + getNomUrl(1); ?> + ref_client; ?> + date, 'day'); ?> + total_ht; + echo price($objectlink->total_ht); + } ?> + + getLibStatut(3); ?> + + 1) +{ + ?> + + trans("Total"); ?> + + + + + + + + + + diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index f1090757dad..0035b18d3c7 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -46,7 +46,9 @@ class EcmFiles //extends CommonObject /** */ - public $label; + public $ref; // hash of file path + public $label; // hash of file content (md5_file(dol_osencode($destfull)) + public $share; // hash for file sharing. empty by default public $entity; public $filename; public $filepath; @@ -94,10 +96,15 @@ class EcmFiles //extends CommonObject $error = 0; // Clean parameters - + if (isset($this->ref)) { + $this->ref = trim($this->ref); + } if (isset($this->label)) { $this->label = trim($this->label); } + if (isset($this->share)) { + $this->share = trim($this->share); + } if (isset($this->entity)) { $this->entity = trim($this->entity); } @@ -136,6 +143,10 @@ class EcmFiles //extends CommonObject } if (empty($this->date_c)) $this->date_c = dol_now(); + // If ref not defined + if (empty($ref)) $ref = dol_hash($this->filepath.'/'.$this->filename, 3); + + $maxposition=0; if (empty($this->position)) // Get max used { @@ -157,7 +168,9 @@ class EcmFiles //extends CommonObject // Insert request $sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '('; + $sql.= 'ref,'; $sql.= 'label,'; + $sql.= 'share,'; $sql.= 'entity,'; $sql.= 'filename,'; $sql.= 'filepath,'; @@ -174,7 +187,9 @@ class EcmFiles //extends CommonObject $sql.= 'fk_user_m,'; $sql.= 'acl'; $sql .= ') VALUES ('; + $sql .= " '".$ref."', "; $sql .= ' '.(! isset($this->label)?'NULL':"'".$this->db->escape($this->label)."'").','; + $sql .= ' '.(! isset($this->share)?'NULL':"'".$this->db->escape($this->share)."'").','; $sql .= ' '.(! isset($this->entity)?$conf->entity:$this->entity).','; $sql .= ' '.(! isset($this->filename)?'NULL':"'".$this->db->escape($this->filename)."'").','; $sql .= ' '.(! isset($this->filepath)?'NULL':"'".$this->db->escape($this->filepath)."'").','; @@ -232,11 +247,13 @@ class EcmFiles //extends CommonObject * Load object in memory from the database * * @param int $id Id object - * @param string $ref Not used yet. Will contains a hash id from filename+filepath + * @param string $ref Hash of file name (filename+filepath). Not always defined on some version. * @param string $relativepath Relative path of file from document directory. Example: path/path2/file + * @param string $hashoffile Hash of file content. Take the first one found if same file is at different places. This hash will also change if file content is changed. + * @param string $hashforshare Hash of file sharing. * @return int <0 if KO, 0 if not found, >0 if OK */ - public function fetch($id, $ref = null, $relativepath = '') + public function fetch($id, $ref = '', $relativepath = '', $hashoffile='', $hashforshare='') { dol_syslog(__METHOD__, LOG_DEBUG); @@ -244,6 +261,7 @@ class EcmFiles //extends CommonObject $sql .= ' t.rowid,'; $sql .= " t.ref,"; $sql .= " t.label,"; + $sql .= " t.share,"; $sql .= " t.entity,"; $sql .= " t.filename,"; $sql .= " t.filepath,"; @@ -268,11 +286,20 @@ class EcmFiles //extends CommonObject if ($relativepath) { $sql .= " AND t.filepath = '" . $this->db->escape(dirname($relativepath)) . "' AND t.filename = '".$this->db->escape(basename($relativepath))."'"; } - elseif (null !== $ref) { + elseif (! empty($ref)) { $sql .= " AND t.ref = '".$this->db->escape($ref)."'"; + } + elseif (! empty($hashoffile)) { + $sql .= " AND t.label = '".$this->db->escape($hashoffile)."'"; + } + elseif (! empty($hashforshare)) { + $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'"; } else { $sql .= ' AND t.rowid = ' . $id; } + // When we search on hash of content, we take the first one. Solve also hash conflict. + $this->db->plimit(1); + $this->db->order('t.rowid', 'ASC'); $resql = $this->db->query($sql); if ($resql) { @@ -283,6 +310,7 @@ class EcmFiles //extends CommonObject $this->id = $obj->rowid; $this->ref = $obj->ref; $this->label = $obj->label; + $this->share = $obj->share; $this->entity = $obj->entity; $this->filename = $obj->filename; $this->filepath = $obj->filepath; @@ -344,6 +372,7 @@ class EcmFiles //extends CommonObject $sql = 'SELECT'; $sql .= ' t.rowid,'; $sql .= " t.label,"; + $sql .= " t.share,"; $sql .= " t.entity,"; $sql .= " t.filename,"; $sql .= " t.filepath,"; @@ -393,8 +422,9 @@ class EcmFiles //extends CommonObject $line = new EcmfilesLine(); $line->id = $obj->rowid; - + $line->ref = $obj->ref; $line->label = $obj->label; + $line->share = $obj->share; $line->entity = $obj->entity; $line->filename = $obj->filename; $line->filepath = $obj->filepath; @@ -438,9 +468,15 @@ class EcmFiles //extends CommonObject // Clean parameters + if (isset($this->ref)) { + $this->ref = trim($this->ref); + } if (isset($this->label)) { $this->label = trim($this->label); } + if (isset($this->share)) { + $this->share = trim($this->share); + } if (isset($this->entity)) { $this->entity = trim($this->entity); } @@ -484,7 +520,9 @@ class EcmFiles //extends CommonObject // Update request $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET'; + $sql .= " ref = '".dol_hash($this->filepath.'/'.$this->filename, 3)."',"; $sql .= ' label = '.(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").','; + $sql .= ' share = '.(! empty($this->share)?"'".$this->db->escape($this->share)."'":"null").','; $sql .= ' entity = '.(isset($this->entity)?$this->entity:$conf->entity).','; $sql .= ' filename = '.(isset($this->filename)?"'".$this->db->escape($this->filename)."'":"null").','; $sql .= ' filepath = '.(isset($this->filepath)?"'".$this->db->escape($this->filepath)."'":"null").','; diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/docfile.php index 192240b4943..f6719d08604 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/docfile.php @@ -19,12 +19,12 @@ * \file htdocs/ecm/docfile.php * \ingroup ecm * \brief Card of a file for ECM module - * \author Laurent Destailleur */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; +require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/ecm.lib.php'; @@ -39,6 +39,9 @@ $langs->load("bills"); $langs->load("contracts"); $langs->load("categories"); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'alpha'); + if (!$user->rights->ecm->setup) accessforbidden(); // Get parameters @@ -61,8 +64,6 @@ $pagenext = $page + 1; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="label"; -$cancel=GETPOST('cancel','alpha'); -$action=GETPOST('action','aZ09'); $section=GETPOST("section"); if (! $section) { @@ -87,39 +88,43 @@ if (! $result > 0) $relativepath=$ecmdir->getRelativePath(); $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; +$fullpath=$conf->ecm->dir_output.'/'.$relativepath.$urlfile; + +$file = new stdClass(); +$file->section_id=$ecmdir->id; +$file->label=$urlfile; + +$relativetodocument = 'ecm/'.$relativepath; // $relativepath is relative to ECM dir, we need relative to document +$filepath=$relativepath.$file->label; +$filepathtodocument=$relativetodocument.$file->label; + +// Try to load object from index +$object = new ECMFiles($db); +$result=$object->fetch(0, '', $filepathtodocument); +if (! ($result >= 0)) +{ + dol_print_error($db, $object->error, $object->errors); + exit; +} + + + /* -$ecmfile = new ECMFile($db); -if (! empty($_GET["fileid"])) -{ - $result=$ecmfile->fetch($_GET["fileid"]); - if (! $result > 0) - { - dol_print_error($db,$ecmfile->error); - exit; - } -} -*/ + * Actions + */ - - -/******************************************************************* - * ACTIONS - * - * Put here all code to do according to value of "action" parameter - ********************************************************************/ - -if ($action == 'cancel') +if ($cancel) { $action =''; - if ($backtourl) + if ($backtopage) { - header("Location: ".$backtourl); + header("Location: ".$backtopage); exit; } else { - header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager§ion='.$section); + header("Location: ".DOL_URL_ROOT.'/ecm/docfile.php?urlfile='.$urlfile.'§ion='.$section); exit; } } @@ -129,8 +134,9 @@ if ($action == 'update') { $error=0; - $oldlabel=GETPOST('urlfile'); - $newlabel=GETPOST('label'); + $oldlabel=GETPOST('urlfile', 'alpha'); + $newlabel=GETPOST('label', 'alpha'); + $shareenabled = GETPOST('shareenabled', 'alpha'); //$db->begin(); @@ -144,7 +150,7 @@ if ($action == 'update') //print $oldfile.' - '.$newfile; if ($newlabel != $oldlabel) { - $result=dol_move($oldfile, $newfile); + $result=dol_move($oldfile, $newfile); // This include update of database if (! $result) { $langs->load('errors'); @@ -153,44 +159,62 @@ if ($action == 'update') } } + // Now we update index of file + $db->begin(); + if (! $error) { - //$db->commit(); + if (is_object($object)) + { + if ($shareenabled) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; + $object->share = getRandomPassword(true); + } + else + { + $object->share = ''; + } + $result = $object->update($user); + if ($result < 0) + { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + } + + if (!$error) + { + $db->commit(); $urlfile=$newlabel; } else { - //$db->rollback(); + $db->rollback(); } } -/******************************************************************* - * PAGE - * - * Put here all code to do according to value of "action" parameter - ********************************************************************/ - -llxHeader(); +/* + * View + */ $form=new Form($db); -$fullpath=$conf->ecm->dir_output.'/'.$relativepath.$urlfile; - -$file = new stdClass(); -$file->section_id=$ecmdir->id; -$file->label=$urlfile; +llxHeader(); $head = ecm_file_prepare_head($file); -if ($_GET["action"] == 'edit') +if ($action == 'edit') { print '
    '; print ''; print ''; print ''; print ''; + print ''; } dol_fiche_head($head, 'card', $langs->trans("File"), 0, 'generic'); @@ -221,11 +245,11 @@ while ($tmpecmdir && $result > 0) print img_picto('','object_dir').' '.$langs->trans("ECMRoot").' -> '; print $s; print ' -> '; -if (GETPOST('action','aZ09') == 'edit') print ''; +if ($action == 'edit') print ''; else print $urlfile; print ''; /*print ''.$langs->trans("Description").''; -if ($_GET["action"] == 'edit') +if ($action == 'edit') { print ''; @@ -1539,7 +1563,7 @@ if ($action=='create') print ''.$langs->trans('NotePrivate').''; print ''; - $doleditor = new DolEditor('note_private', isset($note_private) ? $note_private : GETPOST('note_private'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + $doleditor = new DolEditor('note_private', isset($note_private) ? $note_private : GETPOST('note_private','none'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); print ''; //print ''; @@ -2143,343 +2167,6 @@ elseif (! empty($object->id)) dol_fiche_end(); - - /* - * Action presend - */ - if (GETPOST('modelselected')) { - $action = 'presend'; - } - if ($action == 'presend') - { - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->fournisseur->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file=$fileparams['fullname']; - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - - if (!empty($newlang)) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); - $outputlangs->load('commercial'); - } - - // Build document if it not exists - if (! $file || ! is_readable($file)) - { - $result= $object->generateDocument(GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db,$result); - exit; - } - $fileparams = dol_most_recent_file($conf->fournisseur->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file=$fileparams['fullname']; - } - - print '
    '; - print '
    '; - print '
    '; - print load_fiche_titre($langs->trans('SendOrderByMail')); - - dol_fiche_head(''); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='sor'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'sor'.$object->id); - } - $formmail->withfrom=1; - $liste=array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; - $formmail->withto=GETPOST("sendto")?GETPOST("sendto"):$liste; - $formmail->withtocc=$liste; - $formmail->withtoccc=(! empty($conf->global->MAIN_EMAIL_USECCC)?$conf->global->MAIN_EMAIL_USECCC:false); - $formmail->withtopic=$outputlangs->trans('SendOrderRef','__REF__'); - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - - $object->fetch_projet(); - // Tableau des substitutions - $formmail->setSubstitFromObject($object); - $formmail->substit['__ORDERREF__']=$object->ref; // For backward compatibility - $formmail->substit['__ORDERSUPPLIERREF__']=$object->ref_supplier; // For backward compatibility - $formmail->substit['__SUPPLIERORDERREF__']=$object->ref_supplier; - - //Find the good contact adress - $custcontact=''; - $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); - - if (is_array($contactarr) && count($contactarr)>0) { - foreach($contactarr as $contact) { - if ($contact['libelle']==$langs->trans('TypeContact_order_supplier_external_BILLING')) { - require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; - $contactstatic=new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact=$contactstatic->getFullName($langs,1); - } - } - - if (!empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__']=$custcontact; - } - } - - // Tableau des parametres complementaires - $formmail->param['action']='send'; - $formmail->param['models']='order_supplier_send'; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['orderid']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - - // Init list of files - if (GETPOST("mode")=='init') - { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); - } - - // Show form - print $formmail->get_form(); - - dol_fiche_end(); - } - /* - * Action webservice - */ - elseif ($action == 'webservice' && GETPOST('mode', 'alpha') != "send" && ! GETPOST('cancel','alpha')) - { - $mode = GETPOST('mode', 'alpha'); - $ws_url = $object->thirdparty->webservices_url; - $ws_key = $object->thirdparty->webservices_key; - $ws_user = GETPOST('ws_user','alpha'); - $ws_password = GETPOST('ws_password','alpha'); - - // NS and Authentication parameters - $ws_ns = 'http://www.dolibarr.org/ns/'; - $ws_authentication = array( - 'dolibarrkey'=>$ws_key, - 'sourceapplication'=>'DolibarrWebServiceClient', - 'login'=>$ws_user, - 'password'=>$ws_password, - 'entity'=>'' - ); - - print load_fiche_titre($langs->trans('CreateRemoteOrder'),''); - - //Is everything filled? - if (empty($ws_url) || empty($ws_key)) { - setEventMessages($langs->trans("ErrorWebServicesFieldsRequired"), null, 'errors'); - $mode = "init"; - $error_occurred = true; //Don't allow to set the user/pass if thirdparty fields are not filled - } else if ($mode != "init" && (empty($ws_user) || empty($ws_password))) { - setEventMessages($langs->trans("ErrorFieldsRequired"), null, 'errors'); - $mode = "init"; - } - - if ($mode == "init") - { - //Table/form header - print ''; - print ''; - print ''; - print ''; - print ''; - - if ($error_occurred) - { - print "
    ".$langs->trans("ErrorOccurredReviseAndRetry")."
    "; - print ''; - } - else - { - $textinput_size = "50"; - // Webservice url - print ''; - //Remote User - print ''; - //Remote Password - print ''; - //Submit button - print ''; - } - - //End table/form - print ''; - print '
    '.$langs->trans("WebServiceURL").''.dol_print_url($ws_url).'
    '.$langs->trans("User").'
    '.$langs->trans("Password").'
    '; - print ''; - print '     '; - //Cancel button - print ''; - print '
    '; - } - elseif ($mode == "check") - { - $ws_entity = ''; - $ws_thirdparty = ''; - $error_occurred = false; - - //Create SOAP client and connect it to user - $soapclient_user = new nusoap_client($ws_url."/webservices/server_user.php"); - $soapclient_user->soap_defencoding='UTF-8'; - $soapclient_user->decodeUTF8(false); - - //Get the thirdparty associated to user - $ws_parameters = array('authentication'=>$ws_authentication, 'id' => '', 'ref'=>$ws_user); - $result_user = $soapclient_user->call("getUser", $ws_parameters, $ws_ns, ''); - $user_status_code = $result_user["result"]["result_code"]; - - if ($user_status_code == "OK") - { - //Fill the variables - $ws_entity = $result_user["user"]["entity"]; - $ws_authentication['entity'] = $ws_entity; - $ws_thirdparty = $result_user["user"]["fk_thirdparty"]; - if (empty($ws_thirdparty)) - { - setEventMessages($langs->trans("RemoteUserMissingAssociatedSoc"), null, 'errors'); - $error_occurred = true; - } - else - { - //Create SOAP client and connect it to product/service - $soapclient_product = new nusoap_client($ws_url."/webservices/server_productorservice.php"); - $soapclient_product->soap_defencoding='UTF-8'; - $soapclient_product->decodeUTF8(false); - - // Iterate each line and get the reference that uses the supplier of that product/service - $i = 0; - foreach ($object->lines as $line) { - $i = $i + 1; - $ref_supplier = $line->ref_supplier; - $line_id = $i."º) ".$line->product_ref.": "; - if (empty($ref_supplier)) { - continue; - } - $ws_parameters = array('authentication' => $ws_authentication, 'id' => '', 'ref' => $ref_supplier); - $result_product = $soapclient_product->call("getProductOrService", $ws_parameters, $ws_ns, ''); - if (!$result_product) - { - setEventMessages($line_id.$langs->trans("SOAPError")." ".$soapclient_product->error_str." - ".$soapclient_product->response, null, 'errors'); - $error_occurred = true; - break; - } - - // Check the result code - $status_code = $result_product["result"]["result_code"]; - if (empty($status_code)) //No result, check error str - { - setEventMessages($langs->trans("SOAPError")." '".$soapclient_order->error_str."'", null, 'errors'); - } - else if ($status_code != "OK") //Something went wrong - { - if ($status_code == "NOT_FOUND") - { - setEventMessages($line_id.$langs->trans("SupplierMissingRef")." '".$ref_supplier."'", null, 'warnings'); - } - else - { - setEventMessages($line_id.$langs->trans("ResponseNonOK")." '".$status_code."' - '".$result_product["result"]["result_label"]."'", null, 'errors'); - $error_occurred = true; - break; - } - } - - - // Ensure that price is equal and warn user if it's not - $supplier_price = price($result_product["product"]["price_net"]); //Price of client tab in supplier dolibarr - $local_price = NULL; //Price of supplier as stated in product suppliers tab on this dolibarr, NULL if not found - - $product_fourn = new ProductFournisseur($db); - $product_fourn_list = $product_fourn->list_product_fournisseur_price($line->fk_product); - if (count($product_fourn_list)>0) - { - foreach($product_fourn_list as $product_fourn_line) - { - //Only accept the line where the supplier is the same at this order and has the same ref - if ($product_fourn_line->fourn_id == $object->socid && $product_fourn_line->fourn_ref == $ref_supplier) { - $local_price = price($product_fourn_line->fourn_price); - } - } - } - - if ($local_price != NULL && $local_price != $supplier_price) { - setEventMessages($line_id.$langs->trans("RemotePriceMismatch")." ".$supplier_price." - ".$local_price, null, 'warnings'); - } - - // Check if is in sale - if (empty($result_product["product"]["status_tosell"])) { - setEventMessages($line_id.$langs->trans("ProductStatusNotOnSellShort")." '".$ref_supplier."'", null, 'warnings'); - } - } - } - - } - elseif ($user_status_code == "PERMISSION_DENIED") - { - setEventMessages($langs->trans("RemoteUserNotPermission"), null, 'errors'); - $error_occurred = true; - } - elseif ($user_status_code == "BAD_CREDENTIALS") - { - setEventMessages($langs->trans("RemoteUserBadCredentials"), null, 'errors'); - $error_occurred = true; - } - else - { - setEventMessages($langs->trans("ResponseNonOK")." '".$user_status_code."'", null, 'errors'); - $error_occurred = true; - } - - //Form - print '
    '; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - if ($error_occurred) - { - print "
    ".$langs->trans("ErrorOccurredReviseAndRetry")."
    "; - } - else - { - print ''; - print '     '; - } - print ''; - print '
    '; - } - } - /* - * Show buttons - */ - else - { /** * Boutons actions */ @@ -2700,7 +2387,7 @@ elseif (! empty($object->id)) } print ""; - } + if ($user->rights->fournisseur->commande->commander && $object->statut == 2 && $action == 'makeorder') @@ -2756,51 +2443,271 @@ elseif (! empty($object->id)) $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); print '
    '; - if ($user->rights->fournisseur->commande->receptionner && ($object->statut == 3 || $object->statut == 4)) - { - // Set status to received (action=livraison) - print ''."\n"; - print '
    '; - print ''; - print ''; - print load_fiche_titre($langs->trans("Receive"),'',''); - print ''; - //print ''; - print '\n"; + if ($user->rights->fournisseur->commande->receptionner && ($object->statut == 3 || $object->statut == 4)) + { + // Set status to received (action=livraison) + print ''."\n"; + print ''; + print ''; + print ''; + print load_fiche_titre($langs->trans("Receive"),'',''); - print "'; + print ''; + print ''; + print "
    '.$langs->trans("Receive").'
    '.$langs->trans("DeliveryDate").''; - print $form->select_date('','',1,1,'',"commande",1,1,1); - print "
    ".$langs->trans("Delivery")."\n"; - $liv = array(); - $liv[''] = ' '; - $liv['tot'] = $langs->trans("CompleteOrNoMoreReceptionExpected"); - $liv['par'] = $langs->trans("PartialWoman"); - $liv['nev'] = $langs->trans("NeverReceived"); - $liv['can'] = $langs->trans("Canceled"); + print ''; + //print ''; + print '\n"; - print $form->selectarray("type",$liv); + print "'; - print ''; - print ''; - print "
    '.$langs->trans("Receive").'
    '.$langs->trans("DeliveryDate").''; + print $form->select_date('','',1,1,'',"commande",1,1,1); + print "
    ".$langs->trans("Delivery")."\n"; + $liv = array(); + $liv[''] = ' '; + $liv['tot'] = $langs->trans("CompleteOrNoMoreReceptionExpected"); + $liv['par'] = $langs->trans("PartialWoman"); + $liv['nev'] = $langs->trans("NeverReceived"); + $liv['can'] = $langs->trans("Canceled"); - print '
    '.$langs->trans("Comment").'
    \n"; - print "\n"; - print "
    "; + print $form->selectarray("type",$liv); + + print '
    '.$langs->trans("Comment").'
    \n"; + print "\n"; + print "
    "; + } + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions=new FormActions($db); + $somethingshown = $formactions->showactions($object,'order_supplier',$socid,1,'listaction'.($genallowed?'largetitle':'')); + + print '
    '; } - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions=new FormActions($db); - $somethingshown = $formactions->showactions($object,'order_supplier',$socid,1,'listaction'.($genallowed?'largetitle':'')); + /* + * Action webservice + */ + if ($action == 'webservice' && GETPOST('mode', 'alpha') != "send" && ! GETPOST('cancel','alpha')) + { + $mode = GETPOST('mode', 'alpha'); + $ws_url = $object->thirdparty->webservices_url; + $ws_key = $object->thirdparty->webservices_key; + $ws_user = GETPOST('ws_user','alpha'); + $ws_password = GETPOST('ws_password','alpha'); + + // NS and Authentication parameters + $ws_ns = 'http://www.dolibarr.org/ns/'; + $ws_authentication = array( + 'dolibarrkey'=>$ws_key, + 'sourceapplication'=>'DolibarrWebServiceClient', + 'login'=>$ws_user, + 'password'=>$ws_password, + 'entity'=>'' + ); + + print load_fiche_titre($langs->trans('CreateRemoteOrder'),''); + + //Is everything filled? + if (empty($ws_url) || empty($ws_key)) { + setEventMessages($langs->trans("ErrorWebServicesFieldsRequired"), null, 'errors'); + $mode = "init"; + $error_occurred = true; //Don't allow to set the user/pass if thirdparty fields are not filled + } else if ($mode != "init" && (empty($ws_user) || empty($ws_password))) { + setEventMessages($langs->trans("ErrorFieldsRequired"), null, 'errors'); + $mode = "init"; + } + + if ($mode == "init") + { + //Table/form header + print ''; + print ''; + print ''; + print ''; + print ''; + + if ($error_occurred) + { + print "
    ".$langs->trans("ErrorOccurredReviseAndRetry")."
    "; + print ''; + } + else + { + $textinput_size = "50"; + // Webservice url + print ''; + //Remote User + print ''; + //Remote Password + print ''; + //Submit button + print ''; + } + + //End table/form + print ''; + print '
    '.$langs->trans("WebServiceURL").''.dol_print_url($ws_url).'
    '.$langs->trans("User").'
    '.$langs->trans("Password").'
    '; + print ''; + print '     '; + //Cancel button + print ''; + print '
    '; + } + elseif ($mode == "check") + { + $ws_entity = ''; + $ws_thirdparty = ''; + $error_occurred = false; + + //Create SOAP client and connect it to user + $soapclient_user = new nusoap_client($ws_url."/webservices/server_user.php"); + $soapclient_user->soap_defencoding='UTF-8'; + $soapclient_user->decodeUTF8(false); + + //Get the thirdparty associated to user + $ws_parameters = array('authentication'=>$ws_authentication, 'id' => '', 'ref'=>$ws_user); + $result_user = $soapclient_user->call("getUser", $ws_parameters, $ws_ns, ''); + $user_status_code = $result_user["result"]["result_code"]; + + if ($user_status_code == "OK") + { + //Fill the variables + $ws_entity = $result_user["user"]["entity"]; + $ws_authentication['entity'] = $ws_entity; + $ws_thirdparty = $result_user["user"]["fk_thirdparty"]; + if (empty($ws_thirdparty)) + { + setEventMessages($langs->trans("RemoteUserMissingAssociatedSoc"), null, 'errors'); + $error_occurred = true; + } + else + { + //Create SOAP client and connect it to product/service + $soapclient_product = new nusoap_client($ws_url."/webservices/server_productorservice.php"); + $soapclient_product->soap_defencoding='UTF-8'; + $soapclient_product->decodeUTF8(false); + + // Iterate each line and get the reference that uses the supplier of that product/service + $i = 0; + foreach ($object->lines as $line) { + $i = $i + 1; + $ref_supplier = $line->ref_supplier; + $line_id = $i."º) ".$line->product_ref.": "; + if (empty($ref_supplier)) { + continue; + } + $ws_parameters = array('authentication' => $ws_authentication, 'id' => '', 'ref' => $ref_supplier); + $result_product = $soapclient_product->call("getProductOrService", $ws_parameters, $ws_ns, ''); + if (!$result_product) + { + setEventMessages($line_id.$langs->trans("SOAPError")." ".$soapclient_product->error_str." - ".$soapclient_product->response, null, 'errors'); + $error_occurred = true; + break; + } + + // Check the result code + $status_code = $result_product["result"]["result_code"]; + if (empty($status_code)) //No result, check error str + { + setEventMessages($langs->trans("SOAPError")." '".$soapclient_order->error_str."'", null, 'errors'); + } + else if ($status_code != "OK") //Something went wrong + { + if ($status_code == "NOT_FOUND") + { + setEventMessages($line_id.$langs->trans("SupplierMissingRef")." '".$ref_supplier."'", null, 'warnings'); + } + else + { + setEventMessages($line_id.$langs->trans("ResponseNonOK")." '".$status_code."' - '".$result_product["result"]["result_label"]."'", null, 'errors'); + $error_occurred = true; + break; + } + } + // Ensure that price is equal and warn user if it's not + $supplier_price = price($result_product["product"]["price_net"]); //Price of client tab in supplier dolibarr + $local_price = NULL; //Price of supplier as stated in product suppliers tab on this dolibarr, NULL if not found + $product_fourn = new ProductFournisseur($db); + $product_fourn_list = $product_fourn->list_product_fournisseur_price($line->fk_product); + if (count($product_fourn_list)>0) + { + foreach($product_fourn_list as $product_fourn_line) + { + //Only accept the line where the supplier is the same at this order and has the same ref + if ($product_fourn_line->fourn_id == $object->socid && $product_fourn_line->fourn_ref == $ref_supplier) { + $local_price = price($product_fourn_line->fourn_price); + } + } + } - print '';} + if ($local_price != NULL && $local_price != $supplier_price) { + setEventMessages($line_id.$langs->trans("RemotePriceMismatch")." ".$supplier_price." - ".$local_price, null, 'warnings'); + } + + // Check if is in sale + if (empty($result_product["product"]["status_tosell"])) { + setEventMessages($line_id.$langs->trans("ProductStatusNotOnSellShort")." '".$ref_supplier."'", null, 'warnings'); + } + } + } + + } + elseif ($user_status_code == "PERMISSION_DENIED") + { + setEventMessages($langs->trans("RemoteUserNotPermission"), null, 'errors'); + $error_occurred = true; + } + elseif ($user_status_code == "BAD_CREDENTIALS") + { + setEventMessages($langs->trans("RemoteUserBadCredentials"), null, 'errors'); + $error_occurred = true; + } + else + { + setEventMessages($langs->trans("ResponseNonOK")." '".$user_status_code."'", null, 'errors'); + $error_occurred = true; + } + + //Form + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ($error_occurred) + { + print "
    ".$langs->trans("ErrorOccurredReviseAndRetry")."
    "; + } + else + { + print ''; + print '     '; + } + print ''; + print '
    '; + } + } + + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + // Presend form + $modelmail='supplier_order_send'; + $defaulttopic='SendOrderRef'; + $diroutput = $conf->fournisseur->commande->dir_output; + $trackid = 'sor'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } - - print ''; } // End of page diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index f4f05f96b78..67b22c6767c 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -547,6 +547,9 @@ if ($id > 0 || ! empty($ref)) { print "\n"; print '' . "\n"; + // hidden fields for js function + print ''; + print ''; print ''; $linktoprod = '' . img_object($langs->trans("ShowProduct"), 'product') . ' ' . $objp->ref . ''; @@ -607,9 +610,6 @@ if ($id > 0 || ! empty($ref)) { print ''; } - // hidden fields for js function - print ''; - print ''; print ''; print ''; @@ -649,16 +649,13 @@ if ($id > 0 || ! empty($ref)) { print ''; } - // hidden fields for js function - print ''; - print ''; print ''; } // Qty to dispatch print ''; print ''; - print ''; + print ''; print ''; if (! empty($conf->productbatch->enabled) && $objp->tobatch == 1) { diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 54c78e93d5b..4b7bcb454cd 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -48,7 +48,7 @@ $langs->load('compta'); $langs->load('bills'); $langs->load('projects'); -$action=GETPOST('action','alpha'); +$action=GETPOST('action','aZ09'); $massaction=GETPOST('massaction','alpha'); $show_files=GETPOST('show_files','int'); $confirm=GETPOST('confirm','alpha'); @@ -86,10 +86,6 @@ $optioncss = GETPOST('optioncss','alpha'); $billed = GETPOST('billed','int'); $search_project_ref=GETPOST('search_project_ref','alpha'); -$page = GETPOST('page','int'); -$sortorder = GETPOST('sortorder','alpha'); -$sortfield = GETPOST('sortfield','alpha'); - $status=GETPOST('statut','alpha'); $billed=GETPOST('billed','int'); $viewstatut=GETPOST('viewstatut'); @@ -114,11 +110,11 @@ if (! $sortorder) $sortorder='DESC'; if ($search_status == '') $search_status=-1; -// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$contextpage='supplierorderlist'; +// Initialize technical object to manage context to save list fields +$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'supplierorderlist'; // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('orderlist')); +$hookmanager->initHooks(array($contextpage)); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels @@ -162,7 +158,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -173,7 +169,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab */ if (GETPOST('cancel','alpha')) { $action='list'; $massaction=''; } -if (! GETPOST('confirmmassaction','alpha')) { $massaction=''; } +if (! GETPOST('confirmmassaction','alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; } $parameters=array('socid'=>$socid); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks @@ -207,6 +203,7 @@ if (empty($reshook)) $search_total_ht=''; $search_total_vat=''; $search_total_ttc=''; + $search_project_ref=''; $search_status=-1; $orderyear=''; $ordermonth=''; @@ -216,16 +213,12 @@ if (empty($reshook)) $deliveryyear=''; $billed=''; $toselect=''; - $search_project_ref=''; $search_array_options=array(); - - // Mass actions - $objectclass='Commande'; - $objectlabel='Orders'; - $permtoread = $user->rights->commande->lire; - $permtodelete = $user->rights->commande->supprimer; - $uploaddir = $conf->commande->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + } + if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha') + || GETPOST('button_search_x','alpha') || GETPOST('button_search.x','alpha') || GETPOST('button_search','alpha')) + { + $massaction=''; // Protection to avoid mass action if we force a new search during a mass action confirmation } // Mass actions @@ -581,7 +574,6 @@ if ($search_total_ht != '') $sql.= natural_search('cf.total_ht', $search_total_h if ($search_total_vat != '') $sql.= natural_search('cf.tva', $search_total_vat, 1); if ($search_total_ttc != '') $sql.= natural_search('cf.total_ttc', $search_total_ttc, 1); if ($search_project_ref != '') $sql.= natural_search("p.ref",$search_project_ref); - // Add where from extra fields foreach ($search_array_options as $key => $val) { @@ -650,6 +642,7 @@ if ($resql) if ($search_total_ttc != '') $param.="&search_total_ttc=".$search_total_ttc; if ($search_refsupp) $param.="&search_refsupp=".$search_refsupp; if ($search_status >= 0) $param.="&search_status=".$search_status; + if ($search_project_ref >= 0) $param.="&search_project_ref=".$search_project_ref; if ($billed != '') $param.="&billed=".$billed; if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; @@ -663,7 +656,7 @@ if ($resql) // List of mass actions available $arrayofmassactions = array( - //'presend'=>$langs->trans("SendByMail"), + 'presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"), ); //if($user->rights->fournisseur->facture->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); @@ -678,7 +671,8 @@ if ($resql) print ''; print ''; print ''; - print ''; + print ''; + print ''; print ''; print ''; diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php index b1a8c0c08c1..012574915ab 100644 --- a/htdocs/fourn/commande/orderstoinvoice.php +++ b/htdocs/fourn/commande/orderstoinvoice.php @@ -155,8 +155,8 @@ if (($action == 'create' || $action == 'add') && ! $error) { $object->libelle = GETPOST('libelle'); $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $projectid = GETPOST('projectid'); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 927347eb37e..820768ac7bd 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -114,7 +114,15 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - if ($cancel) $action=''; + if ($cancel) + { + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + $action=''; + } include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once @@ -320,7 +328,7 @@ if (empty($reshook)) // Multicurrency rate else if ($action == 'setmulticurrencyrate' && $user->rights->facture->creer) { - $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx'))); + $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx', 'alpha'))); } // bank account @@ -435,8 +443,8 @@ if (empty($reshook)) $object->libelle = GETPOST('label'); $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); @@ -499,8 +507,8 @@ if (empty($reshook)) $object->libelle = $_POST['label']; $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); @@ -608,8 +616,8 @@ if (empty($reshook)) $object->libelle = $_POST['label']; $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = GETPOST('note_public'); - $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public','none'); + $object->note_private = GETPOST('note_private','none'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); @@ -1211,14 +1219,13 @@ if (empty($reshook)) } } - /* - * Send mail - */ + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to send emails $trigger_name='BILL_SUPPLIER_SENTBYMAIL'; $paramname='id'; - $mode='emailfromsupplierinvoice'; + $autocopy='MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO'; $trackid='sin'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; @@ -1676,8 +1683,8 @@ if ($action == 'create') print $desc; print '
    '; - print '    0 ? 'checked':'').' /> "; - print '
        0 ? 'checked':'').' /> "; + print '    0 ? 'checked':'').' /> "; + print '
        0 ? 'checked':'').' /> "; print '
    '; print ''; @@ -2823,124 +2830,18 @@ else } } - /* - * Show mail form - */ + // Select mail models is same action as presend if (GETPOST('modelselected')) { $action = 'presend'; } - if ($action == 'presend') - { - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2,0,0,$object,'invoice_supplier').$ref, preg_quote($ref,'/').'([^\-])+'); - $file=$fileparams['fullname']; - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; + // Presend form + $modelmail='supplier_order_send'; + $defaulttopic='SendBillRef'; + $diroutput = $conf->fournisseur->facture->dir_output; + $trackid = 'sin'.$object->id; - if (!empty($newlang)) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); - $outputlangs->load('bills'); - } - - // Build document if it not exists - if (! $file || ! is_readable($file)) - { - $result = $object->generateDocument(GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result < 0) - { - dol_print_error($db,$object->error,$object->errors); - exit; - } - $fileparams = dol_most_recent_file($conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2,0,0,$object,'invoice_supplier').$ref, preg_quote($ref,'/').'([^\-])+'); - $file=$fileparams['fullname']; - } - - print '
    '; - print '
    '; - print '
    '; - print load_fiche_titre($langs->trans('SendBillByMail')); - - dol_fiche_head(''); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='sin'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'sin'.$object->id); - } - $formmail->withfrom=1; - $liste=array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key=>$value) $liste[$key]=$value; - $formmail->withto=GETPOST("sendto")?GETPOST("sendto"):$liste; - $formmail->withtocc=$liste; - $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC; - $formmail->withtopic=$outputlangs->trans('SendBillRef','__REF__'); - $formmail->withfile=2; - $formmail->withbody=1; - $formmail->withdeliveryreceipt=1; - $formmail->withcancel=1; - // Tableau des substitutions - $formmail->setSubstitFromObject($object); - $formmail->substit['__SUPPLIERINVREF__']=$object->ref; - - //Find the good contact adress - $custcontact=''; - $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); - - if (is_array($contactarr) && count($contactarr)>0) { - foreach($contactarr as $contact) { - if ($contact['libelle']==$langs->trans('TypeContact_invoice_supplier_external_BILLING')) { - require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; - $contactstatic=new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact=$contactstatic->getFullName($langs,1); - } - } - - if (!empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__']=$custcontact; - } - } - - // Tableau des parametres complementaires - $formmail->param['action']='send'; - $formmail->param['models']='invoice_supplier_send'; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['facid']=$object->id; - $formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id; - - // Init list of files - if (GETPOST("mode")=='init') - { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file,basename($file),dol_mimetype($file)); - } - - // Show form - print $formmail->get_form(); - - dol_fiche_end(); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } } diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 8fae09c1adf..9d6c5e4ccd3 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -54,6 +54,7 @@ $massaction=GETPOST('massaction','alpha'); $show_files=GETPOST('show_files','int'); $confirm=GETPOST('confirm','alpha'); $toselect = GETPOST('toselect', 'array'); +$optioncss = GETPOST('optioncss','alpha'); $socid = GETPOST('socid','int'); @@ -67,6 +68,11 @@ if ($user->societe_id > 0) $mode=GETPOST("mode"); +$search_all = GETPOST('sall', 'alphanohtml'); +$search_label = GETPOST("search_label","alpha"); +$search_company = GETPOST("search_company","alpha"); +$search_amount_no_tax = GETPOST("search_amount_no_tax","alpha"); +$search_amount_all_tax = GETPOST("search_amount_all_tax","alpha"); $search_product_category=GETPOST('search_product_category','int'); $search_ref=GETPOST('sf_ref')?GETPOST('sf_ref','alpha'):GETPOST('search_ref','alpha'); $search_refsupplier=GETPOST('search_refsupplier','alpha'); @@ -93,20 +99,12 @@ $day_lim = GETPOST('day_lim','int'); $month_lim = GETPOST('month_lim','int'); $year_lim = GETPOST('year_lim','int'); $toselect = GETPOST('toselect', 'array'); -$filter = GETPOST('filtre','alpha'); $option = GETPOST('option'); if ($option == 'late') { - $filter = 'paye:0'; + $search_status = '1'; } - -$search_all = GETPOST('sall', 'alphanohtml'); -$search_label = GETPOST("search_label","alpha"); -$search_company = GETPOST("search_company","alpha"); -$search_amount_no_tax = GETPOST("search_amount_no_tax","alpha"); -$search_amount_all_tax = GETPOST("search_amount_all_tax","alpha"); -$search_status=GETPOST('search_status','alpha'); -$optioncss = GETPOST('optioncss','alpha'); +$filter = GETPOST('filtre','alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); @@ -119,8 +117,8 @@ $pagenext = $page + 1; if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="f.datef,f.rowid"; -// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$contextpage='supplierinvoicelist'; +// Initialize technical object to manage context to save list fields +$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'supplierinvoicelist'; $diroutputmassaction=$conf->fournisseur->facture->dir_output . '/temp/massgeneration/'.$user->id; @@ -177,7 +175,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -349,7 +347,6 @@ else if ($year_lim > 0) $sql.= " AND f.date_lim_reglement BETWEEN '".$db->idate(dol_get_first_day($year_lim,1,false))."' AND '".$db->idate(dol_get_last_day($year_lim,12,false))."'"; } if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->fournisseur->warning_delay)."'"; -if ($filter == 'paye:0') $sql.= " AND f.fk_statut = 1"; if ($search_label) $sql .= natural_search('f.libelle', $search_label); if ($search_status != '' && $search_status >= 0) { @@ -361,10 +358,10 @@ if ($filter && $filter != -1) foreach ($aFilter as $fil) { $filt = explode(':', $fil); - $sql .= ' AND ' . trim($filt[0]) . ' = ' . trim($filt[1]); + $sql .= ' AND ' . $db->escape(trim($filt[0])) . ' = ' . $db->escape(trim($filt[1])); } } -if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; +if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$db->escape($search_sale); if ($search_user > 0) { $sql.= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='invoice_supplier' AND tc.source='internal' AND ec.element_id = f.rowid AND ec.fk_socpeople = ".$search_user; diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index f42cc1db110..a1104eeaceb 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -57,7 +57,7 @@ if ($action == 'setnote' && $user->rights->fournisseur->facture->creer) $db->begin(); $object->fetch($id); - $result = $object->update_note(GETPOST('note')); + $result = $object->update_note(GETPOST('note','none')); if ($result > 0) { $db->commit(); diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 7194aae65ac..5a6c39840ac 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -41,6 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/holiday/common.inc.php'; $myparam = GETPOST("myparam"); $action=GETPOST('action', 'alpha'); $id=GETPOST('id', 'int'); +$fuserid = (GETPOST('fuserid','int')?GETPOST('fuserid','int'):$user->id); // Protection if external user if ($user->societe_id > 0) accessforbidden(); diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index ad9ead401dd..10589c9d0b4 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -284,7 +284,7 @@ class Holiday extends CommonObject * @param string $filter SQL Filter * @return int -1 if KO, 1 if OK, 2 if no result */ - function fetchByUser($user_id,$order='',$filter='') + function fetchByUser($user_id, $order='', $filter='') { global $langs, $conf; @@ -692,13 +692,17 @@ class Holiday extends CommonObject } /** - * verifDateHolidayCP + * Check if a user is on holiday (partially or completely) into a period. + * This function can be used to avoid to have 2 leave requests on same period for example. + * Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call. * * @param int $fk_user Id user - * @param date $dateDebut Start date - * @param date $dateFin End date - * @param int $halfday Tag to define half day when holiday start and end - * @return boolean + * @param date $dateDebut Start date of period to check + * @param date $dateFin End date of period to check + * @param int $halfday Tag to define how start and end the period to check: + * 0:Full days, 2:Sart afternoon end monring, -1:Start afternoon, 1:End morning + * @return boolean False is on holiday at least partially into the period, True is never on holiday during chcked period. + * @see verifDateHolidayForTimestamp */ function verifDateHolidayCP($fk_user, $dateDebut, $dateFin, $halfday=0) { @@ -710,14 +714,103 @@ class Holiday extends CommonObject if ($infos_CP['statut'] == 5) continue; // ignore not validated holidays // TODO Also use halfday for the check - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) - { - return false; - } + if ($halfday == 0) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == -1) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == 1) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + elseif ($halfday == 2) + { + if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + { + return false; + } + } + else + { + dol_print_error('', 'Bad value of parameter halfday when calling function verifDateHolidayCP'); + } } return true; + } + + /** + * Check a user is not on holiday for a particular timestamp + * + * @param int $fk_user Id user + * @param timestamp $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00) + * @return array array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp. + * @see verifDateHolidayCP + */ + function verifDateHolidayForTimestamp($fk_user, $timestamp) + { + global $langs, $conf; + + $isavailablemorning=true; + $isavailableafternoon=true; + + $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday"; + $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp"; + $sql.= " WHERE cp.entity IN (".getEntity('holiday').")"; + $sql.= " AND cp.fk_user = ".(int) $fk_user; + $sql.= " AND date_debut <= '".$this->db->idate($timestamp)."' AND date_fin >= '".$this->db->idate($timestamp)."'"; + + $resql = $this->db->query($sql); + if ($resql) + { + $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon + if ($num_rows > 0) + { + $i=0; + while ($i < $num_rows) + { + $obj = $this->db->fetch_object($resql); + + // Note: $obj->halday is 0:Full days, 2:Sart afternoon end morning, -1:Start afternoon, 1:End morning + $arrayofrecord[$obj->rowid]=array('date_start'=>$this->db->jdate($obj->date_start), 'date_end'=>$this->db->jdate($obj->date_end), 'halfday'=>$obj->halfday); + $i++; + } + + // We found a record, user is on holiday by default, so is not available is true. + $isavailablemorning = true; + foreach($arrayofrecord as $record) + { + if ($timestamp == $record['date_start'] && $record['halfday'] == 2) continue; + if ($timestamp == $record['date_start'] && $record['halfday'] == -1) continue; + $isavailablemorning = false; + break; + } + $isavailableafternoon = true; + foreach($arrayofrecord as $record) + { + if ($timestamp == $record['date_end'] && $record['halfday'] == 2) continue; + if ($timestamp == $record['date_end'] && $record['halfday'] == 1) continue; + $isavailableafternoon = false; + break; + } + } + } + else dol_print_error($this->db); + + return array('morning'=>$isavailablemorning, 'afternoon'=>$isavailableafternoon); } diff --git a/htdocs/includes/odtphp/Segment.php b/htdocs/includes/odtphp/Segment.php index 40668215647..f9a44b996b2 100644 --- a/htdocs/includes/odtphp/Segment.php +++ b/htdocs/includes/odtphp/Segment.php @@ -24,7 +24,7 @@ class Segment implements IteratorAggregate, Countable protected $images = array(); protected $odf; protected $file; - + /** * Constructor * @@ -86,15 +86,15 @@ class Segment implements IteratorAggregate, Countable */ public function merge() { - // To provide debug information on line number processed + // To provide debug information on line number processed global $count; if (empty($count)) $count=1; else $count++; - + if (empty($this->savxml)) $this->savxml = $this->xml; // Sav content of line at first line merged, so we will reuse original for next steps $this->xml = $this->savxml; $tmpvars = $this->vars; // Store into $tmpvars so we won't modify this->vars when completing data with empty values - + // Search all tags fou into condition to complete $tmpvars, so we will proceed all tests even if not defined $reg='@\[!--\sIF\s([{}a-zA-Z0-9\.\,_]+)\s--\]@smU'; preg_match_all($reg, $this->xml, $matches, PREG_SET_ORDER); @@ -106,7 +106,7 @@ class Segment implements IteratorAggregate, Countable $tmpvars[$match[1]] = ''; // Not defined, so we set it to '', we just need entry into this->vars for next loop } } - + // Conditionals substitution // Note: must be done before static substitution, else the variable will be replaced by its value and the conditional won't work anymore foreach($tmpvars as $key => $value) @@ -133,7 +133,7 @@ class Segment implements IteratorAggregate, Countable $this->xml = preg_replace($reg, '', $this->xml); } } - + $this->xmlParsed .= str_replace(array_keys($tmpvars), array_values($tmpvars), $this->xml); if ($this->hasChildren()) { foreach ($this->children as $child) { @@ -143,7 +143,7 @@ class Segment implements IteratorAggregate, Countable } $reg = "/\[!--\sBEGIN\s$this->name\s--\](.*)\[!--\sEND\s$this->name\s--\]/sm"; $this->xmlParsed = preg_replace($reg, '$1', $this->xmlParsed); - // Miguel Erill 09704/2017 - Add macro replacement to invoice lines + // Miguel Erill 09704/2017 - Add macro replacement to invoice lines $this->xmlParsed = $this->macroReplace($this->xmlParsed); $this->file->open($this->odf->getTmpfile()); foreach ($this->images as $imageKey => $imageValue) { @@ -155,28 +155,38 @@ class Segment implements IteratorAggregate, Countable } } $this->file->close(); - + return $this->xmlParsed; } /** * Function to replace macros for invoice short and long month, invoice year - * + * * Substitution occur when the invoice is generated, not considering the invoice date * so do not (re)generate in a diferent date than the one that the invoice belongs to * Perhaps it would be better to use the invoice issued date but I still do not know * how to get it here * * Miguel Erill 09/04/2017 - * + * * @param string $value String to convert */ public function macroReplace($text) { global $langs; - $patterns=array( '__CURRENTDAY__','__CURRENTDAYTEXT__','__CURRENTMONTHSHORT__','__CURRENTMONTH__','__CURRENTYEAR__' ); - $values=array( date('j'), $langs->trans(date('l')), $langs->trans(date('M')), $langs->trans(date('F')), date('Y') ); + $hoy = dol_getdate(dol_now('tzuser')); + $dateinonemontharray = dol_get_next_month($hoy['mon'], $hoy['year']); + $nextMonth = $dateinonemontharray['month']; + + $patterns=array( '/__CURRENTDAY__/u','/__CURENTWEEKDAY__/u', + '/__CURRENTMONTH__/u','/__CURRENTMONTHLONG__/u', + '/__NEXTMONTH__/u','/__NEXTMONTHLONG__/u', + '/__CURRENTYEAR__/u','/__NEXTYEAR__/u' ); + $values=array( $hoy['mday'], $langs->transnoentitiesnoconv($hoy['weekday']), + $hoy['mon'], $langs->transnoentitiesnoconv($hoy['month']), + $nextMonth, monthArray($langs)[$nextMonth], + $hoy['year'], $hoy['year']+1 ); $text=preg_replace($patterns, $values, $text); @@ -203,7 +213,7 @@ class Segment implements IteratorAggregate, Countable } return $this; } - + /** * Assign a template variable to replace * diff --git a/htdocs/index.php b/htdocs/index.php index 597d41423e5..f8e90919c6a 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -373,135 +373,135 @@ require DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php'; // Number of actions to do (late) if (! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->read) { - include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; - $board=new ActionComm($db); - - $dashboardlines[] = $board->load_board($user); + include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; + $board=new ActionComm($db); + + $dashboardlines[] = $board->load_board($user); } // Number of project opened if (! empty($conf->projet->enabled) && $user->rights->projet->lire) { - include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - $board=new Project($db); - $dashboardlines[] = $board->load_board($user); + include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + $board=new Project($db); + $dashboardlines[] = $board->load_board($user); } // Number of tasks to do (late) if (! empty($conf->projet->enabled) && empty($conf->global->PROJECT_HIDE_TASKS) && $user->rights->projet->lire) { - include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; - $board=new Task($db); - $dashboardlines[] = $board->load_board($user); + include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; + $board=new Task($db); + $dashboardlines[] = $board->load_board($user); } // Number of commercial proposals opened (expired) if (! empty($conf->propal->enabled) && $user->rights->propale->lire) { - include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; - $board=new Propal($db); - $dashboardlines[] = $board->load_board($user,"opened"); - // Number of commercial proposals CLOSED signed (billed) - $dashboardlines[] = $board->load_board($user,"signed"); + include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; + $board=new Propal($db); + $dashboardlines[] = $board->load_board($user,"opened"); + // Number of commercial proposals CLOSED signed (billed) + $dashboardlines[] = $board->load_board($user,"signed"); } // Number of commercial proposals opened (expired) if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire) { - include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php'; - $board=new SupplierProposal($db); - $dashboardlines[] = $board->load_board($user,"opened"); - // Number of commercial proposals CLOSED signed (billed) - $dashboardlines[] = $board->load_board($user,"signed"); + include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php'; + $board=new SupplierProposal($db); + $dashboardlines[] = $board->load_board($user,"opened"); + // Number of commercial proposals CLOSED signed (billed) + $dashboardlines[] = $board->load_board($user,"signed"); } // Number of customer orders a deal if (! empty($conf->commande->enabled) && $user->rights->commande->lire) { - include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; - $board=new Commande($db); + include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; + $board=new Commande($db); $dashboardlines[] = $board->load_board($user); } // Number of suppliers orders a deal if (! empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire) { - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; - $board=new CommandeFournisseur($db); + include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; + $board=new CommandeFournisseur($db); $dashboardlines[] = $board->load_board($user); } // Number of services enabled (delayed) if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire) { - include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; - $board=new Contrat($db); - $dashboardlines[] = $board->load_board($user,"inactives"); + include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; + $board=new Contrat($db); + $dashboardlines[] = $board->load_board($user,"inactives"); // Number of active services (expired) - $dashboardlines[] = $board->load_board($user,"expired"); + $dashboardlines[] = $board->load_board($user,"expired"); } // Number of invoices customers (has paid) if (! empty($conf->facture->enabled) && $user->rights->facture->lire) { - include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - $board=new Facture($db); - $dashboardlines[] = $board->load_board($user); + include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $board=new Facture($db); + $dashboardlines[] = $board->load_board($user); } // Number of supplier invoices (has paid) if (! empty($conf->supplier_invoice->enabled) && ! empty($user->rights->fournisseur->facture->lire)) { - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; - $board=new FactureFournisseur($db); - $dashboardlines[] = $board->load_board($user); + include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; + $board=new FactureFournisseur($db); + $dashboardlines[] = $board->load_board($user); } // Number of transactions to conciliate if (! empty($conf->banque->enabled) && $user->rights->banque->lire && ! $user->societe_id) { - include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; - $board=new Account($db); - $nb = $board::countAccountToReconcile(); // Get nb of account to reconciliate - if ($nb > 0) - { - $dashboardlines[] = $board->load_board($user); - } + include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + $board=new Account($db); + $nb = $board::countAccountToReconcile(); // Get nb of account to reconciliate + if ($nb > 0) + { + $dashboardlines[] = $board->load_board($user); + } } // Number of cheque to send if (! empty($conf->banque->enabled) && $user->rights->banque->lire && ! $user->societe_id && empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT)) { - include_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; - $board=new RemiseCheque($db); - $dashboardlines[] = $board->load_board($user); + include_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; + $board=new RemiseCheque($db); + $dashboardlines[] = $board->load_board($user); } // Number of foundation members if (! empty($conf->adherent->enabled) && $user->rights->adherent->lire && ! $user->societe_id) { - include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; - $board=new Adherent($db); - $dashboardlines[] = $board->load_board($user); + include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; + $board=new Adherent($db); + $dashboardlines[] = $board->load_board($user); } // Number of expense reports to approve if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->approve) { - include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; - $board=new ExpenseReport($db); + include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; + $board=new ExpenseReport($db); $dashboardlines[] = $board->load_board($user,'toapprove'); } // Number of expense reports to pay if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->to_paid) { - include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; - $board=new ExpenseReport($db); + include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; + $board=new ExpenseReport($db); $dashboardlines[] = $board->load_board($user,'topay'); } // Calculate total nb of late -$totallate=0; +$totallate=$totaltodo=0; $var=true; //Remove any invalid response @@ -516,11 +516,13 @@ foreach($dashboardlines as $tmp) foreach($valid_dashboardlines as $board) { if ($board->nbtodolate > 0) { + if(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) $totaltodo += $board->nbtodo; $totallate += $board->nbtodolate; } } - - +//var_dump($totallate, $totaltodo); +if(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) $totallate = round($totallate / $totaltodo * 100, 2); +//var_dump($totallate); $boxwork=''; $boxwork.='
    '; $boxwork.=''."\n"; @@ -533,7 +535,7 @@ if ($showweather) $boxwork.=''; $boxwork.=''; foreach($listofmodulesextra as $tablename => $elementtype) @@ -303,6 +304,10 @@ if ($ok) print "\n"; } + else + { + dol_print_error($db); + } } } diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 9e1efae59bb..8ab0ddc018c 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -66,7 +66,7 @@ AccountancyAreaDescAnalyze=STEP %s: Add or edit existing transactions and genera AccountancyAreaDescClosePeriod=STEP %s: Close period so we can't make modification in a future. -TheJournalCodeIsNotDefinedOnSomeBankAccount=A mandatory step in setup was not complete (accountancy code journal not defined for all bank accounts) +TheJournalCodeIsNotDefinedOnSomeBankAccount=A mandatory step in setup was not complete (accounting code journal not defined for all bank accounts) MenuAccountancy=Accountancy Selectchartofaccounts=Select active chart of accounts ChangeAndLoad=Change and load @@ -170,7 +170,7 @@ DelBookKeeping=Delete record of the Ledger FinanceJournal=Finance journal ExpenseReportsJournal=Expense reports journal DescFinanceJournal=Finance journal including all the types of payments by bank account -DescJournalOnlyBindedVisible=This is a view of record that are bound to accountancy account and can be recorded into the Ledger. +DescJournalOnlyBindedVisible=This is a view of record that are bound to accounting account and can be recorded into the Ledger. VATAccountNotDefined=Account for VAT not defined ThirdpartyAccountNotDefined=Account for third party not defined ProductAccountNotDefined=Account for product not defined @@ -256,14 +256,14 @@ ChartofaccountsId=Chart of accounts Id ## Tools - Init accounting account on product / service InitAccountancy=Init accountancy -InitAccountancyDesc=This page can be used to initialize an accounting account on products and services that does not have accountancy account defined for sales and purchases. +InitAccountancyDesc=This page can be used to initialize an accounting account on products and services that does not have accounting account defined for sales and purchases. DefaultBindingDesc=This page can be used to set a default account to use to link transactions record about payment salaries, donation, taxes and vat when no specific accounting account were already set. Options=Options OptionModeProductSell=Mode sales OptionModeProductBuy=Mode purchases OptionModeProductSellDesc=Show all products with accounting account for sales. OptionModeProductBuyDesc=Show all products with accounting account for purchases. -CleanFixHistory=Remove accountancy code from lines that not exists into charts of account +CleanFixHistory=Remove accounting code from lines that not exists into charts of account CleanHistory=Reset all bindings for selected year PredefinedGroups=Predefined groups WithoutValidAccount=Without valid dedicated account diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 5395acdd3d2..bd868cf4e9e 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -441,9 +441,9 @@ DisplayCompanyInfo=Display company address DisplayCompanyManagers=Display manager names DisplayCompanyInfoAndManagers=Display company address and manager names EnableAndSetupModuleCron=If you want to have this recurring invoice beeing generated automatically, module *%s* must be enabled and correctly setup. Otherwise, generation of invoices must be done manually from this template with button *Create*. Note that even if you enabled automatic generation, you can still safely launch manual generation. Duplicates generation for same period are not possible. -ModuleCompanyCodeAquarium=Return an accountancy code built by:
    %s followed by third party supplier code for a supplier accountancy code,
    %s followed by third party customer code for a customer accountancy code. -ModuleCompanyCodePanicum=Return an empty accountancy code. -ModuleCompanyCodeDigitaria=Accountancy code depends on third party code. The code is composed of the character "C" in the first position followed by the first 5 characters of the third party code. +ModuleCompanyCodeAquarium=Return an accounting code built by:
    %s followed by third party supplier code for a supplier accounting code,
    %s followed by third party customer code for a customer accounting code. +ModuleCompanyCodePanicum=Return an empty accounting code. +ModuleCompanyCodeDigitaria=Accounting code depends on third party code. The code is composed of the character "C" in the first position followed by the first 5 characters of the third party code. Use3StepsApproval=By default, Purchase Orders need to be created and approved by 2 different users (one step/user to create and one step/user to approve. Note that if user has both permission to create and approve, one step/user will be enough). You can ask with this option to introduce a third step/user approval, if amount is higher than a dedicated value (so 3 steps will be necessary: 1=validation, 2=first approval and 3=second approval if amount is enough).
    Set this to empty if one approval (2 steps) is enough, set it to a very low value (0.1) if a second approval (3 steps) is always required. UseDoubleApproval=Use a 3 steps approval when amount (without tax) is higher than... WarningPHPMail=WARNING: Some email providers (like Yahoo) does not allow you to send an email from another server than the Yahoo server if the email address used as a sender is your Yahoo email (like myemail@yahoo.com, myemail@yahoo.fr, ...). Your current setup use the server of the application to send email, so some recipients (the one compatible with the restrictive DMARC protocol), will ask Yahoo if they can accept your email and Yahoo will respond "no" because the server is not a server owned by Yahoo, so few of your sent Emails may not be accepted.
    If your Email provider (like Yahoo) has this restriction, you must change Email setup to choose the other method "SMTP server" and enter the SMTP server and credentials provided by your Email provider (ask your EMail provider to get SMTP credentials for your account). @@ -452,8 +452,8 @@ DependsOn=This module need the module(s) RequiredBy=This module is required by module(s) TheKeyIsTheNameOfHtmlField=This is the name of the HTML field. This need to have technical knowledges to read the content of the HTML page to get the key name of a field. PageUrlForDefaultValues=You must enter here the relative url of the page. If you include parameters in URL, the default values will be effective if all parameters are set to same value. Examples: -PageUrlForDefaultValuesCreate=
    For form to create a new thirdparty, it is %s,
    If we want default only if url has some parameter, we can use %s -PageUrlForDefaultValuesList=
    For page that list thirdparties, it is %s,
    If we want default only if url has some parameter, we can use %s +PageUrlForDefaultValuesCreate=
    For form to create a new thirdparty, it is %s,
    If you want default value only if url has some parameter, you can use %s +PageUrlForDefaultValuesList=
    For page that list thirdparties, it is %s,
    If you want default value only if url has some parameter, you can use %s EnableDefaultValues=Enable usage of personalized default values EnableOverwriteTranslation=Enable usage of overwrote translation GoIntoTranslationMenuToChangeThis=A translation has been found for the key with this code, so to change this value, you must edit it fom Home-Setup-translation. @@ -1089,6 +1089,11 @@ ShowProfIdInAddress=Show professionnal id with addresses on documents ShowVATIntaInAddress=Hide VAT Intra num with addresses on documents TranslationUncomplete=Partial translation MAIN_DISABLE_METEO=Disable meteo view +MeteoStdMod=Standard mode +MeteoStdModEnabled=Standard mode enabled +MeteoPercentageMod=Percentage mode +MeteoPercentageModEnabled=Percentage mode enabled +MeteoUseMod=Click to use %s TestLoginToAPI=Test login to API ProxyDesc=Some features of Dolibarr need to have an Internet access to work. Define here parameters for this. If the Dolibarr server is behind a Proxy server, those parameters tells Dolibarr how to access Internet through it. ExternalAccess=External access @@ -1170,7 +1175,7 @@ HRMSetup=HRM module setup ##### Company setup ##### CompanySetup=Companies module setup CompanyCodeChecker=Module for third parties code generation and checking (customer or supplier) -AccountCodeManager=Module for accountancy code generation (customer or supplier) +AccountCodeManager=Module for accounting code generation (customer or supplier) NotificationsDesc=EMails notifications feature allows you to silently send automatic mail, for some Dolibarr events. Targets of notifications can be defined: NotificationsDescUser=* per users, one user at time. NotificationsDescContact=* per third parties contacts (customers or suppliers), one contact at time. @@ -1253,6 +1258,7 @@ LDAPUsersSynchro=Users LDAPGroupsSynchro=Groups LDAPContactsSynchro=Contacts LDAPMembersSynchro=Members +LDAPMembersTypesSynchro=Members types LDAPSynchronization=LDAP synchronisation LDAPFunctionsNotAvailableOnPHP=LDAP functions are not available on your PHP LDAPToDolibarr=LDAP -> Dolibarr @@ -1261,7 +1267,8 @@ LDAPNamingAttribute=Key in LDAP LDAPSynchronizeUsers=Organization of users in LDAP LDAPSynchronizeGroups=Organization of groups in LDAP LDAPSynchronizeContacts=Organization of contacts in LDAP -LDAPSynchronizeMembers=Organization of foundation's members in LDAP +LDAPSynchronizeMembers=Organization of foundation's members in LDAP +LDAPSynchronizeMembersTypes=Organization of foundation's members types in LDAP LDAPPrimaryServer=Primary server LDAPSecondaryServer=Secondary server LDAPServerPort=Server port @@ -1285,12 +1292,18 @@ LDAPDnContactActive=Contacts' synchronization LDAPDnContactActiveExample=Activated/Unactivated synchronization LDAPDnMemberActive=Members' synchronization LDAPDnMemberActiveExample=Activated/Unactivated synchronization +LDAPDnMemberTypeActive=Members types' synchronization +LDAPDnMemberTypeActiveExample=Activated/Unactivated synchronization LDAPContactDn=Dolibarr contacts' DN LDAPContactDnExample=Complete DN (ex: ou=contacts,dc=example,dc=com) LDAPMemberDn=Dolibarr members DN LDAPMemberDnExample=Complete DN (ex: ou=members,dc=example,dc=com) LDAPMemberObjectClassList=List of objectClass LDAPMemberObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) +LDAPMemberTypeDn=Dolibarr members types DN +LDAPMemberTypepDnExample=Complete DN (ex: ou=memberstypes,dc=example,dc=com) +LDAPMemberTypeObjectClassList=List of objectClass +LDAPMemberTypeObjectClassListExample=List of objectClass defining record attributes (ex: top,groupOfUniqueNames) LDAPUserObjectClassList=List of objectClass LDAPUserObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) LDAPGroupObjectClassList=List of objectClass @@ -1302,6 +1315,7 @@ LDAPTestSynchroContact=Test contacts synchronization LDAPTestSynchroUser=Test user synchronization LDAPTestSynchroGroup=Test group synchronization LDAPTestSynchroMember=Test member synchronization +LDAPTestSynchroMemberType=Test member type synchronization LDAPTestSearch= Test a LDAP search LDAPSynchroOK=Synchronization test successful LDAPSynchroKO=Failed synchronization test @@ -1367,6 +1381,7 @@ LDAPDescContact=This page allows you to define LDAP attributes name in LDAP tree LDAPDescUsers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr users. LDAPDescGroups=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr groups. LDAPDescMembers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members module. +LDAPDescMembersTypes=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members types. LDAPDescValues=Example values are designed for OpenLDAP with following loaded schemas: core.schema, cosine.schema, inetorgperson.schema). If you use thoose values and OpenLDAP, modify your LDAP config file slapd.conf to have all thoose schemas loaded. ForANonAnonymousAccess=For an authenticated access (for a write access for example) PerfDolibarr=Performance setup/optimizing report @@ -1390,7 +1405,7 @@ CompressionOfResources=Compression of HTTP responses CompressionOfResourcesDesc=For exemple using the Apache directive "AddOutputFilterByType DEFLATE" TestNotPossibleWithCurrentBrowsers=Such an automatic detection is not possible with current browsers DefaultValuesDesc=You can define/force here the default value you want to get when your create a new record, and/or defaut filters or sort order when your list record. -DefaultCreateForm=Default values for new objects +DefaultCreateForm=Default values for creation form DefaultSearchFilters=Default search filters DefaultSortOrder=Default sort orders DefaultFocus=Default focus fields @@ -1529,7 +1544,7 @@ Buy=Buy Sell=Sell InvoiceDateUsed=Invoice date used YourCompanyDoesNotUseVAT=Your company has been defined to not use VAT (Home - Setup - Company/Organisation), so there is no VAT options to setup. -AccountancyCode=Accountancy Code +AccountancyCode=Accounting Code AccountancyCodeSell=Sale account. code AccountancyCodeBuy=Purchase account. code ##### Agenda ##### @@ -1694,6 +1709,7 @@ MailToSendSupplierOrder=To send supplier order MailToSendSupplierInvoice=To send supplier invoice MailToSendContract=To send a contract MailToThirdparty=To send email from third party page +MailToMember=To send email from member page ByDefaultInList=Show by default on list view YouUseLastStableVersion=You use the latest stable version TitleExampleForMajorRelease=Example of message you can use to announce this major release (feel free to use it on your web sites) diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index f88fc541b13..88c6bbc54f5 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -85,6 +85,9 @@ EXPENSE_REPORT_VALIDATEInDolibarr=Expense report %s validated EXPENSE_REPORT_APPROVEInDolibarr=Expense report %s approved EXPENSE_REPORT_DELETEInDolibarr=Expense report %s deleted EXPENSE_REPORT_REFUSEDInDolibarr=Expense report %s refused +PROJECT_CREATEInDolibarr=Project %s created +PROJECT_MODIFYInDolibarr=Project %s modified +PROJECT_DELETEInDolibarr=Project %s deleted ##### End agenda events ##### AgendaModelModule=Document templates for event DateActionStart=Start date diff --git a/htdocs/langs/en_US/banks.lang b/htdocs/langs/en_US/banks.lang index caed4498f3b..d45c0c15c1c 100644 --- a/htdocs/langs/en_US/banks.lang +++ b/htdocs/langs/en_US/banks.lang @@ -157,4 +157,6 @@ NewVariousPayment=New miscellaneous payments VariousPayment=Miscellaneous payments VariousPayments=Miscellaneous payments ShowVariousPayment=Show miscellaneous payments -AddVariousPayment=Add miscellaneous payments \ No newline at end of file +AddVariousPayment=Add miscellaneous payments +YourSEPAMandate=Your SEPA mandate +FindYourSEPAMandate=This is your SEPA mandate to authorize our company to make direct debit order to your bank. Thanks to return it signed (scan of the signed document) or sent it by mail to diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index a7918fc702c..f093726ed4b 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -149,7 +149,7 @@ ErrorCantCancelIfReplacementInvoiceNotValidated=Error, can't cancel an invoice t BillFrom=From BillTo=To ActionsOnBill=Actions on invoice -RecurringInvoiceTemplate=Template/Recurring invoice +RecurringInvoiceTemplate=Template / Recurring invoice NoQualifiedRecurringInvoiceTemplateFound=No recurring template invoice qualified for generation. FoundXQualifiedRecurringInvoiceTemplate=Found %s recurring template invoice(s) qualified for generation. NotARecurringInvoiceTemplate=Not a recurring template invoice @@ -331,6 +331,7 @@ ListOfNextSituationInvoices=List of next situation invoices FrequencyPer_d=Every %s days FrequencyPer_m=Every %s months FrequencyPer_y=Every %s years +FrequencyUnit=Frequency unit toolTipFrequency=Examples:
    Set 7, Day: give a new invoice every 7 days
    Set 3, Month: give a new invoice every 3 month NextDateToExecution=Date for next invoice generation DateLastGeneration=Date of latest generation @@ -343,6 +344,7 @@ DateIsNotEnough=Date not reached yet InvoiceGeneratedFromTemplate=Invoice %s generated from recurring template invoice %s WarningInvoiceDateInFuture=Warning, the invoice date is higher than current date WarningInvoiceDateTooFarInFuture=Warning, the invoice date is too far from current date +ViewAvailableGlobalDiscounts=View available discounts # PaymentConditions Statut=Status PaymentConditionShortRECEP=Due Upon Receipt diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index 54ebb4bf1ee..9febf20505f 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -106,8 +106,8 @@ SocialContributionsPayments=Social/fiscal taxes payments ShowVatPayment=Show VAT payment TotalToPay=Total to pay BalanceVisibilityDependsOnSortAndFilters=Balance is visible in this list only if table is sorted ascending on %s and filtered for 1 bank account -CustomerAccountancyCode=Customer accountancy code -SupplierAccountancyCode=Supplier accountancy code +CustomerAccountancyCode=Customer accounting code +SupplierAccountancyCode=Supplier accounting code CustomerAccountancyCodeShort=Cust. account. code SupplierAccountancyCodeShort=Sup. account. code AccountNumber=Account number @@ -210,7 +210,7 @@ CalculationRuleDesc=To calculate total VAT, there is two methods:
    Method 1 is CalculationRuleDescSupplier=According to supplier, choose appropriate method to apply same calculation rule and get same result expected by your supplier. TurnoverPerProductInCommitmentAccountingNotRelevant=Turnover report per product, when using a cash accountancy mode is not relevant. This report is only available when using engagement accountancy mode (see setup of accountancy module). CalculationMode=Calculation mode -AccountancyJournal=Accountancy code journal +AccountancyJournal=Accounting code journal ACCOUNTING_VAT_SOLD_ACCOUNT=Accounting account by default for collecting VAT - VAT on sales (used if not defined on VAT dictionary setup) ACCOUNTING_VAT_BUY_ACCOUNT=Accounting account by default for recovered VAT - VAT on purchases (used if not defined on VAT dictionary setup) ACCOUNTING_VAT_PAY_ACCOUNT=Accounting account by default for paying VAT diff --git a/htdocs/langs/en_US/ecm.lang b/htdocs/langs/en_US/ecm.lang index 5f651413301..0b199c15de1 100644 --- a/htdocs/langs/en_US/ecm.lang +++ b/htdocs/langs/en_US/ecm.lang @@ -41,4 +41,8 @@ ECMDirectoryForFiles=Relative directory for files CannotRemoveDirectoryContainsFiles=Removed not possible because it contains some files ECMFileManager=File manager ECMSelectASection=Select a directory on left tree... -DirNotSynchronizedSyncFirst=This directory seems to be created or modified outside ECM module. You must click on "Refresh" button first to synchronize disk and database to get content of this directory. +DirNotSynchronizedSyncFirst=This directory seems to be created or modified outside ECM module. You must click on "Resync" button first to synchronize disk and database to get content of this directory. +ReSyncListOfDir=Resync list of directories +HashOfFileContent=Hash of file content +FileNotYetIndexedInDatabase=File not yet indexed into database (try to re-upload it) +FileSharedViaALink=File shared via a link \ No newline at end of file diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 7ace47fb781..b61d81c6d48 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -104,6 +104,7 @@ ErrorForbidden2=Permission for this login can be defined by your Dolibarr admini ErrorForbidden3=It seems that Dolibarr is not used through an authenticated session. Take a look at Dolibarr setup documentation to know how to manage authentications (htaccess, mod_auth or other...). ErrorNoImagickReadimage=Class Imagick is not found in this PHP. No preview can be available. Administrators can disable this tab from menu Setup - Display. ErrorRecordAlreadyExists=Record already exists +ErrorLabelAlreadyExists=This label already exists ErrorCantReadFile=Failed to read file '%s' ErrorCantReadDir=Failed to read directory '%s' ErrorBadLoginPassword=Bad value for login or password @@ -157,7 +158,7 @@ ErrorPriceExpression22=Negative result '%s' ErrorPriceExpressionInternal=Internal error '%s' ErrorPriceExpressionUnknown=Unknown error '%s' ErrorSrcAndTargetWarehouseMustDiffers=Source and target warehouses must differs -ErrorTryToMakeMoveOnProductRequiringBatchData=Error, trying to make a stock movement without lot/serial information, on a product requiring lot/serial information +ErrorTryToMakeMoveOnProductRequiringBatchData=Error, trying to make a stock movement without lot/serial information, on product '%s' requiring lot/serial information ErrorCantSetReceptionToTotalDoneWithReceptionToApprove=All recorded receptions must first be verified (approved or denied) before being allowed to do this action ErrorCantSetReceptionToTotalDoneWithReceptionDenied=All recorded receptions must first be verified (approved) before being allowed to do this action ErrorGlobalVariableUpdater0=HTTP request failed with error '%s' @@ -200,7 +201,7 @@ ErrorObjectMustHaveStatusDraftToBeValidated=Object %s must have status 'Draft' t ErrorObjectMustHaveLinesToBeValidated=Object %s must have lines to be validated. ErrorOnlyInvoiceValidatedCanBeSentInMassAction=Only validated invoices can be sent using the "Send by email" mass action. ErrorChooseBetweenFreeEntryOrPredefinedProduct=You must choose if article is a predefined product or not - +ErrorDiscountLargerThanRemainToPaySplitItBefore=The discount you try to apply is larger than remain to pay. Split the discount in 2 smaller discounts before. # Warnings WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. WarningMandatorySetupNotComplete=Mandatory setup parameters are not yet defined diff --git a/htdocs/langs/en_US/ldap.lang b/htdocs/langs/en_US/ldap.lang index 42e699de311..d6360f3e540 100644 --- a/htdocs/langs/en_US/ldap.lang +++ b/htdocs/langs/en_US/ldap.lang @@ -6,6 +6,7 @@ LDAPInformationsForThisContact=Information in LDAP database for this contact LDAPInformationsForThisUser=Information in LDAP database for this user LDAPInformationsForThisGroup=Information in LDAP database for this group LDAPInformationsForThisMember=Information in LDAP database for this member +LDAPInformationsForThisMemberType=Information in LDAP database for this member type LDAPAttributes=LDAP attributes LDAPCard=LDAP card LDAPRecordNotFound=Record not found in LDAP database @@ -20,6 +21,7 @@ LDAPFieldSkypeExample=Example : skypeName UserSynchronized=User synchronized GroupSynchronized=Group synchronized MemberSynchronized=Member synchronized +MemberTypeSynchronized=Member type synchronized ContactSynchronized=Contact synchronized ForceSynchronize=Force synchronizing Dolibarr -> LDAP ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility. diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 4ab81a4ceb6..0caae25c1d5 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -69,8 +69,11 @@ ActivateCheckReadKey=Key used to encrypt URL used for "Read Receipt" and "Unsubc EMailSentToNRecipients=EMail sent to %s recipients. EMailSentForNElements=EMail sent for %s elements. XTargetsAdded=%s recipients added into target list -OnlyPDFattachmentSupported=If the PDF document was already generated for the object to send, it will be attached to email. If not, no email will be sent (also, note that only pdf documents are supported as attachment in mass sending in this version). -AllRecipientSelected=The %s thirdparties selected, and if an email is set. +OnlyPDFattachmentSupported=If the PDF documents were already generated for the objects to send, they will be attached to email. If not, no email will be sent (also, note that only pdf documents are supported as attachment in mass sending in this version). +AllRecipientSelected=The recipients of the %s record selected (if their email is known). +GroupEmails=Group emails +OneEmailPerRecipient=One email per recipient (by default, one email per record selected) +WarningIfYouCheckOneRecipientPerEmail=Warning, if you check this box, it means only one email will be sent for several different record selected, so, if your message contains substitution variables that refers to data of a record, it becomes not possible to replace them. ResultOfMailSending=Result of mass EMail sending NbSelected=Nb selected NbIgnored=Nb ignored @@ -159,5 +162,5 @@ OutGoingEmailSetup=Outgoing email setup InGoingEmailSetup=Incoming email setup OutGoingEmailSetupForEmailing=Outgoing email setup (for mass emailing) DefaultOutgoingEmailSetup=Default outgoing email setup - +Information=Information diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index d16da33e0a4..bfcbb5a2010 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -262,6 +262,7 @@ DateBuild=Report build date DatePayment=Date of payment DateApprove=Approving date DateApprove2=Approving date (second approval) +RegistrationDate=Registration date UserCreation=Creation user UserModification=Modification user UserCreationShort=Creat. user @@ -376,12 +377,15 @@ VATIN=IGST VATs=Sales taxes VATINs=IGST taxes LT1=Sales tax 2 +LT1Type=Sales tax 2 type LT2=Sales tax 3 +LT2Type=Sales tax 3 type LT1ES=RE LT2ES=IRPF LT1IN=CGST LT2IN=SGST VATRate=Tax Rate +DefaultTaxRate=Default tax rate Average=Average Sum=Sum Delta=Delta @@ -747,7 +751,7 @@ SaveUploadedFileWithMask=Save file on server with name "%s" (ot OriginFileName=Original filename SetDemandReason=Set source SetBankAccount=Define Bank Account -AccountCurrency=Account Currency +AccountCurrency=Account currency ViewPrivateNote=View notes XMoreLines=%s line(s) hidden ShowMoreLines=Show more lines @@ -767,6 +771,7 @@ Genderwoman=Woman ViewList=List view Mandatory=Mandatory Hello=Hello +GoodBye=GoodBye Sincerely=Sincerely DeleteLine=Delete line ConfirmDeleteLine=Are you sure you want to delete this line? @@ -792,7 +797,8 @@ GroupBy=Group by... ViewFlatList=View flat list RemoveString=Remove string '%s' SomeTranslationAreUncomplete=Some languages may be partially translated or may contains errors. If you detect some, you can fix language files registering to https://transifex.com/projects/p/dolibarr/. -DirectDownloadLink=Direct download link +DirectDownloadLink=Direct download link (public/external) +DirectDownloadInternalLink=Direct download link (need to be logged and need permissions) Download=Download ActualizeCurrency=Update currency rate Fiscalyear=Fiscal year @@ -809,6 +815,7 @@ ImportId=Import id Websites=Web sites Events=Events EMailTemplates=Emails templates +FileNotShared=File not shared to exernal public # Week day Monday=Monday Tuesday=Tuesday diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 5e7ad30ec3f..dc25d792517 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -57,6 +57,11 @@ NewCotisation=New contribution PaymentSubscription=New contribution payment SubscriptionEndDate=Subscription's end date MembersTypeSetup=Members type setup +MemberTypeModified=Member type modified +DeleteAMemberType=Delete a member type +ConfirmDeleteMemberType=Are you sure you want to delete this member type? +MemberTypeDeleted=Member type deleted +MemberTypeCanNotBeDeleted=Member type can not be deleted NewSubscription=New subscription NewSubscriptionDesc=This form allows you to record your subscription as a new member of the foundation. If you want to renew your subscription (if already a member), please contact foundation board instead by email %s. Subscription=Subscription diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 1b9b00a28d2..e5e662a7852 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -3,7 +3,8 @@ ModuleBuilderDesc=This tools must be used by experienced users or developers. It EnterNameOfModuleDesc=Enter name of the module/application to create with no spaces. Use uppercase to separate words (For example: MyModule, EcommerceForShop, SyncWithMySystem...) EnterNameOfObjectDesc=Enter name of the object to create with no spaces. Use uppercase to separate words (For example: MyObject, Student, Teacher...). The CRUD class file, but also API file, pages to list/add/edit/delete object and SQL files will be generated. ModuleBuilderDesc2=Path where modules are generated/edited (first alternative directory defined into %s): %s -ModuleBuilderDesc3=Generated/editable modules found: %s (they are detected as editable when the file %s exists in root of module directory). +ModuleBuilderDesc3=Generated/editable modules found: %s +ModuleBuilderDesc4=A module is detected as 'editable' when the file %s exists in root of module directory NewModule=New module NewObject=New object ModuleKey=Module key @@ -51,6 +52,8 @@ DatabaseIndex=Database index FileAlreadyExists=File %s already exists TriggersFile=File for triggers code HooksFile=File for hooks code +ArrayOfKeyValues=Array of key-val +ArrayOfKeyValuesDesc=Array of keys and values if field is a combo list with fixed values WidgetFile=Widget file ReadmeFile=Readme file ChangeLog=ChangeLog file @@ -63,4 +66,16 @@ UseAsciiDocFormat=You can use Markdown format, but it is recommanded to use Asci IsAMeasure=Is a measure DirScanned=Directory scanned NoTrigger=No trigger -NoWidget=No widget \ No newline at end of file +NoWidget=No widget +GoToApiExplorer=Go to API explorer +ListOfPermissionsDefined=List of defined permissions +EnabledDesc=Condition to have this field active (Examples: 1 or $conf->global->MYMODULE_MYOPTION) +VisibleDesc=Is the field visible into list ? (Examples: 0=not visible, 1=visible by default on list, -1=not shown by default on list but can be added into list to be viewed) +IsAMeasureDesc=Can the value of field be cumulated to get a total into list ? (Examples: 1 or 0) +SearchAllDesc=Is the field used to make a search from the quick search tool ? (Examples: 1 or 0) +SpecDefDesc=Enter here all documentation you want to provide with your module that is not already defined by other tabs. You can use .md or better, the rich .asciidoc syntax. +LanguageDefDesc=Enter in this files, all the key and the translation for each language file. +MenusDefDesc=Define here the menus provided by your module (once defined, they are visible into the menu editor %s) +PermissionsDefDesc=Define here the new permissions provided by your module (once defined, they are visible into the default permissions setup %s) +HooksDefDesc=Define in the module_parts['hooks'] property in the module descriptor the context of hooks you want to manage (list of contexts can be found by a search on 'initHooks(' in core code).
    Edit the hook file to add code of your hooked functions (hookable functions can be found by a search on 'executeHooks' in core code). +TriggerDefDesc=Define in the trigger file the code you want to execute for each business event executed diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang index fcf84791a1f..bd19ab1b0e9 100644 --- a/htdocs/langs/en_US/multicurrency.lang +++ b/htdocs/langs/en_US/multicurrency.lang @@ -17,3 +17,4 @@ rate=rate MulticurrencyReceived=Received, original currency MulticurrencyRemainderToTake=Remaining amout, original currency MulticurrencyPaymentAmount=Payment amount, original currency +AmountToOthercurrency=Amount To (in currency of receiving account) \ No newline at end of file diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index f1cca6a1696..a78981f32a1 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -87,8 +87,8 @@ PredefinedMailContentSendSupplierOrder=__CONTACTCIVNAME__\n\nYou will find here PredefinedMailContentSendSupplierInvoice=__CONTACTCIVNAME__\n\nYou will find here the invoice __REF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ PredefinedMailContentSendShipping=__CONTACTCIVNAME__\n\nYou will find here the shipping __SHIPPINGREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ PredefinedMailContentSendFichInter=__CONTACTCIVNAME__\n\nYou will find here the intervention __FICHINTERREF__\n\n__PERSONALIZED__Sincerely\n\n__SIGNATURE__ -PredefinedMailContentThirdparty=__CONTACTCIVNAME__\n\n__PERSONALIZED__\n\n__SIGNATURE__ -PredefinedMailContentUser=aa__PERSONALIZED__\n\n__SIGNATURE__ +PredefinedMailContentThirdparty=\n\n__SIGNATURE__ +PredefinedMailContentUser=\n\n__SIGNATURE__ DemoDesc=Dolibarr is a compact ERP/CRM supporting several business modules. A demo showcasing all modules makes no sense as this scenario never occurs (several hundred available). So, several demo profiles are available. ChooseYourDemoProfil=Choose the demo profile that best suits your needs... ChooseYourDemoProfilMore=...or build your own profile
    (manual module selection) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index f33968e0ff9..b324154e9d0 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -20,8 +20,8 @@ ProductVatMassChange=Mass VAT change ProductVatMassChangeDesc=This page can be used to modify a VAT rate defined on products or services from a value to another. Warning, this change is done on all database. MassBarcodeInit=Mass barcode init MassBarcodeInitDesc=This page can be used to initialize a barcode on objects that does not have barcode defined. Check before that setup of module barcode is complete. -ProductAccountancyBuyCode=Accountancy code (purchase) -ProductAccountancySellCode=Accountancy code (sale) +ProductAccountancyBuyCode=Accounting code (purchase) +ProductAccountancySellCode=Accounting code (sale) ProductOrService=Product or Service ProductsAndServices=Products and Services ProductsOrServices=Products or Services @@ -152,7 +152,7 @@ BuyingPrices=Buying prices CustomerPrices=Customer prices SuppliersPrices=Supplier prices SuppliersPricesOfProductsOrServices=Supplier prices (of products or services) -CustomCode=Customs code +CustomCode=Customs/Commodity/HS code CountryOrigin=Origin country Nature=Nature ShortLabel=Short label diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index cda14147ece..6019977120e 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -195,4 +195,6 @@ InventoryFlushed=Inventory flushed ExitEditMode=Exit edition inventoryDeleteLine=Delete line RegulateStock=Regulate Stock -ListInventory=List \ No newline at end of file +ListInventory=List +StockSupportServices=Stock management support services +StockSupportServicesDesc=By default, you can stock only product with type "product". If on, and if module service is on, you can also stock a product with type "service" \ No newline at end of file diff --git a/htdocs/langs/en_US/supplier_proposal.lang b/htdocs/langs/en_US/supplier_proposal.lang index dc3eae23672..d5b51978920 100644 --- a/htdocs/langs/en_US/supplier_proposal.lang +++ b/htdocs/langs/en_US/supplier_proposal.lang @@ -1,7 +1,7 @@ # Dolibarr language file - Source file is en_US - supplier_proposal SupplierProposal=Supplier commercial proposals supplier_proposalDESC=Manage price requests to suppliers -SupplierProposalNew=New request +SupplierProposalNew=New price request CommRequest=Price request CommRequests=Price requests SearchRequest=Find a request diff --git a/htdocs/langs/en_US/users.lang b/htdocs/langs/en_US/users.lang index 645ff0d0773..1a9b5cde8d0 100644 --- a/htdocs/langs/en_US/users.lang +++ b/htdocs/langs/en_US/users.lang @@ -99,7 +99,7 @@ LoginUsingOpenID=Use OpenID to login WeeklyHours=Weekly hours ColorUser=Color of the user DisabledInMonoUserMode=Disabled in maintenance mode -UserAccountancyCode=User accountancy code +UserAccountancyCode=User accounting code UserLogoff=User logout UserLogged=User logged DateEmployment=Date of Employment \ No newline at end of file diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index af9fdebe2c9..514b76af16c 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -37,7 +37,7 @@ VirtualHostUrlNotDefined=URL of the virtual host served by external web server n NoPageYet=No pages yet SyntaxHelp=Help on specific syntax tips YouCanEditHtmlSourceckeditor=You can edit HTML source code using the "Source" button in editor. -YouCanEditHtmlSource=You can include PHP code into this source using tags <?php ?>. The following global variables are available: $conf, $langs, $db, $mysoc, $user, $website.

    You can also include content of another Page/Container with the following syntax: <?php dolIncludeHtmlContent($websitekey.'/contentaliastoinclude.php'); ?>

    To include a link to download a file stored into the documents directory, use the document.php wrapper:
    Example, for a file into documents/ecm (need to be logged), syntax is:
    <a href="/document.php?modulepart=ecm&file=reldir/filename.ext">.
    for a file into documents/media (open access), syntax is:
    <a href="/document.php?modulepart=medias&file=reldir/filename.ext">.

    To include an image stored into the documents directory, use the viewimage.php wrapper:
    Example, for an image into documents/media (open access), syntax is:
    <a href="/viewimage.php?modulepart=medias&file=filename.ext">. +YouCanEditHtmlSource=You can include PHP code into this source using tags <?php ?>. The following global variables are available: $conf, $langs, $db, $mysoc, $user, $website.

    You can also include content of another Page/Container with the following syntax:
    <?php dolIncludeHtmlContent($websitekey.'/alias_of_content_to_include.php'); ?>

    To include a link to download a file stored into the documents directory, use the document.php wrapper:
    Example, for a file into documents/ecm (need to be logged), syntax is:
    <a href="/document.php?modulepart=ecm&file=relative_dir/filename.ext">
    For same file into documents/ecm (open access using the sharing hash key), syntax is:
    <a href="/document.php?modulepart=ecm&file=relative_dir/filename.ext&hashp=publicsharekeyoffile">
    For a file into documents/media (open directory for public access), syntax is:
    <a href="/document.php?modulepart=medias&file=relative_dir/filename.ext">

    To include an image stored into the documents directory, use the viewimage.php wrapper:
    Example, for an image into documents/media (open access), syntax is:
    <a href="/viewimage.php?modulepart=medias&file=relative_dir/filename.ext"> ClonePage=Clone page/container CloneSite=Clone site ConfirmClonePage=Please enter code/alias of new page and if it is a translation of the cloned page. @@ -49,3 +49,4 @@ CreateByFetchingExternalPage=Create page/container by fetching page from externa OrEnterPageInfoManually=Or create empty page from scratch... FetchAndCreate=Fetch and Create ExportSite=Export site +IDOfPage=Id of page \ No newline at end of file diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 8e80a111516..308987575f5 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -12,7 +12,7 @@ WithdrawalsLines=Direct debit order lines RequestStandingOrderToTreat=Request for direct debit payment order to process RequestStandingOrderTreated=Request for direct debit payment order processed NotPossibleForThisStatusOfWithdrawReceiptORLine=Not yet possible. Withdraw status must be set to 'credited' before declaring reject on specific lines. -NbOfInvoiceToWithdraw=Nb. of invoice with direct debit order +NbOfInvoiceToWithdraw=Nb. of qualified invoice with waiting direct debit order NbOfInvoiceToWithdrawWithInfo=Nb. of customer invoice with direct debit payment orders having defined bank account information InvoiceWaitingWithdraw=Invoice waiting for direct debit AmountToWithdraw=Amount to withdraw @@ -72,7 +72,7 @@ IfInvoiceNeedOnWithdrawPaymentWontBeClosed=However, if invoice has at least one DoStandingOrdersBeforePayments=This tab allows you to request a direct debit payment order. Once done, go into menu Bank->Direct Debit orders to manage the direct debit payment order. When payment order is closed, payment on invoice will be automatically recorded, and invoice closed if remainder to pay is null. WithdrawalFile=Withdrawal file SetToStatusSent=Set to status "File Sent" -ThisWillAlsoAddPaymentOnInvoice=This will also apply payments to invoices and will classify them as "Paid" +ThisWillAlsoAddPaymentOnInvoice=This will also record payments to invoices and will classify them as "Paid" if remain to pay is null StatisticsByLineStatus=Statistics by status of lines RUM=UMR RUMLong=Unique Mandate Reference @@ -94,6 +94,8 @@ SEPAFrstOrRecur=Type of payment ModeRECUR=Reccurent payment ModeFRST=One-off payment PleaseCheckOne=Please check one only +DirectDebitOrderCreated=Direct debit order %s created +AmountRequested=Amount requested ### Notifications InfoCreditSubject=Payment of direct debit payment order %s by the bank diff --git a/htdocs/livraison/card.php b/htdocs/livraison/card.php index 81237d39782..d6ebf7b68aa 100644 --- a/htdocs/livraison/card.php +++ b/htdocs/livraison/card.php @@ -565,6 +565,14 @@ else } // Other attributes + if ($action = 'create_delivery') { + // copy from expedition + $expeditionExtrafields = new Extrafields($db); + $expeditionExtrafieldLabels = $expeditionExtrafields->fetch_name_optionals_label($expedition->table_element); + if ($expedition->fetch_optionals($object->origin_id, $expeditionExtrafieldLabels) > 0) { + $object->array_options = array_merge($object->array_options, $expedition->array_options); + } + } $cols = 2; include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; @@ -665,6 +673,13 @@ else $mode = ($object->statut == 0) ? 'edit' : 'view'; $line = new LivraisonLigne($db); $line->fetch_optionals($object->lines[$i]->id,$extralabelslines); + if ($action = 'create_delivery') { + $srcLine = new ExpeditionLigne($db); + $expeditionLineExtrafields = new Extrafields($db); + $expeditionLineExtrafieldLabels = $expeditionLineExtrafields->fetch_name_optionals_label($srcLine->table_element); + $srcLine->fetch_optionals($expedition->lines[$i]->id,$expeditionLineExtrafieldLabels); + $line->array_options = array_merge($line->array_options, $srcLine->array_options); + } print ''; print $line->showOptionals($extrafieldsline, $mode, array('style'=>$bc[$var], 'colspan'=>$colspan),$i); print ''; diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 4f61aa833bf..1f76d705305 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -133,8 +133,8 @@ if (empty($reshook)) $object->dateend = $dateend; $object->nbterm = GETPOST('nbterm'); $object->rate = $rate; - $object->note_private = GETPOST('note_private'); - $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private','none'); + $object->note_public = GETPOST('note_public','none'); $object->fk_project = GETPOST('projectid','int'); $accountancy_account_capital = GETPOST('accountancy_account_capital'); diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php index dc927035954..bea15f288a0 100644 --- a/htdocs/loan/payment/payment.php +++ b/htdocs/loan/payment/payment.php @@ -101,8 +101,8 @@ if ($action == 'add_payment') $payment->amount_interest = GETPOST('amount_interest'); $payment->paymenttype = GETPOST('paymenttype'); $payment->num_payment = GETPOST('num_payment'); - $payment->note_private = GETPOST('note_private'); - $payment->note_public = GETPOST('note_public'); + $payment->note_private = GETPOST('note_private','none'); + $payment->note_public = GETPOST('note_public','none'); if (! $error) { diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 06a6b4658ae..8f5c5fb11bd 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -179,7 +179,9 @@ if (! empty($_SERVER['DOCUMENT_ROOT']) && substr($_SERVER['DOCUMENT_ROOT'], -6) // Include the conf.php and functions.lib.php require_once 'filefunc.inc.php'; -// If there is a POST parameter to tell to save automatically some POST parameters into cookies, we do it +// If there is a POST parameter to tell to save automatically some POST parameters into cookies, we do it. +// This is used for example by form of boxes to save personalization of some options. +// DOL_AUTOSET_COOKIE=cookiename:val1,val2 and cookiename_val1=aaa cookiename_val2=bbb will set cookie_name with value json_encode(array('val1'=> , )) if (! empty($_POST["DOL_AUTOSET_COOKIE"])) { $tmpautoset=explode(':',$_POST["DOL_AUTOSET_COOKIE"],2); @@ -194,7 +196,7 @@ if (! empty($_POST["DOL_AUTOSET_COOKIE"])) $cookiename=$tmpautoset[0]; $cookievalue=json_encode($cookiearrayvalue); //var_dump('setcookie cookiename='.$cookiename.' cookievalue='.$cookievalue); - setcookie($cookiename, empty($cookievalue)?'':$cookievalue, empty($cookievalue)?0:(time()+(86400*354)), '/'); // keep cookie 1 year + setcookie($cookiename, empty($cookievalue)?'':$cookievalue, empty($cookievalue)?0:(time()+(86400*354)), '/', null, false, true); // keep cookie 1 year and add tag httponly if (empty($cookievalue)) unset($_COOKIE[$cookiename]); } @@ -204,7 +206,7 @@ $sessionname='DOLSESSID_'.$prefix; $sessiontimeout='DOLSESSTIMEOUT_'.$prefix; if (! empty($_COOKIE[$sessiontimeout])) ini_set('session.gc_maxlifetime',$_COOKIE[$sessiontimeout]); session_name($sessionname); -session_set_cookie_params(0, '/', null, false, true); // Add tag httponly on session cookie +session_set_cookie_params(0, '/', null, false, true); // Add tag httponly on session cookie (same as setting session.cookie_httponly into php.ini). Must be called before the session_start. // This create lock released until session_write_close() or end of page. // We need this lock as long as we read/write $_SESSION ['vars']. We can close released when finished. if (! defined('NOSESSION')) @@ -1279,7 +1281,6 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs { $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT; print ''."\n"; - print ''."\n"; } } @@ -1319,13 +1320,13 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs // Global js function print ''."\n"; - print ''."\n"; + print ''."\n"; // Add datepicker default options - if (! defined('DISABLE_DATE_PICKER')) + /*if (! defined('DISABLE_DATE_PICKER')) { print ''."\n"; - } + }*/ // JS forced by modules (relative url starting with /) if (! empty($conf->modules_parts['js'])) // $conf->modules_parts['js'] is array('module'=>array('file1','file2')) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index dfd12354399..dade8847aa6 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -23,7 +23,7 @@ * \brief Home page for module builder module */ -if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test +if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti SQL+XSS injection attack test require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -337,13 +337,13 @@ if ($dirins && $action == 'initobject' && $module && $objectname) if (! $error) { // Edit the class file to write properties - $result=rebuildObjectClass($destdir, $module, $objectname, $newmask); - if ($result < 0) $error++; + $object=rebuildObjectClass($destdir, $module, $objectname, $newmask); + if (is_numeric($object) && $object < 0) $error++; } if (! $error) { // Edit sql with new properties - $result=rebuildObjectSql($destdir, $module, $objectname, $newmask); + $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, '', $object); if ($result < 0) $error++; } @@ -362,22 +362,32 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj)) dol_mkdir($destdir); $addfieldentry = array( - 'name'=>GETPOST('propname','aZ09'),'type'=>GETPOST('proptype','aZ09'),'label'=>GETPOST('proplabel','aZ09'),'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'), + 'name'=>GETPOST('propname','aZ09'),'label'=>GETPOST('proplabel','alpha'),'type'=>GETPOST('proptype','alpha'), + 'arrayofkeyval'=>GETPOST('proparrayofkeyval','none'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}' + 'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'), 'position'=>GETPOST('propposition','int'),'notnull'=>GETPOST('propnotnull','int'),'index'=>GETPOST('propindex','int'),'searchall'=>GETPOST('propsearchall','int'), 'isameasure'=>GETPOST('propisameasure','int'), 'comment'=>GETPOST('propcomment','alpha'),'help'=>GETPOST('prophelp')); + if (! empty($addfieldentry['arrayofkeyval']) && ! is_array($addfieldentry['arrayofkeyval'])) + { + $addfieldentry['arrayofkeyval'] = dol_json_decode($addfieldentry['arrayofkeyval'], true); + } + // Edit the class file to write properties if (! $error) { - $result=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry); - if ($result <= 0) $error++; + $object=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry); + if (is_numeric($result) && $result <= 0) $error++; } // Edit sql with new properties if (! $error) { - $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir); - if ($result <= 0) $error++; + $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object); + if ($result <= 0) + { + $error++; + } } if (! $error) @@ -405,14 +415,14 @@ if ($dirins && $action == 'confirm_deleteproperty' && $propertykey) // Edit the class file to write properties if (! $error) { - $result=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey); - if ($result <= 0) $error++; + $object=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey); + if (is_numeric($object) && $object <= 0) $error++; } // Edit sql with new properties if (! $error) { - $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir); + $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object); if ($result <= 0) $error++; } @@ -675,16 +685,26 @@ if ($action == 'savefile' && empty($cancel)) // Save old version if (dol_is_file($pathoffile)) { - dol_move($pathoffile, $pathoffilebackup, 0, 1, 0, 0); + dol_copy($pathoffile, $pathoffilebackup, 0, 1); } - $content = GETPOST('editfilecontent'); + $content = GETPOST('editfilecontent','none'); // Save file on disk - file_put_contents($pathoffile, $content); - @chmod($pathoffile, octdec($newmask)); + if ($content) + { + dol_delete_file($pathoffile); + file_put_contents($pathoffile, $content); + @chmod($pathoffile, octdec($newmask)); - setEventMessages($langs->trans("FileSaved"), null); + setEventMessages($langs->trans("FileSaved"), null); + } + else + { + setEventMessages($langs->trans("ContentCantBeEmpty"), null, 'errors'); + //$action='editfile'; + $error++; + } } } @@ -831,7 +851,8 @@ if ($message) print $message; } -print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'
    '; +//print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'
    '; +$infomodulesfound = '
    '.$form->textwithpicto($langs->trans("ModuleBuilderDesc3", count($listofmodules)), $langs->trans("ModuleBuilderDesc4", $FILEFLAG)).'
    '; // Load module descriptor @@ -891,7 +912,7 @@ $head[$h][2] = 'deletemodule'; $h++; -dol_fiche_head($head, $module, $langs->trans("Modules"), -1, 'generic'); // Modules +dol_fiche_head($head, $module, $langs->trans("Modules"), -1, 'generic', 0, $infomodulesfound); // Modules if ($module == 'initmodule') { @@ -950,12 +971,14 @@ elseif (! empty($module)) $linktoenabledisable.=img_picto($langs->trans("Disabled"),'switch_off'); $linktoenabledisable.="\n"; } - - $modulestatusinfo=img_info('').' '.$langs->trans("ModuleIsNotActive", $urltomodulesetup); - if (! empty($conf->$module->enabled)) + if (! empty($conf->$modulelowercase->enabled)) { $modulestatusinfo=img_warning().' '.$langs->trans("ModuleIsLive"); } + else + { + $modulestatusinfo=img_info('').' '.$langs->trans("ModuleIsNotActive", $urltomodulesetup); + } $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=description&module='.$module.($forceddirread?'@'.$dirread:''); $head2[$h][1] = $langs->trans("Description"); @@ -1134,9 +1157,12 @@ elseif (! empty($module)) } else { - $fullpathoffile=dol_buildpath($file, 0); // Description - level 2 + $fullpathoffile=dol_buildpath($file, 0, 1); // Description - level 2 - $content = file_get_contents($fullpathoffile); + if ($fullpathoffile) + { + $content = file_get_contents($fullpathoffile); + } // New module print ''; @@ -1154,7 +1180,7 @@ elseif (! empty($module)) dol_fiche_end(); print '
    '; - print ''; + print ''; print '   '; print ''; print '
    '; @@ -1172,6 +1198,9 @@ elseif (! empty($module)) { if ($action != 'editfile' || empty($file)) { + print $langs->trans("SpecDefDesc").'
    '; + print '
    '; + $specs=dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$'); foreach ($specs as $spec) @@ -1206,7 +1235,7 @@ elseif (! empty($module)) print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html')); print '
    '; print '
    '; - print ''; + print ''; print '   '; print ''; print '
    '; @@ -1219,6 +1248,9 @@ elseif (! empty($module)) { if ($action != 'editfile' || empty($file)) { + print $langs->trans("LanguageDefDesc").'
    '; + print '
    '; + $langfiles=dol_dir_list(dol_buildpath($modulelowercase.'/langs', 0), 'files', 1, '\.lang$'); foreach ($langfiles as $langfile) @@ -1251,7 +1283,7 @@ elseif (! empty($module)) print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'text')); print '
    '; print '
    '; - print ''; + print ''; print '   '; print ''; print '
    '; @@ -1288,12 +1320,12 @@ elseif (! empty($module)) //$objectname = preg_replace('/\.txt$/', '', $fileobj['name']); $objectname = $reg[1]; if (empty($firstobjectname)) $firstobjectname = $objectname; - } - $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname; - $head3[$h][1] = $objectname; - $head3[$h][2] = $objectname; - $h++; + $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname; + $head3[$h][1] = $objectname; + $head3[$h][2] = $objectname; + $h++; + } } $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj=deleteobject'; @@ -1367,40 +1399,84 @@ elseif (! empty($module)) $pathtosql = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.sql'; $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($tabobj).'_extrafields.sql'; $pathtosqlkey = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.key.sql'; + $pathtolib = strtolower($module).'/lib/'.strtolower($tabobj).'.lib.php'; + $pathtopicto = strtolower($module).'/img/object_'.strtolower($tabobj).'.png'; + + $realpathtoclass = dol_buildpath($pathtoclass, 0, 1); + $realpathtoapi = dol_buildpath($pathtoapi, 0, 1); + $realpathtoagenda = dol_buildpath($pathtoagenda, 0, 1); + $realpathtocard = dol_buildpath($pathtocard, 0, 1); + $realpathtodocument = dol_buildpath($pathtodocument, 0, 1); + $realpathtolist = dol_buildpath($pathtolist, 0, 1); + $realpathtonote = dol_buildpath($pathtonote, 0, 1); + $realpathtophpunit = dol_buildpath($pathtophpunit, 0, 1); + $realpathtosql = dol_buildpath($pathtosql, 0, 1); + $realpathtosqlextra = dol_buildpath($pathtosqlextra, 0, 1); + $realpathtosqlkey = dol_buildpath($pathtosqlkey, 0, 1); + $realpathtolib = dol_buildpath($pathtolib, 0, 1); + $realpathtopicto = dol_buildpath($pathtopicto, 0, 1); + print '
    '; - print ' '.$langs->trans("ClassFile").' : '.$pathtoclass.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass?'':'').$pathtoclass.($realpathtoclass?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; - print ' '.$langs->trans("ApiClassFile").' : '.$pathtoapi.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.$langs->trans("ApiClassFile").' : '.($realpathtoapi?'':'').$pathtoapi.($realpathtoapi?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '   '.$langs->trans("GoToApiExplorer").''; print '
    '; - print ' '.$langs->trans("TestClassFile").' : '.$pathtophpunit.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.$langs->trans("TestClassFile").' : '.($realpathtophpunit?'':'').$pathtophpunit.($realpathtophpunit?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; - print ' '.$langs->trans("SqlFile").' : '.$pathtosql.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
    '; - print ' '.$langs->trans("SqlFileExtraFields").' : '.$pathtosqlextra.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + + print ' '.$langs->trans("PageForLib").' : '.($realpathtolib?'':'').$pathtolib.($realpathtodocument?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
    '; + print ' '.$langs->trans("PageForPicto").' : '.($realpathtopicto?'':'').$pathtopicto.($realpathtopicto?'':'').''; + //print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
    '; + + print '
    '; + print ' '.$langs->trans("SqlFile").' : '.($realpathtosql?'':'').$pathtosql.($realpathtosql?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '   '.$langs->trans("DropTableIfEmpty").''; + //print '   '.$langs->trans("RunSql").''; + print '
    '; + print ' '.$langs->trans("SqlFileExtraFields").' : '.($realpathtosqlextra?'':'').$pathtosqlextra.($realpathtosqlextra?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + //print '   '.$langs->trans("RunSql").''; + print '
    '; + print ' '.$langs->trans("SqlFileKey").' : '.($realpathtosqlkey?'':'').$pathtosqlkey.($realpathtosqlkey?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + //print '   '.$langs->trans("RunSql").''; + print '
    '; + print '
    '; - print ' '.$langs->trans("SqlFileKey").' : '.$pathtosqlkey.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; + + $urloflist = dol_buildpath($pathtolist, 1); + $urlofcard = dol_buildpath($pathtocard, 1); + print '
    '; - print ' '.$langs->trans("PageForList").' : '.$pathtolist.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.$langs->trans("PageForList").' : '.($realpathtosql?'':'').$pathtolist.($realpathtosql?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; - print ' '.$langs->trans("PageForCreateEditView").' : '.$pathtocard.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.$langs->trans("PageForCreateEditView").' : '.($realpathtocard?'':'').$pathtocard.($realpathtocard?'':'').'?action=create'; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; - print ' '.$langs->trans("PageForAgendaTab").' : '.$pathtoagenda.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.$langs->trans("PageForAgendaTab").' : '.($realpathtoagenda?'':'').$pathtoagenda.($realpathtoagenda?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; - print ' '.$langs->trans("PageForDocumentTab").' : '.$pathtodocument.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.$langs->trans("PageForDocumentTab").' : '.($realpathtodocument?'':'').$pathtodocument.($realpathtodocument?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; - print ' '.$langs->trans("PageForNoteTab").' : '.$pathtonote.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.$langs->trans("PageForNoteTab").' : '.($realpathtonote?'':'').$pathtonote.($realpathtonote?'':'').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
    '; + + print '
    '; + print '
    '; print '


    '; @@ -1413,139 +1489,174 @@ elseif (! empty($module)) { $result = @include_once($dirread.'/'.$pathtoclass); } - if (class_exists($tabobj)) $tmpobjet = new $tabobj($db); - - $reflector = new ReflectionClass($tabobj); - $properties = $reflector->getProperties(); // Can also use get_object_vars - $propdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars - //$propstat = $reflector->getStaticProperties(); - - print load_fiche_titre($langs->trans("Properties"), '', ''); - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - print '
    '; - print '
    '; $text=''; - if ($totallate > 0) $text=$langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",$totallate).')'; + if ($totallate > 0) $text=$langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",$totallate.(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE) ? '%' : '')).')'; $text.='. '.$langs->trans("LateDesc"); //$text.=$form->textwithpicto('',$langs->trans("LateDesc")); $options='height="64px"'; @@ -686,15 +688,17 @@ $db->close(); function showWeather($totallate,$text,$options) { global $conf; - + $out=''; $offset=0; $factor=10; // By default - $level0=$offset; if (! empty($conf->global->MAIN_METEO_LEVEL0)) $level0=$conf->global->MAIN_METEO_LEVEL0; - $level1=$offset+1*$factor; if (! empty($conf->global->MAIN_METEO_LEVEL1)) $level1=$conf->global->MAIN_METEO_LEVEL1; - $level2=$offset+2*$factor; if (! empty($conf->global->MAIN_METEO_LEVEL2)) $level2=$conf->global->MAIN_METEO_LEVEL2; - $level3=$offset+3*$factor; if (! empty($conf->global->MAIN_METEO_LEVEL3)) $level3=$conf->global->MAIN_METEO_LEVEL3; + $used_conf = !empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE) ? 'MAIN_METEO_PERCENTAGE_LEVEL' : 'MAIN_METEO_LEVEL'; + + $level0=$offset; if (! empty($conf->global->{$used_conf.'0'})) $level0=$conf->global->{$used_conf.'0'}; + $level1=$offset+1*$factor; if (! empty($conf->global->{$used_conf.'1'})) $level1=$conf->global->{$used_conf.'1'}; + $level2=$offset+2*$factor; if (! empty($conf->global->{$used_conf.'2'})) $level2=$conf->global->{$used_conf.'2'}; + $level3=$offset+3*$factor; if (! empty($conf->global->{$used_conf.'3'})) $level3=$conf->global->{$used_conf.'3'}; if ($totallate <= $level0) $out.=img_weather($text,'weather-clear.png',$options); if ($totallate > $level0 && $totallate <= $level1) $out.=img_weather($text,'weather-few-clouds.png',$options); diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index 94202f6570f..ccc1f9b77bd 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -50,8 +50,12 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_PAYED','Customer invoice payed','Executed when a customer invoice is payed','facture',7); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_CANCEL','Customer invoice canceled','Executed when a customer invoice is conceled','facture',8); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SENTBYMAIL','Customer invoice sent by mail','Executed when a customer invoice is sent by mail','facture',9); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_UNVALIDATE','Customer invoice unvalidated','Executed when a customer invoice status set back to draft','facture',10); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_CREATE','Supplier order created','Executed when a supplier order is created','order_supplier',11); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_UNVALIDATE','Customer invoice unvalidated','Executed when a customer invoice status set back to draft','facture',9); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_VALIDATE','Price request validated','Executed when a commercial proposal is validated','proposal_supplier',10); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_SENTBYMAIL','Price request sent by mail','Executed when a commercial proposal is sent by mail','proposal_supplier',10); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_CLOSE_SIGNED','Price request closed signed','Executed when a customer proposal is closed signed','proposal_supplier',10); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_CLOSE_REFUSED','Price request closed refused','Executed when a customer proposal is closed refused','proposal_supplier',10); +--insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_CREATE','Supplier order created','Executed when a supplier order is created','order_supplier',11); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_VALIDATE','Supplier order validated','Executed when a supplier order is validated','order_supplier',12); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_APPROVE','Supplier order request approved','Executed when a supplier order is approved','order_supplier',13); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_SUBMIT','Supplier order request submited','Executed when a supplier order is approved','order_supplier',13); @@ -69,6 +73,7 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('SHIPPING_VALIDATE','Shipping validated','Executed when a shipping is validated','shipping',20); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('SHIPPING_SENTBYMAIL','Shipping sent by mail','Executed when a shipping is sent by mail','shipping',21); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_VALIDATE','Member validated','Executed when a member is validated','member',22); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SENTBYMAIL','Mails sent from member card','Executed when you send email from member card','member',23); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SUBSCRIPTION','Member subscribed','Executed when a member is subscribed','member',24); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_RESILIATE','Member resiliated','Executed when a member is resiliated','member',25); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_DELETE','Member deleted','Executed when a member is deleted','member',26); diff --git a/htdocs/install/mysql/data/llx_c_email_templates.sql b/htdocs/install/mysql/data/llx_c_email_templates.sql new file mode 100644 index 00000000000..bfa183781c7 --- /dev/null +++ b/htdocs/install/mysql/data/llx_c_email_templates.sql @@ -0,0 +1,26 @@ +-- Copyright (C) 2017 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 +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- + +-- +-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors +-- de l'install et tous les sigles '--' sont supprimés. +-- + +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'adherent','member','',0,null,null,'(SendAnEMailToMember)',1,1,1,'__(CardContent)__','__(Hello)__,

    \n\n__(ThisIsContentOfYourCard)__
    \n__(ID)__ : __ID__
    \n__(Civiliyty)__ : __MEMBER_CIVILITY__
    \n__(Firstname)__ : __MEMBER_FIRSTNAME__
    \n__(Lastname)__ : __MEMBER_LASTNAME__
    \n__(Fullname)__ : __MEMBER_FULLNAME__
    \n__(Company)__ : __MEMBER_COMPANY__
    \n__(Address)__ : __MEMBER_ADDRESS__
    \n__(Zip)__ : __MEMBER_ZIP__
    \n__(Town)__ : __MEMBER_TOWN__
    \n__(Country)__ : __MEMBER_COUNTRY__
    \n__(Email)__ : __MEMBER_EMAIL__
    \n__(Birthday)__ : __MEMBER_BIRTH__
    \n__(Photo)__ : __MEMBER_PHOTO__
    \n__(Login)__ : __MEMBER_LOGIN__
    \n__(Password)__ : __MEMBER_PASSWORD__
    \n__(Phone)__ : __MEMBER_PHONE__
    \n__(PhonePerso)__ : __MEMBER_PHONEPRO__
    \n__(PhoneMobile)__ : __MEMBER_PHONEMOBILE__

    \n__(Sincerely)__
    __USER_SIGNATURE__',null); +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'banque','thirdparty','',0,null,null,'(YourSEPAMandate)',1,1,0,'__(YourSEPAMandate)__','__(Hello)__,

    \n\n__(FindYourSEPAMandate)__ :
    \n__MYCOMPANY_NAME__
    \n__MYCOMPANY_FULLADDRESS__

    \n__(Sincerely)__
    \n__USER_SIGNATURE__',null); + + diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql index cce279d79da..b805b9f8014 100644 --- a/htdocs/install/mysql/data/llx_c_tva.sql +++ b/htdocs/install/mysql/data/llx_c_tva.sql @@ -88,6 +88,8 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 9 -- CYPRUS (id country=78) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (781, 78, '19','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (782, 78, '9','0','VAT Rate 9',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (783, 78, '5','0','VAT Rate 5',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (784, 78, '0','0','VAT Rate 0',1); -- DANMERK (id country=80) @@ -133,13 +135,16 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 3 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 34, 3, '0','0','VAT Rate 0',1); -- INDIA (id country=117) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '12.5','0','VAT standard rate', 0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1172, 117, '4','0','VAT reduced rate', 0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1173, 117, '1','0','VAT super-reduced rate',0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1174, 117, '0','0','VAT Rate 0', 0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '0','0','VAT Rate 0', 0); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'CGST+SGST', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'IGST' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1178, 117, 'C+S-5', 0, 2.5, '1', 2.5, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1179, 117, 'I-5' , 5, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1180, 117, 'C+S-12', 0, 6, '1', 6, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1181, 117, 'I-12' , 12, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'C+S-18', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'I-18' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1182, 117, 'C+S-28', 0, 14, '1', 14, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1183, 117, 'I-28' , 28, 0, '0', 0, '0', 0, 'IGST', 1); -- IRELAND (id country=8) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (81, 8, '0','0','VAT Rate 0',1); diff --git a/htdocs/install/mysql/migration/3.0.0-3.1.0.sql b/htdocs/install/mysql/migration/3.0.0-3.1.0.sql index fa94a5deeed..a4ab666299d 100644 --- a/htdocs/install/mysql/migration/3.0.0-3.1.0.sql +++ b/htdocs/install/mysql/migration/3.0.0-3.1.0.sql @@ -63,7 +63,7 @@ ALTER TABLE llx_facturedet ADD UNIQUE INDEX uk_fk_remise_except (fk_remise_excep ALTER TABLE llx_societe ADD COLUMN fk_currency integer DEFAULT 0 AFTER fk_forme_juridique; ALTER TABLE llx_societe ADD COLUMN status tinyint DEFAULT 1; -ALTER TABLE llx_societe ADD COLUMN logo varchar(255); +ALTER TABLE llx_societe ADD COLUMN logo varchar(255) DEFAULT NULL; ALTER TABLE llx_societe_remise MODIFY remise_client double(6,3) DEFAULT 0 NOT NULL; diff --git a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql index 25a92f1e265..175e03ec179 100644 --- a/htdocs/install/mysql/migration/4.0.0-5.0.0.sql +++ b/htdocs/install/mysql/migration/4.0.0-5.0.0.sql @@ -4,6 +4,7 @@ -- when current version is 5.0.0 or higher. -- -- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- -- VPGSQL8.2 ALTER SEQUENCE IF EXISTS llx_table_rowid_seq RENAME TO llx_table_new_rowid_seq; -- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; -- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); -- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; @@ -121,6 +122,8 @@ create table llx_expensereport_extrafields ALTER TABLE llx_expensereport_extrafields ADD INDEX idx_expensereport_extrafields (fk_object); ALTER TABLE llx_cotisation RENAME TO llx_subscription; +-- VPGSQL8.2 ALTER SEQUENCE IF EXISTS llx_cotisation_rowid_seq RENAME TO llx_subscription_rowid_seq; + ALTER TABLE llx_subscription ADD UNIQUE INDEX uk_subscription (fk_adherent,dateadh); ALTER TABLE llx_subscription CHANGE COLUMN cotisation subscription real; ALTER TABLE llx_adherent_type CHANGE COLUMN cotisation subscription varchar(3) NOT NULL DEFAULT '1'; diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 91df00b3448..4e3272a88c9 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -338,6 +338,7 @@ UPDATE llx_const SET value = __ENCRYPT('moono-lisa')__ WHERE value = __ENCRYPT DELETE FROM llx_document_model where nom = 'fsfe.fr.php' and type='donation'; ALTER TABLE llx_product_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; +ALTER TABLE llx_product_customer_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; ALTER TABLE llx_product_fournisseur_price ADD COLUMN default_vat_code varchar(10) AFTER tva_tx; ALTER TABLE llx_user ADD COLUMN model_pdf varchar(255); @@ -510,6 +511,7 @@ ALTER TABLE llx_user_rights DROP FOREIGN KEY fk_user_rights_fk_user_user; ALTER TABLE llx_user_rights DROP INDEX uk_user_rights; ALTER TABLE llx_user_rights DROP INDEX fk_user; ALTER TABLE llx_user_rights ADD UNIQUE INDEX uk_user_rights (entity, fk_user, fk_id); +DELETE FROM llx_user_rights WHERE fk_user NOT IN (select rowid from llx_user); ALTER TABLE llx_user_rights ADD CONSTRAINT fk_user_rights_fk_user_user FOREIGN KEY (fk_user) REFERENCES llx_user (rowid); ALTER TABLE llx_usergroup_rights ADD COLUMN entity integer DEFAULT 1 NOT NULL AFTER rowid; @@ -616,5 +618,11 @@ CREATE TABLE llx_facturedet_rec_extrafields ALTER TABLE llx_facturedet_rec_extrafields ADD INDEX idx_facturedet_rec_extrafields (fk_object); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'CGST+SGST', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'IGST' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1178, 117, 'C+S-5', 0, 2.5, '1', 2.5, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1179, 117, 'I-5' , 5, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1180, 117, 'C+S-12', 0, 6, '1', 6, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1181, 117, 'I-12' , 12, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'C+S-18', 0, 9, '1', 9, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'I-18' , 18, 0, '0', 0, '0', 0, 'IGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1182, 117, 'C+S-28', 0, 14, '1', 14, '1', 0, 'CGST+SGST - Same state sales', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1183, 117, 'I-28' , 28, 0, '0', 0, '0', 0, 'IGST', 1); diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index 5af427242f4..f3f0f143ec8 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -41,6 +41,21 @@ ALTER TABLE llx_website_page ADD COLUMN fk_user_modif integer; -- For 7.0 +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax1_tx double(6,3) DEFAULT 0; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax1_type varchar(10) NOT NULL DEFAULT '0'; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax2_tx double(6,3) DEFAULT 0; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN localtax2_type varchar(10) NOT NULL DEFAULT '0'; + + +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SENTBYMAIL','Mails sent from member card','Executed when you send email from member card','member',23); + +ALTER TABLE llx_ecm_files MODIFY label varchar(128) NOT NULL; +ALTER TABLE llx_ecm_files ADD COLUMN share varchar(128) NULL after label; + + +ALTER TABLE llx_c_paiement ADD COLUMN position integer NOT NULL DEFAULT 0; +ALTER TABLE llx_c_payment_term ADD COLUMN position integer NOT NULL DEFAULT 0; + ALTER TABLE llx_product MODIFY COLUMN seuil_stock_alerte integer DEFAULT NULL; -- VPGSQL8.2 ALTER TABLE llx_product ALTER COLUMN seuil_stock_alerte SET DEFAULT NULL; @@ -55,6 +70,12 @@ ALTER TABLE llx_contrat MODIFY COLUMN ref_ext varchar(50); UPDATE llx_c_email_templates SET position = 0 WHERE position IS NULL; +UPDATE llx_c_email_templates SET lang = '' WHERE lang IS NULL; + +ALTER TABLE llx_c_email_templates ADD COLUMN enabled varchar(255) DEFAULT '1'; + +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'adherent','member','',0,null,null,'(SendAnEMailToMember)',1,1,1,'__(CardContent)__','__(Hello)__,

    \n\n__(ThisIsContentOfYourCard)__
    \n__(ID)__ : __ID__
    \n__(Civiliyty)__ : __MEMBER_CIVILITY__
    \n__(Firstname)__ : __MEMBER_FIRSTNAME__
    \n__(Lastname)__ : __MEMBER_LASTNAME__
    \n__(Fullname)__ : __MEMBER_FULLNAME__
    \n__(Company)__ : __MEMBER_COMPANY__
    \n__(Address)__ : __MEMBER_ADDRESS__
    \n__(Zip)__ : __MEMBER_ZIP__
    \n__(Town)__ : __MEMBER_TOWN__
    \n__(Country)__ : __MEMBER_COUNTRY__
    \n__(Email)__ : __MEMBER_EMAIL__
    \n__(Birthday)__ : __MEMBER_BIRTH__
    \n__(Photo)__ : __MEMBER_PHOTO__
    \n__(Login)__ : __MEMBER_LOGIN__
    \n__(Password)__ : __MEMBER_PASSWORD__
    \n__(Phone)__ : __MEMBER_PHONE__
    \n__(PhonePerso)__ : __MEMBER_PHONEPRO__
    \n__(PhoneMobile)__ : __MEMBER_PHONEMOBILE__

    \n__(Sincerely)__
    __USER_SIGNATURE__',null); +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'banque','thirdparty','',0,null,null,'(YourSEPAMandate)',1,1,0,'__(YourSEPAMandate)__','__(Hello)__,

    \n\n__(FindYourSEPAMandate)__ :
    \n__MYCOMPANY_NAME__
    \n__MYCOMPANY_FULLADDRESS__

    \n__(Sincerely)__
    \n__USER_SIGNATURE__',null); INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES ( 1, 'VENTES', 'Income of products/services', 'Exemple: 7xxxxx', 0, 0, '', '10', 1, 1); INSERT INTO llx_c_accounting_category (rowid, code, label, range_account, sens, category_type, formula, position, fk_country, active) VALUES ( 2, 'DEPENSES', 'Expenses of products/services', 'Exemple: 6xxxxx', 0, 0, '', '20', 1, 1); @@ -82,6 +103,7 @@ ALTER TABLE llx_website_page MODIFY COLUMN pageurl varchar(255); ALTER TABLE llx_website_page ADD COLUMN lang varchar(6); ALTER TABLE llx_website_page ADD COLUMN fk_page integer; ALTER TABLE llx_website_page ADD COLUMN grabbed_from varchar(255); +ALTER TABLE llx_website_page ADD COLUMN htmlheader text; ALTER TABLE llx_website_page MODIFY COLUMN status INTEGER DEFAULT 1; UPDATE llx_website_page set status = 1 WHERE status IS NULL; @@ -240,6 +262,12 @@ ALTER TABLE llx_extrafields ADD COLUMN fk_user_modif integer; ALTER TABLE llx_extrafields ADD COLUMN datec datetime; ALTER TABLE llx_extrafields ADD COLUMN tms timestamp; +-- We fix value of 'list' fro m0 to 1 for all extrafields created before this migration +UPDATE llx_extrafields SET list = 1 WHERE list = 0 AND fk_user_author IS NULL and fk_user_modif IS NULL and datec IS NULL; + +ALTER TABLE llx_extrafields MODIFY COLUMN list integer DEFAULT 1; +--VPGSQL8.2 ALTER TABLE llx_extrafields ALTER COLUMN list SET DEFAULT 1; + ALTER TABLE llx_extrafields MODIFY COLUMN langs varchar(64); ALTER TABLE llx_holiday_config MODIFY COLUMN name varchar(128); @@ -261,8 +289,16 @@ UPDATE llx_accounting_account SET pcg_type = 'EXPENSE' where pcg_type = 'CHARGE' UPDATE llx_accounting_account SET pcg_type = 'INCOME' where pcg_type = 'VENTAS_E_INGRESOS'; UPDATE llx_accounting_account SET pcg_type = 'EXPENSE' where pcg_type = 'COMPRAS_GASTOS'; +ALTER TABLE llx_c_action_trigger MODIFY COLUMN elementtype varchar(24) NOT NULL; + insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTRACT_SENTBYMAIL','Contract sent by mail','Executed when a contract is sent by mail','contrat',18); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_VALIDATE','Price request validated','Executed when a commercial proposal is validated','proposal_supplier',10); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_SENTBYMAIL','Price request sent by mail','Executed when a commercial proposal is sent by mail','proposal_supplier',10); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_CLOSE_SIGNED','Price request closed signed','Executed when a customer proposal is closed signed','proposal_supplier',10); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_CLOSE_REFUSED','Price request closed refused','Executed when a customer proposal is closed refused','proposal_supplier',10); + + CREATE TABLE llx_projet_task_comment ( rowid integer AUTO_INCREMENT PRIMARY KEY, datec datetime DEFAULT NULL, @@ -274,6 +310,19 @@ CREATE TABLE llx_projet_task_comment ( import_key varchar(125) DEFAULT NULL )ENGINE=innodb; +-- Accountancy - Remove old constants +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_SELL_JOURNAL')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_PURCHASE_JOURNAL')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_SOCIAL_JOURNAL')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_MISCELLANEOUS_JOURNAL')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_GROUPBYACCOUNT')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_EXPORT_GLOBAL_ACCOUNT')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_EXPORT_LABEL')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_EXPORT_AMOUNT')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_EXPORT_DEVISE')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_EXPORT_PIECE')__; +DELETE FROM llx_const WHERE name = __ENCRYPT('ACCOUNTING_EXPENSEREPORT_JOURNAL')__; + -- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) CHARACTER SET utf8; -- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) COLLATE utf8_unicode_ci; -- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_bookkeeping MODIFY numero_compte VARCHAR(20) CHARACTER SET utf8; diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index dcf5e9b104a..1fed846bd44 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -90,6 +90,7 @@ delete from llx_livraison where ref = ''; delete from llx_expeditiondet where fk_expedition in (select rowid from llx_expedition where ref = ''); delete from llx_expedition where ref = ''; delete from llx_holiday_logs where fk_user_update not IN (select rowid from llx_user); +delete from llx_user_rights where fk_user not IN (select rowid from llx_user); update llx_deplacement set dated='2010-01-01' where dated < '2000-01-01'; diff --git a/htdocs/install/mysql/tables/llx_c_action_trigger.sql b/htdocs/install/mysql/tables/llx_c_action_trigger.sql index cbec0c81437..4f7dbccc786 100644 --- a/htdocs/install/mysql/tables/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/tables/llx_c_action_trigger.sql @@ -22,7 +22,7 @@ create table llx_c_action_trigger ( rowid integer AUTO_INCREMENT PRIMARY KEY, - elementtype varchar(16) NOT NULL, + elementtype varchar(24) NOT NULL, code varchar(32) NOT NULL, label varchar(128) NOT NULL, description varchar(255), diff --git a/htdocs/install/mysql/tables/llx_c_email_templates.sql b/htdocs/install/mysql/tables/llx_c_email_templates.sql index 9d82d37768a..69cbc186ebd 100644 --- a/htdocs/install/mysql/tables/llx_c_email_templates.sql +++ b/htdocs/install/mysql/tables/llx_c_email_templates.sql @@ -23,13 +23,14 @@ create table llx_c_email_templates entity integer DEFAULT 1 NOT NULL, -- multi company id module varchar(32), -- Nom du module en rapport avec le modele type_template varchar(32), -- template for which type of email (send invoice by email, send order, ...) - lang varchar(6), + lang varchar(6) DEFAULT '', -- We use a default to '' so the unique index that include this field will work private smallint DEFAULT 0 NOT NULL, -- Template public or private fk_user integer, -- Id user owner if template is private, or null datec datetime, tms timestamp, label varchar(255), -- Label of predefined email position smallint, -- Position + enabled varchar(255) DEFAULT '1', -- Condition to have this module visible active tinyint DEFAULT 1 NOT NULL, topic text, -- Predefined topic content text, -- Predefined text diff --git a/htdocs/install/mysql/tables/llx_c_paiement.sql b/htdocs/install/mysql/tables/llx_c_paiement.sql index 1759af781f8..7db85510608 100644 --- a/htdocs/install/mysql/tables/llx_c_paiement.sql +++ b/htdocs/install/mysql/tables/llx_c_paiement.sql @@ -26,7 +26,8 @@ create table llx_c_paiement type smallint, -- 0: input money, 1: output money, 2: input and output, 3: other active tinyint DEFAULT 1 NOT NULL, accountancy_code varchar(32) NULL, - module varchar(32) NULL + module varchar(32) NULL, + position integer NOT NULL DEFAULT 0 )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_c_payment_term.sql b/htdocs/install/mysql/tables/llx_c_payment_term.sql index a2d79af2502..d0f07abc5a1 100644 --- a/htdocs/install/mysql/tables/llx_c_payment_term.sql +++ b/htdocs/install/mysql/tables/llx_c_payment_term.sql @@ -28,5 +28,6 @@ create table llx_c_payment_term type_cdr tinyint, -- Type of change date reckoning. 1=Payment at end of current month, 2=the Nth of next month nbjour smallint, decalage smallint, - module varchar(32) NULL + module varchar(32) NULL, + position integer NOT NULL DEFAULT 0 )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_ecm_files.sql b/htdocs/install/mysql/tables/llx_ecm_files.sql index dcc9dd40b9d..5360660a7bc 100644 --- a/htdocs/install/mysql/tables/llx_ecm_files.sql +++ b/htdocs/install/mysql/tables/llx_ecm_files.sql @@ -19,8 +19,9 @@ CREATE TABLE llx_ecm_files ( rowid integer AUTO_INCREMENT PRIMARY KEY, - ref varchar(128), -- Not used yet. Will contains a hash id from filename+filepath - label varchar(64) NOT NULL, -- label contains a md5 + ref varchar(128), -- contains a hash id from filename+filepath + label varchar(128) NOT NULL, -- contains hash of file content + share varchar(128) NULL, -- contains a hash for file sharing entity integer DEFAULT 1 NOT NULL, -- multi company id filepath varchar(255) NOT NULL, -- relative to dolibarr document dir. Example module/def filename varchar(255) NOT NULL, -- file name only without any directory diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql index 3b9a9b2d72b..548508d451d 100644 --- a/htdocs/install/mysql/tables/llx_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_extrafields.sql @@ -34,7 +34,7 @@ create table llx_extrafields pos integer DEFAULT 0, alwayseditable integer DEFAULT 0, -- 1 if field can be edited whatever is element status param text, -- extra parameters to define possible values of field - list integer DEFAULT 0, -- list of values for field that are combo lists + list integer DEFAULT 1, -- list of values for field that are combo lists langs varchar(64), -- example: fileofmymodule@mymodule ishidden integer DEFAULT 0, -- Can be foreign key of external system fk_user_author integer, -- user making creation diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index f341b103edb..1c86bfe04f8 100755 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -38,6 +38,10 @@ create table llx_product_fournisseur_price unitcharges double(24,8) DEFAULT 0, -- deprecated default_vat_code varchar(10), tva_tx double(6,3) NOT NULL, + localtax1_tx double(6,3) DEFAULT 0, + localtax1_type varchar(10) NOT NULL DEFAULT '0', + localtax2_tx double(6,3) DEFAULT 0, + localtax2_type varchar(10) NOT NULL DEFAULT '0', info_bits integer NOT NULL DEFAULT 0, fk_user integer, fk_supplier_price_expression integer, -- Link to the rule for dynamic price calculation diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index 20440b692d7..0f0cb437750 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -95,13 +95,13 @@ create table llx_societe barcode varchar(255), -- barcode fk_barcode_type integer NULL DEFAULT 0, -- barcode type price_level integer NULL, -- level of price for multiprices - outstanding_limit double(24,8) DEFAULT NULL, -- allowed outstanding limit + outstanding_limit double(24,8) DEFAULT NULL, -- allowed outstanding limit default_lang varchar(6), -- default language - logo varchar(255), - canvas varchar(32), -- type of canvas if used (null by default) + logo varchar(255) DEFAULT NULL, + canvas varchar(32) DEFAULT NULL, -- type of canvas if used (null by default) import_key varchar(14), -- import key - webservices_url varchar(255), -- supplier webservice url - webservices_key varchar(128), -- supplier webservice key + webservices_url varchar(255), -- supplier webservice url + webservices_key varchar(128), -- supplier webservice key fk_multicurrency integer, multicurrency_code varchar(255) diff --git a/htdocs/install/mysql/tables/llx_website_page.sql b/htdocs/install/mysql/tables/llx_website_page.sql index f3d1cca4786..5393177a3bb 100644 --- a/htdocs/install/mysql/tables/llx_website_page.sql +++ b/htdocs/install/mysql/tables/llx_website_page.sql @@ -27,6 +27,7 @@ CREATE TABLE llx_website_page keywords varchar(255), lang varchar(6), fk_page integer, + htmlheader text, content mediumtext, -- text is not enough in size status integer DEFAULT 1, grabbed_from varchar(255), diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 7fc3744e334..a93081cd5b2 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -211,7 +211,8 @@ if ($ok) $extrafields=new ExtraFields($db); $listofmodulesextra=array('societe'=>'societe','adherent'=>'adherent','product'=>'product', 'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture', - 'commande_fournisseur'=>'commande_fournisseur', 'actioncomm'=>'actioncomm', + 'supplier_proposal'=>'supplier_proposal', 'commande_fournisseur'=>'commande_fournisseur', 'facture_fourn'=>'facture_fourn', + 'actioncomm'=>'actioncomm', 'adherent_type'=>'adherent_type','user'=>'user','projet'=>'projet', 'projet_task'=>'projet_task'); print '

    *** Check fields into extra table structure match table of definition. If not add column into table
     
    '; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $properties = $tmpobjet->fields; - - foreach($properties as $propkey => $propval) + if (class_exists($tabobj)) { - /* If from Reflection - if ($propval->class == $tabobj) - { - $propname=$propval->getName(); - $comment=$propval->getDocComment(); - $type=gettype($tmpobjet->$propname); - $default=$propdefault[$propname]; - // Discard generic properties - if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue; - - // Keep or not lines - if (in_array($propname, array('fk_element', 'lines'))) continue; - }*/ - - $propname=$propkey; - $proplabel=$propval['label']; - $proptype=$propval['type']; - $propnotnull=$propval['notnull']; - $propsearchall=$propval['searchall']; - //$propdefault=$propval['default']; - $propindex=$propval['index']; - $propposition=$propval['position']; - $propenabled=$propval['enabled']; - $propvisible=$propval['visible']; - $propisameasure=$propval['isameasure']; - $propcomment=$propval['comment']; - - print ''; - - print ''; - print ''; - print ''; - print ''; - /*print '';*/ - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - print ''; + try { + $tmpobjet = @new $tabobj($db); + } + catch(Exception $e) + { + dol_syslog('Failed to load Constructor of class: '.$e->getMessage(), LOG_WARNING); + } } - print '
    '.$langs->trans("Property"); - print ' ('.$langs->trans("Example").')'; - print ''; - print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")); - print ''.$langs->trans("Type").''.$langs->trans("NotNull").''.$langs->trans("DefaultValue").''.$langs->trans("DatabaseIndex").''.$langs->trans("Position").''.$langs->trans("Enabled").''.$langs->trans("Visible").''.$langs->trans("IsAMeasure").''.$langs->trans("SearchAll").''.$langs->trans("Comment").'
    '; - print ''; - print '
    '; - print $propname; - print ''; - print $proplabel; - print ''; - print $proptype; - print ''; - print $propnotnull; - print ''; - print $propdefault; - print ''; - print $propindex?'X':''; - print ''; - print $propposition; - print ''; - print $propenabled?$propenabled:''; - print ''; - print $propvisible?$propvisible:''; - print ''; - print $propisameasure?$propisameasure:''; - print ''; - print $propsearchall?'X':''; - print ''; - print $propcomment; - print ''; - print ''.img_delete().''; - print '
    '; - print '
    '; - print ''; + if (! empty($tmpobjet)) + { + $reflector = new ReflectionClass($tabobj); + $properties = $reflector->getProperties(); // Can also use get_object_vars + $propdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars + //$propstat = $reflector->getStaticProperties(); + + print load_fiche_titre($langs->trans("Properties"), '', ''); + + print '
    '; + + print ''; + print ''; + print ''; + print ''; + print ''; + + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + //print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $properties = dol_sort_array($tmpobjet->fields, 'position'); + + if (! empty($properties)) + { + // Line to add a property + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + //print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + foreach($properties as $propkey => $propval) + { + /* If from Reflection + if ($propval->class == $tabobj) + { + $propname=$propval->getName(); + $comment=$propval->getDocComment(); + $type=gettype($tmpobjet->$propname); + $default=$propdefault[$propname]; + // Discard generic properties + if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue; + + // Keep or not lines + if (in_array($propname, array('fk_element', 'lines'))) continue; + }*/ + + $propname=$propkey; + $proplabel=$propval['label']; + $proptype=$propval['type']; + $proparrayofkeyval=$propval['arrayofkeyval']; + $propnotnull=$propval['notnull']; + $propsearchall=$propval['searchall']; + //$propdefault=$propval['default']; + $propindex=$propval['index']; + $propposition=$propval['position']; + $propenabled=$propval['enabled']; + $propvisible=$propval['visible']; + $propisameasure=$propval['isameasure']; + $propcomment=$propval['comment']; + + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + /*print '';*/ + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + print ''; + } + } + else + { + print ''; + } + print '
    '.$langs->trans("Property"); + print ' ('.$langs->trans("Example").')'; + print ''; + print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")); + print ''.$langs->trans("Type").''.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).''.$langs->trans("NotNull").''.$langs->trans("DefaultValue").''.$langs->trans("DatabaseIndex").''.$langs->trans("Position").''.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc")).''.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).''.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).''.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).''.$langs->trans("Comment").'
    '; + print ''; + print '
    '; + print $propname; + print ''; + print $proplabel; + print ''; + print $proptype; + print ''; + if ($proparrayofkeyval) + { + print json_encode($proparrayofkeyval); + } + print ''; + print $propnotnull; + print ''; + print $propdefault; + print ''; + print $propindex?'X':''; + print ''; + print $propposition; + print ''; + print $propenabled?$propenabled:''; + print ''; + print $propvisible?$propvisible:''; + print ''; + print $propisameasure?$propisameasure:''; + print ''; + print $propsearchall?'X':''; + print ''; + print $propcomment; + print ''; + print ''.img_delete().''; + print '
    '.$langs->trans('Property $field not found into the class. The class was probably not generated by modulebuilder.').'
    '; + print '
    '; + + print '
    '; + } + else + { + print ''.$langs->trans('Failed to init the object with the new.').''; + } } catch(Exception $e) { @@ -1571,13 +1682,14 @@ elseif (! empty($module)) print ''; print ''; print ''; + print ''; print ''; $doleditor=new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%'); print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html')); print '
    '; print '
    '; - print ''; + print ''; print '   '; print ''; print '
    '; @@ -1591,22 +1703,267 @@ elseif (! empty($module)) if ($tab == 'menus') { - print $langs->trans("FeatureNotYetAvailable"); + $pathtofile = $modulelowercase.'/core/modules/mod'.$module.'.class.php'; + //$menus = $moduleobj->; + + if ($action != 'editfile' || empty($file)) + { + print $langs->trans("MenusDefDesc", ''.$langs->trans('Menus').'').'
    '; + print '
    '; + + print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
    '; + + print '
    '; + //print load_fiche_titre($langs->trans("MenusList"), '', ''); + + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + + /* + print '
    '; + print ''; + + print ''; + print_liste_field_titre("Menu",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); + print_liste_field_titre("CronTask",'','',"",$param,'',$sortfield,$sortorder); + print_liste_field_titre("CronFrequency",'',"","",$param,'',$sortfield,$sortorder); + print_liste_field_titre("StatusAtInstall",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); + print_liste_field_titre("Comment",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); + print "\n"; + + if (count($menus)) + { + foreach ($cronjobs as $cron) + { + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + } + } + else + { + print ''; + } + + print '
    '; + print $cron['label']; + print ''; + if ($cron['jobtype']=='method') + { + $text=$langs->trans("CronClass"); + $texttoshow=$langs->trans('CronModule').': '.$module.'
    '; + $texttoshow.=$langs->trans('CronClass').': '. $cron['class'].'
    '; + $texttoshow.=$langs->trans('CronObject').': '. $cron['objectname'].'
    '; + $texttoshow.=$langs->trans('CronMethod').': '. $cron['method']; + $texttoshow.='
    '.$langs->trans('CronArgs').': '. $cron['parameters']; + $texttoshow.='
    '.$langs->trans('Comment').': '. $langs->trans($cron['comment']); + } + elseif ($cron['jobtype']=='command') + { + $text=$langs->trans('CronCommand'); + $texttoshow=$langs->trans('CronCommand').': '.dol_trunc($cron['command']); + $texttoshow.='
    '.$langs->trans('CronArgs').': '. $cron['parameters']; + $texttoshow.='
    '.$langs->trans('Comment').': '. $langs->trans($cron['comment']); + } + print $form->textwithpicto($text, $texttoshow, 1); + print '
    '; + if($cron['unitfrequency'] == "60") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes'); + if($cron['unitfrequency'] == "3600") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours'); + if($cron['unitfrequency'] == "86400") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days'); + if($cron['unitfrequency'] == "604800") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks'); + print ''; + print $cron['status']; + print ''; + if (!empty($cron['comment'])) {print $cron['comment'];} + print '
    '.$langs->trans("None").'
    '; + print '
    '; + + print '
    '; + */ + } + else + { + $fullpathoffile=dol_buildpath($file, 0); + + $content = file_get_contents($fullpathoffile); + + // New module + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + + $doleditor=new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%'); + print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html')); + print '
    '; + print '
    '; + print ''; + print '   '; + print ''; + print '
    '; + + print '
    '; + } } if ($tab == 'permissions') { - print $langs->trans("FeatureNotYetAvailable"); + $pathtofile = $modulelowercase.'/core/modules/mod'.$module.'.class.php'; + //$perms = $moduleobj->; + + if ($action != 'editfile' || empty($file)) + { + print $langs->trans("PermissionsDefDesc", ''.$langs->trans('DefaultPermissions').'').'
    '; + print '
    '; + + print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
    '; + + print '
    '; + print load_fiche_titre($langs->trans("ListOfPermissionsDefined"), '', ''); + + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + + print 'TODO...'; + /* + print '
    '; + print ''; + + print ''; + print_liste_field_titre("CronLabel",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); + print_liste_field_titre("CronTask",'','',"",$param,'',$sortfield,$sortorder); + print_liste_field_titre("CronFrequency",'',"","",$param,'',$sortfield,$sortorder); + print_liste_field_titre("StatusAtInstall",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); + print_liste_field_titre("Comment",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); + print "\n"; + + if (count($cronjobs)) + { + foreach ($cronjobs as $cron) + { + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + + print ''; + } + } + else + { + print ''; + } + + print '
    '; + print $cron['label']; + print ''; + if ($cron['jobtype']=='method') + { + $text=$langs->trans("CronClass"); + $texttoshow=$langs->trans('CronModule').': '.$module.'
    '; + $texttoshow.=$langs->trans('CronClass').': '. $cron['class'].'
    '; + $texttoshow.=$langs->trans('CronObject').': '. $cron['objectname'].'
    '; + $texttoshow.=$langs->trans('CronMethod').': '. $cron['method']; + $texttoshow.='
    '.$langs->trans('CronArgs').': '. $cron['parameters']; + $texttoshow.='
    '.$langs->trans('Comment').': '. $langs->trans($cron['comment']); + } + elseif ($cron['jobtype']=='command') + { + $text=$langs->trans('CronCommand'); + $texttoshow=$langs->trans('CronCommand').': '.dol_trunc($cron['command']); + $texttoshow.='
    '.$langs->trans('CronArgs').': '. $cron['parameters']; + $texttoshow.='
    '.$langs->trans('Comment').': '. $langs->trans($cron['comment']); + } + print $form->textwithpicto($text, $texttoshow, 1); + print '
    '; + if($cron['unitfrequency'] == "60") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes'); + if($cron['unitfrequency'] == "3600") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours'); + if($cron['unitfrequency'] == "86400") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days'); + if($cron['unitfrequency'] == "604800") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks'); + print ''; + print $cron['status']; + print ''; + if (!empty($cron['comment'])) {print $cron['comment'];} + print '
    '.$langs->trans("None").'
    '; + print '
    '; + + print '
    '; + */ + } + else + { + $fullpathoffile=dol_buildpath($file, 0); + + $content = file_get_contents($fullpathoffile); + + // New module + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + + $doleditor=new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%'); + print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html')); + print '
    '; + print '
    '; + print ''; + print '   '; + print ''; + print '
    '; + + print '
    '; + } } if ($tab == 'hooks') { if ($action != 'editfile' || empty($file)) { - $pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php'; - print ' '.$langs->trans("HooksFile").' : '.$pathtohook.''; + print $langs->trans("HooksDefDesc").'
    '; + print '
    '; + + $pathtofile = $modulelowercase.'/core/modules/mod'.$module.'.class.php'; + print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
    '; + + $pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php'; + print ' '.$langs->trans("HooksFile").' : '.$pathtohook.''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; } @@ -1628,7 +1985,7 @@ elseif (! empty($module)) print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html')); print '
    '; print '
    '; - print ''; + print ''; print '   '; print ''; print '
    '; @@ -1646,6 +2003,9 @@ elseif (! empty($module)) if ($action != 'editfile' || empty($file)) { + print $langs->trans("TriggerDefDesc").'
    '; + print '
    '; + if (! empty($triggers)) { foreach ($triggers as $trigger) @@ -1680,7 +2040,7 @@ elseif (! empty($module)) print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html')); print '
    '; print '
    '; - print ''; + print ''; print '   '; print ''; print '
    '; @@ -1731,7 +2091,7 @@ elseif (! empty($module)) print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html')); print '
    '; print '
    '; - print ''; + print ''; print '   '; print ''; print '
    '; @@ -1832,6 +2192,8 @@ elseif (! empty($module)) print ''; print ''; + + print ''; } else { @@ -1851,7 +2213,7 @@ elseif (! empty($module)) print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html')); print '
    '; print '
    '; - print ''; + print ''; print '   '; print ''; print '
    '; diff --git a/htdocs/modulebuilder/template/ChangeLog.md b/htdocs/modulebuilder/template/ChangeLog.md index 0f04e316f58..28f0d04e47d 100644 --- a/htdocs/modulebuilder/template/ChangeLog.md +++ b/htdocs/modulebuilder/template/ChangeLog.md @@ -1,4 +1,4 @@ -# CHANGELOG FOR DOLIBARR ERP CRM +# CHANGELOG MYMODULE FOR DOLIBARR ERP CRM ## 1.0 Initial version diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 1ad33b502ad..e91a9751b60 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -62,7 +62,7 @@ class MyObject extends CommonObject * 'type' if the field format. * 'label' the translation key. * 'enabled' is a condition when the filed must be managed. - * 'visible' says if field is visible in list (-1 means not shown by default but can be aded into list to be viewed). + * 'visible' says if field is visible in list (-1 means not shown by default but can be added into list to be viewed). * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). * 'index' if we want an index in database. * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). @@ -78,19 +78,21 @@ class MyObject extends CommonObject * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. */ public $fields=array( - 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'), - 'ref' =>array('type'=>'varchar(64)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'), - 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'index'=>1, 'position'=>20), - 'label' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1), + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'), + 'ref' =>array('type'=>'varchar(64)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'index'=>1, 'position'=>20), + 'label' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth200'), 'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Amount'), - 'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'index'=>1, 'position'=>1000), - 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'note_public' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>45), + 'note_private' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>46), + 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), //'date_valid' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>500), - 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'notnull'=>-1, 'position'=>500), //'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValid', 'enabled'=>1, 'visible'=>-1, 'position'=>500), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'notnull'=>-1, 'index'=>1, 'position'=>1000), + 'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')), ); public $rowid; @@ -144,7 +146,7 @@ class MyObject extends CommonObject $this->db = $db; - if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) $fields['rowid']['visible']=0; + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) $this->fields['rowid']['visible']=0; } /** @@ -324,6 +326,17 @@ class MyObject extends CommonObject return $result; } + /** + * Return link to download file from a direct external access + * + * @param int $withpicto Add download picto into link + * @return string HTML link to file + */ + function getDirectExternalLink($withpicto=0) + { + return 'todo'; + } + /** * Retourne le libelle du status d'un user (actif, inactif) * diff --git a/htdocs/modulebuilder/template/doc/Specifications.asciidoc b/htdocs/modulebuilder/template/doc/Specifications.asciidoc index 7b1711cf514..adfaeb4e9b5 100644 --- a/htdocs/modulebuilder/template/doc/Specifications.asciidoc +++ b/htdocs/modulebuilder/template/doc/Specifications.asciidoc @@ -1 +1,127 @@ -# SPECIFICATIONS OF MODULE MYMODULE FOR DOLIBARR ERP CRM \ No newline at end of file += MYMODULE = +Copyright (C) ---Put here your own copyright and developer email--- +:subtitle: MYMODULE SPECIFICATIONS + + + +== Topic of document + +This document was build from following input: + +* Date 1 +... + +* Date 2 +... + + +The document includes an introductory chapter of functional specifications, presenting the different actors involved in the rebuild of the definitions +of business terms that will be used (some of which may be new or different). +The main following chapter will present the entire process, also known as *uses cases*, according to a principle of a description, in chronological sequence if possible, +to present the actor and the action performed, as in the following example: + +* *X* Actor realizes Action A. +* *Y* Actor communicates Info B to Actor *Z* +* *Automaton* performs update of data for... +* Etc ... + +Functional requirements are complemented by a chapter of technical requirements. +The chapter on data lists key information specific to Presto that were identified at the time of writing specification. It will be enriched as +iterations occurs. + +Finally, in the Appendix, the documents known when writing this document are centralized to illustrate the existing document or inspire the new expected one. +These documents have their content directly integrated in this specification or have a reference to +external documents stored in the *Appendices* directory accompanying this document. + + + +*Log of versions* + +[options="header",format="csv"] +|=== +Author, Date, Version +John Doe, Date YYY-MM-DD, Version 1.0 +|=== + + + +<<< + + +== BUSINESS SPECIFICATIONS - INTRODUCTION + +=== List of actors [[actors]] + +Actors are physical people or moral entities working on at least one process. +The following chart prensts list of actors or partners identified by the project for the defined scope of project. We will use then the name defined into first column to speak about roles in the rest of documents. + +[options="header",format="csv"] +|=== +Actor/profil/role, Description of role, Access to system or not, Example of actor +Customer Service, Receive and create Sales orders (SO), Yes, Mr Smith +Purchase, Make puchase order (PO), Yes, 5 people +Administrator - IT, Administration of users/groups and IT services, Yes, John Doe +Automaton, Execute automatic data processing, Yes, NA +|=== + + +=== Definitions [[definitions]] + +To understand the descriptions of the target process, it was necessary to define or redefine some vocabulary concepts. We must see these definitions as defined in the +new system. Indeed, some terms are already being used but have either not a definition in line with standards, or even differs between services. To bring everyone, +and to consolidate the process, these terms are redefined here, and with their definition in the target objective. + +*Definition ABC* + +... + +*Definition DEF* + +... + + +[NOTE] +============== +Important information will be noticed with a notice like this one. + +* Main information 1 +* Main information 2 +============== + + + +== BUSINESS SPECIFICATION - PROCESS + +Specifications were cut into different business process. We call a business process a workflow with a starting situation and ending situation. Between start and end, we will find actions +done by actors to bring the value of the company. This actions are described using the syntax rule: +*Actor X* do action Y, *Actor Z* do action W. + +_Each process/use case is described into a separate chapter._ + + +=== Use case / Process 1 [[process_1]] + +==== Title and goals + +... + +==== Actors or roles + +* Members of group *...* + +==== Standard flow + +* Members of Groupe *...*: Do ... +* Members of Groupe *...*: Do ... +* Members of Groupe *...*: Do ... + +==== Alternative flow + +* A user without role *...*: Can't do ... + +==== Business rules + +* Business rule 1 +* Business rule 2 + + diff --git a/htdocs/modulebuilder/template/lib/myobject.lib.php b/htdocs/modulebuilder/template/lib/myobject.lib.php index 25f85052133..5ce7c4f7c97 100644 --- a/htdocs/modulebuilder/template/lib/myobject.lib.php +++ b/htdocs/modulebuilder/template/lib/myobject.lib.php @@ -29,7 +29,7 @@ */ function myobjectPrepareHead($object) { - global $langs, $conf; + global $db, $langs, $conf; $langs->load("mymodule@mymodule"); @@ -40,17 +40,30 @@ function myobjectPrepareHead($object) $head[$h][1] = $langs->trans("Card"); $head[$h][2] = 'card'; $h++; - if (isset($object->fields['note_public']) || isset($object->fields['note_pricate'])) + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { - $head[$h][0] = dol_buildpath("/mymodule/myobject_note.php", 1).'?id='.$object->id; - $head[$h][1] = $langs->trans("Notes"); + $nbNote = 0; + if(!empty($object->fields['note_private'])) $nbNote++; + if(!empty($object->fields['note_public'])) $nbNote++; + $head[$h][0] = dol_buildpath('/mymodule/myobject_note.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) $head[$h][1].= ' '.$nbNote.''; $head[$h][2] = 'note'; $h++; } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->mymodule->dir_output . "/myobject/" . dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir,'files',0,'','(\.meta|_preview.*\.png)$')); + $nbLinks=Link::count($db, $object->element, $object->id); $head[$h][0] = dol_buildpath("/mymodule/myobject_document.php", 1).'?id='.$object->id; - $head[$h][1] = $langs->trans("Documents"); + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' '.($nbFiles+$nbLinks).''; $head[$h][2] = 'document'; $h++; + $head[$h][0] = dol_buildpath("/mymodule/myobject_agenda.php", 1).'?id='.$object->id; $head[$h][1] = $langs->trans("Events"); $head[$h][2] = 'agenda'; diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 8aa6cc3ad9a..4160b2045fd 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -27,8 +27,8 @@ //if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); //if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test done when option MAIN_SECURITY_CSRF_WITH_TOKEN is on. //if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data //if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test //if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu @@ -114,13 +114,11 @@ if (empty($reshook)) if ($cancel) { - if ($action != 'addlink') + if (! empty($backtopage)) { - $urltogo=$backtopage?$backtopage:dol_buildpath('/mymodule/myobject_list.php',1); - header("Location: ".$urltogo); + header("Location: ".$backtopage); exit; } - if ($id > 0 || ! empty($ref)) $ret = $object->fetch($id,$ref); $action=''; } @@ -168,8 +166,9 @@ if (empty($reshook)) { foreach ($object->fields as $key => $val) { + if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue; // Ignore special fields + $object->$key=GETPOST($key,'alpha'); - if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue; if ($val['notnull'] > 0 && $object->$key == '') { $error++; @@ -215,6 +214,15 @@ if (empty($reshook)) else setEventMessages($object->error, null, 'errors'); } } + + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + + // Actions to send emails + $trigger_name='MYOBJECT_SENTBYMAIL'; + $autocopy='MAIN_MAIL_AUTOCOPY_MYOBJECT_TO'; + $trackid='myobject'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; } @@ -263,14 +271,39 @@ if ($action == 'create') foreach($object->fields as $key => $val) { if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue; - print ''; + print ''.$langs->trans($val['label']).''; - print ''; + if ($val['type'] == 'text') print ' tdtop'; + print '"'; + print '>'; + print $langs->trans($val['label']); + print ''; + print ''; + $defaultcss='minwidth100'; + if ($val['type'] == 'text') + { + print ''; + } + elseif (is_array($val['arrayofkeyval'])) + { + print $form->selectarray($key, $val['arrayofkeyval'], GETPOST($key, 'int')); + } + else + { + $cssforinput = empty($val['css'])?$defaultcss:$val['css']; + print ''; + } + print ''; print ''; } + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_add.tpl.php'; + print ''."\n"; dol_fiche_end(); @@ -280,12 +313,10 @@ if ($action == 'create') print ''; } - - // Part to edit record if (($id || $ref) && $action == 'edit') { - print load_fiche_titre($langs->trans("MyModule")); + print load_fiche_titre($langs->trans("MyObject")); print '
    '; print ''; @@ -298,14 +329,37 @@ if (($id || $ref) && $action == 'edit') foreach($object->fields as $key => $val) { if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue; + print ''.$langs->trans($val['label']).''; - print ''; + print ''; + $defaultcss='minwidth100'; + if ($val['type'] == 'text') + { + print ''; + } + elseif (is_array($val['arrayofkeyval'])) + { + print $form->selectarray($key, $val['arrayofkeyval'], GETPOST($key, 'int')!=''?GETPOST($key, 'int'):$object->$key); + } + else + { + $cssforinput = empty($val['css'])?$defaultcss:$val['css']; + print ''; + } + print ''; print ''; } + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php'; + print ''; dol_fiche_end(); @@ -317,8 +371,6 @@ if (($id || $ref) && $action == 'edit') print ''; } - - // Part to show record if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { @@ -418,18 +470,20 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea foreach($object->fields as $key => $val) { - if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue; + if (in_array($key, array('rowid', 'ref', 'entity', 'note_public', 'note_private', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key', 'status'))) continue; + print ' 0) print ' fieldrequired'; print '"'; print '>'.$langs->trans($val['label']).''; - print ''; + print ''; + print dol_escape_htmltag($object->$key, 1, 1); + print ''; print ''; - } - // Other attributes - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + //if ($key == 'targetsrcfile3') break; // key used for break on second column + } print ''; print ''; @@ -438,7 +492,30 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
    '; print ''; - // ... + $alreadyoutput = 1; + foreach($object->fields as $key => $val) + { + if ($alreadyoutput) + { + //if ($key == 'targetsrcfile3') $alreadyoutput = 0; // key used for break on second column + continue; + } + + if (in_array($key, array('rowid', 'ref', 'entity', 'note_public', 'note_private', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key', 'status'))) continue; + + print ''.$langs->trans($val['label']).''; + print ''; + print ''; + } + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; print '
    '; + print dol_escape_htmltag($object->$key, 1, 1); + print '
    '; print ''; @@ -467,6 +544,20 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''."\n"; } + /* + if ($user->rights->sellyoursaas->create) + { + if ($object->status == 1) + { + print ''."\n"; + } + else + { + print ''."\n"; + } + } + */ + if ($user->rights->mymodule->delete) { print ''."\n"; @@ -502,135 +593,23 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
    '; + $MAXEVENT = 10; + // List of actions on element include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'myobject', $socid, 1); + $somethingshown = $formactions->showactions($object, 'myobject', $socid, 1, '', $MAXEVENT); print '
    '; } + // Presend form + $modelmail='myobject'; + $defaulttopic='Information'; + $diroutput = $conf->mymodule->dir_output; + $trackid = 'myobject'.$object->id; - /* - * Action presend - */ - /* - if ($action == 'presend') - { - $object->fetch_projet(); - - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - - if (!empty($newlang)) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); - $outputlangs->load('commercial'); - } - - // Build document if it not exists - if (! $file || ! is_readable($file)) { - $result = $object->generateDocument(GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) { - dol_print_error($db, $object->error, $object->errors); - exit(); - } - $fileparams = dol_most_recent_file($conf->commande->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - } - - print '
    '; - print '
    '; - print '
    '; - print load_fiche_titre($langs->trans('SendMyObjectByMail')); - - dol_fiche_head(''); - - // Cree l'objet formulaire mail - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='ord'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id); - } - $formmail->withfrom = 1; - $liste = array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) - $liste [$key] = $value; - $formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste; - $formmail->withtocc = $liste; - $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; - if (empty($object->ref_client)) { - $formmail->withtopic = $outputlangs->trans('SendMyObjectRef', '__REF__'); - } else if (! empty($object->ref_client)) { - $formmail->withtopic = $outputlangs->trans('SendMyObjectRef', '__REF__ (__REFCLIENT__)'); - } - $formmail->withfile = 2; - $formmail->withbody = 1; - $formmail->withdeliveryreceipt = 1; - $formmail->withcancel = 1; - // Tableau des substitutions - $formmail->setSubstitFromObject($object); - $formmail->substit ['__REF__'] = $object->ref; - - $custcontact = ''; - $contactarr = array(); - $contactarr = $object->liste_contact(- 1, 'external'); - - if (is_array($contactarr) && count($contactarr) > 0) - { - foreach ($contactarr as $contact) - { - if ($contact['libelle'] == $langs->trans('TypeContact_commande_external_CUSTOMER')) { // TODO Use code and not label - $contactstatic = new Contact($db); - $contactstatic->fetch($contact ['id']); - $custcontact = $contactstatic->getFullName($langs, 1); - } - } - - if (! empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__'] = $custcontact; - } - } - - // Tableau des parametres complementaires - $formmail->param['action'] = 'send'; - $formmail->param['models'] = 'myobject_send'; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['myobjectid'] = $object->id; - $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id; - - // Init list of files - if (GETPOST("mode") == 'init') { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); - } - - // Show form - print $formmail->get_form(); - - dol_fiche_end(); - }*/ + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } diff --git a/htdocs/modulebuilder/template/myobject_document.php b/htdocs/modulebuilder/template/myobject_document.php index 0f8ce367bb5..05b76b3d588 100644 --- a/htdocs/modulebuilder/template/myobject_document.php +++ b/htdocs/modulebuilder/template/myobject_document.php @@ -79,7 +79,9 @@ $extralabels = $extrafields->fetch_name_optionals_label('myobject'); // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals -if ($id > 0 || ! empty($ref)) $upload_dir = $conf->mymodule->multidir_output[$object->entity] . "/" . $object->id; + +//if ($id > 0 || ! empty($ref)) $upload_dir = $conf->sellyoursaas->multidir_output[$object->entity] . "/packages/" . dol_sanitizeFileName($object->id); +if ($id > 0 || ! empty($ref)) $upload_dir = $conf->sellyoursaas->multidir_output[$object->entity] . "/packages/" . dol_sanitizeFileName($object->ref); @@ -167,10 +169,16 @@ if ($object->id) dol_fiche_end(); - $modulepart = 'societe'; - $permission = $user->rights->societe->creer; - $permtoedit = $user->rights->societe->creer; + $modulepart = 'mymodule'; + //$permission = $user->rights->mymodule->create; + $permission = 1; + //$permtoedit = $user->rights->mymodule->create; + $permtoedit = 1; $param = '&id=' . $object->id; + + //$relativepathwithnofile='myobject/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile='myobject/' . dol_sanitizeFileName($object->ref).'/'; + include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php'; } else diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index c144c539dd4..5677ab3baf2 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -27,8 +27,8 @@ //if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); //if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test done when option MAIN_SECURITY_CSRF_WITH_TOKEN is on. //if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data //if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test //if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu @@ -130,7 +130,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -238,6 +238,21 @@ foreach ($search_array_options as $key => $val) $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; + +/* If a group by is required +$sql.= " GROUP BY " +foreach($object->fields as $key => $val) +{ + $sql.='t.'.$key.', '; +} +// Add fields from extrafields +foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key : ''); +// Add where from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; +*/ + $sql.=$db->order($sortfield,$sortorder); // Count total nb of records @@ -476,19 +491,19 @@ $totalarray=array(); while ($i < min($num, $limit)) { $obj = $db->fetch_object($resql); - if ($obj) - { - // Store properties in $object - $object->id = $obj->rowid; - foreach($object->fields as $key => $val) - { - if (isset($obj->$key)) $object->$key = $obj->$key; - } + if (empty($obj)) break; // Should not happen - // Show here line of result - print ''; - foreach($object->fields as $key => $val) - { + // Store properties in $object + $object->id = $obj->rowid; + foreach($object->fields as $key => $val) + { + if (isset($obj->$key)) $object->$key = $obj->$key; + } + + // Show here line of result + print ''; + foreach($object->fields as $key => $val) + { if (in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; $align=''; if (in_array($val['type'], array('date','datetime','timestamp'))) $align='center'; @@ -509,70 +524,70 @@ while ($i < min($num, $limit)) $totalarray['val']['t.'.$key] += $obj->$key; } } - } - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - if (! empty($val['isameasure'])) - { - if (! $i) $totalarray['pos'][$totalarray['nbfield']]='ef.'.$tmpkey; - $totalarray['val']['ef.'.$tmpkey] += $obj->$tmpkey; - } - } - } - } - // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); - $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Rest of fields - foreach($object->fields as $key => $val) + } + // Extra fields + if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) + { + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + print 'getAlignFlag($key); + if ($align) print ' align="'.$align.'"'; + print '>'; + $tmpkey='options_'.$key; + print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); + print ''; + if (! $i) $totalarray['nbfield']++; + if (! empty($val['isameasure'])) + { + if (! $i) $totalarray['pos'][$totalarray['nbfield']]='ef.'.$tmpkey; + $totalarray['val']['ef.'.$tmpkey] += $obj->$tmpkey; + } + } + } + } + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Rest of fields + foreach($object->fields as $key => $val) + { + if (! in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; + $align=''; + if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center'; + if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; + if ($key == 'status') $align.=($align?' ':'').'center'; + if (! empty($arrayfields['t.'.$key]['checked'])) { - if (! in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; - $align=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center'; - if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; - if ($key == 'status') $align.=($align?' ':'').'center'; - if (! empty($arrayfields['t.'.$key]['checked'])) + print ''; + if (in_array($val['type'], array('date','datetime','timestamp'))) print dol_print_date($db->jdate($obj->$key), 'dayhour'); + elseif ($key == 'status') print $object->getLibStatut(3); + else print $obj->$key; + print ''; + if (! $i) $totalarray['nbfield']++; + if (! empty($val['isameasure'])) { - print ''; - if (in_array($val['type'], array('date','datetime','timestamp'))) print dol_print_date($db->jdate($obj->$key), 'dayhour'); - elseif ($key == 'status') print $object->getLibStatut(3); - else print $obj->$key; - print ''; - if (! $i) $totalarray['nbfield']++; - if (! empty($val['isameasure'])) - { - if (! $i) $totalarray['pos'][$totalarray['nbfield']]='t.'.$key; - $totalarray['val']['t.'.$key] += $obj->$key; - } + if (! $i) $totalarray['pos'][$totalarray['nbfield']]='t.'.$key; + $totalarray['val']['t.'.$key] += $obj->$key; } } - // Action column - print ''; - if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - { - $selected=0; - if (in_array($obj->rowid, $arrayofselected)) $selected=1; - print ''; - } - print ''; - if (! $i) $totalarray['nbfield']++; - - print ''; } + // Action column + print ''; + if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + { + $selected=0; + if (in_array($obj->rowid, $arrayofselected)) $selected=1; + print ''; + } + print ''; + if (! $i) $totalarray['nbfield']++; + + print ''; + $i++; } @@ -592,7 +607,7 @@ if (isset($totalarray['pos'])) if ($num < $limit) print ''.$langs->trans("Total").''; else print ''.$langs->trans("Totalforthispage").''; } - print ''; + else print ''; } } print ''; diff --git a/htdocs/product/admin/product_tools.php b/htdocs/product/admin/product_tools.php index 85351a0fb2a..f19f672a25e 100644 --- a/htdocs/product/admin/product_tools.php +++ b/htdocs/product/admin/product_tools.php @@ -38,8 +38,8 @@ $langs->load("products"); if (! $user->admin) accessforbidden(); $action = GETPOST('action','alpha'); -$oldvatrate=GETPOST('oldvatrate'); -$newvatrate=GETPOST('newvatrate'); +$oldvatrate=GETPOST('oldvatrate', 'alpha'); +$newvatrate=GETPOST('newvatrate', 'alpha'); //$price_base_type=GETPOST('price_base_type'); @@ -67,13 +67,31 @@ if ($action == 'convert') $db->begin(); + // Clean vat code old + $vat_src_code_old=''; + if (preg_match('/\((.*)\)/', $oldvatrate, $reg)) + { + $vat_src_code_old = $reg[1]; + $oldvatrateclean = preg_replace('/\s*\(.*\)/', '', $oldvatrate); // Remove code into vatrate. + } + + // Clean vat code new + $vat_src_code_new=''; + if (preg_match('/\((.*)\)/', $newvatrate, $reg)) + { + $vat_src_code_new = $reg[1]; + $newvatrateclean = preg_replace('/\s*\(.*\)/', '', $newvatrate); // Remove code into vatrate. + } + // If country to edit is my country, so we change customer prices if ($country_id == $mysoc->country_id) { $sql = 'SELECT rowid'; $sql.= ' FROM '.MAIN_DB_PREFIX.'product'; $sql.= ' WHERE entity IN ('.getEntity('product').')'; - $sql.= " AND tva_tx = '".$db->escape($oldvatrate)."'"; + $sql.= " AND tva_tx = '".$db->escape($oldvatrateclean)."'"; + if ($vat_src_code_old) $sql.= " AND default_vat_code = '".$vat_src_code_old."'"; + else " AND default_vat_code = IS NULL"; $resql=$db->query($sql); if ($resql) @@ -109,12 +127,15 @@ if ($action == 'convert') $newminprice=$objectstatic->multiprices_min[$level]; } if ($newminprice > $newprice) $newminprice=$newprice; + $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); $newnpr=$objectstatic->multiprices_recuperableonly[$level]; + $newdefaultvatcode=$vat_src_code_new; $newlevel=$level; //print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
    \n"; - $retm=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvat, $newminprice, $newlevel, $newnpr); + $retm=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatratclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode); if ($retm < 0) { $error++; @@ -138,19 +159,21 @@ if ($action == 'convert') } if ($newminprice > $newprice) $newminprice=$newprice; $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); $newnpr=$objectstatic->recuperableonly; + $newdefaultvatcode=$vat_src_code_new; $newlevel=0; if (! empty($price_base_type) && ! $updatelevel1) { //print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
    \n"; - $ret=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvat, $newminprice, $newlevel, $newnpr); + $ret=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatrateclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode); } if ($ret < 0 || $retm < 0) $error++; else $nbrecordsmodified++; } unset($objectstatic); - + $i++; } } @@ -164,6 +187,8 @@ if ($action == 'convert') $sql.= ' FROM '.MAIN_DB_PREFIX.'product_fournisseur_price as pfp, '.MAIN_DB_PREFIX.'societe as s'; $sql.= ' WHERE pfp.fk_soc = s.rowid AND pfp.entity IN ('.getEntity('product').')'; $sql.= " AND tva_tx = '".$db->escape($oldvatrate)."'"; + if ($vat_src_code_old) $sql.= " AND default_vat_code = '".$vat_src_code_old."'"; + else " AND default_vat_code = IS NULL"; $sql.= " AND s.fk_pays = '".$country_id."'"; //print $sql; $resql=$db->query($sql); @@ -196,26 +221,33 @@ if ($action == 'convert') //} //if ($newminprice > $newprice) $newminprice=$newprice; $newvat=str_replace('*','',$newvatrate); + $localtaxes_type=getLocalTaxesFromRate($newvat, 0, $mysoc, $mysoc); //$newnpr=$objectstatic2->recuperableonly; + $newnpr=0; + $newdefaultvatcode=$vat_src_code_new; + + $newpercent = $objectstatic2->fourn_remise_percent; + $newdeliverydelay = $objectstatic2->delivery_time_days; + $newsupplierreputation = $objectstatic2->supplier_reputation; + $newlevel=0; if (! empty($price_base_type) && ! $updatelevel1) { //print "$objectstatic2->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
    \n"; $fourn->id=$obj->fk_soc; - $ret=$objectstatic2->update_buyprice($obj->qty, $newprice, $user, $price_base_type, $fourn, $obj->fk_availability, $obj->ref_fourn, $newvat); + $ret=$objectstatic2->update_buyprice($obj->qty, $newprice, $user, $price_base_type, $fourn, $obj->fk_availability, $obj->ref_fourn, $newvat, '', $newpercent, 0, $newnpr, $newdeliverydelay, $newsupplierreputation, $localtaxes_type, $newdefaultvatcode); } if ($ret < 0 || $retm < 0) $error++; else $nbrecordsmodified++; } unset($objectstatic2); - + $i++; } } else dol_print_error($db); - if (! $error) { $db->commit(); @@ -274,24 +306,24 @@ else print ''.$langs->trans("Value").''."\n"; print ''."\n"; - + print ''."\n"; print ''.$langs->trans("OldVATRates").''."\n"; print ''."\n"; - print $form->load_tva('oldvatrate', $oldvatrate, $mysoc); + print $form->load_tva('oldvatrate', $oldvatrate, $mysoc, null, 0, 0, '', false, 1); print ''."\n"; print ''."\n"; - + print ''."\n"; print ''.$langs->trans("NewVATRates").''."\n"; print ''."\n"; - print $form->load_tva('newvatrate', $newvatrate, $mysoc); + print $form->load_tva('newvatrate', $newvatrate, $mysoc, null, 0, 0, '', false, 1); print ''."\n"; print ''."\n"; /* - + print ''."\n"; print ''.$langs->trans("PriceBaseTypeToChange").''."\n"; print ''."\n"; @@ -303,7 +335,7 @@ else print ''; print '
    '; - + // Boutons actions print '
    '; print ''; diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 54afc80691f..f5e6c906e7d 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -281,9 +281,9 @@ if (empty($reshook)) $object->barcode_type_coder = $stdobject->barcode_type_coder; $object->barcode_type_label = $stdobject->barcode_type_label; - $object->description = dol_htmlcleanlastbr(GETPOST('desc')); + $object->description = dol_htmlcleanlastbr(GETPOST('desc','none')); $object->url = GETPOST('url'); - $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private')); + $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private','none')); $object->note = $object->note_private; // deprecated $object->customcode = GETPOST('customcode'); $object->country_id = GETPOST('country_id'); @@ -340,7 +340,7 @@ if (empty($reshook)) if ($id > 0) { // Category association - $categories = GETPOST('categories'); + $categories = GETPOST('categories', 'array'); $object->setCategories($categories); header("Location: ".$_SERVER['PHP_SELF']."?id=".$id); @@ -370,11 +370,11 @@ if (empty($reshook)) $object->ref = $ref; $object->label = GETPOST('label'); - $object->description = dol_htmlcleanlastbr(GETPOST('desc')); + $object->description = dol_htmlcleanlastbr(GETPOST('desc','none')); $object->url = GETPOST('url'); if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) { - $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private')); + $object->note_private = dol_htmlcleanlastbr(GETPOST('note_private','none')); $object->note = $object->note_private; } $object->customcode = GETPOST('customcode'); @@ -444,7 +444,7 @@ if (empty($reshook)) if ($object->update($object->id, $user) > 0) { // Category association - $categories = GETPOST('categories'); + $categories = GETPOST('categories', 'array'); $object->setCategories($categories); $action = 'view'; @@ -977,7 +977,7 @@ else // Description (used in invoice, propal...) print ''.$langs->trans("Description").''; - $doleditor = new DolEditor('desc', GETPOST('desc'), '', 160, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_4, '90%'); + $doleditor = new DolEditor('desc', GETPOST('desc','none'), '', 160, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_4, '90%'); $doleditor->Create(); print ""; @@ -1092,7 +1092,7 @@ else print ''.$langs->trans("NoteNotVisibleOnBill").''; // We use dolibarr_details as type of DolEditor here, because we must not accept images as description is included into PDF and not accepted by TCPDF. - $doleditor = new DolEditor('note_private', GETPOST('note_private'), '', 140, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_8, '90%'); + $doleditor = new DolEditor('note_private', GETPOST('note_private','none'), '', 140, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_8, '90%'); $doleditor->Create(); print ""; diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index 1c4c3249791..8d4ddc4705d 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -219,10 +219,9 @@ class FormProduct include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname, $events); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } - $out.=''; if ($empty) $out.=''; foreach($this->cache_warehouses as $id => $arraytypes) { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index d3347557332..0dd16fd99dc 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1532,6 +1532,7 @@ class Product extends CommonObject $obj->price = $price_result; } } + $this->product_fourn_price_id = $obj->rowid; $this->buyprice = $obj->price; // deprecated $this->fourn_pu = $obj->price / $obj->quantity; // Unit price of product of supplier $this->fourn_price_base_type = 'HT'; // Price base type @@ -1577,6 +1578,7 @@ class Product extends CommonObject $obj->price = $price_result; } } + $this->product_fourn_price_id = $obj->rowid; $this->buyprice = $obj->price; // deprecated $this->fourn_qty = $obj->quantity; // min quantity for price for a virtual supplier $this->fourn_pu = $obj->price / $obj->quantity; // Unit price of product for a virtual supplier @@ -2133,6 +2135,49 @@ class Product extends CommonObject } + /** + * Charge tableau des stats propale pour le produit/service + * + * @param int $socid Id thirdparty + * @return array Tableau des stats + */ + function load_stats_proposal_supplier($socid=0) + { + global $conf; + global $user; + + $sql = "SELECT COUNT(DISTINCT p.fk_soc) as nb_suppliers, COUNT(DISTINCT p.rowid) as nb,"; + $sql.= " COUNT(pd.rowid) as nb_rows, SUM(pd.qty) as qty"; + $sql.= " FROM ".MAIN_DB_PREFIX."supplier_proposaldet as pd"; + $sql.= ", ".MAIN_DB_PREFIX."supplier_proposal as p"; + $sql.= ", ".MAIN_DB_PREFIX."societe as s"; + if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE p.rowid = pd.fk_supplier_proposal"; + $sql.= " AND p.fk_soc = s.rowid"; + $sql.= " AND p.entity IN (".getEntity('supplier_proposal').")"; + $sql.= " AND pd.fk_product = ".$this->id; + if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND p.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; + //$sql.= " AND pr.fk_statut != 0"; + if ($socid > 0) $sql.= " AND p.fk_soc = ".$socid; + + $result = $this->db->query($sql); + if ( $result ) + { + $obj=$this->db->fetch_object($result); + $this->stats_proposal_supplier['suppliers']=$obj->nb_suppliers; + $this->stats_proposal_supplier['nb']=$obj->nb; + $this->stats_proposal_supplier['rows']=$obj->nb_rows; + $this->stats_proposal_supplier['qty']=$obj->qty?$obj->qty:0; + return 1; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + /** * Charge tableau des stats commande client pour le produit/service * diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php index 3b83ae6b858..5b41cb0f02b 100644 --- a/htdocs/product/class/productcustomerprice.class.php +++ b/htdocs/product/class/productcustomerprice.class.php @@ -329,6 +329,8 @@ class Productcustomerprice extends CommonObject $sql .= " t.recuperableonly,"; $sql .= " t.localtax1_tx,"; $sql .= " t.localtax2_tx,"; + $sql .= " t.localtax1_type,"; + $sql .= " t.localtax2_type,"; $sql .= " t.fk_user,"; $sql .= " t.import_key,"; $sql .= " soc.nom as socname,"; @@ -386,6 +388,8 @@ class Productcustomerprice extends CommonObject $line->recuperableonly = $obj->recuperableonly; $line->localtax1_tx = $obj->localtax1_tx; $line->localtax2_tx = $obj->localtax2_tx; + $line->localtax1_type = $obj->localtax1_type; + $line->localtax2_type = $obj->localtax2_type; $line->fk_user = $obj->fk_user; $line->import_key = $obj->import_key; $line->socname = $obj->socname; diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index dada74a2c59..a4012b7d3c4 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -208,7 +208,7 @@ if ($id > 0 || ! empty($ref)) $shownav = 1; if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0; - dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', '', '', '', 0, '', '', 1); + dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', '', '', '', 0, '', '', 0); if ($object->type!=Product::TYPE_SERVICE || empty($conf->global->PRODUIT_MULTIPRICES)) { diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index ed53163615d..cb295012795 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -472,7 +472,9 @@ if ($id > 0 || $ref) $default_vat=$object->tva_tx; } } - print ''; + $vattosuggest=(GETPOST("tva_tx")?vatrate(GETPOST("tva_tx")):($default_vat!=''?vatrate($default_vat):'')); + $vattosuggest=preg_replace('/\s*\(.*\)$/','', $vattosuggest); + print ''; print ''; if (! empty($conf->dynamicprices->enabled)) //Only show price mode and expression selector if module is enabled diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index c5eca27b348..dae399a9907 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -1,6 +1,5 @@ - * Copyright (C) ---Put here your own copyright and developer email--- * * 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 @@ -17,43 +16,14 @@ */ /** - * \file product/inventory/card.php + * \file htdocs/product/inventory/card.php * \ingroup inventory - * \brief This file is an example of a php page - * Put here some comments + * \brief Inventory card */ -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) - -// Load Dolibarr environment -$res=0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"); -// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME -$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1; -while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; } -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php"); -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php"); -// Try main.inc.php using relative path -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php"); -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php"); -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php"); -if (! $res) die("Include of main fails"); - -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); -dol_include_once('/inventory/class/inventory.class.php'); +require '../../main.inc.php'; +include_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; // Load traductions files requiredby by page $langs->loadLangs(array("inventory","other")); @@ -572,7 +542,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formmail->withdeliveryreceipt = 1; $formmail->withcancel = 1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit ['__ORDERREF__'] = $object->ref; $custcontact = ''; diff --git a/htdocs/product/inventory/list.php b/htdocs/product/inventory/list.php index 6f443324f6b..4861fe83ff6 100644 --- a/htdocs/product/inventory/list.php +++ b/htdocs/product/inventory/list.php @@ -1,6 +1,5 @@ - * Copyright (C) ---Put here your own copyright and developer email--- * * 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 @@ -17,45 +16,16 @@ */ /** - * \file product/inventory/list.php + * \file htdocs/product/inventory/list.php * \ingroup inventory - * \brief List page for monmodule + * \brief List page for inventory */ -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session) - - -// Load Dolibarr environment -$res=0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"); -// Try main.inc.php into web root detected using web root caluclated from SCRIPT_FILENAME -$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1; -while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; } -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php"); -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php"); -// Try main.inc.php using relative path -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php"); -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php"); -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php"); -if (! $res) die("Include of main fails"); - -require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -dol_include_once('/inventory/class/inventory.class.php'); +require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; // Load traductions files requiredby by page $langs->loadLangs(array("inventory","other")); @@ -130,7 +100,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -177,7 +147,7 @@ if (empty($reshook)) $permtoread = $user->rights->inventory->read; $permtodelete = $user->rights->inventory->delete; $uploaddir = $conf->inventory->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + //include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; // TODO to fix for product module } diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 7d2b1a22b68..71bbee0a016 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -183,7 +183,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } diff --git a/htdocs/product/price.php b/htdocs/product/price.php index b03a8763770..af9fa2a927f 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1,9 +1,9 @@ +/* Copyright (C) 2001-2007 Rodolphe Quiedeville * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005 Eric Seigne - * Copyright (C) 2005-2015 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2014 Florian Henry * Copyright (C) 2014-2016 Juanjo Menent * Copyright (C) 2014-2015 Philippe Grand @@ -107,8 +107,15 @@ if (empty($reshook)) $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' // We must define tva_tx, npr and local taxes + $tva_tx = $tva_tx_txt; $vatratecode = ''; - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -217,8 +224,15 @@ if (empty($reshook)) $tva_tx_txt = $newvattx[$i]; + $tva_tx = $tva_tx_txt; $vatratecode = ''; - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = $newlocaltax1_tx[$i]; $localtax1_type = $newlocaltax1_type[$i]; @@ -266,9 +280,15 @@ if (empty($reshook)) { $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' + $tva_tx = $tva_tx_txt; $vatratecode = ''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -280,7 +300,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -469,11 +489,17 @@ if (empty($reshook)) $prodcustprice->price_min = price2num(GETPOST("price_min"), 'MU'); $prodcustprice->price_base_type = GETPOST("price_base_type", 'alpha'); - $tva_tx_txt = GETPOST("tva_tx"); + $tva_tx_txt = GETPOST("tva_tx",'alpha'); + $tva_tx = $tva_tx_txt; $vatratecode = ''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -485,7 +511,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -565,9 +591,15 @@ if (empty($reshook)) $tva_tx_txt = GETPOST("tva_tx"); - $vatratecode=''; - // We must define tva_tx, npr and local taxes - $tva_tx = preg_replace('/[^0-9\.].*$/', '', $tva_tx_txt); // keep remove all after the numbers and dot + $tva_tx = $tva_tx_txt; + $vatratecode = ''; + if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) + { + $vat_src_code = $reg[1]; + $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx_txt); // Remove code into vatrate. + } + $tva_tx = price2num(preg_replace('/\*/', '', $tva_tx)); // keep remove all after the numbers and dot + $npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0; $localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0'; // If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes @@ -579,7 +611,7 @@ if (empty($reshook)) $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql.= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; $sql.= " WHERE t.fk_pays = c.rowid AND c.code = '".$mysoc->country_code."'"; - $sql.= " AND t.taux = ".((float) $tva_tx)." AND t.active = 1"; + $sql.= " AND t.taux = ".$tva_tx." AND t.active = 1"; $sql.= " AND t.code ='".$vatratecode."'"; $resql=$db->query($sql); if ($resql) @@ -712,17 +744,34 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // TVA - print '' . $langs->trans("VATRate") . '' . vatrate($object->multiprices_tva_tx[$soc->price_level], true) . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; + + $positiverates=''; + if (price2num($object->multiprices_tva_tx[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_tva_tx[$soc->price_level]); + if (price2num($object->multiprices_localtax1_type[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_localtax1_tx[$soc->price_level]); + if (price2num($object->multiprices_localtax2_type[$soc->price_level])) $positiverates.=($positiverates?'/':'').price2num($object->multiprices_localtax2_tx[$soc->price_level]); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + //print vatrate($object->multiprices_tva_tx[$soc->price_level], true); + print ''; } else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true); + else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/ print ''; } @@ -732,19 +781,27 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility { // We show only vat for level 1 - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; print '' . vatrate($object->multiprices_tva_tx[1], true) . ''; print ''; } else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true); + else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/ print ''; } print ''; @@ -888,12 +945,20 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES)) else { // TVA - print '' . $langs->trans("VATRate") . ''; + print '' . $langs->trans("DefaultTaxRate") . ''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + /* if ($object->default_vat_code) { print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')'; } - else print vatrate($object->tva_tx, true, $object->tva_npr, true); + else print vatrate($object->tva_tx, true, $object->tva_npr, true);*/ print ''; // Price @@ -1058,7 +1123,7 @@ if ($action == 'edit_vat' && ($user->rights->produit->creer || $user->rights->se print ''; // VAT - print ''; @@ -1092,7 +1157,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) print '
    ' . $langs->trans("VATRate") . ''; + print '
    ' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
    '; // VAT - print ''; @@ -1171,7 +1236,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) } print ''; print ''; - + $parameters=array('colspan' => 2); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook @@ -1233,7 +1298,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) print ''; - if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) print ''; + if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) print ''; else print ''; print ''; @@ -1317,7 +1382,7 @@ if ($action == 'edit_price' && $object->getRights()->creer) if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_price') && ! in_array($action, array('edit_price','edit_vat'))) { - $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.recuperableonly,"; + $sql = "SELECT p.rowid, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.recuperableonly, p.localtax1_tx, p.localtax1_type, p.localtax2_tx, p.localtax2_type,"; $sql .= " p.price_level, p.price_min, p.price_min_ttc,p.price_by_qty,"; $sql .= " p.date_price as dp, p.fk_price_expression, u.rowid as user_id, u.login"; $sql .= " FROM " . MAIN_DB_PREFIX . "product_price as p,"; @@ -1374,7 +1439,7 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_ print ''; print $conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL; - if (empty($conf->global->PRODUIT_MULTIPRICES)) print ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) print ''; print ''; print ''; if (! empty($conf->dynamicprices->enabled)) { @@ -1413,11 +1478,19 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action=='showlog_default_ if (empty($conf->global->PRODUIT_MULTIPRICES)) { print '"; } @@ -1493,10 +1566,8 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); - $page = GETPOST("page", 'int'); - if ($page == - 1) { - $page = 0; - } + $page = (GETPOST("page",'int')?GETPOST("page", 'int'):0); + if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -1535,7 +1606,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; // VAT - print ''; @@ -1624,7 +1695,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; // VAT - print ''; @@ -1728,7 +1799,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; @@ -1772,7 +1843,17 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ""; print ""; print '"; - print '"; + print '"; print '"; print '"; @@ -1839,7 +1920,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; @@ -1876,8 +1957,16 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '"; print '"; print '"; @@ -1942,7 +2031,16 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ""; print '"; - print '"; + print '"; print '"; print '"; diff --git a/htdocs/product/stats/commande.php b/htdocs/product/stats/commande.php index 5a371554058..4eb8992d837 100644 --- a/htdocs/product/stats/commande.php +++ b/htdocs/product/stats/commande.php @@ -228,7 +228,7 @@ if ($id > 0 || ! empty($ref)) print ''; print "\n"; print '"; + print dol_print_date($db->jdate($objp->date_commande), 'dayhour').""; print '\n"; print '\n"; print ''; diff --git a/htdocs/product/stats/commande_fournisseur.php b/htdocs/product/stats/commande_fournisseur.php index daf2a9c3654..17d4bb5f962 100644 --- a/htdocs/product/stats/commande_fournisseur.php +++ b/htdocs/product/stats/commande_fournisseur.php @@ -51,13 +51,13 @@ $hookmanager->initHooks(array ( $mesg = ''; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { - $page = 0; -} -$offset = $conf->liste_limit * $page; +// Load variable for pagination +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) @@ -236,7 +236,7 @@ if ($id > 0 || ! empty($ref)) { print ''; print "\n"; print '"; + print dol_print_date($db->jdate($objp->date_commande), 'dayhour') . ""; print '\n"; print '\n"; print ''; diff --git a/htdocs/product/stats/contrat.php b/htdocs/product/stats/contrat.php index f9eed565903..8780a8a6a3b 100644 --- a/htdocs/product/stats/contrat.php +++ b/htdocs/product/stats/contrat.php @@ -190,7 +190,7 @@ if ($id > 0 || ! empty($ref)) print ''; print "\n"; print ""; + print dol_print_date($db->jdate($objp->date_contrat), 'dayhour').""; //print "\n"; //print ''; diff --git a/htdocs/product/stats/facture.php b/htdocs/product/stats/facture.php index 8cdc0efd5c0..36359d1bd35 100644 --- a/htdocs/product/stats/facture.php +++ b/htdocs/product/stats/facture.php @@ -251,7 +251,7 @@ if ($id > 0 || ! empty($ref)) print ''; print "\n"; print '"; + print dol_print_date($db->jdate($objp->datef),'dayhour').""; print '\n"; print '\n"; print ''; diff --git a/htdocs/product/stats/facture_fournisseur.php b/htdocs/product/stats/facture_fournisseur.php index 586741496c2..6618d8deac8 100644 --- a/htdocs/product/stats/facture_fournisseur.php +++ b/htdocs/product/stats/facture_fournisseur.php @@ -229,7 +229,7 @@ if ($id > 0 || ! empty($ref)) print ''; print "\n"; print '"; + print dol_print_date($db->jdate($objp->datef), 'dayhour') . ""; print '\n"; print '\n"; print ''; diff --git a/htdocs/product/stats/propal.php b/htdocs/product/stats/propal.php index a5801c422e0..aa2c9a8e603 100644 --- a/htdocs/product/stats/propal.php +++ b/htdocs/product/stats/propal.php @@ -48,11 +48,13 @@ $hookmanager->initHooks(array ('productstatspropal')); $mesg = ''; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); -$page = GETPOST("page", 'int'); -if ($page == - 1) { $page = 0;} -$offset = $conf->liste_limit * $page; +// Load variable for pagination +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder = "DESC"; @@ -230,7 +232,7 @@ if ($id > 0 || ! empty($ref)) $societestatic->fetch($objp->socid); print ''; print '"; + print dol_print_date($db->jdate($objp->datep), 'dayhour') . ""; print "\n"; print '' . "\n"; print ''; diff --git a/htdocs/product/stats/supplier_proposal.php b/htdocs/product/stats/supplier_proposal.php new file mode 100644 index 00000000000..9406ade286f --- /dev/null +++ b/htdocs/product/stats/supplier_proposal.php @@ -0,0 +1,268 @@ + + * Copyright (C) 2004-2009 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2014 Florian Henry + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/product/stats/supplier_proposal.php + * \ingroup product service propal + * \brief Page des stats des propals pour un produit + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/supplier_proposal/class/supplier_proposal.class.php'; +require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; + +$langs->load("products"); +$langs->load("companies"); + +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); + +// Security check +$fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); +$fieldtype = (! empty($ref) ? 'ref' : 'rowid'); +$socid=''; +if (! empty($user->societe_id)) $socid=$user->societe_id; +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array ('productstatspropal')); + +$mesg = ''; + +// Load variable for pagination +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (! $sortorder) $sortorder = "DESC"; +if (! $sortfield) $sortfield = "p.date_valid"; + +$search_month = GETPOST('search_month', 'aplha'); +$search_year = GETPOST('search_year', 'int'); + +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter','alpha')) { + $search_month = ''; + $search_year = ''; +} + +/* + * View + */ + +$propalstatic = new SupplierProposal($db); +$societestatic=new Societe($db); + +$form = new Form($db); +$formother = new FormOther($db); + +if ($id > 0 || ! empty($ref)) +{ + $product = new Product($db); + $result = $product->fetch($id, $ref); + + $object = $product; + + $parameters = array ('id' => $id); + $reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + + llxHeader("", "", $langs->trans("CardProduct" . $product->type)); + + if ($result > 0) + { + $head = product_prepare_head($product); + $titre = $langs->trans("CardProduct" . $product->type); + $picto = ($product->type == Product::TYPE_SERVICE ? 'service' : 'product'); + dol_fiche_head($head, 'referers', $titre, -1, $picto); + + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $product, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + + $linkback = ''.$langs->trans("BackToList").''; + + $shownav = 1; + if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0; + + dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref'); + + print '
    '; + + print '
    '; + print '
    ' . $langs->trans("VATRate") . ''; + print '
    ' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
    '.$langs->trans("PriceLevel").''.$langs->trans("VATRate").''.$langs->trans("DefaultTaxRate").''.$langs->trans("SellingPrice").'' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . ''; + + $positiverates=''; + if (price2num($objp->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($objp->tva_tx); + if (price2num($objp->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax1_tx); + if (price2num($objp->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($objp->default_vat_code?' ('.$objp->default_vat_code.')':''), '%', $objp->tva_npr); + /* if ($objp->default_vat_code) { print vatrate($objp->tva_tx, true) . ' ('.$objp->default_vat_code.')'; } - else print vatrate($objp->tva_tx, true, $objp->recuperableonly); + else print vatrate($objp->tva_tx, true, $objp->recuperableonly);*/ print "
    ' . $langs->trans("VATRate") . ''; + print '
    ' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $object->default_vat_code ? $object->tva_tx.' ('.$object->default_vat_code.')' : $object->tva_tx, $mysoc, '', $object->id, $object->tva_npr, $object->type, false, 1); print '
    ' . $langs->trans("VATRate") . ''; + print '
    ' . $langs->trans("DefaultTaxRate") . ''; print $form->load_tva("tva_tx", $prodcustprice->default_vat_code ? $prodcustprice->tva_tx.' ('.$prodcustprice->default_vat_code.')' : $prodcustprice->tva_tx, $mysoc, '', $object->id, $prodcustprice->recuperableonly, $object->type, false, 1); print '
    ' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '" . $staticsoc->getNomUrl(1) . "" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "' . vatrate($tva_tx, true, $line->recuperableonly) . "'; +var_dump($prodcustprice);exit; + $positiverates=''; + if (price2num($objp->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($objp->tva_tx); + if (price2num($objp->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax1_tx); + if (price2num($objp->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($objp->default_vat_code?' ('.$objp->default_vat_code.')':''), '%', $objp->tva_npr); + + //. vatrate($tva_tx, true, $line->recuperableonly) . + print "' . price($line->price) . "' . price($line->price_ttc) . "' . $langs->trans("ThirdParty") . '' . $langs->trans("AppliedPricesFrom") . '' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("DefaultTaxRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '' . $langs->trans($object->price_base_type) . "'; - print vatrate($object->tva_tx, true, $object->recuperableonly); - print $object->default_vat_code?' ('.$object->default_vat_code.')':''; + + $positiverates=''; + if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx); + if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx); + if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr); + + //print vatrate($object->tva_tx, true, $object->tva_npr); + //print $object->default_vat_code?' ('.$object->default_vat_code.')':''; print "' . price($object->price) . "" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "' . vatrate($tva_tx, true, $line->recuperableonly) . "'; + + $positiverates=''; + if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); + if (price2num($line->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); + if (price2num($line->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); + if (empty($positiverates)) $positiverates='0'; + echo vatrate($positiverates.($line->default_vat_code?' ('.$line->default_vat_code.')':''), '%', $line->tva_npr); + + print "' . price($line->price) . "' . price($line->price_ttc) . "'.$societestatic->getNomUrl(1).'".$objp->code_client."'; - print dol_print_date($db->jdate($objp->date_commande))."'.$objp->qty."'.price($objp->total_ht)."'.$orderstatic->LibStatut($objp->statut,$objp->facture,5).'' . $societestatic->getNomUrl(1) . '" . $objp->code_client . "'; - print dol_print_date($db->jdate($objp->date_commande)) . "' . $objp->qty . "' . price($objp->total_ht) . "' . $supplierorderstatic->getLibStatut(4) . ''.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($objp->name,44).'".$objp->code_client.""; - print dol_print_date($db->jdate($objp->date_contrat))."".price($objp->total_ht)."'; print ''.($objp->nb_initial>0?$objp->nb_initial:'').''.$societestatic->getNomUrl(1).'".$objp->code_client."'; - print dol_print_date($db->jdate($objp->datef),'day')."'.$objp->qty."'.price($objp->total_ht)."'.$invoicestatic->LibStatut($objp->paye,$objp->statut,5,$paiement,$objp->type).'' . $societestatic->getNomUrl(1) . '" . $objp->code_client . "'; - print dol_print_date($db->jdate($objp->datef)) . "' . $objp->qty . "' . price($objp->total_ht) . "' . $supplierinvoicestatic->LibStatut($objp->paye, $objp->statut, 5) . ''.$societestatic->getNomUrl(1).''; - print dol_print_date($db->jdate($objp->datep)) . "" . $objp->qty . "' . price($objp->amount) . '' . $propalstatic->LibStatut($objp->statut, 5) . '
    '; + + show_stats_for_company($product, $socid); + + print "
    "; + + print '
    '; + print '
    '; + + dol_fiche_end(); + + + if ($user->rights->propale->lire) + { + $sql = "SELECT DISTINCT s.nom as name, s.rowid as socid, p.rowid as propalid, p.ref, d.total_ht as amount,"; + //$sql .= " p.ref_supplier,"; + $sql .= "p.date_valid, p.fk_statut as statut, d.rowid, d.qty"; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= ", sc.fk_soc, sc.fk_user "; + $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s"; + $sql .= "," . MAIN_DB_PREFIX . "supplier_proposal as p"; + $sql .= ", " . MAIN_DB_PREFIX . "supplier_proposaldet as d"; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc"; + $sql .= " WHERE p.fk_soc = s.rowid"; + $sql .= " AND p.entity IN (".getEntity('propal').")"; + $sql .= " AND d.fk_supplier_proposal = p.rowid"; + $sql .= " AND d.fk_product =" . $product->id; + if (! empty($search_month)) + $sql .= ' AND MONTH(p.datep) IN (' . $search_month . ')'; + if (! empty($search_year)) + $sql .= ' AND YEAR(p.datep) IN (' . $search_year . ')'; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . $user->id; + if ($socid) + $sql .= " AND p.fk_soc = " . $socid; + $sql .= " ORDER BY $sortfield $sortorder "; + + // Calcul total qty and amount for global if full scan list + $total_ht = 0; + $total_qty = 0; + $totalrecords = 0; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $result = $db->query($sql); + if ($result) { + $totalrecords = $db->num_rows($result); + while ( $objp = $db->fetch_object($result) ) { + $total_ht += $objp->amount; + $total_qty += $objp->qty; + } + } + } + + $sql .= $db->plimit($conf->liste_limit + 1, $offset); + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + + if (! empty($id)) + $option .= '&id=' . $product->id; + if (! empty($search_month)) + $option .= '&search_month=' . $search_month; + if (! empty($search_year)) + $option .= '&search_year=' . $search_year; + + print '
    ' . "\n"; + if (! empty($sortfield)) + print ''; + if (! empty($sortorder)) + print ''; + if (! empty($page)) { + print ''; + $option .= '&page=' . $page; + } + + print_barre_liste($langs->trans("Proposals"), $page, $_SERVER["PHP_SELF"], "&id=$product->id", $sortfield, $sortorder, '', $num, $totalrecords, ''); + print '
    '; + print '
    '; + print $langs->trans('Period') . ' (' . $langs->trans("DatePropal") . ') - '; + print $langs->trans('Month') . ': '; + print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print '
    '; + print ''; + print ''; + print '
    '; + print '
    '; + print '
    '; + + $i = 0; + print '
    '; + print ''; + print ''; + print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "p.rowid", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre("Company", $_SERVER["PHP_SELF"], "s.nom", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre("DatePropal", $_SERVER["PHP_SELF"], "p.date_valid", "", $option, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre("Qty", $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "p.total", "", $option, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "p.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder); + print "\n"; + + if ($num > 0) + { + $var = True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + $var = ! $var; + + print ''; + print '\n"; + $societestatic->fetch($objp->socid); + print ''; + print '"; + print "\n"; + print '' . "\n"; + print ''; + print "\n"; + $i ++; + + if (! empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $total_ht += $objp->total_ht; + $total_qty += $objp->qty; + } + } + } + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "
    '; + $propalstatic->id=$objp->propalid; + $propalstatic->ref=$objp->ref; + print $propalstatic->getNomUrl(1); + print "'.$societestatic->getNomUrl(1).''; + print dol_print_date($db->jdate($objp->date_valid), 'dayhour') . "" . $objp->qty . "' . price($objp->amount) . '' . $propalstatic->LibStatut($objp->statut, 5) . '
    ' . $langs->trans('Total') . '' . $total_qty . '' . price($total_ht) . '
    "; + print '
    '; + print '
    '; + } else { + dol_print_error($db); + } + $db->free($result); + } + } +} else { + dol_print_error(); +} + +llxFooter(); +$db->close(); diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 2ddc9f29464..2c889d589df 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -96,6 +96,7 @@ class MouvementStock extends CommonObject require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php'; + $langs->load("errors"); $error = 0; dol_syslog(get_class($this)."::_create start userid=$user->id, fk_product=$fk_product, warehouse_id=$entrepot_id, qty=$qty, type=$type, price=$price, label=$label, inventorycode=$inventorycode, datem=".$datem.", eatby=".$eatby.", sellby=".$sellby.", batch=".$batch.", skip_batch=".$skip_batch); @@ -141,7 +142,7 @@ class MouvementStock extends CommonObject { if (empty($batch)) { - $this->errors[]=$langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->name); + $this->errors[]=$langs->trans("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->ref); dol_syslog("Try to make a movement of a product with status_batch on without any batch data"); $this->db->rollback(); diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 567d60911ae..6c282f12101 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -114,7 +114,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 55fe5908c7f..2811ccce891 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -357,17 +357,17 @@ if ($usevirtualstock) if ($salert == 'on') // Option to see when stock is lower than alert { - $sql.= ' AND ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')'; + $sql.= ' AND ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')'; $sql.= ' - ('.$sqlCommandesCli.' - '.$sqlExpeditionsCli.') + ('.$sqlCommandesFourn.' - '.$sqlReceptionFourn.')))'; $alertchecked = 'checked'; } } else { - $sql.= ' HAVING (('.$sqldesiredtock.' > 0 AND ('.$sqldesiredtock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; - $sql.= ' OR ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").'))))'; + $sql.= ' HAVING (('.$sqldesiredtock.' >= 0 AND ('.$sqldesiredtock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; + $sql.= ' OR ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").'))))'; if ($salert == 'on') // Option to see when stock is lower than alert { - $sql.= ' AND ('.$sqlalertstock.' > 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; + $sql.= ' AND ('.$sqlalertstock.' >= 0 AND ('.$sqlalertstock.' > SUM('.$db->ifsql("s.reel IS NULL", "0", "s.reel").')))'; $alertchecked = 'checked'; } } diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index 004662972c4..791da80c05d 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -205,7 +205,7 @@ $linkback = ''.$langs->trans("BackTo $shownav = 1; if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0; -dol_banner_tab($object, 'ref', $linkback, shownav, 'ref'); +dol_banner_tab($object, 'ref', $linkback, shownav, 'ref', '', '', '', 0, '', '', 1); dol_fiche_end(); diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 4dff34ad30b..c9c577742e6 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; $langs->load('projects'); $langs->load('users'); @@ -84,7 +85,7 @@ if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) $usertoprocess=$user; $search_usertoprocessid=$usertoprocess->id; } -elseif (search_usertoprocessid > 0) +elseif ($search_usertoprocessid > 0) { $usertoprocess=new User($db); $usertoprocess->fetch($search_usertoprocessid); @@ -332,8 +333,7 @@ $tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($proj //var_dump($projectsrole); //var_dump($taskrole); - -llxHeader("",$title,""); +llxHeader("",$title,"",'','','',array('/core/js/timesheet.js')); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project'); @@ -485,10 +485,27 @@ print "\n"; // By default, we can edit only tasks we are assigned to $restrictviewformytask=(empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED)?1:0); +// Get if user is available or not for each day +$holiday = new Holiday($db); +$isavailable=array(); + +$isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $daytoparse); // $daytoparse is a date with hours = 0 +$isavailable[$daytoparse]=$isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day + if (count($tasksarray) > 0) { $j=0; - projectLinesPerDay($j, 0, $usertoprocess, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $daytoparse); + projectLinesPerDay($j, 0, $usertoprocess, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $daytoparse, $isavailable); + + $colspan = 8; + if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) $colspan++; + + print ' + '.$langs->trans("Total").' +
     
    + + + '; } else { @@ -497,16 +514,20 @@ else print ""; print ''; +print ''."\n"; + print '
    '; print ''; print '
    '; print ''; +$modeinput='hours'; print ''; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 6ea60f3d76f..b808017123d 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; $langs->load('projects'); $langs->load('users'); @@ -97,7 +98,7 @@ if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) $usertoprocess=$user; $search_usertoprocessid=$usertoprocess->id; } -elseif (search_usertoprocessid > 0) +elseif ($search_usertoprocessid > 0) { $usertoprocess=new User($db); $usertoprocess->fetch($search_usertoprocessid); @@ -474,9 +475,25 @@ print ''.$langs->trans("TimeSpent").'' $startday=dol_mktime(12, 0, 0, $startdayarray['first_month'], $startdayarray['first_day'], $startdayarray['first_year']); -for($i=0;$i<7;$i++) +// Get if user is available or not for each day +$holiday = new Holiday($db); +$isavailable=array(); + +for ($i=0;$i<7;$i++) { - print ''.dol_print_date($startday + ($i * 3600 * 24), '%a').'
    '.dol_print_date($startday + ($i * 3600 * 24), 'dayreduceformat').''; + $dayinloopfromfirstdaytoshow = dol_time_plus_duree($firstdaytoshow, $i, 'd'); // $firstdaytoshow is a date with hours = 0 + $dayinloop = dol_time_plus_duree($startday, $i, 'd'); + + // Useless because $dayinloopwithouthours should be same than $dayinloopfromfirstdaytoshow + //$tmparray = dol_getdate($dayinloop); + //$dayinloopwithouthours=dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); + //print dol_print_date($dayinloop, 'dayhour').' '; + //print dol_print_date($dayinloopwithouthours, 'dayhour').' '; + //print dol_print_date($dayinloopfromfirstdaytoshow, 'dayhour').'
    '; + + $isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $dayinloopfromfirstdaytoshow); + $isavailable[$dayinloopfromfirstdaytoshow]=$isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day + print ''.dol_print_date($dayinloopfromfirstdaytoshow, '%a').'
    '.dol_print_date($dayinloopfromfirstdaytoshow, 'dayreduceformat').''; } print ''; print "\n"; @@ -491,7 +508,7 @@ if (count($tasksarray) > 0) $j=0; $level=0; - projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask); + projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $isavailable); $colspan=7; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) $colspan++; @@ -515,7 +532,6 @@ else print ""; print ''; -print ''."\n"; print ''."\n"; print '
    '; diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 085af055f38..1146ba49b80 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -187,7 +187,7 @@ if (empty($reshook)) if (! $error && !empty($object->id) > 0) { // Category association - $categories = GETPOST('categories'); + $categories = GETPOST('categories', 'array'); $result=$object->setCategories($categories); if ($result<0) { $langs->load("errors"); @@ -282,7 +282,7 @@ if (empty($reshook)) else setEventMessages($object->error, $object->errors, 'errors'); }else { // Category association - $categories = GETPOST('categories'); + $categories = GETPOST('categories', 'array'); $result=$object->setCategories($categories); if ($result < 0) { @@ -528,7 +528,7 @@ if ($action == 'create' && $user->rights->projet->creer) print ''; $filteronlist=''; if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; - $text=$form->select_thirdparty_list(GETPOST('socid','int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), '', 0, 0, 'minwidth300'); + $text=$form->select_company(GETPOST('socid','int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300'); if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) { $texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty"); @@ -747,7 +747,7 @@ elseif ($object->id > 0) print ''; $filteronlist=''; if (! empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) $filteronlist=$conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST; - $text=$form->select_thirdparty_list($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), '', 0, 0, 'minwidth300'); + $text=$form->select_company($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), 0, 'minwidth300'); if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) { $texthelp=$langs->trans("IfNeedToUseOhterObjectKeepEmpty"); diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 10a78e017c8..32ae678b016 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1693,8 +1693,8 @@ class Task extends CommonObject return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref); } - - + + /** * Load indicators for dashboard (this->nbtodo and this->nbtodolate) * @@ -1703,65 +1703,114 @@ class Task extends CommonObject */ function load_board($user) { - global $conf, $langs; - - $mine=0; $socid=$user->societe_id; - - $projectstatic = new Project($this->db); - $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1,$socid); - - // List of tasks (does not care about permissions. Filtering will be done later) - $sql = "SELECT p.rowid as projectid, p.fk_statut as projectstatus,"; - $sql.= " t.rowid as taskid, t.progress as progress, t.fk_statut as status,"; - $sql.= " t.dateo as date_start, t.datee as datee"; - $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; - if (! $user->rights->societe->client->voir && ! $socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid"; - $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; - $sql.= " WHERE p.entity IN (".getEntity('project', 0).')'; - $sql.= " AND p.fk_statut = 1"; - $sql.= " AND t.fk_projet = p.rowid"; - $sql.= " AND t.progress < 100"; // tasks to do - if ($mine || ! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; - // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser - //if ($socid || ! $user->rights->societe->client->voir) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; - if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))"; - //print $sql; - $resql=$this->db->query($sql); - if ($resql) - { - $task_static = new Task($this->db); - - $response = new WorkboardResponse(); - $response->warning_delay = $conf->projet->task->warning_delay/60/60/24; - $response->label = $langs->trans("OpenedTasks"); - if ($user->rights->projet->all->lire) $response->url = DOL_URL_ROOT.'/projet/tasks/list.php?mainmenu=project'; - else $response->url = DOL_URL_ROOT.'/projet/tasks/list.php?mode=mine&mainmenu=project'; - $response->img = img_object('',"task"); - - // This assignment in condition is not a bug. It allows walking the results. - while ($obj=$this->db->fetch_object($resql)) - { - $response->nbtodo++; - - $task_static->projectstatus = $obj->projectstatus; - $task_static->progress = $obj->progress; - $task_static->fk_statut = $obj->status; - $task_static->date_end = $this->db->jdate($obj->datee); - - if ($task_static->hasDelay()) { - $response->nbtodolate++; - } - } - - return $response; - } - else - { - $this->error=$this->db->error(); - return -1; - } + global $conf, $langs; + + $mine=0; $socid=$user->societe_id; + + $projectstatic = new Project($this->db); + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1,$socid); + + // List of tasks (does not care about permissions. Filtering will be done later) + $sql = "SELECT p.rowid as projectid, p.fk_statut as projectstatus,"; + $sql.= " t.rowid as taskid, t.progress as progress, t.fk_statut as status,"; + $sql.= " t.dateo as date_start, t.datee as datee"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; + if (! $user->rights->societe->client->voir && ! $socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid"; + $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; + $sql.= " WHERE p.entity IN (".getEntity('project', 0).')'; + $sql.= " AND p.fk_statut = 1"; + $sql.= " AND t.fk_projet = p.rowid"; + $sql.= " AND t.progress < 100"; // tasks to do + if ($mine || ! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; + // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser + //if ($socid || ! $user->rights->societe->client->voir) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))"; + //print $sql; + $resql=$this->db->query($sql); + if ($resql) + { + $task_static = new Task($this->db); + + $response = new WorkboardResponse(); + $response->warning_delay = $conf->projet->task->warning_delay/60/60/24; + $response->label = $langs->trans("OpenedTasks"); + if ($user->rights->projet->all->lire) $response->url = DOL_URL_ROOT.'/projet/tasks/list.php?mainmenu=project'; + else $response->url = DOL_URL_ROOT.'/projet/tasks/list.php?mode=mine&mainmenu=project'; + $response->img = img_object('',"task"); + + // This assignment in condition is not a bug. It allows walking the results. + while ($obj=$this->db->fetch_object($resql)) + { + $response->nbtodo++; + + $task_static->projectstatus = $obj->projectstatus; + $task_static->progress = $obj->progress; + $task_static->fk_statut = $obj->status; + $task_static->date_end = $this->db->jdate($obj->datee); + + if ($task_static->hasDelay()) { + $response->nbtodolate++; + } + } + + return $response; + } + else + { + $this->error=$this->db->error(); + return -1; + } + } + + + /** + * Charge indicateurs this->nb de tableau de bord + * + * @return int <0 if ko, >0 if ok + */ + function load_state_board() + { + global $user; + + $mine=0; $socid=$user->societe_id; + + $projectstatic = new Project($this->db); + $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1,$socid); + + // List of tasks (does not care about permissions. Filtering will be done later) + $sql = "SELECT count(p.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; + if (! $user->rights->societe->client->voir && ! $socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid"; + $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; + $sql.= " WHERE p.entity IN (".getEntity('project', 0).')'; + $sql.= " AND t.fk_projet = p.rowid"; // tasks to do + if ($mine || ! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; + // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser + //if ($socid || ! $user->rights->societe->client->voir) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))"; + + $resql=$this->db->query($sql); + if ($resql) + { + + // This assignment in condition is not a bug. It allows walking the results. + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["tasks"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } } /** diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index 8777d83e419..fbf9574bd75 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -20,7 +20,7 @@ /** * \file htdocs/projet/document.php * \ingroup project - * \brief Page de gestion des documents attachees a un projet + * \brief Page to managed related documents linked to a project */ require '../main.inc.php'; @@ -106,11 +106,11 @@ if ($object->id > 0) $totalsize+=$file['size']; } - + // Project card - + $linkback = ''.$langs->trans("BackToList").''; - + $morehtmlref='
    '; // Title $morehtmlref.=$object->title; @@ -120,19 +120,19 @@ if ($object->id > 0) $morehtmlref.='
    '.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'project'); } $morehtmlref.='
    '; - + // Define a complementary filter for search of next/prev ref. if (! $user->rights->projet->all->lire) { $objectsListId = $object->getProjectsAuthorizedForUser($user,0,0); $object->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")"; } - + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - + + print '
    '; - print '
    '; + print '
    '; print ''; @@ -141,10 +141,10 @@ if ($object->id > 0) print ''; print "
    '.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
    \n"; - + print '
    '; - + dol_fiche_end(); $modulepart = 'project'; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 1e4d4132944..8dd7f6bbed5 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -643,33 +643,6 @@ foreach ($listofreferent as $key => $value) $total_ttc = -$total_ttc; } - /*switch ($classname) { - case 'FactureFournisseur': - $newclassname = 'SupplierInvoice'; - break; - case 'Facture': - $newclassname = 'Bill'; - break; - case 'Propal': - $newclassname = 'CommercialProposal'; - break; - case 'Commande': - $newclassname = 'Order'; - break; - case 'Expedition': - $newclassname = 'Sending'; - break; - case 'Contrat': - $newclassname = 'Contract'; - break; - case 'MouvementStock': - $newclassname = 'StockMovement'; - break; - default: - $newclassname = $classname; - }*/ - - $var = ! $var; print ''; // Module print ''.$name.''; @@ -693,7 +666,6 @@ print ''; print ""; - print '

    '; print '
    '; @@ -771,7 +743,7 @@ foreach ($listofreferent as $key => $value) print ''; print ''; - // Remove link + // Remove link column print ''; // Ref print ''.$langs->trans("Ref").''; @@ -862,11 +834,15 @@ foreach ($listofreferent as $key => $value) } print ''; + // Remove link print '\n"; @@ -1157,13 +1133,11 @@ foreach ($listofreferent as $key => $value) } // Enhance with select2 -$nodatarole=''; if ($conf->use_javascript_ajax) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox('.elementselect'); $out.=$comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); print $comboenhancement; } diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 657e6d610d3..560853ac1c9 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -137,7 +137,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } diff --git a/htdocs/projet/tasks/comment.php b/htdocs/projet/tasks/comment.php index 3ee3cf2593b..a36337c324d 100644 --- a/htdocs/projet/tasks/comment.php +++ b/htdocs/projet/tasks/comment.php @@ -259,7 +259,7 @@ if ($id > 0 || ! empty($ref)) { print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$_GET["id"].'&withproject='.$withproject,$langs->trans("DeleteATask"),$langs->trans("ConfirmDeleteATask"),"confirm_delete"); } - + if (! GETPOST('withproject') || empty($projectstatic->id)) { $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1); @@ -286,14 +286,14 @@ if ($id > 0 || ! empty($ref)) } dol_banner_tab($task, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); - + print '
    '; print '
    '; print '
    '; if ($tablename != 'projet_task' && $tablename != 'stock_mouvement') { - print '' . img_picto($langs->trans('Unlink'), 'editdelete') . ''; + if (empty($conf->global->PROJECT_DISABLE_UNLINK_FROM_OVERVIEW) || $user->admin) // PROJECT_DISABLE_UNLINK_FROM_OVERVIEW is empty by defaut, so this test true + { + print '' . img_picto($langs->trans('Unlink'), 'editdelete') . ''; + } } print "
    '; - + // Nb comments - print ''; @@ -307,46 +307,46 @@ if ($id > 0 || ! empty($ref)) print ''; dol_fiche_end(); - - + + print '
    '; print '
    '; - + // Add comment - + print '
    '; print ''; print ''; print ''; print ''; - + print '
    '.$langs->trans("TaskNbComments").''; + print ''.$langs->trans("TaskNbComments").''; print $task->getNbComments(); print '
    '; - + print ''; print ''; print ''; print ''; print ''; print "\n"; - + print ''; print ''; - + // Description print ''; - + print ''; print '
    '.$langs->trans("Comments").'
    '; - + $desc = ($_POST['comment_description']?$_POST['comment_description']:''); - + $doleditor = new DolEditor('comment_description', $desc, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '100%'); print $doleditor->Create(1); - + print ''; print ''; print '
    '; - + // List of comments if(!empty($task->comments)) { // Default color for current user @@ -367,7 +367,7 @@ if ($id > 0 || ! empty($ref)) if($comment->fk_user == $user->id) { print '
     
    '; } - + print '
    '; print '
    '; if (! empty($user->photo)) @@ -377,7 +377,7 @@ if ($id > 0 || ! empty($ref)) print $langs->trans('User').' : '.$userstatic->getNomUrl().'
    '; print $langs->trans('Date').' : '.dol_print_date($comment->datec,'dayhoursec'); print '
    '; // End comment-info - + print '
    '; print '
    '; print '
    '; @@ -391,17 +391,17 @@ if ($id > 0 || ! empty($ref)) print '
    '; // End comment-table print '
    '; // End comment-right print '
    '; // End comment - + if($comment->fk_user != $user->id) { print '
     
    '; } print '
    '; print '
    '; // end 100p - + $first = false; } } - + print '
    '; print '
    '; diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php index d4029847534..6cdbc204749 100644 --- a/htdocs/projet/tasks/contact.php +++ b/htdocs/projet/tasks/contact.php @@ -187,7 +187,7 @@ if ($id > 0 || ! empty($ref)) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($projectstatic->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -272,8 +272,11 @@ if ($id > 0 || ! empty($ref)) print '
    '; dol_fiche_end(); + + print '
    '; } + // To verify role of users //$userAccess = $projectstatic->restrictedProjectArea($user); // We allow task affected to user even if a not allowed project //$arrayofuseridoftask=$object->getListContactId('internal'); @@ -394,7 +397,7 @@ if ($id > 0 || ! empty($ref)) print ''; $thirdpartyofproject=$projectstatic->getListContactId('thirdparty'); - $selectedCompany = isset($_GET["newcompany"])?$_GET["newcompany"]:$projectstatic->societe->id; + $selectedCompany = isset($_GET["newcompany"])?$_GET["newcompany"]:$projectstatic->socid; $selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', $thirdpartyofproject, 0, '&withproject='.$withproject); print ''; diff --git a/htdocs/projet/tasks/document.php b/htdocs/projet/tasks/document.php index 649e1efd575..f6f206f90ec 100644 --- a/htdocs/projet/tasks/document.php +++ b/htdocs/projet/tasks/document.php @@ -130,7 +130,8 @@ if ($object->id > 0) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"),0,($projectstatic->public?'projectpub':'project')); + + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); @@ -215,6 +216,8 @@ if ($object->id > 0) print '
    '; dol_fiche_end(); + + print '
    '; } $head = task_prepare_head($object); diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index c730fd074d5..f2da27ea56f 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -127,7 +127,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php index 13a8979ae91..87d949eb645 100644 --- a/htdocs/projet/tasks/note.php +++ b/htdocs/projet/tasks/note.php @@ -110,7 +110,7 @@ if ($object->id > 0) // Tabs for project $tab='tasks'; $head=project_prepare_head($projectstatic); - dol_fiche_head($head, $tab, $langs->trans("Project"), 0, ($projectstatic->public?'projectpub':'project')); + dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public?'projectpub':'project')); $param=($mode=='mine'?'&mode=mine':''); // Project card @@ -194,6 +194,8 @@ if ($object->id > 0) print '
    '; dol_fiche_end(); + + print '
    '; } $head = task_prepare_head($object); diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index 1b43940029f..db56534f851 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -279,6 +279,7 @@ if ($id > 0 || ! empty($ref)) print ''; print ''; + print '
    '; print '
    '; print '
    '; @@ -468,6 +469,7 @@ if ($id > 0 || ! empty($ref)) dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param); print '
    '; + print '
    '; print '
    '; print ''; @@ -490,8 +492,21 @@ if ($id > 0 || ! empty($ref)) } print ''; + // Description + print ''; + + print '
    '.$langs->trans("Description").''; + print nl2br($object->description); + print '
    '; + print '
    '; + + print '
    '; + + print '
    '; + print ''; + // Progress declared - print ''; - - // Description - print ''; // Other attributes @@ -522,6 +532,10 @@ if ($id > 0 || ! empty($ref)) print '
    '.$langs->trans("ProgressDeclared").''; + print '
    '.$langs->trans("ProgressDeclared").''; if ($object->progress != '') { print $object->progress.' %'; @@ -506,12 +521,7 @@ if ($id > 0 || ! empty($ref)) if ($tmparray['total_duration'] > 0 && ! empty($object->planned_workload)) print round($tmparray['total_duration'] / $object->planned_workload * 100, 2).' %'; else print '0 %'; } - else print ''; - print '
    '.$langs->trans("Description").''; - print nl2br($object->description); + else print ''.$langs->trans("WorkloadNotDefined").''; print '
    '; print '
    '; + print '
    '; + + print '
    '; + print '
    '; dol_fiche_end(); } diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 8b85c299fdc..85e05c41f96 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -418,6 +418,10 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print '
    '; } + else + { + print '
    '; + } } } @@ -442,7 +446,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) else $object->next_prev_filter=" fk_projet = ".$projectstatic->id; $morehtmlref=''; - + // Project if (empty($withproject)) { @@ -450,7 +454,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) $morehtmlref.=$langs->trans("Project").': '; $morehtmlref.=$projectstatic->getNomUrl(1); $morehtmlref.='
    '; - + // Third party $morehtmlref.=$langs->trans("ThirdParty").': '; if (is_object($projectstatic->thirdparty)) { @@ -464,7 +468,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print '
    '; print '
    '; - print '
    '; + print '
    '; print ''; // Date start - Date end @@ -491,7 +495,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) print '
    '; // Progress declared - print ''; @@ -503,7 +507,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) if ($tmparray['total_duration'] > 0) print round($tmparray['total_duration']/$object->planned_workload*100, 2).' %'; else print '0 %'; } - else print ''; + else print ''.$langs->trans("WorkloadNotDefined").''; print ''; print '
    '.$langs->trans("ProgressDeclared").''; + print '
    '.$langs->trans("ProgressDeclared").''; print $object->progress.' %'; print '
    '; @@ -618,7 +622,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0) { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } diff --git a/htdocs/public/members/new.php b/htdocs/public/members/new.php index 2869d2254e7..6a5fcbdfc62 100644 --- a/htdocs/public/members/new.php +++ b/htdocs/public/members/new.php @@ -572,7 +572,7 @@ foreach($extrafields->attribute_label as $key=>$value) // Comments print ''; print ''.$langs->trans("Comments").''; -print ''; +print ''; print ''."\n"; // Add specific fields used by Dolibarr foundation for example diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 72ad0390cce..1862a5b8a47 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -66,21 +66,22 @@ $suffix=GETPOST("suffix",'aZ09'); $amount=price2num(GETPOST("amount",'alpha')); if (! GETPOST("currency",'alpha')) $currency=$conf->currency; else $currency=GETPOST("currency",'alpha'); -$source = GETPOST("source",'alpha'); +$source = GETPOST("s",'alpha')?GETPOST("s",'alpha'):GETPOST("source",'alpha'); +$download = GETPOST('d','int')?GETPOST('d','int'):GETPOST('download','int'); if (! $action) { - if (! GETPOST("amount",'alpha') && ! GETPOST("source",'alpha')) + if (! GETPOST("amount",'alpha') && ! $source) { print $langs->trans('ErrorBadParameters')." - amount or source"; exit; } - if (is_numeric($amount) && ! GETPOST("tag",'alpha') && ! GETPOST("source",'alpha')) + if (is_numeric($amount) && ! GETPOST("tag",'alpha') && ! $source) { print $langs->trans('ErrorBadParameters')." - tag or source"; exit; } - if (GETPOST("source",'alpha') && ! GETPOST("ref",'alpha')) + if ($source && ! GETPOST("ref",'alpha')) { print $langs->trans('ErrorBadParameters')." - ref"; exit; @@ -111,7 +112,6 @@ $urlok=$urlwithroot.'/public/payment/paymentok.php?'; $urlko=$urlwithroot.'/public/payment/paymentko.php?'; // Complete urls for post treatment -$SOURCE=GETPOST("source",'alpha'); $ref=$REF=GETPOST('ref','alpha'); $TAG=GETPOST("tag",'alpha'); $FULLTAG=GETPOST("fulltag",'alpha'); // fulltag is tag with more informations @@ -123,10 +123,10 @@ if (! empty($suffix)) $urlok.='suffix='.urlencode($suffix).'&'; $urlko.='suffix='.urlencode($suffix).'&'; } -if (! empty($SOURCE)) +if ($source) { - $urlok.='source='.urlencode($SOURCE).'&'; - $urlko.='source='.urlencode($SOURCE).'&'; + $urlok.='s='.urlencode($source).'&'; + $urlko.='s='.urlencode($source).'&'; } if (! empty($REF)) { @@ -150,8 +150,8 @@ if (! empty($SECUREKEY)) } if (! empty($entity)) { - $urlok.='entity='.urlencode($entity).'&'; - $urlko.='entity='.urlencode($entity).'&'; + $urlok.='e='.urlencode($entity).'&'; + $urlko.='e='.urlencode($entity).'&'; } $urlok=preg_replace('/&$/','',$urlok); // Remove last & $urlko=preg_replace('/&$/','',$urlko); // Remove last & @@ -223,7 +223,7 @@ if (! empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (! empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { - if ($SOURCE && $REF) $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . $SOURCE . $REF, 2); // Use the source in the hash to avoid duplicates if the references are identical + if ($source && $REF) $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . $source . $REF, 2); // Use the source in the hash to avoid duplicates if the references are identical else $token = dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); } else @@ -335,18 +335,23 @@ if ($action == 'dopayment') $origfulltag=GETPOST("fulltag",'alpha'); + // Securekey into back url useless for back url and we need an url lower than 150. + $urlok = preg_replace('/securekey=[^&]+/', '', $urlok); + $urlko = preg_replace('/securekey=[^&]+/', '', $urlko); + $mesg=''; if (empty($PRICE) || ! is_numeric($PRICE)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Amount")); elseif (empty($email)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("YourEMail")); elseif (! isValidEMail($email)) $mesg=$langs->trans("ErrorBadEMail",$email); elseif (! $origfulltag) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("PaymentCode")); - elseif (dol_strlen($urlok) > 150) $mesg='Error urlok too long '.$urlok; - elseif (dol_strlen($urlko) > 150) $mesg='Error urlko too long '.$urlko; + elseif (dol_strlen($urlok) > 150) $mesg='Error urlok too long '.$urlok.'( Paybox requires 150, found '.strlen($urlok).')'; + elseif (dol_strlen($urlko) > 150) $mesg='Error urlko too long '.$urlko.'( Paybox requires 150, found '.strlen($urlok).')'; if (empty($mesg)) { dol_syslog("newpayment.php call paybox api and do redirect", LOG_DEBUG); + include_once DOL_DOCUMENT_ROOT.'/paybox/lib/paybox.lib.php'; print_paybox_redirect($PRICE, $conf->currency, $email, $urlok, $urlko, $FULLTAG); session_destroy(); @@ -499,10 +504,10 @@ $conf->dol_hide_leftmenu=1; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); // Check link validity -if (! empty($SOURCE) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) +if ($source && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) { $langs->load("errors"); - dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $SOURCE, $ref)); + dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref)); llxFooter(); $db->close(); exit; @@ -528,7 +533,7 @@ print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; -print ''; +print ''; print "\n"; print ''."\n"; print ''."\n"; @@ -602,7 +607,7 @@ print $text; // Output payment summary form print ''; print ''; -print ''."\n"; +print ''."\n"; $found=false; $error=0; @@ -709,8 +714,8 @@ if ($source == 'order') $text=''.$langs->trans("PaymentOrderRef",$order->ref).''; print ''."\n"; // Amount @@ -808,7 +813,7 @@ if ($source == 'invoice') print ''."\n"; // Debitor @@ -821,8 +826,8 @@ if ($source == 'invoice') $text=''.$langs->trans("PaymentInvoiceRef",$invoice->ref).''; print ''."\n"; // Amount @@ -846,13 +851,21 @@ if ($source == 'invoice') print ''."\n"; // Tag - print ''."\n"; + // Add download link + if ($download > 0) + { + print ''."\n"; + } + // Shipping address $shipToName=$invoice->thirdparty->name; $shipToStreet=$invoice->thirdparty->address; @@ -996,8 +1009,8 @@ if ($source == 'contractline') print ''."\n"; // Quantity @@ -1138,8 +1151,8 @@ if ($source == 'membersubscription') $text=''.$langs->trans("PaymentSubscription").''; print ''."\n"; if ($member->last_subscription_date || $member->last_subscription_amount) @@ -1264,7 +1277,7 @@ if ($action != 'dopayment') if (! empty($conf->stripe->enabled)) { // If STRIPE_PICTO_FOR_PAYMENT is 'cb' we show a picto of a crdit card instead of stripe - print '
    '; + print '
    '; } if (! empty($conf->paypal->enabled)) @@ -1357,12 +1370,12 @@ if (preg_match('/^dopayment/',$action)) print ''."\n"; print ''."\n"; print ''."\n"; - print ''."\n"; + print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; - print ''; + print ''; print ''."\n"; print ''."\n"; diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index cbea7db650f..bdc301a0dce 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -31,7 +31,7 @@ define("NOCSRFCHECK",1); // We accept to go on this page from external web site. // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php // TODO This should be useless. Because entity must be retreive from object ref and not from url. -$entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); +$entity=(! empty($_GET['e']) ? (int) $_GET['e'] : (! empty($_POST['e']) ? (int) $_POST['e'] : 1)); if (is_numeric($entity)) define("DOLENTITY", $entity); require '../../main.inc.php'; diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 29d2b78d142..7ccd95abcdf 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -31,7 +31,7 @@ define("NOCSRFCHECK",1); // We accept to go on this page from external web site. // For MultiCompany module. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php // TODO This should be useless. Because entity must be retreive from object ref and not from url. -$entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); +$entity=(! empty($_GET['e']) ? (int) $_GET['e'] : (! empty($_POST['e']) ? (int) $_POST['e'] : 1)); if (is_numeric($entity)) define("DOLENTITY", $entity); require '../../main.inc.php'; @@ -76,7 +76,7 @@ if (! empty($conf->paypal->enabled)) $FULLTAG=GETPOST('FULLTAG'); if (empty($FULLTAG)) $FULLTAG=GETPOST('fulltag'); -$source=GETPOST('source'); +$source=GETPOST('s','alpha')?GETPOST('s','alpha'):GETPOST('source','alpha'); $ref=GETPOST('ref'); $suffix=GETPOST("suffix",'aZ09'); @@ -145,7 +145,6 @@ $conf->dol_hide_leftmenu=1; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); - // Show message print ''."\n"; print '
    '."\n"; diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index 550fa9a6898..e10fc07a6ef 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -205,14 +205,13 @@ else // Link to other agenda views $out=''; - $out.=img_picto($langs->trans("ViewPerUser"),'object_calendarperuser','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewPerUser"),'object_calendarperuser','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewPerUser").''; - $out.='
    '; - $out.=img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewCal").''; - $out.=img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewWeek").''; - $out.=img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); + $out.='
  • '.img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); $out.=''.$langs->trans("ViewDay").''; $linkback.=$out; diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index c4d783739c0..1b5c11df748 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -135,6 +135,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x', { $search_ref=""; $search_label=""; + $search_type=""; $search_array_options=array(); $filter=array(); } @@ -163,14 +164,7 @@ if ($action == 'delete_resource') print $form->formconfirm($_SERVER['PHP_SELF']."?element=".$element."&element_id=".$element_id."&lineid=".$lineid,$langs->trans("DeleteResource"),$langs->trans("ConfirmDeleteResourceElement"),"confirm_delete_resource",'','',1); } -// Load object list -$ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset, $filter); -if($ret == -1) { - dol_print_error($db,$object->error); - exit; -} else { - print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $ret+1, $object->num_all,'title_generic.png'); -} + $var=true; @@ -187,6 +181,26 @@ print ''; print ''; print ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $ret = $object->fetch_all('', '', 0, 0, $filter); + if($ret == -1) { + dol_print_error($db,$object->error); + exit; + } else { + $nbtotalofrecords = $ret; + } +} + +// Load object list +$ret = $object->fetch_all($sortorder, $sortfield, $limit, $offset, $filter); +if($ret == -1) { + dol_print_error($db,$object->error); + exit; +} else { + print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $ret+1, $nbtotalofrecords,'title_generic.png', 0, '', '', $limit); +} + $moreforfilter = ''; print '
    '; @@ -237,7 +251,7 @@ print "\n"; print '
  • '; if (! empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'],$_SERVER["PHP_SELF"],"t.ref","",$param,"",$sortfield,$sortorder); -if (! empty($arrayfields['ty.label']['checked'])) print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"t.code","",$param,"",$sortfield,$sortorder); +if (! empty($arrayfields['ty.label']['checked'])) print_liste_field_titre($arrayfields['ty.label']['label'],$_SERVER["PHP_SELF"],"ty.label","",$param,"",$sortfield,$sortorder); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 7b4bae14a14..dc02303e3bb 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -59,7 +59,7 @@ $action = (GETPOST('action','aZ09') ? GETPOST('action','aZ09') : 'view'); $cancel = GETPOST('cancel','alpha'); $backtopage = GETPOST('backtopage','alpha'); $confirm = GETPOST('confirm'); -$socid = GETPOST('socid','int'); +$socid = GETPOST('socid','int')?GETPOST('socid','int'):GETPOST('id','int'); if ($user->societe_id) $socid=$user->societe_id; if (empty($socid) && $action == 'view') $action='create'; @@ -94,8 +94,6 @@ if (! empty($canvas)) $result = restrictedArea($user, 'societe', $socid, '&societe', '', 'fk_soc', 'rowid', $objcanvas); - - /* * Actions */ @@ -310,159 +308,155 @@ if (empty($reshook)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ThirdPartyName")), null, 'errors'); $error++; - $action=($action=='add'?'create':'edit'); } if (GETPOST('client') < 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProspectCustomer")), null, 'errors'); $error++; - $action=($action=='add'?'create':'edit'); } if (GETPOST('fournisseur') < 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Supplier")), null, 'errors'); $error++; - $action=($action=='add'?'create':'edit'); + } - if ($action == 'update') + if (! $error) { - $ret=$object->fetch($socid); - $object->oldcopy = clone $object; - } - else $object->canvas=$canvas; + if ($action == 'update') + { + $ret=$object->fetch($socid); + $object->oldcopy = clone $object; + } + else $object->canvas=$canvas; - if (GETPOST("private") == 1) // Ask to create a contact - { - $object->particulier = GETPOST("private"); + if (GETPOST("private") == 1) // Ask to create a contact + { + $object->particulier = GETPOST("private"); - $object->name = dolGetFirstLastname(GETPOST('firstname','alpha'),GETPOST('name','alpha')); - $object->civility_id = GETPOST('civility_id'); // Note: civility id is a code, not an int - // Add non official properties - $object->name_bis = GETPOST('name','alpha'); - $object->firstname = GETPOST('firstname','alpha'); - } - else - { - $object->name = GETPOST('name', 'alpha'); - } - $object->name_alias = GETPOST('name_alias'); - $object->address = GETPOST('address'); - $object->zip = GETPOST('zipcode', 'alpha'); - $object->town = GETPOST('town', 'alpha'); - $object->country_id = GETPOST('country_id', 'int'); - $object->state_id = GETPOST('state_id', 'int'); - $object->skype = GETPOST('skype', 'alpha'); - $object->phone = GETPOST('phone', 'alpha'); - $object->fax = GETPOST('fax','alpha'); - $object->email = trim(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL)); - $object->url = trim(GETPOST('url', 'custom', 0, FILTER_SANITIZE_URL)); - $object->idprof1 = trim(GETPOST('idprof1', 'alpha')); - $object->idprof2 = trim(GETPOST('idprof2', 'alpha')); - $object->idprof3 = trim(GETPOST('idprof3', 'alpha')); - $object->idprof4 = trim(GETPOST('idprof4', 'alpha')); - $object->idprof5 = trim(GETPOST('idprof5', 'alpha')); - $object->idprof6 = trim(GETPOST('idprof6', 'alpha')); - $object->prefix_comm = GETPOST('prefix_comm', 'alpha'); - $object->code_client = GETPOST('code_client', 'alpha'); - $object->code_fournisseur = GETPOST('code_fournisseur', 'alpha'); - $object->capital = GETPOST('capital', 'alpha'); - $object->barcode = GETPOST('barcode', 'alpha'); + $object->name = dolGetFirstLastname(GETPOST('firstname','alpha'),GETPOST('name','alpha')); + $object->civility_id = GETPOST('civility_id'); // Note: civility id is a code, not an int + // Add non official properties + $object->name_bis = GETPOST('name','alpha'); + $object->firstname = GETPOST('firstname','alpha'); + } + else + { + $object->name = GETPOST('name', 'alpha'); + } + $object->name_alias = GETPOST('name_alias'); + $object->address = GETPOST('address'); + $object->zip = GETPOST('zipcode', 'alpha'); + $object->town = GETPOST('town', 'alpha'); + $object->country_id = GETPOST('country_id', 'int'); + $object->state_id = GETPOST('state_id', 'int'); + $object->skype = GETPOST('skype', 'alpha'); + $object->phone = GETPOST('phone', 'alpha'); + $object->fax = GETPOST('fax','alpha'); + $object->email = trim(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL)); + $object->url = trim(GETPOST('url', 'custom', 0, FILTER_SANITIZE_URL)); + $object->idprof1 = trim(GETPOST('idprof1', 'alpha')); + $object->idprof2 = trim(GETPOST('idprof2', 'alpha')); + $object->idprof3 = trim(GETPOST('idprof3', 'alpha')); + $object->idprof4 = trim(GETPOST('idprof4', 'alpha')); + $object->idprof5 = trim(GETPOST('idprof5', 'alpha')); + $object->idprof6 = trim(GETPOST('idprof6', 'alpha')); + $object->prefix_comm = GETPOST('prefix_comm', 'alpha'); + $object->code_client = GETPOST('code_client', 'alpha'); + $object->code_fournisseur = GETPOST('code_fournisseur', 'alpha'); + $object->capital = GETPOST('capital', 'alpha'); + $object->barcode = GETPOST('barcode', 'alpha'); - $object->tva_intra = GETPOST('tva_intra', 'alpha'); - $object->tva_assuj = GETPOST('assujtva_value', 'alpha'); - $object->status = GETPOST('status', 'alpha'); + $object->tva_intra = GETPOST('tva_intra', 'alpha'); + $object->tva_assuj = GETPOST('assujtva_value', 'alpha'); + $object->status = GETPOST('status', 'alpha'); - // Local Taxes - $object->localtax1_assuj = GETPOST('localtax1assuj_value', 'alpha'); - $object->localtax2_assuj = GETPOST('localtax2assuj_value', 'alpha'); + // Local Taxes + $object->localtax1_assuj = GETPOST('localtax1assuj_value', 'alpha'); + $object->localtax2_assuj = GETPOST('localtax2assuj_value', 'alpha'); - $object->localtax1_value = GETPOST('lt1', 'alpha'); - $object->localtax2_value = GETPOST('lt2', 'alpha'); + $object->localtax1_value = GETPOST('lt1', 'alpha'); + $object->localtax2_value = GETPOST('lt2', 'alpha'); - $object->forme_juridique_code = GETPOST('forme_juridique_code', 'int'); - $object->effectif_id = GETPOST('effectif_id', 'int'); - $object->typent_id = GETPOST('typent_id','int'); + $object->forme_juridique_code = GETPOST('forme_juridique_code', 'int'); + $object->effectif_id = GETPOST('effectif_id', 'int'); + $object->typent_id = GETPOST('typent_id','int'); - $object->typent_code = dol_getIdFromCode($db, $object->typent_id, 'c_typent', 'id', 'code'); // Force typent_code too so check in verify() will be done on new type + $object->typent_code = dol_getIdFromCode($db, $object->typent_id, 'c_typent', 'id', 'code'); // Force typent_code too so check in verify() will be done on new type - $object->client = GETPOST('client', 'int'); - $object->fournisseur = GETPOST('fournisseur', 'int'); + $object->client = GETPOST('client', 'int'); + $object->fournisseur = GETPOST('fournisseur', 'int'); - $object->commercial_id = GETPOST('commercial_id', 'int'); - $object->default_lang = GETPOST('default_lang'); + $object->commercial_id = GETPOST('commercial_id', 'int'); + $object->default_lang = GETPOST('default_lang'); - // Webservices url/key - $object->webservices_url = GETPOST('webservices_url', 'custom', 0, FILTER_SANITIZE_URL); - $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); + // Webservices url/key + $object->webservices_url = GETPOST('webservices_url', 'custom', 0, FILTER_SANITIZE_URL); + $object->webservices_key = GETPOST('webservices_key', 'san_alpha'); - // Incoterms - if (!empty($conf->incoterm->enabled)) - { - $object->fk_incoterms = GETPOST('incoterm_id', 'int'); - $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); - } + // Incoterms + if (!empty($conf->incoterm->enabled)) + { + $object->fk_incoterms = GETPOST('incoterm_id', 'int'); + $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); + } - // Multicurrency - if (!empty($conf->multicurrency->enabled)) - { - $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - } + // Multicurrency + if (!empty($conf->multicurrency->enabled)) + { + $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); + } - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); - if ($ret < 0) - { - $error++; - $action = ($action=='add'?'create':'edit'); - } + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + if ($ret < 0) + { + $error++; + } - if (GETPOST('deletephoto')) $object->logo = ''; - else if (! empty($_FILES['photo']['name'])) $object->logo = dol_sanitizeFileName($_FILES['photo']['name']); + if (GETPOST('deletephoto')) $object->logo = ''; + else if (! empty($_FILES['photo']['name'])) $object->logo = dol_sanitizeFileName($_FILES['photo']['name']); - // Check parameters - if (! GETPOST('cancel','alpha')) - { - if (! empty($object->email) && ! isValidEMail($object->email)) - { - $langs->load("errors"); - $error++; - setEventMessages('', $langs->trans("ErrorBadEMail",$object->email), 'errors'); - $action = ($action=='add'?'create':'edit'); - } - if (! empty($object->url) && ! isValidUrl($object->url)) - { - $langs->load("errors"); - setEventMessages('', $langs->trans("ErrorBadUrl",$object->url), 'errors'); - $action = ($action=='add'?'create':'edit'); - } - if ($object->fournisseur && ! $conf->fournisseur->enabled) - { - $langs->load("errors"); - setEventMessages('', $langs->trans("ErrorSupplierModuleNotEnabled"), 'errors'); - $action = ($action=='add'?'create':'edit'); - } - if (! empty($object->webservices_url)) { - //Check if has transport, without any the soap client will give error - if (strpos($object->webservices_url, "http") === false) - { - $object->webservices_url = "http://".$object->webservices_url; - } - if (! isValidUrl($object->webservices_url)) { - $langs->load("errors"); - $error++; $errors[] = $langs->trans("ErrorBadUrl",$object->webservices_url); - $action = ($action=='add'?'create':'edit'); - } - } + // Check parameters + if (! GETPOST('cancel','alpha')) + { + if (! empty($object->email) && ! isValidEMail($object->email)) + { + $langs->load("errors"); + $error++; + setEventMessages('', $langs->trans("ErrorBadEMail",$object->email), 'errors'); + } + if (! empty($object->url) && ! isValidUrl($object->url)) + { + $langs->load("errors"); + setEventMessages('', $langs->trans("ErrorBadUrl",$object->url), 'errors'); + } + if ($object->fournisseur && ! $conf->fournisseur->enabled) + { + $langs->load("errors"); + setEventMessages('', $langs->trans("ErrorSupplierModuleNotEnabled"), 'errors'); + } + if (! empty($object->webservices_url)) { + //Check if has transport, without any the soap client will give error + if (strpos($object->webservices_url, "http") === false) + { + $object->webservices_url = "http://".$object->webservices_url; + } + if (! isValidUrl($object->webservices_url)) { + $langs->load("errors"); + $error++; $errors[] = $langs->trans("ErrorBadUrl",$object->webservices_url); + } + } - // We set country_id, country_code and country for the selected country - $object->country_id=GETPOST('country_id')!=''?GETPOST('country_id'):$mysoc->country_id; - if ($object->country_id) - { - $tmparray=getCountry($object->country_id,'all'); - $object->country_code=$tmparray['code']; - $object->country=$tmparray['label']; - } + // We set country_id, country_code and country for the selected country + $object->country_id=GETPOST('country_id')!=''?GETPOST('country_id'):$mysoc->country_id; + if ($object->country_id) + { + $tmparray=getCountry($object->country_id,'all'); + $object->country_code=$tmparray['code']; + $object->country=$tmparray['label']; + } + } } if (! $error) @@ -490,7 +484,7 @@ if (empty($reshook)) } // Customer categories association - $custcats = GETPOST( 'custcats', 'array' ); + $custcats = GETPOST('custcats', 'array'); $object->setCategories($custcats, 'customer'); // Supplier categories association @@ -607,7 +601,7 @@ if (empty($reshook)) } // Customer categories association - $categories = GETPOST( 'custcats', 'array' ); + $categories = GETPOST('custcats', 'array'); $object->setCategories($categories, 'customer'); // Supplier categories association @@ -992,7 +986,7 @@ else dol_htmloutput_mesg(is_numeric($error)?'':$error, $errors, 'error'); - print ''; + print ''; // Chrome ignor autocomplete print ''; print ''; @@ -2372,69 +2366,68 @@ else /* * Actions */ - print '
    '."\n"; + if ($action != 'presend') + { + print '
    '."\n"; - $parameters=array(); - $reshook=$hookmanager->executeHooks('addMoreActionsButtons',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - if (empty($reshook)) - { - $at_least_one_email_contact = false; - $TContact = $object->contact_array_objects(); - foreach ($TContact as &$contact) + $parameters=array(); + $reshook=$hookmanager->executeHooks('addMoreActionsButtons',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { - if (!empty($contact->email)) + $at_least_one_email_contact = false; + $TContact = $object->contact_array_objects(); + foreach ($TContact as &$contact) { - $at_least_one_email_contact = true; - break; + if (!empty($contact->email)) + { + $at_least_one_email_contact = true; + break; + } } + + if (! empty($object->email) || $at_least_one_email_contact) + { + $langs->load("mails"); + print ''; + } + else + { + $langs->load("mails"); + print ''; + } + + if ($user->rights->societe->creer) + { + print ''."\n"; + } + + if ($user->rights->societe->supprimer) + { + print ''; + } + + if ($user->rights->societe->supprimer) + { + if ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile)) // We can't use preloaded confirm form with jmobile + { + print '
    '.$langs->trans('Delete').'
    '."\n"; + } + else + { + print ''."\n"; + } + } } - if (! empty($object->email) || $at_least_one_email_contact) - { - $langs->load("mails"); - print ''; - } - else - { - $langs->load("mails"); - print ''; - } - - if ($user->rights->societe->creer) - { - print ''."\n"; - } - - if ($user->rights->societe->supprimer) - { - print ''; - } - - if ($user->rights->societe->supprimer) - { - if ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile)) // We can't use preloaded confirm form with jmobile - { - print '
    '.$langs->trans('Delete').'
    '."\n"; - } - else - { - print ''."\n"; - } - } - } - - print '
    '."\n"; + print '
    '."\n"; + } //Select mail models is same action as presend if (GETPOST('modelselected')) { $action = 'presend'; } - if ($action == 'presend') + /*if ($action == 'presend') { - /* - * Affiche formulaire mail - */ - // By default if $action=='presend' $titreform='SendMail'; $topicmail=''; @@ -2485,38 +2478,12 @@ else $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Array of substitutions - $formmail->withsubstit='AvailableVariables'; - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit['__THIRDPARTY_ID__']=$object->id; // substit in setSubstitFromObject was wrong for this one $formmail->substit['__THIRDPARTY_NAME__']=$object->name; // substit in setSubstitFromObject was wrong for this one - $formmail->substit['__PERSONALIZED__']=''; + $formmail->substit['__PERSONALIZED__']=''; // deprecated $formmail->substit['__CONTACTCIVNAME__']=''; - //Find the good contact adress - /* - $custcontact=''; - $contactarr=array(); - $contactarr=$object->liste_contact(-1,'external'); - - if (is_array($contactarr) && count($contactarr)>0) - { - foreach($contactarr as $contact) - { - if ($contact['libelle']==$langs->trans('TypeContact_facture_external_BILLING')) { - - require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; - - $contactstatic=new Contact($db); - $contactstatic->fetch($contact['id']); - $custcontact=$contactstatic->getFullName($langs,1); - } - } - - if (!empty($custcontact)) { - $formmail->substit['__CONTACTCIVNAME__']=$custcontact; - } - }*/ - // Tableau des parametres complementaires du post $formmail->param['action']=$action; @@ -2534,14 +2501,15 @@ else print $formmail->get_form(); dol_fiche_end(); - } - else + }*/ + + if ($action != 'presend') { + print '
    '; if (empty($conf->global->SOCIETE_DISABLE_BUILDDOC)) { - print '
    '; - print ''; // ancre + print ''; // ancre /* * Documents generes @@ -2554,35 +2522,34 @@ else $var=true; print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang); - - print '
    '; - - - print '
    '; - - print '
    '; } - print '

    '; - // Subsidiaries list if (empty($conf->global->SOCIETE_DISABLE_SUBSIDIARIES)) { - $result=show_subsidiaries($conf,$langs,$db,$object); + $result=show_subsidiaries($conf,$langs,$db,$object); } - // Contacts list - if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) - { - $result=show_contacts($conf,$langs,$db,$object,$_SERVER["PHP_SELF"].'?socid='.$object->id); - } + print '
    '; - // Addresses list - if (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT)) - { - $result=show_addresses($conf,$langs,$db,$object,$_SERVER["PHP_SELF"].'?socid='.$object->id); - } + $MAX = 5; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, '', $socid, 1, '', $MAX); // Show all action for thirdparty + + print '
    '; } + + // Presend form + $modelmail='thirdparty'; + $defaulttopic='Information'; + $diroutput = $conf->societe->dir_output; + $trackid = 'thi'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; + } } diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 55a328e2538..1c8c515545a 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1077,7 +1077,7 @@ class Societe extends CommonObject $sql = 'SELECT s.rowid, s.nom as name, s.name_alias, s.entity, s.ref_ext, s.ref_int, s.address, s.datec as date_creation, s.prefix_comm'; $sql .= ', s.status'; $sql .= ', s.price_level'; - $sql .= ', s.tms as date_modification'; + $sql .= ', s.tms as date_modification, s.fk_user_creat, s.fk_user_modif'; $sql .= ', s.phone, s.fax, s.email, s.skype, s.url, s.zip, s.town, s.note_private, s.note_public, s.model_pdf, s.client, s.fournisseur'; $sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6'; $sql .= ', s.capital, s.tva_intra'; @@ -1144,8 +1144,10 @@ class Societe extends CommonObject $this->ref_ext = $obj->ref_ext; $this->ref_int = $obj->ref_int; - $this->date_creation = $this->db->jdate($obj->date_creation); + $this->date_creation = $this->db->jdate($obj->date_creation); $this->date_modification = $this->db->jdate($obj->date_modification); + $this->user_creation = $obj->fk_user_creat; + $this->user_modification = $obj->fk_user_modif; $this->address = $obj->address; $this->zip = $obj->zip; @@ -1896,6 +1898,11 @@ class Societe extends CommonObject $label.= '' . $langs->trans("ShowMargin") . ''; $linkstart = ''; + $linkstart = 'load("commercial"); +$langs->load("bills"); +$langs->load("banks"); +$langs->load("users"); +if (! empty($conf->categorie->enabled)) $langs->load("categories"); +if (! empty($conf->incoterm->enabled)) $langs->load("incoterm"); +if (! empty($conf->notification->enabled)) $langs->load("mails"); + +$mesg=''; $error=0; $errors=array(); + +$action = (GETPOST('action','aZ09') ? GETPOST('action','aZ09') : 'view'); +$cancel = GETPOST('cancel','alpha'); +$backtopage = GETPOST('backtopage','alpha'); +$confirm = GETPOST('confirm'); +$socid = GETPOST('socid','int')?GETPOST('socid','int'):GETPOST('id','int'); +if ($user->societe_id) $socid=$user->societe_id; +if (empty($socid) && $action == 'view') $action='create'; + +$object = new Societe($db); +$extrafields = new ExtraFields($db); + +// fetch optionals attributes and labels +$extralabels=$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('thirdpartycard','globalcard')); + +if ($action == 'view' && $object->fetch($socid)<=0) +{ + $langs->load("errors"); + print($langs->trans('ErrorRecordNotFound')); + exit; +} + +// Get object canvas (By default, this is not defined, so standard usage of dolibarr) +$object->getCanvas($socid); +$canvas = $object->canvas?$object->canvas:GETPOST("canvas"); +$objcanvas=null; +if (! empty($canvas)) +{ + require_once DOL_DOCUMENT_ROOT.'/core/class/canvas.class.php'; + $objcanvas = new Canvas($db, $action); + $objcanvas->getCanvas('thirdparty', 'card', $canvas); +} + +// Security check +$result = restrictedArea($user, 'societe', $socid, '&societe', '', 'fk_soc', 'rowid', $objcanvas); + + + + +/* + * Actions + */ + +$parameters=array('id'=>$socid, 'objcanvas'=>$objcanvas); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + if ($cancel) + { + $action=''; + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formadmin = new FormAdmin($db); +$formcompany = new FormCompany($db); + +if ($socid > 0 && empty($object->id)) +{ + $result=$object->fetch($socid); + if ($result <= 0) dol_print_error('',$object->error); +} + +$title=$langs->trans("ThirdParty"); +if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$langs->trans('Card'); +$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('',$title,$help_url); + +$countrynotdefined=$langs->trans("ErrorSetACountryFirst").' ('.$langs->trans("SeeAbove").')'; + +if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) +{ + // ----------------------------------------- + // When used with CANVAS + // ----------------------------------------- + $objcanvas->assign_values($action, $object->id, $object->ref); // Set value for templates + $objcanvas->display_canvas($action); // Show template +} +else +{ + + if (!empty($object->id)) $res=$object->fetch_optionals($object->id,$extralabels); + //if ($res < 0) { dol_print_error($db); exit; } + + + $head = societe_prepare_head($object); + + dol_fiche_head($head, 'contact', $langs->trans("ThirdParty"), 0, 'company'); + + $linkback = ''.$langs->trans("BackToList").''; + + dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom'); + + dol_fiche_end(); + + print '
    '; + + if ($action != 'presend') + { + print '
    '; + + // Contacts list + if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) + { + $result=show_contacts($conf,$langs,$db,$object,$_SERVER["PHP_SELF"].'?socid='.$object->id); + } + + // Addresses list + if (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT)) + { + $result=show_addresses($conf,$langs,$db,$object,$_SERVER["PHP_SELF"].'?socid='.$object->id); + } + + + print '
    '; + + } + +} + + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 786e5a09890..4f8b5513016 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -197,7 +197,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } @@ -608,7 +608,7 @@ foreach(array(1,2,3,4,5,6) as $key) if ($massaction == 'presend') { - $topicmail="SendEmail"; + $topicmail="Information"; $modelmail="thirdparty"; $objecttmp=new Societe($db); $trackid='thi'.$object->id; @@ -1024,6 +1024,7 @@ while ($i < min($num, $limit)) $companystatic->id=$obj->rowid; $companystatic->name=$obj->name; + $companystatic->name_alias=$obj->name_alias; $companystatic->canvas=$obj->canvas; $companystatic->client=$obj->client; $companystatic->status=$obj->status; @@ -1053,7 +1054,6 @@ while ($i < min($num, $limit)) } if (! empty($arrayfields['s.name_alias']['checked'])) { - $companystatic->name_alias=$obj->name_alias; // Added after the getNomUrl print '\n"; diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php index 515aef60a6a..fc864bd5e01 100644 --- a/htdocs/societe/price.php +++ b/htdocs/societe/price.php @@ -237,9 +237,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { $sortorder = GETPOST("sortorder", 'alpha'); $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit; $page = GETPOST("page", 'int'); - if ($page == - 1) { - $page = 0; - } + if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php index 0cc15c7fb60..9aaed7cf0b9 100644 --- a/htdocs/stripe/config.php +++ b/htdocs/stripe/config.php @@ -1,6 +1,7 @@ * Copyright (C) 2017 Saasprov + * Copyright (C) 2017 Ferran Marcet * * 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 @@ -32,7 +33,7 @@ global $conf; //use \includes\stripe as stripe; $stripe = array(); -if (empty($conf->global->SKYPE_LIVE)) +if (empty($conf->global->STRIPE_LIVE)) { $stripe = array( "secret_key" => $conf->global->STRIPE_TEST_SECRET_KEY, diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index fda4eea65ea..a997b5f4b96 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -115,7 +115,15 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e if (empty($reshook)) { - if ($cancel) $action=''; + if ($cancel) + { + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + $action=''; + } include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once @@ -260,7 +268,7 @@ if (empty($reshook)) $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated - $object->note = GETPOST('note'); + $object->note = GETPOST('note','none'); $object->statut = SupplierProposal::STATUS_DRAFT; $id = $object->create_from($user); @@ -278,7 +286,7 @@ if (empty($reshook)) $object->fk_project = GETPOST('projectid'); $object->modelpdf = GETPOST('model'); $object->author = $user->id; // deprecated - $object->note = GETPOST('note'); + $object->note = GETPOST('note','none'); $object->origin = GETPOST('origin'); $object->origin_id = GETPOST('originid'); @@ -457,21 +465,24 @@ if (empty($reshook)) } else { // prevent browser refresh from closing proposal several times if ($object->statut == SupplierProposal::STATUS_VALIDATED) { - $object->cloture($user, GETPOST('statut'), GETPOST('note')); + $object->cloture($user, GETPOST('statut'), GETPOST('note','none')); } } } - // Action for direct print + // Actions when printing a doc from card include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to send emails - $trigger_name='SUPPLIER_PROPOSAL_SENTBYMAIL'; - $paramname='id'; - $mode='emailfromsupplierproposal'; + $trigger_name='PROPOSAL_SUPPLIER_SENTBYMAIL'; + $autocopy='MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO'; $trackid='spr'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + // Actions to build doc + $upload_dir = $conf->supplier_proposal->dir_output; + $permissioncreate = $user->rights->supplier_proposal->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; // Go back to draft @@ -763,7 +774,7 @@ if (empty($reshook)) $info_bits |= 0x01; // Clean parameters - $description = dol_htmlcleanlastbr(GETPOST('product_desc')); + $description = dol_htmlcleanlastbr(GETPOST('product_desc','none')); // Define vat_rate $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); @@ -876,44 +887,6 @@ if (empty($reshook)) exit(); } - // Generation doc (depuis lien ou depuis cartouche doc) - else if ($action == 'builddoc' && $user->rights->supplier_proposal->creer) { - if (GETPOST('model')) { - $object->setDocModel($user, GETPOST('model')); - } - - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - $action=''; - } - } - - // Remove file in doc form - else if ($action == 'remove_file' && $user->rights->supplier_proposal->creer) { - if ($object->id > 0) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $langs->load("other"); - $upload_dir = $conf->supplier_proposal->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) - setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); - else - setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors'); - } - } - // Set project else if ($action == 'classin' && $user->rights->supplier_proposal->creer) { $object->setProject($_POST['projectid']); @@ -1811,108 +1784,18 @@ if ($action == 'create') print ''; } - /* - * Action presend - */ + // Select mail models is same action as presend if (GETPOST('modelselected')) { $action = 'presend'; } - if ($action == 'presend') - { - $object->fetch_projet(); - $ref = dol_sanitizeFileName($object->ref); - include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - $fileparams = dol_most_recent_file($conf->supplier_proposal->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; + // Presend form + $modelmail='supplier_proposal_send'; + $defaulttopic='SendAskRef'; + $diroutput = $conf->supplier_proposal->dir_output; + $trackid = 'spr'.$object->id; - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) - $newlang = $_REQUEST['lang_id']; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) - $newlang = $object->thirdparty->default_lang; - - if (!empty($newlang)) - { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); - $outputlangs->load('commercial'); - $outputlangs->load('supplier_proposal'); - } - - // Build document if it not exists - if (! $file || ! is_readable($file)) { - $result = $object->generateDocument(GETPOST('model') ? GETPOST('model') : $object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - dol_print_error($db, $object->error, $object->errors); - exit(); - } - $fileparams = dol_most_recent_file($conf->supplier_proposal->dir_output . '/' . $ref, preg_quote($ref, '/').'[^\-]+'); - $file = $fileparams['fullname']; - } - - print '
    '; - print '
    '; - print '
    '; - print load_fiche_titre($langs->trans('SendAskByMail')); - - dol_fiche_head(''); - - // Create form object - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); - $formmail->fromtype = (GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); - - if($formmail->fromtype === 'user'){ - $formmail->fromid = $user->id; - - } - $formmail->trackid='spr'.$object->id; - if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set - { - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'spr'.$object->id); - } - - $formmail->withfrom = 1; - $liste = array(); - foreach ($object->thirdparty->thirdparty_and_contact_email_array(1) as $key => $value) - $liste [$key] = $value; - $formmail->withto = GETPOST("sendto") ? GETPOST("sendto") : $liste; - $formmail->withtocc = $liste; - $formmail->withtoccc = (! empty($conf->global->MAIN_EMAIL_USECCC) ? $conf->global->MAIN_EMAIL_USECCC : false); - - $formmail->withtopic = $outputlangs->trans('SendAskRef', '__SUPPLIERPROPREF__'); - - $formmail->withfile = 2; - $formmail->withbody = 1; - $formmail->withdeliveryreceipt = 1; - $formmail->withcancel = 1; - - // Tableau des substitutions - $formmail->setSubstitFromObject($object); - $formmail->substit['__SUPPLIERPROPREF__'] = $object->ref; - - // Tableau des parametres complementaires - $formmail->param['action'] = 'send'; - $formmail->param['models'] = 'supplier_proposal_send'; - $formmail->param['models_id']=GETPOST('modelmailselected','int'); - $formmail->param['id'] = $object->id; - $formmail->param['returnurl'] = $_SERVER["PHP_SELF"] . '?id=' . $object->id; - // Init list of files - if (GETPOST("mode") == 'init') { - $formmail->clear_attached_files(); - $formmail->add_attached_files($file, basename($file), dol_mimetype($file)); - } - - print $formmail->get_form(); - - dol_fiche_end(); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } // End of page diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index 7ad6c0d1b82..013ad832898 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -157,7 +157,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } diff --git a/htdocs/theme/common/cheque.png b/htdocs/theme/common/cheque.png new file mode 100644 index 00000000000..34b89a1e1d0 Binary files /dev/null and b/htdocs/theme/common/cheque.png differ diff --git a/htdocs/theme/eldy/img/stcomm0.png b/htdocs/theme/eldy/img/stcomm0.png index b6c11d4569a..1220cf8113e 100644 Binary files a/htdocs/theme/eldy/img/stcomm0.png and b/htdocs/theme/eldy/img/stcomm0.png differ diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 3d58211fbde..36a92396d3e 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -344,55 +344,53 @@ input.buttongen { vertical-align: middle; } input.buttonpayment { - width: 300px; + min-width: 280px; margin-bottom: 15px; background-image: none; line-height: 24px; padding: 8px; + background: none; + border: 2px solid #666666; } input.buttonpaymentcb { background-image: url(); background-size: 26px; background-repeat: no-repeat; - background-position: 5px 5px; + background-position: 2px 11px; } input.buttonpaymentcheque { background-image: url(); - background-repeat: no-repeat; - background-position: 8px 7px; -} -input.buttonpaymentcb { - background-image: url(); background-size: 24px; background-repeat: no-repeat; - background-position: 5px 4px; -} -input.buttonpaymentcheque { - background-image: url(); - background-repeat: no-repeat; - background-position: 5px 4px; + background-position: 2px 8px; } input.buttonpaymentpaypal { background-image: url(); background-repeat: no-repeat; - background-position: 8px 7px; + background-position: 8px 11px; } input.buttonpaymentpaybox { background-image: url(); background-repeat: no-repeat; - background-position: 8px 7px; + background-position: 8px 11px; } input.buttonpaymentstripe { background-image: url(); background-repeat: no-repeat; - background-position: 8px 7px; + background-position: 8px 11px; } +/* Used by timesheets */ span.timesheetalreadyrecorded input { border: none; border-bottom: solid 1px rgba(0,0,0,0.4); margin-right: 1px !important; } - +td.onholidaymorning, td.onholidayafternoon { + background-color: #fdf6f2; +} +td.onholidayallday { + background-color: #f4eede; +} select.flat, form.flat select { font-weight: normal; } @@ -691,6 +689,12 @@ div.myavailability { text-overflow: ellipsis; white-space: nowrap; } +.tdoverflowmax200 { /* For tdoverflow, the max-midth become a minimum ! */ + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} .tdoverflowmax300 { /* For tdoverflow, the max-midth become a minimum ! */ max-width: 300px; overflow: hidden; @@ -721,7 +725,9 @@ div.myavailability { margin-top: 6px; margin-bottom: 12px; } - +#builddoc_form ~ .showlinkedobjectblock { + margin-top: 20px; +} /* For the long description of module */ .moduledesclong p img, .moduledesclong p a img { @@ -865,11 +871,11 @@ div.fiche>form>div.div-table-responsive { .minwidth500imp { min-width: 250px !important; } } -/* Force values for small screen 570 */ +/* Force values for small screen 767 */ @media only screen and (max-width: 767px) { body { - font-size: px; + font-size: px; } } @@ -877,7 +883,7 @@ div.fiche>form>div.div-table-responsive { @media only screen and (max-width: 570px) { body { - font-size: px; + font-size: px; } .divmainbodylarge { margin-left: 20px !important; margin-right: 20px !important; } @@ -1086,7 +1092,7 @@ div.fiche { dol_hide_leftmenu)) print 'margin-bottom: 12px;'."\n"; ?> } body.onlinepaymentbody div.fiche { /* For online payment page */ - margin: 40px !important; + margin: 20px !important; } div.fiche>table:first-child { margin-bottom: 15px !important; @@ -1227,6 +1233,9 @@ div.heightref { div.divphotoref { padding-right: 20px; } +div.paginationref { + padding-bottom: 10px; +} div.statusref { float: right; padding-left: 12px; @@ -2039,7 +2048,9 @@ div.tabs { div.tabsElem { margin-top: 1px; } /* To avoid overlap of tabs when not browser */ - +div.tabsElem a { + font-weight: normal !important; +} div.tabBar { color: #; padding-top: 16px; @@ -2751,14 +2762,16 @@ input.liste_titre { line-height: 24px; } -.noborder tr.liste_total, .noborder tr.liste_total td, tr.liste_total, form.liste_total { - /* height: 32px; */ -} -.noborder tr.liste_total td, tr.liste_total td, form.liste_total div { +.noborder tr.liste_total td, tr.liste_total td, form.liste_total div, .noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { color: #551188; font-weight: normal; +} +.noborder tr.liste_total td, tr.liste_total td, form.liste_total div { white-space: nowrap; } +.noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { + white-space: normal; +} form.liste_total div { border-top: 1px solid #DDDDDD; } @@ -2923,13 +2936,11 @@ span.dashboardlineko { float: right; position: relative; text-align: right; - top: -24px; - padding: 1px 2px 1px 2px; + top: -26px; + padding: 0px 5px 0px 5px; border-radius: .25em; background-color: #9f4705; - padding: 0px 5px 0px 5px; - top: -26px; } .imglatecoin { padding: 1px 3px 1px 1px; @@ -3027,11 +3038,12 @@ div.warning { color: #302020; padding: 0.3em 0.3em 0.3em 0.3em; margin: 0.5em 0em 0.5em 0em; - border: 1px solid #e0d0b0; + /* border: 1px solid #e0d0b0; */ + border: 2px solid #805000; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; - background: #EFDF9A; + /* background: #EFDF9A; */ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } @@ -3133,15 +3145,14 @@ td.legendLabel { padding: 2px 2px 2px 0 !important; } div.titre { font-family: ; font-size: 14px; - font-weight: bold; + /* font-weight: bold; */ color: rgb(); text-decoration: none; padding-top: 5px; padding-bottom: 5px; - /* text-shadow: 1px 1px 2px #FFFFFF; */ } -#dolpaymenttable { width: 600px; font-size: 13px; } +#dolpaymenttable { min-width: 310px; font-size: 16px; } /* Width must have min to make stripe input area visible */ #tablepublicpayment { border: 1px solid #CCCCCC !important; width: 100%; padding: 20px; } #tablepublicpayment .CTableRow1 { background-color: #F0F0F0 !important; } #tablepublicpayment tr.liste_total { border-bottom: 1px solid #CCCCCC !important; } @@ -3986,6 +3997,12 @@ div#ecm-layout-center { padding-left: 10px !important; padding-right: 10px !important; } +.jnotify-container .jnotify-notification .jnotify-message { + font-weight: normal; +} +.jnotify-container .jnotify-notification-warning .jnotify-close, .jnotify-container .jnotify-notification-warning .jnotify-message { + color: #a28918 !important; +} /* use or not ? */ div.jnotify-background { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 36fbd2bdd20..e29b3a7c9d3 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -341,11 +341,13 @@ input.buttongen { vertical-align: middle; } input.buttonpayment { - width: 300px; + min-width: 280px; margin-bottom: 15px; background-image: none; line-height: 24px; padding: 8px; + background: none; + border: 2px solid #666666; } input.buttonpaymentcb { background-image: url(); @@ -384,11 +386,18 @@ input.buttonpaymentstripe { background-repeat: no-repeat; background-position: 8px 7px; } +/* Used for timesheets */ span.timesheetalreadyrecorded input { border: none; border-bottom: solid 1px rgba(0,0,0,0.1); margin-right: 1px !important; } +td.onholidaymorning, td.onholidayafternoon { + background-color: #fdf6f2; +} +td.onholidayallday { + background-color: #f4eede; +} select.flat, form.flat select { font-weight: normal; @@ -691,6 +700,12 @@ div.myavailability { text-overflow: ellipsis; white-space: nowrap; } +.tdoverflowmax200 { /* For tdoverflow, the max-midth become a minimum ! */ + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} .tdoverflowmax300 { max-width: 300px; overflow: hidden; @@ -721,7 +736,9 @@ div.myavailability { margin-top: 6px; margin-bottom: 12px; } - +#builddoc_form ~ .showlinkedobjectblock { + margin-top: 20px; +} /* For the long description of module */ .moduledesclong p img,.moduledesclong p a img { @@ -856,11 +873,11 @@ div.fiche>form>div.div-table-responsive { .minwidth500imp { min-width: 100px !important; } } -/* Force values for small screen 570 */ +/* Force values for small screen 767 */ @media only screen and (max-width: 767px) { body { - font-size: px; + font-size: px; } } @@ -868,7 +885,7 @@ div.fiche>form>div.div-table-responsive { @media only screen and (max-width: 570px) { body { - font-size: px; + font-size: px; } .divmainbodylarge { margin-left: 20px; margin-right: 20px; } @@ -1111,6 +1128,9 @@ div.fiche { dol_hide_leftmenu) && ! empty($conf->dol_hide_topmenu)) print 'margin-top: 4px;'; ?> margin-bottom: 15px; } +body.onlinepaymentbody div.fiche { /* For online payment page */ + margin: 20px !important; +} div.fichecenter { width: 100%; clear: both; /* This is to have div fichecenter that are true rectangles */ @@ -1253,6 +1273,9 @@ div.heightref { div.divphotoref { padding-right: 20px; } +div.paginationref { + padding-bottom: 10px; +} div.statusref { float: right; padding-left: 12px; @@ -2050,8 +2073,12 @@ div.tabs { clear:both; height:100%; } -div.tabsElem { margin-top: 6px; } /* To avoid overlap of tabs when not browser */ - +div.tabsElem { + margin-top: 6px; +} /* To avoid overlap of tabs when not browser */ +div.tabsElem a { + font-weight: normal !important; +} div.tabBar { color: #; padding-top: 16px; @@ -2853,16 +2880,19 @@ input.liste_titre { border: 0px; } -.noborder tr.liste_total, .noborder tr.liste_total td, tr.liste_total, form.liste_total { - /* height: 32px; */ -} -.noborder tr.liste_total td, tr.liste_total td, form.liste_total div { - /* border-top: 1px solid #f4f4f4; */ +.noborder tr.liste_total td, tr.liste_total td, form.liste_total div, .noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { color: #332266; font-weight: normal; - white-space: nowrap; padding: 4px; } +.noborder tr.liste_total td, tr.liste_total td, form.liste_total div { + white-space: nowrap; +} +.noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div { + white-space: normal; +} + + tr.liste_sub_total, tr.liste_sub_total td { border-bottom: 2px solid #aaa; } @@ -3112,11 +3142,12 @@ div.warning { color: #302020; padding: 0.3em 0.3em 0.3em 0.3em; margin: 0.5em 0em 0.5em 0em; - border: 1px solid #e0d0b0; + /* border: 1px solid #e0d0b0; */ + border: 2px solid #805000 -moz-border-radius:3px; -webkit-border-radius: 3px; border-radius: 3px; - background: #EFDF9A; + /* background: #EFDF9A; */ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } @@ -3230,7 +3261,7 @@ div.titre { dol_optimize_smallscreen)?'':'margin-top: 4px;'); ?> } -#dolpaymenttable { width: 600px; font-size: 13px; } +#dolpaymenttable { min-width: 320px; font-size: 16px; } /* Width must have min to make stripe input area visible */ #tablepublicpayment { border: 1px solid #CCCCCC !important; width: 100%; padding: 20px; } #tablepublicpayment .CTableRow1 { background-color: #F0F0F0 !important; } #tablepublicpayment tr.liste_total { border-bottom: 1px solid #CCCCCC !important; } @@ -4021,6 +4052,12 @@ div#ecm-layout-center { padding-left: 10px !important; padding-right: 10px !important; } +.jnotify-container .jnotify-notification .jnotify-message { + font-weight: normal; +} +.jnotify-container .jnotify-notification-warning .jnotify-close, .jnotify-container .jnotify-notification-warning .jnotify-message { + color: #a28918 !important; +} /* use or not ? */ div.jnotify-background { diff --git a/htdocs/user/card.php b/htdocs/user/card.php index a495290f47a..40fa4db7a37 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -260,7 +260,7 @@ if (empty($reshook)) { } if (! empty($conf->categorie->enabled)) { // Categories association - $usercats = GETPOST( 'usercats', 'array' ); + $usercats = GETPOST('usercats', 'array'); $object->setCategories($usercats); } $db->commit(); @@ -478,7 +478,7 @@ if (empty($reshook)) { if (! $error && ! count($object->errors)) { // Then we add the associated categories - $categories = GETPOST( 'usercats', 'array' ); + $categories = GETPOST('usercats', 'array'); $object->setCategories($categories); } @@ -1760,7 +1760,7 @@ else $formmail->withdeliveryreceipt=1; $formmail->withcancel=1; // Tableau des substitutions - $formmail->setSubstitFromObject($object); + $formmail->setSubstitFromObject($object, $outputlangs); $formmail->substit['__LASTNAME__']=$object->lastname; $formmail->substit['__FIRSTNAME__']=$object->firstname; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 40124109961..4382ace94ff 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -384,7 +384,9 @@ class User extends CommonObject { if (! empty($obj->page) && ! empty($obj->type) && ! empty($obj->param)) { - // $obj->page is relative URL with or without params, $obj->type can be 'filters', 'sortorder', 'createform', ... + // $obj->page is relative URL with or without params + // $obj->type can be 'filters', 'sortorder', 'createform', ... + // $obj->param is key or param $pagewithoutquerystring=$obj->page; $pagequeries=''; if (preg_match('/^([^\?]+)\?(.*)$/', $pagewithoutquerystring, $reg)) // There is query param @@ -392,10 +394,18 @@ class User extends CommonObject $pagewithoutquerystring=$reg[1]; $pagequeries=$reg[2]; } - $this->default_values[$pagewithoutquerystring][$obj->type][$obj->param]=$obj->value; - if ($pagequeries) $this->default_values[$pagewithoutquerystring][$obj->type.'_queries']=$pagequeries; + $this->default_values[$pagewithoutquerystring][$obj->type][$pagequeries?$pagequeries:'_noquery_'][$obj->param]=$obj->value; + //if ($pagequeries) $this->default_values[$pagewithoutquerystring][$obj->type.'_queries']=$pagequeries; } } + // Sort by key, so _noquery_ is last + foreach($this->default_values as $a => $b) + { + foreach($b as $c => $d) + { + krsort($this->default_values[$a][$c]); + } + } $this->db->free($resql); } else @@ -2058,7 +2068,7 @@ class User extends CommonObject $label.= '
    '; $label.= '' . $langs->trans("User") . '
    '; - $label.= '' . $langs->trans('Name') . ': ' . $this->getFullName($langs,'',''); + $label.= '' . $langs->trans('Name') . ': ' . $this->getFullName($langs,''); if (! empty($this->login)) $label.= '
    ' . $langs->trans('Login') . ': ' . $this->login; $label.= '
    ' . $langs->trans("EMail").': '.$this->email; diff --git a/htdocs/user/group/ldap.php b/htdocs/user/group/ldap.php index c195136863e..ae0d974be9a 100644 --- a/htdocs/user/group/ldap.php +++ b/htdocs/user/group/ldap.php @@ -63,30 +63,31 @@ $object->getrights(); if ($action == 'dolibarr2ldap') { - $db->begin(); - $ldap=new Ldap(); $result=$ldap->connect_bind(); - $info=$object->_load_ldap_info(); - // Get a gid number for objectclass PosixGroup - if(in_array('posixGroup',$info['objectclass'])) - $info['gidNumber'] = $ldap->getNextGroupGid(); + if ($result > 0) + { + $info=$object->_load_ldap_info(); - $dn=$object->_load_ldap_dn($info); - $olddn=$dn; // We can say that old dn = dn as we force synchro + // Get a gid number for objectclass PosixGroup + if (in_array('posixGroup',$info['objectclass'])) { + $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); + } - $result=$ldap->update($dn,$info,$user,$olddn); + $dn=$object->_load_ldap_dn($info); + $olddn=$dn; // We can say that old dn = dn as we force synchro + + $result=$ldap->update($dn,$info,$user,$olddn); + } if ($result >= 0) { setEventMessages($langs->trans("GroupSynchronized"), null, 'mesgs'); - $db->commit(); } else { setEventMessages($ldap->error, $ldap->errors, 'errors'); - $db->rollback(); } } @@ -206,12 +207,10 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print '
    '.$langs->trans("ThisIsInformationOnPayment").' :
    '.$langs->trans("ThisIsInformationOnPayment").' :
    '.$langs->trans("Designation"); print ''.$text; - print ''; - print ''; + print ''; + print ''; print '
    '.$langs->trans("Creditor"); print ''.$creditor.''; - print ''; + print ''; print '
    '.$langs->trans("Designation"); print ''.$text; - print ''; - print ''; + print ''; + print ''; print '
    '.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
    '.$langs->trans("Document"); + print ''; + print $invoice->getDirectExternalLink(1); + print '
    '.$langs->trans("Designation"); print ''.$text; - print ''; - print ''; + print ''; + print ''; print '
    '.$langs->trans("Designation"); print ''.$text; - print ''; - print ''; + print ''; + print ''; print '
    '; print $companystatic->name_alias; print "
    '; llxFooter(); - $db->close(); - diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 04bbbcf8b81..47b8bb4879e 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -105,7 +105,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab { foreach($extrafields->attribute_label as $key => $val) { - $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>$extrafields->attribute_list[$key], 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>$extrafields->attribute_perms[$key]); } } diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php index 49739fa7c77..001915a8004 100644 --- a/htdocs/user/ldap.php +++ b/htdocs/user/ldap.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2015 Regis Houssin + * Copyright (C) 2006-2017 Regis Houssin * * 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 @@ -214,7 +214,7 @@ if ($result > 0) } else { - dol_print_error('',$ldap->error); + setEventMessages($ldap->error, $ldap->errors, 'errors'); } print ''; diff --git a/htdocs/user/note.php b/htdocs/user/note.php index 1734e7286d4..78fe25adfe9 100644 --- a/htdocs/user/note.php +++ b/htdocs/user/note.php @@ -65,7 +65,7 @@ if (empty($reshook)) { if ($action == 'update' && $user->rights->user->user->creer && !$_POST["cancel"]) { $db->begin(); - $res = $object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $res = $object->update_note(dol_html_entity_decode(GETPOST('note_private','none'), ENT_QUOTES)); if ($res < 0) { $mesg = '
    '.$adh->error.'
    '; $db->rollback(); diff --git a/htdocs/variants/admin/admin.php b/htdocs/variants/admin/admin.php index eedacb086b3..f3752469538 100644 --- a/htdocs/variants/admin/admin.php +++ b/htdocs/variants/admin/admin.php @@ -37,6 +37,12 @@ if ($_POST) { setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); } + if (dolibarr_set_const($db, 'PRODUIT_ATTRIBUTES_SEPARATOR', GETPOST('PRODUIT_ATTRIBUTES_SEPARATOR'), 'chaine', 0, '', $conf->entity)) { + setEventMessage($langs->trans('RecordSaved')); + } else { + setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); + } + } $title = $langs->trans('ModuleSetup').' '.$langs->trans('ProductAttributes'); @@ -55,6 +61,13 @@ print ''.$langs->trans("Value").''."\n"; print ' '."\n"; print ''.$langs->trans('HideProductCombinations').''; print $form->selectyesno("PRODUIT_ATTRIBUTES_HIDECHILD",$conf->global->PRODUIT_ATTRIBUTES_HIDECHILD,1).''; +print ''.$langs->trans('CombinationsSeparator').''; +if(isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { + $separator = $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR; +} else { + $separator = "_"; +} +print ''; print ''; print '
    '; print ''; diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index d3e6964aea6..04b987192e1 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -476,7 +476,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; */ public function createProductCombination(Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false) { - global $db, $user; + global $db, $user, $conf; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttribute.class.php'; require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'; @@ -542,7 +542,11 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']); } - $newproduct->ref .= '_'.$prodattrval->ref; + if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { + $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; + } else { + $newproduct->ref .= '_'.$prodattrval->ref; + } //The first one should not contain a linebreak if ($newproduct->description) { @@ -660,4 +664,4 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; return 1; } -} \ No newline at end of file +} diff --git a/htdocs/websites/class/websitepage.class.php b/htdocs/websites/class/websitepage.class.php index 756d927aed9..ae10398795c 100644 --- a/htdocs/websites/class/websitepage.class.php +++ b/htdocs/websites/class/websitepage.class.php @@ -52,6 +52,7 @@ class WebsitePage extends CommonObject public $title; public $description; public $keywords; + public $htmlheader; public $content; public $status; public $date_creation; @@ -67,11 +68,12 @@ class WebsitePage extends CommonObject 'title' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1), 'description' =>array('type'=>'varchar(255)', 'label'=>'Description', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1), 'keywords' =>array('type'=>'varchar(255)', 'label'=>'Keywords', 'enabled'=>1, 'visible'=>1, 'position'=>45, 'searchall'=>0), - 'content' =>array('type'=>'mediumtext', 'label'=>'Content', 'enabled'=>1, 'visible'=>1, 'position'=>45, 'searchall'=>0), - 'lang' =>array('type'=>'varchar(6)', 'label'=>'Lang', 'enabled'=>1, 'visible'=>1, 'position'=>45, 'searchall'=>0), + 'lang' =>array('type'=>'varchar(6)', 'label'=>'Lang', 'enabled'=>1, 'visible'=>1, 'position'=>45, 'searchall'=>0), //'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'index'=>true, 'position'=>1000), 'fk_website' =>array('type'=>'integer', 'label'=>'WebsiteId', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>40, 'searchall'=>0, 'foreignkey'=>'websitepage.rowid'), 'fk_page' =>array('type'=>'integer', 'label'=>'ParentPageId', 'enabled'=>1, 'visible'=>1, 'notnull'=>-1, 'position'=>45, 'searchall'=>0, 'foreignkey'=>'website.rowid'), + 'htmlheader' =>array('type'=>'text', 'label'=>'HtmlHeader', 'enabled'=>1, 'visible'=>0, 'position'=>50, 'searchall'=>0), + 'content' =>array('type'=>'mediumtext', 'label'=>'Content', 'enabled'=>1, 'visible'=>0, 'position'=>51, 'searchall'=>0), 'grabbed_from' =>array('type'=>'varchar(255)', 'label'=>'GrabbedFrom', 'enabled'=>1, 'visible'=>1, 'index'=>1, 'position'=>400, 'comment'=>'URL page content was grabbed from'), 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), @@ -126,6 +128,7 @@ class WebsitePage extends CommonObject $sql .= " t.title,"; $sql .= " t.description,"; $sql .= " t.keywords,"; + $sql .= " t.htmlheader,"; $sql .= " t.content,"; $sql .= " t.lang,"; $sql .= " t.fk_page,"; @@ -162,6 +165,7 @@ class WebsitePage extends CommonObject $this->title = $obj->title; $this->description = $obj->description; $this->keywords = $obj->keywords; + $this->htmlheader = $obj->htmlheader; $this->content = $obj->content; $this->lang = $obj->lang; $this->fk_page = $obj->fk_page; @@ -210,6 +214,7 @@ class WebsitePage extends CommonObject $sql .= " t.title,"; $sql .= " t.description,"; $sql .= " t.keywords,"; + $sql .= " t.htmlheader,"; $sql .= " t.content,"; $sql .= " t.lang,"; $sql .= " t.fk_page,"; @@ -255,6 +260,7 @@ class WebsitePage extends CommonObject $record->title = $obj->title; $record->description = $obj->description; $record->keywords = $obj->keywords; + $record->htmlheader = $obj->htmlheader; $record->content = $obj->content; $record->lang = $obj->lang; $record->fk_page = $obj->fk_page; @@ -469,6 +475,7 @@ class WebsitePage extends CommonObject $this->title = 'My Page'; $this->description = 'This is my page'; $this->keywords = 'keyword1, keyword2'; + $this->htmlheader = ''; $this->content = 'This is a html content'; $this->status = ''; $this->grabbed_from = ''; diff --git a/htdocs/websites/index.php b/htdocs/websites/index.php index 35731bc3bb0..95ef8f37948 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -94,6 +94,7 @@ $pageid=GETPOST('pageid', 'int'); $pageref=GETPOST('pageref', 'aZ09'); $action=GETPOST('action','alpha'); + if (GETPOST('delete')) { $action='delete'; } if (GETPOST('preview')) $action='preview'; if (GETPOST('createsite')) { $action='createsite'; } @@ -246,7 +247,11 @@ if ($action == 'add') $urltograbwithoutdomain = preg_replace('/^https?:\/\/[^\/]+\/?/i', '', $urltograbwithoutdomain); $objectpage->pageurl = basename($urltograbwithoutdomain); - if (empty($objectpage->pageurl)) $objectpage->pageurl='home'; + if (empty($objectpage->pageurl)) + { + $tmpdomain = getDomainFromURL($urltograb); + $objectpage->pageurl='home'.$tmpdomain; + } if (preg_match('/(.*)<\/title>/ims', $head, $regtmp)) { @@ -270,16 +275,62 @@ if ($action == 'add') $objectpage->content = preg_replace('/^.*<body[^>]*>/ims', '', $objectpage->content); $objectpage->content = preg_replace('/<\/body[^>]*>.*$/ims', '', $objectpage->content); + + // Now loop to fetch all css files. Include them inline into header of page + // TODO... + + + $tmp = $objectpage->content; + + // Now loop to fetch all images + preg_match_all('/<img([^\.\/]+)src="([^>"]+)"([^>]*)>/i', $objectpage->content, $regs); + foreach ($regs[0] as $key => $val) + { + $urltograbbis = $urltograb.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; + $linkwithoutdomain = $regs[2][$key]; + $filetosave = $conf->medias->multidir_output[$conf->entity].'/image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; + if (preg_match('/^http/', $regs[2][$key])) + { + $urltograbbis = $regs[2][$key]; + $linkwithoutdomain = preg_replace('/^https?:\/\/[^\/]+\//i', '', $regs[2][$key]); + $filetosave = $conf->medias->multidir_output[$conf->entity].'/image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; + } + + $tmpgeturl = getURLContent($urltograbbis); + if ($tmpgeturl['curl_error_no']) + { + $error++; + setEventMessages($tmpgeturl['curl_error_msg'], null, 'errors'); + $action='create'; + } + else + { + dol_mkdir(dirname($filetosave)); + + $fp = fopen($filetosave, "w"); + fputs($fp, $tmpgeturl['content']); + fclose($fp); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + } + + $filename = 'image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $linkwithoutdomain)?'':'/').$linkwithoutdomain; + $tmp = preg_replace('/'.preg_quote($regs[0][$key],'/').'/i', '<img'.$regs[1][$key].'src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file='.$filename.'"'.$regs[3][$key].'>', $tmp); + } + + //print dol_escape_htmltag($tmp);exit; + $objectpage->content = $tmp; + $objectpage->grabbed_from = $urltograb; } } else { - $objectpage->title = GETPOST('WEBSITE_TITLE'); - $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME'); - $objectpage->description = GETPOST('WEBSITE_DESCRIPTION'); - $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS'); - $objectpage->lang = GETPOST('WEBSITE_LANG'); + $objectpage->title = GETPOST('WEBSITE_TITLE','alpha'); + $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME','alpha'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION','alpha'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS','alpha'); + $objectpage->lang = GETPOST('WEBSITE_LANG','alpha'); } if (! $error) @@ -312,6 +363,33 @@ if ($action == 'add') $error++; setEventMessages($objectpage->error, $objectpage->errors, 'errors'); } + } + if (! $error) + { + if (! empty($objectpage->content)) + { + $filealias=$pathofwebsite.'/'.$objectpage->pageurl.'.php'; + $filetpl=$pathofwebsite.'/page'.$objectpage->id.'.tpl.php'; + + // Save page alias + $result=dolSavePageAlias($filealias, $object, $objectpage); + if (! $result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); + + // Save page of content + $result=dolSavePageContent($filetpl, $object, $objectpage); + if ($result) + { + setEventMessages($langs->trans("Saved"), null, 'mesgs'); + //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + //exit; + } + else + { + setEventMessages('Failed to write file '.$filetpl, null, 'errors'); + //header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid); + //exit; + } + } } if (! $error) { @@ -326,8 +404,36 @@ if ($action == 'add') if (! $error) { - $action = 'preview'; - $pageid = $objectpage->id; + $pageid = $objectpage->id; + + // To generate the CSS, robot and htmlheader file. + + if (! dol_is_file($filehtmlheader)) + { + // TODO use header of page for common header ? + $htmlheadercontent = "<!-- HTML header content (common for all pages) -->"; + $result=dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent); + } + + if (! dol_is_file($filecss)) + { + $csscontent = "/* CSS content (all pages) */\nbody.bodywebsite { margin: 0; }'"; + $result=dolSaveCssFile($filecss, $csscontent); + } + + if (! dol_is_file($filerobot)) + { + $robotcontent = "# Robot file. Generated with Dolibarr\nUser-agent: *\nAllow: /public/\nDisallow: /administrator/"; + $result=dolSaveRobotFile($filerobot, $robotcontent); + } + + if (! dol_is_file($filehtaccess)) + { + $htaccesscontent = "# Order allow,deny\n# Deny from all"; + $result=dolSaveHtaccessFile($filehtaccess, $htaccesscontent); + } + + $action = 'preview'; } } @@ -392,7 +498,7 @@ if ($action == 'updatecss') // $htmlheadercontent.= "header('Content-type: text/html');\n"; // Not required. htmlheader.html is never call as a standalone page $htmlheadercontent.= "// END PHP ?>\n";*/ - $htmlheadercontent.= preg_replace(array('/<html>\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER')); + $htmlheadercontent.= preg_replace(array('/<html>\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER', 'none')); /*$htmlheadercontent.= "\n".'<?php // BEGIN PHP'."\n"; $htmlheadercontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; @@ -400,18 +506,8 @@ if ($action == 'updatecss') $htmlheadercontent = trim($htmlheadercontent)."\n"; - dol_syslog("Save html header into ".$filehtmlheader); + dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent); - dol_mkdir($pathofwebsite); - $result = file_put_contents($filehtmlheader, $htmlheadercontent); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($filehtmlheader, octdec($conf->global->MAIN_UMASK)); - - if (! $result) - { - $error++; - setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors'); - } // Css file $csscontent =''; @@ -425,7 +521,7 @@ if ($action == 'updatecss') $csscontent.= "header('Content-type: text/css');\n"; $csscontent.= "// END PHP ?>\n"; - $csscontent.= GETPOST('WEBSITE_CSS_INLINE'); + $csscontent.= GETPOST('WEBSITE_CSS_INLINE', 'none'); $csscontent.= "\n".'<?php // BEGIN PHP'."\n"; $csscontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; @@ -457,7 +553,7 @@ if ($action == 'updatecss') $robotcontent.= "header('Content-type: text/css');\n"; $robotcontent.= "// END PHP ?>\n";*/ - $robotcontent.= GETPOST('WEBSITE_ROBOT'); + $robotcontent.= GETPOST('WEBSITE_ROBOT', 'none'); /*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n"; $robotcontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; @@ -489,7 +585,7 @@ if ($action == 'updatecss') $robotcontent.= "header('Content-type: text/css');\n"; $robotcontent.= "// END PHP ?>\n";*/ - $htaccesscontent.= GETPOST('WEBSITE_HTACCESS'); + $htaccesscontent.= GETPOST('WEBSITE_HTACCESS', 'none'); /*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n"; $robotcontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n"; @@ -587,11 +683,11 @@ if ($action == 'updatemeta') { $objectpage->old_object = clone $objectpage; - $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME'); - $objectpage->title = GETPOST('WEBSITE_TITLE'); - $objectpage->description = GETPOST('WEBSITE_DESCRIPTION'); - $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS'); - $objectpage->lang = GETPOST('WEBSITE_LANG'); + $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha'); + $objectpage->title = GETPOST('WEBSITE_TITLE', 'alpha'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alpha'); + $objectpage->lang = GETPOST('WEBSITE_LANG', 'alpha'); $res = $objectpage->update($user); if (! $res > 0) @@ -1446,6 +1542,12 @@ if ($action == 'editmeta' || $action == 'create') if ($action != 'create') { + print '<tr><td class="titlefield">'; + print $langs->trans('IDOfPage'); + print '</td><td>'; + print $pageid; + print '</td></tr>'; + print '<tr><td class="titlefield">'; print $langs->trans('WEBSITE_PAGEURL'); print '</td><td>'; @@ -1737,3 +1839,117 @@ function dolSavePageContent($filetpl, $object, $objectpage) return $result; } + + +/** + * Save content of a page on disk + * + * @param string $filetpl Full path of filename to generate + * @param string $htmlheadercontent Content of file + * @return boolean True if OK + */ +function dolSaveHtmlHeader($filehtmlheader, $htmlheadercontent) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save html header into ".$filehtmlheader); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filehtmlheader, $htmlheadercontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filehtmlheader, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filehtmlheader, null, 'errors'); + return false; + } + + return true; +} + +/** + * Save content of a page on disk + * + * @param string $filecss Full path of filename to generate + * @param string $csscontent Content of file + * @return boolean True if OK + */ +function dolSaveCssFile($filecss, $csscontent) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save html header into ".$filecss); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filecss, $csscontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filecss, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filecss, null, 'errors'); + return false; + } + + return true; +} + +/** + * Save content of a page on disk + * + * @param string $filerobot Full path of filename to generate + * @param string $robotcontent Content of file + * @return boolean True if OK + */ +function dolSaveRobotFile($filerobot, $robotcontent) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save html header into ".$filerobot); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filerobot, $robotcontent); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filerobot, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filerobot, null, 'errors'); + return false; + } + + return true; +} + +/** + * Save content of a page on disk + * + * @param string $filehtaccess Full path of filename to generate + * @param string $htaccess Content of file + * @return boolean True if OK + */ +function dolSaveHtaccessFile($filehtaccess, $htaccess) +{ + global $conf, $pathofwebsite; + + dol_syslog("Save html header into ".$filehtaccess); + + dol_mkdir($pathofwebsite); + $result = file_put_contents($filehtaccess, $htaccess); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($filehtaccess, octdec($conf->global->MAIN_UMASK)); + + if (! $result) + { + $error++; + setEventMessages('Failed to write file '.$filehtaccess, null, 'errors'); + return false; + } + + return true; +} + diff --git a/scripts/emailings/mailing-send.php b/scripts/emailings/mailing-send.php index 0de6ca4f5fd..a6cf54ab40d 100755 --- a/scripts/emailings/mailing-send.php +++ b/scripts/emailings/mailing-send.php @@ -163,22 +163,25 @@ if ($resql) $tmpfield=explode('=',$other[4],2); $other5=(isset($tmpfield[1])?$tmpfield[1]:$tmpfield[0]); $signature = ((!empty($user->signature) && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))?$user->signature:''); - // Array of possible substitutions (See also file mailing-send.php that should manage same substitutions) - $substitutionarray=array( - '__ID__' => $obj2->source_id, - '__EMAIL__' => $obj2->email, - '__LASTNAME__' => $obj2->lastname, - '__FIRSTNAME__' => $obj2->firstname, - '__MAILTOEMAIL__' => '<a href="mailto:'.$obj2->email.'">'.$obj2->email.'</a>', - '__OTHER1__' => $other1, - '__OTHER2__' => $other2, - '__OTHER3__' => $other3, - '__OTHER4__' => $other4, - '__OTHER5__' => $other5, - '__SIGNATURE__' => $signature, // Signature is empty when ran from command line or taken from user in parameter) - '__CHECK_READ__' => '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.$obj2->tag.'&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" width="1" height="1" style="width:1px;height:1px" border="0"/>', - '__UNSUBSCRIBE__' => '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.$obj2->tag.'&unsuscrib=1&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" target="_blank">'.$langs->trans("MailUnsubcribe").'</a>' - ); + $object = null; // Not defined with mass emailing + $parameters=array('mode'=>'emailing'); + $substitutionarray=getCommonSubstitutionArray($langs, 2, array('object','objectamount'), $object); // Note: On mass emailing, this is null because we don't know object + + // Array of possible substitutions (See also file mailing-send.php that should manage same substitutions) + $substitutionarray['__ID__'] = $obj->source_id; + $substitutionarray['__EMAIL__'] = $obj->email; + $substitutionarray['__LASTNAME__'] = $obj->lastname; + $substitutionarray['__FIRSTNAME__'] = $obj->firstname; + $substitutionarray['__MAILTOEMAIL__'] = '<a href="mailto:'.$obj->email.'">'.$obj->email.'</a>'; + $substitutionarray['__OTHER1__'] = $other1; + $substitutionarray['__OTHER2__'] = $other2; + $substitutionarray['__OTHER3__'] = $other3; + $substitutionarray['__OTHER4__'] = $other4; + $substitutionarray['__OTHER5__'] = $other5; + $substitutionarray['__SIGNATURE__'] = $signature; // Signature is empty when ran from command line or taken from user in parameter) + $substitutionarray['__CHECK_READ__'] = '<img src="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-read.php?tag='.$obj->tag.'&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" width="1" height="1" style="width:1px;height:1px" border="0"/>'; + $substitutionarray['__UNSUBSCRIBE__'] = '<a href="'.DOL_MAIN_URL_ROOT.'/public/emailing/mailing-unsubscribe.php?tag='.$obj->tag.'&unsuscrib=1&securitykey='.urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY).'" target="_blank">'.$langs->trans("MailUnsubcribe").'</a>'; + $onlinepaymentenabled = 0; if (! empty($conf->paypal->enabled)) $onlinepaymentenabled++; if (! empty($conf->paybox->enabled)) $onlinepaymentenabled++; @@ -186,18 +189,20 @@ if ($resql) if ($onlinepaymentenabled && ! empty($conf->global->PAYMENT_SECURITY_TOKEN)) { $substitutionarray['__SECUREKEYPAYMENT__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - - if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYMENT_MEMBER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYMENT_MEMBER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2); - - if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYMENT_ORDER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYMENT_ORDER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'order' . $obj->source_id, 2); - - if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYMENT_INVOICE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYMENT_INVOICE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'invoice' . $obj->source_id, 2); - - if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); - else $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'contractline' . $obj->source_id, 2); + if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) + { + $substitutionarray['__SECUREKEYPAYMENT_MEMBER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); + $substitutionarray['__SECUREKEYPAYMENT_ORDER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); + $substitutionarray['__SECUREKEYPAYMENT_INVOICE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); + $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2); + } + else + { + $substitutionarray['__SECUREKEYPAYMENT_MEMBER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'membersubscription' . $obj->source_id, 2); + $substitutionarray['__SECUREKEYPAYMENT_ORDER__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'order' . $obj->source_id, 2); + $substitutionarray['__SECUREKEYPAYMENT_INVOICE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'invoice' . $obj->source_id, 2); + $substitutionarray['__SECUREKEYPAYMENT_CONTRACTLINE__']=dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . 'contractline' . $obj->source_id, 2); + } } /* For backward compatibility */ if (! empty($conf->paypal->enabled) && ! empty($conf->global->PAYPAL_SECURITY_TOKEN)) @@ -216,6 +221,7 @@ if ($resql) if (empty($conf->global->PAYPAL_SECURITY_TOKEN_UNIQUE)) $substitutionarray['__SECUREKEYPAYPAL_CONTRACTLINE__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN, 2); else $substitutionarray['__SECUREKEYPAYPAL_CONTRACTLINE__']=dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'contractline' . $obj->source_id, 2); } + complete_substitutions_array($substitutionarray,$langs); $newsubject=make_substitutions($subject,$substitutionarray); $newmessage=make_substitutions($message,$substitutionarray); diff --git a/scripts/members/sync_members_types_dolibarr2ldap.php b/scripts/members/sync_members_types_dolibarr2ldap.php new file mode 100755 index 00000000000..939a98c8728 --- /dev/null +++ b/scripts/members/sync_members_types_dolibarr2ldap.php @@ -0,0 +1,131 @@ +#!/usr/bin/env php +<?php +/** + * Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2006 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2017 Regis Houssin <regis.houssin@capnetworks.com> + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file scripts/user/sync_members_types_dolibarr2ldap.php + * \ingroup ldap core + * \brief Script de mise a jour des types de membres dans LDAP depuis base Dolibarr + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +if (! isset($argv[1]) || ! $argv[1]) { + print "Usage: ".$script_file." now\n"; + exit(-1); +} +$now=$argv[1]; + +require_once($path."../../htdocs/master.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php"); +require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"); + +// Global variables +$version=DOL_VERSION; +$error=0; + + +/* + * Main + */ + +@set_time_limit(0); +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +dol_syslog($script_file." launched with arg ".join(',',$argv)); + +/* +if (! $conf->global->LDAP_SYNCHRO_ACTIVE) +{ + print $langs->trans("LDAPSynchronizationNotSetupInDolibarr"); + exit(-1); +} +*/ + +$sql = "SELECT rowid"; +$sql .= " FROM ".MAIN_DB_PREFIX."adherent_type"; + +$resql = $db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + + $ldap=new Ldap(); + $result=$ldap->connect_bind(); + + if ($result > 0) + { + while ($i < $num) + { + $ldap->error=""; + + $obj = $db->fetch_object($resql); + + $membertype = new AdherentType($db); + $membertype->id = $obj->rowid; + $membertype->fetch($membertype->id); + + print $langs->trans("UpdateMemberType")." rowid=".$membertype->id." ".$membertype-label; + + $oldobject=$membertype; + + $oldinfo=$membertype->_load_ldap_info(); + $olddn=$membertype->_load_ldap_dn($oldinfo); + + $info=$membertype->_load_ldap_info(); + $dn=$membertype->_load_ldap_dn($info); + + $result=$ldap->add($dn,$info,$user); // Wil fail if already exists + $result=$ldap->update($dn,$info,$user,$olddn); + if ($result > 0) + { + print " - ".$langs->trans("OK"); + } + else + { + $error++; + print " - ".$langs->trans("KO").' - '.$ldap->error; + } + print "\n"; + + $i++; + } + + $ldap->unbind(); + $ldap->close(); + } + else { + print $ldap->error; + } +} +else +{ + dol_print_error($db); +} + +exit($error); diff --git a/scripts/members/sync_members_types_ldap2dolibarr.php b/scripts/members/sync_members_types_ldap2dolibarr.php new file mode 100755 index 00000000000..fb8fb160d36 --- /dev/null +++ b/scripts/members/sync_members_types_ldap2dolibarr.php @@ -0,0 +1,221 @@ +#!/usr/bin/env php +<?php +/** + * Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2006-2012 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2013 Maxime Kohlhaas <maxime@atm-consulting.fr> + * Copyright (C) 2017 Regis Houssin <regis.houssin@capnetworks.com> + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file scripts/user/sync_members_types_ldap2dolibarr.php + * \ingroup ldap member + * \brief Script to update members types into Dolibarr from LDAP + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit(-1); +} + +require_once($path."../../htdocs/master.inc.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php"); +require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php"); + +$langs->load("main"); +$langs->load("errors"); + + +// Global variables +$version=DOL_VERSION; +$error=0; +$forcecommit=0; +$confirmed=0; + + +/* + * Main + */ + +@set_time_limit(0); +print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +dol_syslog($script_file." launched with arg ".join(',',$argv)); + +// List of fields to get from LDAP +$required_fields = array( + $conf->global->LDAP_KEY_MEMBERS_TYPES, + $conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME, + $conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION, + $conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS +); + +// Remove from required_fields all entries not configured in LDAP (empty) and duplicated +$required_fields=array_unique(array_values(array_filter($required_fields, "dolValidElement"))); + + +if (! isset($argv[1])) { + //print "Usage: $script_file (nocommitiferror|commitiferror) [id_group]\n"; + print "Usage: $script_file (nocommitiferror|commitiferror) [--server=ldapserverhost] [--excludeuser=user1,user2...] [-y]\n"; + exit(-1); +} + +foreach($argv as $key => $val) +{ + if ($val == 'commitiferror') $forcecommit=1; + if (preg_match('/--server=([^\s]+)$/',$val,$reg)) $conf->global->LDAP_SERVER_HOST=$reg[1]; + if (preg_match('/--excludeuser=([^\s]+)$/',$val,$reg)) $excludeuser=explode(',',$reg[1]); + if (preg_match('/-y$/',$val,$reg)) $confirmed=1; +} + +print "Mails sending disabled (useless in batch mode)\n"; +$conf->global->MAIN_DISABLE_ALL_MAILS=1; // On bloque les mails +print "\n"; +print "----- Synchronize all records from LDAP database:\n"; +print "host=".$conf->global->LDAP_SERVER_HOST."\n"; +print "port=".$conf->global->LDAP_SERVER_PORT."\n"; +print "login=".$conf->global->LDAP_ADMIN_DN."\n"; +print "pass=".preg_replace('/./i','*',$conf->global->LDAP_ADMIN_PASS)."\n"; +print "DN to extract=".$conf->global->LDAP_MEMBER_TYPE_DN."\n"; +print 'Filter=('.$conf->global->LDAP_KEY_MEMBERS_TYPES.'=*)'."\n"; +print "----- To Dolibarr database:\n"; +print "type=".$conf->db->type."\n"; +print "host=".$conf->db->host."\n"; +print "port=".$conf->db->port."\n"; +print "login=".$conf->db->user."\n"; +print "database=".$conf->db->name."\n"; +print "----- Options:\n"; +print "commitiferror=".$forcecommit."\n"; +print "Mapped LDAP fields=".join(',',$required_fields)."\n"; +print "\n"; + +if (! $confirmed) +{ + print "Hit Enter to continue or CTRL+C to stop...\n"; + $input = trim(fgets(STDIN)); +} + +if (empty($conf->global->LDAP_MEMBER_TYPE_DN)) +{ + print $langs->trans("Error").': '.$langs->trans("LDAP setup for members types not defined inside Dolibarr"); + exit(-1); +} + + +$ldap = new Ldap(); +$result = $ldap->connect_bind(); +if ($result >= 0) +{ + $justthese=array(); + + + // We disable synchro Dolibarr-LDAP + $conf->global->LDAP_MEMBER_TYPE_ACTIVE=0; + + $ldaprecords = $ldap->getRecords('*',$conf->global->LDAP_MEMBER_TYPE_DN, $conf->global->LDAP_KEY_MEMBERS_TYPES, $required_fields, 0, array($conf->global->LDAP_MEMBER_TYPE_FIELD_GROUPMEMBERS)); + if (is_array($ldaprecords)) + { + $db->begin(); + + // Warning $ldapuser has a key in lowercase + foreach ($ldaprecords as $key => $ldapgroup) + { + $membertype = new AdherentType($db); + $membertype->fetch('', $ldapgroup[$conf->global->LDAP_KEY_MEMBERS_TYPES]); + $membertype->label = $ldapgroup[$conf->global->LDAP_MEMBER_TYPE_FIELD_FULLNAME]; + $membertype->description = $ldapgroup[$conf->global->LDAP_MEMBER_TYPE_FIELD_DESCRIPTION]; + $membertype->entity = $conf->entity; + + //print_r($ldapgroup); + + if ($membertype->id > 0) { // Member type update + print $langs->transnoentities("MemberTypeUpdate").' # '.$key.': name='.$membertype->label; + $res=$membertype->update($user); + + if ($res > 0) + { + print ' --> Updated member type id='.$membertype->id.' name='.$membertype->label; + } + else + { + $error++; + print ' --> '.$res.' '.$membertype->error; + } + print "\n"; + } else { // Member type creation + print $langs->transnoentities("MemberTypeCreate").' # '.$key.': name='.$membertype->label; + $res=$membertype->create($user); + + if ($res > 0) + { + print ' --> Created member type id='.$membertype->id.' name='.$membertype->label; + } + else + { + $error++; + print ' --> '.$res.' '.$membertype->error; + } + print "\n"; + } + + //print_r($membertype); + } + + if (! $error || $forcecommit) + { + if (! $error) print $langs->transnoentities("NoErrorCommitIsDone")."\n"; + else print $langs->transnoentities("ErrorButCommitIsDone")."\n"; + $db->commit(); + } + else + { + print $langs->transnoentities("ErrorSomeErrorWereFoundRollbackIsDone",$error)."\n"; + $db->rollback(); + } + print "\n"; + } + else + { + dol_print_error('',$ldap->error); + $error++; + } +} +else +{ + dol_print_error('',$ldap->error); + $error++; +} + + +exit($error); + + +/** + * Function to say if a value is empty or not + * + * @param string $element Value to test + * @return boolean True of false + */ +function dolValidElement($element) +{ + return (trim($element) != ''); +} + diff --git a/test/phpunit/AdherentTest.php b/test/phpunit/AdherentTest.php index 34ec0a80917..4c92f507f66 100644 --- a/test/phpunit/AdherentTest.php +++ b/test/phpunit/AdherentTest.php @@ -138,8 +138,8 @@ class AdherentTest extends PHPUnit_Framework_TestCase $localobject=new AdherentType($this->savdb); $localobject->statut=1; - $localobject->libelle='Adherent type test'; - $localobject->cotisation=1; + $localobject->label='Adherent type test'; + $localobject->subscription=1; $localobject->vote=1; $result=$localobject->create($user); print __METHOD__." result=".$result."\n"; @@ -196,7 +196,6 @@ class AdherentTest extends PHPUnit_Framework_TestCase $result=$localobject->fetch($id); print __METHOD__." id=".$id." result=".$result."\n"; $this->assertLessThan($result, 0); - return $localobject; } @@ -318,14 +317,13 @@ class AdherentTest extends PHPUnit_Framework_TestCase $langs=$this->savlangs; $db=$this->savdb; - $template = '%DOL_MAIN_URL_ROOT%,%ID%,%CIVILITY%,%FIRSTNAME%,%LASTNAME%,%FULLNAME%,%COMPANY%,'. - '%ADDRESS%,%ZIP%,%TOWN%,%COUNTRY%,%EMAIL%,%BIRTH%,%PHOTO%,%LOGIN%,%PASSWORD%,%PRENOM%,'. - '%NOM%,%SOCIETE%,%ADDRESS%,%ZIP%,%TOWN%,%COUNTRY%'; + $template = '__CIVILITY__,__FIRSTNAME__,__LASTNAME__,__FULLNAME__,__COMPANY__,'. + '__ADDRESS__,__ZIP__,__TOWN__,__COUNTRY__,__EMAIL__,__BIRTH__,__PHOTO__,__LOGIN__'; // If option to store clear password has been set, we get 'dolibspec' into PASSWORD field. - $expected = DOL_MAIN_URL_ROOT.','.$localobject->id.',,New firstname,New name,New firstname New name,'. + $expected = ',New firstname,New name,New firstname New name,'. 'New company,New address,New zip,New town,Belgium,newemail@newemail.com,'.dol_print_date($localobject->birth,'day').',,'. - 'newlogin,dolibspec,New firstname,New name,New company,New address,New zip,New town,Belgium'; + 'newlogin'; $result = $localobject->makeSubstitution($template); print __METHOD__." result=".$result."\n"; diff --git a/test/phpunit/FactureTest.php b/test/phpunit/FactureTest.php index 8c3d4a2374a..eed67935032 100644 --- a/test/phpunit/FactureTest.php +++ b/test/phpunit/FactureTest.php @@ -272,12 +272,41 @@ class FactureTest extends PHPUnit_Framework_TestCase $langs=$this->savlangs; $db=$this->savdb; + // Force default setup + unset($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED); + unset($conf->global->INVOICE_CAN_NEVER_BE_REMOVED); + $localobject=new Facture($this->savdb); $result=$localobject->fetch($id); - $result=$localobject->delete($user); + // Create another invoice and validate it after $localobject + $localobject2=new Facture($this->savdb); + $result=$localobject2->initAsSpecimen(); + $result=$localobject2->create($user); + $result=$localobject2->validate($user); + print 'Invoice localobject ref = '.$localobject->ref."\n"; + print 'Invoice $localobject2 created with ref = '.$localobject2->ref."\n"; + + $conf->global->INVOICE_CAN_NEVER_BE_REMOVED = 1; + + $result=$localobject2->delete($user); // Deletion is KO, option INVOICE_CAN_NEVER_BE_REMOVED is on print __METHOD__." id=".$id." result=".$result."\n"; - $this->assertGreaterThanOrEqual(0, $result); + $this->assertEquals(0, $result, 'Deletion should fail, option INVOICE_CAN_NEVER_BE_REMOVED is on'); + + unset($conf->global->INVOICE_CAN_NEVER_BE_REMOVED); + + $result=$localobject->delete($user); // Deletion is KO, it is not last invoice + print __METHOD__." id=".$id." result=".$result."\n"; + $this->assertEquals(0, $result, 'Deletion should fail, it is not last invoice'); + + $result=$localobject2->delete($user); // Deletion is OK, it is last invoice + print __METHOD__." id=".$id." result=".$result."\n"; + $this->assertGreaterThan(0, $result, 'Deletion should work, it is last invoice'); + + $result=$localobject->delete($user); // Deletion is KO, it is not last invoice + print __METHOD__." id=".$id." result=".$result."\n"; + $this->assertGreaterThan(0, $result, 'Deletion should work, it is again last invoice'); + return $result; }