From 517301f014179525bd626a5fa62abe1d4c3b65c7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 21 Mar 2018 16:40:09 +0100 Subject: [PATCH] Work on subscription reminder --- htdocs/adherents/admin/adherent_emails.php | 2 +- htdocs/adherents/class/adherent.class.php | 129 ++++++++++++++++++ htdocs/admin/mails_templates.php | 8 +- htdocs/core/class/html.formmail.class.php | 7 +- htdocs/core/modules/modAdherent.class.php | 6 + .../mysql/data/llx_c_email_templates.sql | 4 +- .../install/mysql/migration/7.0.0-8.0.0.sql | 6 + htdocs/langs/en_US/members.lang | 6 +- 8 files changed, 158 insertions(+), 10 deletions(-) diff --git a/htdocs/adherents/admin/adherent_emails.php b/htdocs/adherents/admin/adherent_emails.php index 2dedd8fd265..292b9c77339 100644 --- a/htdocs/adherents/admin/adherent_emails.php +++ b/htdocs/adherents/admin/adherent_emails.php @@ -157,6 +157,7 @@ print ''; * Editing global variables not related to a specific theme */ $constantes=array( + 'ADHERENT_MAIL_FROM', 'ADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT', 'ADHERENT_AUTOREGISTER_NOTIF_MAIL', 'ADHERENT_AUTOREGISTER_MAIL_SUBJECT', @@ -167,7 +168,6 @@ $constantes=array( 'ADHERENT_MAIL_COTIS', 'ADHERENT_MAIL_RESIL_SUBJECT', 'ADHERENT_MAIL_RESIL', - 'ADHERENT_MAIL_FROM', ); $helptext='*'.$langs->trans("FollowingConstantsWillBeSubstituted").'
'; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index cf120f3871f..39916de0849 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -2492,4 +2492,133 @@ class Adherent extends CommonObject return $this->datefin < ($now - $conf->adherent->subscription->warning_delay); } + + + + /** + * Send reminders by emails before subscription end + * CAN BE A CRON TASK + * + * @param int $daysbeforeend Nb of days before end of subscription (negative number = after subscription) + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function sendReminderForExpiredSubscription($daysbeforeend=10) + { + global $conf, $langs, $mysoc, $user; + + $this->output = ''; + $this->error=''; + + $blockingerrormsg = ''; + + /*if (empty($conf->global->MEMBER_REMINDER_EMAIL)) + { + $langs->load("agenda"); + $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent")); + return 0; + }*/ + + $now = dol_now(); + + dol_syslog(__METHOD__, LOG_DEBUG); + + $tmp=dol_getdate($now); + $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year']), -1 * $daysbeforeend, 'd'); + + $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent'; + $sql.= " WHERE datefin = '".$this->db->idate($datetosearchfor)."'"; + + $resql = $this->db->query($sql); + if ($resql) + { + $num_rows = $this->db->num_rows($resql); + + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $adherent = new Adherent($this->db); + $formmail=new FormMail($db); + + $i=0; + $nbok = 0; + $nbko = 0; + while ($i < $num_rows) + { + $obj = $this->db->fetch_object($resql); + + $adherent->fetch($obj->rowid); + + if (empty($adherent->email)) + { + $nbko++; + } + else + { + $adherent->fetch_thirdparty(); + + // Send reminder email + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang(empty($adherent->thirdparty->default_lang) ? $mysoc->default_lang : $adherent->thirdparty->default_lang); + $outputlangs->loadLangs(array("main", "members")); + + $arraydefaultmessage=$formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, '(SendReminderForExpiredSubscriptionTitle)'); + + if (is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) + { + $substitutionarray=getCommonSubstitutionArray($outputlangs, 0, null, $adherent); + //if (is_array($adherent->thirdparty)) $substitutionarraycomp = ... + complete_substitutions_array($substitutionarray, $outputlangs, $adherent); + + $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs); + $msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs); + $from = $conf->global->ADHERENT_MAIL_FROM; + $to = $adherent->email; + + $cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), '', '', 0, 1); + $result = $cmail->sendfile(); + if (! $result) + { + $error++; + $this->error = $cmail->error; + $this->errors += $cmail->errors; + $nbko++; + } + else + { + $nbok++; + } + } + else + { + $blockingerrormsg="Can't find email template '(SendReminderForExpiredSubscriptionTitle)'"; + $nbko++; + break; + } + } + + $i++; + } + } + else + { + $this->error = $this->db->lasterror(); + return 1; + } + + if ($blockingerrormsg) + { + $this->error = $blockingerrormsg; + return 1; + } + else + { + $this->output = 'Found '.($nbok + $nbko).' members to send reminder to.'; + $this->output.= ' Send successfull to '.$nbok.' members'; + if ($nbko) $this->output.= ' - Canceled for '.$nbko.' member (no email or email sending error)'; + } + + return 0; + } + } diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 77f969181f4..21d3cb2eae5 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -646,7 +646,7 @@ if ($resql) elseif ($value == 'lang') { print ''; - print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1); + print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1, 0, 0, 'maxwidth150'); print ''; } elseif ($value == 'fk_user') @@ -661,7 +661,7 @@ if ($resql) 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').''; + print ''.$form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth200 maxwidth100onsmartphone').''; } elseif (! in_array($value, array('content', 'content_lines'))) print ''; } @@ -867,7 +867,7 @@ if ($resql) print ""; // Modify link / Delete link - print ''; + print ''; if ($canbemodified) print ''.img_edit().''; if ($iserasable) { @@ -1016,7 +1016,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') } else { - print $form->selectarray('type_template', $elementList, (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), 1); + print $form->selectarray('type_template', $elementList, (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), 1, 0, 0, '', 0, 0, 0, '', 'maxwidth200'); } print ''; } diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 5ff93994e73..a5446440f31 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -994,9 +994,9 @@ class FormMail extends Form * * @param DoliDB $db Database handler * @param string $type_template Get message for type=$type_template, type='all' also included. - * @param string $user Use template public or limited to this user + * @param string $user Get template public or limited to this user * @param Translate $outputlangs Output lang object - * @param int $id Id of template to find, or -1 for first found with position 0, or 0 for first found whatever is position or -2 for exact match with label (no aswer if not found) + * @param int $id Id of template to find, or -1 for first found with position 0, or 0 for first found whatever is position (priority order depends on lang provided or not) or -2 for exact match with label (no answer if not found) * @param int $active 1=Only active template, 0=Only disabled, -1=All * @param string $label Label of template * @return ModelMail @@ -1011,7 +1011,7 @@ class FormMail extends Form return -1; } - $sql = "SELECT label, topic, joinfiles, content, content_lines, lang"; + $sql = "SELECT rowid, label, topic, joinfiles, content, content_lines, lang"; $sql.= " FROM ".MAIN_DB_PREFIX.'c_email_templates'; $sql.= " WHERE (type_template='".$db->escape($type_template)."' OR type_template='all')"; $sql.= " AND entity IN (".getEntity('c_email_templates').")"; @@ -1033,6 +1033,7 @@ class FormMail extends Form $obj = $db->fetch_object($resql); if ($obj) { + $ret->id = $obj->rowid; $ret->label = $obj->label; $ret->lang = $obj->lang; $ret->topic = $obj->topic; diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php index d26836fa646..f3369d58582 100644 --- a/htdocs/core/modules/modAdherent.class.php +++ b/htdocs/core/modules/modAdherent.class.php @@ -324,6 +324,12 @@ class modAdherent extends DolibarrModules $this->import_fieldshidden_array[$r]=array('extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'adherent'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) $this->import_regex_array[$r]=array('a.civility'=>'code@'.MAIN_DB_PREFIX.'c_civility','a.fk_adherent_type'=>'rowid@'.MAIN_DB_PREFIX.'adherent_type','a.morphy'=>'(phy|mor)','a.statut'=>'^[0|1]','a.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','a.datefin'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'); $this->import_examplevalues_array[$r]=array('a.civility'=>"MR",'a.lastname'=>'Smith','a.firstname'=>'John','a.login'=>'jsmith','a.pass'=>'passofjsmith','a.fk_adherent_type'=>'1','a.morphy'=>'"mor" or "phy"','a.societe'=>'JS company','a.address'=>'21 jump street','a.zip'=>'55000','a.town'=>'New York','a.country'=>'1','a.email'=>'jsmith@example.com','a.birth'=>'1972-10-10','a.statut'=>"0 or 1",'a.note_public'=>"This is a public comment on member",'a.note_private'=>"This is private comment on member",'a.datec'=>dol_print_date($now,'%Y-%m__%d'),'a.datefin'=>dol_print_date(dol_time_plus_duree($now, 1, 'y'),'%Y-%m-%d')); + + // Cronjobs + $this->cronjobs = array( + 0=>array('label'=>'SendReminderForExpiredSubscription', 'jobtype'=>'method', 'class'=>'adherents/class/adherent.class.php', 'objectname'=>'Adherent', 'method'=>'sendReminderForExpiredSubscription', 'parameters'=>'10', 'comment'=>'sendReminderForExpiredSubscription', 'frequency'=>1, 'unitfrequency'=> 3600 * 24, 'priority'=>50, 'status'=>0, 'test'=>true), + ); + } diff --git a/htdocs/install/mysql/data/llx_c_email_templates.sql b/htdocs/install/mysql/data/llx_c_email_templates.sql index 3a99e44cd8b..ad8d8ffd199 100644 --- a/htdocs/install/mysql/data/llx_c_email_templates.sql +++ b/htdocs/install/mysql/data/llx_c_email_templates.sql @@ -20,7 +20,9 @@ -- de l'install et tous les sigles '--' sont supprimés. -- -INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'adherent','member','',0,null,null,'(SendAnEMailToMember)',1,1,1,'__(CardContent)__','__(Hello)__,

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

