diff --git a/ChangeLog b/ChangeLog index 1235a85e097..7823d4cefb1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,8 +17,48 @@ Following changes may create regressions for some external modules, but were nec __PROPALREF__, ...) +***** 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/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/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..783934deb34 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -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/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/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..2f440f9f873 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,6 +175,7 @@ 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['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,10 +287,9 @@ 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]=''; @@ -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/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/api/admin/index.php b/htdocs/api/admin/index.php index f2c5160db38..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 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/comm/action/card.php b/htdocs/comm/action/card.php index b491c9007cb..02a16af3c17 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -824,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 ''; diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index c40192723a8..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; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 8fb2a102c22..4fc1eebb66d 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -358,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'); @@ -386,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'); @@ -979,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); 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/remx.php b/htdocs/comm/remx.php index 332181922d2..7a34d1a3a76 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -292,7 +292,7 @@ if ($socid > 0) print $form->load_tva('tva_tx',GETPOST('tva_tx'),$mysoc,$object); print ''; print ''.$langs->trans("NoteReason").''; - print ''; + print ''; print ""; } diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 4c49cef6820..5da8423c0a2 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -256,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'); @@ -927,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'); @@ -1210,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 @@ -1254,6 +1249,11 @@ 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->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'; @@ -2492,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 ''; diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index cd4d659d743..8cb5b878dc0 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; @@ -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/class/account.class.php b/htdocs/compta/bank/class/account.class.php index b575180feed..cb59862e005 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; } } diff --git a/htdocs/compta/bank/index.php b/htdocs/compta/bank/index.php index 5a0ab062b29..4485680a4e9 100644 --- a/htdocs/compta/bank/index.php +++ b/htdocs/compta/bank/index.php @@ -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), @@ -121,7 +122,7 @@ 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 { $search_ref=''; $search_label=''; @@ -142,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 @@ -337,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)) { @@ -407,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)) @@ -442,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 ''; @@ -462,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']++; } @@ -477,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']++; } @@ -485,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']++; } @@ -496,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']++; @@ -514,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 @@ -525,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")).')'; @@ -570,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']++; } @@ -578,7 +595,7 @@ 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']++; } @@ -586,7 +603,7 @@ foreach ($accounts as $key=>$type) // Status if (! empty($arrayfields['b.clos']['checked'])) { - print ''.$acc->getLibStatut(5).''; + print ''.$obj->getLibStatut(5).''; if (! $i) $totalarray['nbfield']++; } @@ -594,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']; @@ -614,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 b3a21f9af31..2535d8e7442 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1414,6 +1414,7 @@ if (empty($reshook)) { $line->origin = $object->origin; $line->origin_id = $line->id; + $line->fetch_optionals($line->id); } } @@ -1435,7 +1436,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(); + } + } } } @@ -1801,7 +1816,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'); @@ -2550,8 +2565,8 @@ if ($action == 'create') print $desc; print '
'; - print '    0 ? 'checked':'').' /> "; - print '
    0 ? 'checked':'').' /> "; + print '    0 ? 'checked':'').' /> "; + print '
    0 ? 'checked':'').' /> "; print '