\n__(Sincerely)__
__USER_SIGNATURE__',null); +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'adherent','member','',0,null,null,'(SendAnEMailToMember)',1,1,1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(CardContent)__','__(Hello)__,

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

\n__(Sincerely)__
__USER_SIGNATURE__',null); +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'adherent','member','',0,null,null,'(SendReminderForExpiredSubscriptionTitle)',1,1,1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourSubscriptionHasExpired)__','__(Hello)__ __MEMBER_FULLNAME__,

\n\n__(ThisIsContentOfSubscriptionReminderEmail)__
\n
__ONLINE_PAYMENT_URL__
\n

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

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

\n__(Sincerely)__
\n__USER_SIGNATURE__',null); diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql index 35813d8b635..c1d7e59cbed 100644 --- a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -304,3 +304,9 @@ ALTER TABLE llx_societe_account ADD CONSTRAINT llx_societe_account_fk_societe FO ALTER TABLE llx_societe_rib MODIFY COLUMN max_total_amount_of_all_payments double(24,8); ALTER TABLE llx_societe_rib MODIFY COLUMN total_amount_of_all_payments double(24,8); + + +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'adherent','member','',0,null,null,'(SendAnEMailToMember)',1,1,1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(CardContent)__','__(Hello)__,

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

\n__(Sincerely)__
__USER_SIGNATURE__',null); +INSERT INTO llx_c_email_templates (entity,module,type_template,lang,private,fk_user,datec,label,position,enabled,active,topic,content,content_lines) VALUES (0,'adherent','member','',0,null,null,'(SendReminderForExpiredSubscriptionTitle)',1,1,1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourSubscriptionHasExpired)__','__(Hello)__ __MEMBER_FULLNAME__,

\n\n__(ThisIsContentOfSubscriptionReminderEmail)__
\n
__ONLINE_PAYMENT_URL__
\n

\n__(Sincerely)__
__USER_SIGNATURE__',null); + + diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index bfa338605f2..b6e872097b5 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -179,4 +179,8 @@ ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS=Product used for subscription line into in NameOrCompany=Name or company SubscriptionRecorded=Subscription recorded NoEmailSentToMember=No email sent to member -EmailSentToMember=Email sent to member at %s \ No newline at end of file +EmailSentToMember=Email sent to member at %s +SendReminderForExpiredSubscriptionTitle=Send reminder by email for expired subscription +SendReminderForExpiredSubscription=Send reminder by email to members when subscription is about to expire (parameter is number of days before end of subscription to send the remind) +YourSubscriptionHasExpired=Your subscription has expired +ThisIsContentOfSubscriptionReminderEmail=This is a email to remind you that your subscription is about to expire.