'; print '
'; 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 b3a8a68611d..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'); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 41cc8042144..b6d294c6e18 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; 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..e911f6eab74 --- /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) + { + $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 + */ + +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/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/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/contrat/card.php b/htdocs/contrat/card.php index 16c843466f9..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,135 +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->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 69bda6f2b1c..61cd62bd338 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -790,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,"; @@ -828,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; @@ -934,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"); @@ -2711,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,"; @@ -2764,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; diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index c6fbaf478bf..2afee019bed 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -47,6 +47,7 @@ $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")); @@ -116,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), @@ -156,7 +158,8 @@ 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=''; @@ -199,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,'; @@ -246,6 +249,7 @@ 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); @@ -275,7 +279,7 @@ $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 fields from extrafields @@ -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; @@ -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/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 2ac0b3a5885..e0acad65ab8 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -104,7 +104,7 @@ if (! $error && $massaction == 'confirm_presend') if (empty($receiver) || $receiver == '-1') $receiver=array(); else $receiver=array($receiver); } - if (count($receiver) == 0 && count($listofobjectthirdparties) == 1) // if only one recipient, receiver is mandatory + 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'); @@ -322,114 +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; - - $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
'; - } - } + $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
'; + } + } + } + } } } diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 144cba07779..4439f0034ce 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -18,8 +18,8 @@ /** * \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 @@ -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; @@ -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 71a9a4e3125..d3059daba53 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -435,7 +435,7 @@ class box_activity extends ModeleBoxes } // 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/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 54a907a3c0f..bd6f658185d 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); diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index ad224fec97d..aa1651d6fc6 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -254,6 +254,7 @@ 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"; @@ -287,15 +288,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/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 53327f67a15..f79198a7096 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 @@ -898,7 +899,7 @@ class ExtraFields { $tmp=explode(',',$size); $newsize=$tmp[0]; - $out=''; + $out=''; } elseif ($type == 'varchar') { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 628be5660df..8db18e2c748 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= ''; - // TODO Use an internal dolibarr component instead of select2 - $outdelayed=' + $tmpplugin='select2'; + $outdelayed="\n".' '."\n"; - print ''."\n"; } } @@ -1319,7 +1320,7 @@ 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')) 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 ''; - 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..259db698024 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,19 @@ 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), + '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), '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), + '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 +144,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; } /** 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/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 37354d854b0..515768b8011 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 @@ -270,12 +270,32 @@ 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 ''; + if ($val['type'] == 'text') + { + print ''; + } + elseif (is_array($val['arrayofkeyval'])) + { + print $form->selectarray($key, $val['arrayofkeyval'], GETPOST($key, 'int')); + } + else + { + $cssforinput = 'minwidth100'; + print ''; + } + print ''; print ''; } print ''."\n"; @@ -292,7 +312,7 @@ if ($action == 'create') // 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 ''; @@ -308,9 +328,26 @@ if (($id || $ref) && $action == 'edit') print ''.$langs->trans($val['label']).''; - print ''; + print ''; + if ($val['type'] == 'text') + { + print ''; + } + elseif (is_array($val['arrayofkeyval'])) + { + print $form->selectarray($key, $val['arrayofkeyval'], GETPOST($key, 'int')); + } + else + { + $cssforinput = 'minwidth100'; + print ''; + } + print ''; print ''; } print ''; @@ -326,6 +363,7 @@ if (($id || $ref) && $action == 'edit') + // Part to show record if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { @@ -509,10 +547,12 @@ 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 '
'; } diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index f591fa7db80..475716114fa 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 @@ -491,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'; @@ -524,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++; } @@ -607,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/card.php b/htdocs/product/card.php index 143b375f5b3..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'); @@ -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'); @@ -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 bdb9f3349af..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 diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index c5eca27b348..7ef847855e5 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")); diff --git a/htdocs/product/inventory/list.php b/htdocs/product/inventory/list.php index 6f443324f6b..a8ce9c404e6 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")); @@ -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/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/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/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/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 ''; -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 52aa5950a92..1862a5b8a47 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -143,12 +143,11 @@ if (! empty($FULLTAG)) $urlok.='fulltag='.urlencode($FULLTAG).'&'; $urlko.='fulltag='.urlencode($FULLTAG).'&'; } -/* This make url too long. Seems not required into the back url if (! empty($SECUREKEY)) { $urlok.='securekey='.urlencode($SECUREKEY).'&'; $urlko.='securekey='.urlencode($SECUREKEY).'&'; -}*/ +} if (! empty($entity)) { $urlok.='e='.urlencode($entity).'&'; @@ -336,6 +335,10 @@ 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")); 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 80d6799e278..3b56046e55f 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -2488,7 +2488,7 @@ else $formmail->setSubstitFromObject($object); $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 diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 786e5a09890..f280a9db89c 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -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; 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 1b3857fdbf1..a997b5f4b96 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -268,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); @@ -286,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'); @@ -465,7 +465,7 @@ 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')); } } } @@ -774,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); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index e6bf4d8233a..71f741a907b 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -689,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; @@ -719,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 { @@ -863,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; } } @@ -875,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; } @@ -2037,7 +2045,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; @@ -2749,14 +2759,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; } @@ -3025,11 +3037,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); } @@ -3131,12 +3144,11 @@ 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 { min-width: 310px; font-size: 16px; } /* Width must have min to make stripe input area visible */ @@ -3984,6 +3996,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 64210218799..02705f63801 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -700,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; @@ -730,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 { @@ -865,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; } } @@ -877,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; } @@ -2062,8 +2070,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; @@ -2865,16 +2877,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; } @@ -3124,11 +3139,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); } @@ -4033,6 +4049,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/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 '
'; 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 "
'.$langs->trans("Comments").'
'; llxFooter(); - $db->close(); - 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/index.php b/htdocs/websites/index.php index 35731bc3bb0..96947035113 100644 --- a/htdocs/websites/index.php +++ b/htdocs/websites/index.php @@ -275,11 +275,11 @@ if ($action == 'add') } 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) @@ -392,7 +392,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('/\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER')); + $htmlheadercontent.= preg_replace(array('/\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER', 'none')); /*$htmlheadercontent.= "\n".'\n"; - $csscontent.= GETPOST('WEBSITE_CSS_INLINE'); + $csscontent.= GETPOST('WEBSITE_CSS_INLINE', 'none'); $csscontent.= "\n".'\n";*/ - $robotcontent.= GETPOST('WEBSITE_ROBOT'); + $robotcontent.= GETPOST('WEBSITE_ROBOT', 'none'); /*$robotcontent.= "\n".'\n";*/ - $htaccesscontent.= GETPOST('WEBSITE_HTACCESS'); + $htaccesscontent.= GETPOST('WEBSITE_HTACCESS', 'none'); /*$robotcontent.= "\n".'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) 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__' => ''.$obj2->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").'' - ); + $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__'] = ''.$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++; @@ -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 + + * Copyright (C) 2006 Laurent Destailleur + * Copyright (C) 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 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 + + * Copyright (C) 2006-2012 Laurent Destailleur + * Copyright (C) 2013 Maxime Kohlhaas + * Copyright (C) 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 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";