Compare commits

..

No commits in common. "master" and "0.3.1" have entirely different histories.

10 changed files with 49 additions and 335 deletions

View file

@ -1,25 +1,4 @@
# CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR [DOLIBARR ERP CRM](https://www.dolibarr.org)
## 0.3.4
Fix: the hook was also triggered by supplier invoices.
Thanks to jpardenoy for the report and the fix.
## 0.3.3
Fix: adds CSRF protection.
## 0.3.2
Note: This release includes a DB schema modification. Reactivate the module to trigger it.
Enhancements:
* Mails can now be sent in HTML (via global module configuration and via the customzation tab).
* Mails can now be sent even when the invoice is a draft.
# CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR <a href="https://www.dolibarr.org">DOLIBARR ERP CRM</a>
## 0.3.1

View file

@ -2,9 +2,9 @@
## Features
(en) This module sends by email the customer invoice generated with a recurring invoice template via scheduled jobs.
(en) This module send the invoice generated with recurring invoices by email to the client.
(fr) Ce module envoie par mail les factures clientes générées automatiquement par les travaux planifiés et les factures modèles.
(fr) Ce module envoie par mail les factures générées automatiquement par les travaux planifiés et les factures modèles.
You can customize the mail globally or by recurring invoice.
@ -14,7 +14,7 @@ To edit the default global mail template, go to Home > Setup > Emails > Email te
To edit the default sender address, go to Home > Setup > Emails, and edit the `Sender email for automatic emails` field.
This module hooks himself on the end of the `Recurring invoices` job from the Scheduled jobs (aka. `cron`) module. It will only be triggered via this Scheduled job and will not send mail when manually generating an invoice from a recurring invoice template.
This module is triggered by the cron (Scheduled jobs module) and will not send emails when manually generating an invoice.
## Requirements
@ -30,18 +30,11 @@ Other modules are available on <a href="https://www.dolistore.com" target="_new"
### From the ZIP file and GUI interface
Go to `Home` > `Setup` > `Modules/Applications` and finally the `Deploy/install external app/module` tab
and upload the module_sendrecurringinvoicebymail-x.y.z.zip file (you can get it from the
[original forge](https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail/releases)
or [Github](https://github.com/bugness-chl/sendrecurringinvoicebymail/releases)).
Next, on the `Modules/Applications` page, activate the newly available sendrecurringinvoicebymail module,
and probably the Scheduled jobs (alias cron or modCron) integrated module too.
- If you get the module in a zip file (like when downloading it from the market place [Dolistore](https://www.dolistore.com)), go into
menu ```Home - Setup - Modules - Deploy external module``` and upload the zip file.
#### Troubleshooting
Note: If the module screen tells you there is no custom directory, check that your setup is correct:
Note: If this screen tell you there is no custom directory, check your setup is correct:
- In your Dolibarr installation directory, edit the ```htdocs/conf/conf.php``` file and check that following lines are not commented:
@ -72,10 +65,12 @@ Note: If the module screen tells you there is no custom directory, check that yo
```sh
cd ....../custom
git clone https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail.git sendrecurringinvoicebymail
git clone git@github.com:bugness-chl/sendrecurringinvoicebymail.git sendrecurringinvoicebymail
```
Then, from your browser:
### Final steps
From your browser:
- Log into Dolibarr as a super-administrator
- Go to "Setup" -> "Modules"
@ -99,7 +94,7 @@ GPLv3 or (at your option) any later version.
See file COPYING for more information.
### Documentation
#### Documentation
All texts and readmes.

View file

@ -1,181 +0,0 @@
<?php
/* Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2021 Chl <chl-dev@bugness.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file sendrecurringinvoicebymail/admin/setup.php
* \ingroup sendrecurringinvoicebymail
* \brief SRIBM setup page.
*/
// 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 calculated 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) die("Include of main fails");
global $langs, $user;
// Libraries
require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
//require_once '../lib/mymodule.lib.php';
//require_once "../class/myclass.class.php";
// Translations
$langs->loadLangs(array("admin", "sendrecurringinvoicebymail@sendrecurringinvoicebymail"));
// Access control
if (! $user->admin) accessforbidden();
// Parameters
$action = GETPOST('action', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
$arrayofparameters=array(
//'SENDRECURRINGINVOICEBYMAIL_MYPARAM2'=>array('css'=>'minwidth500','enabled'=>1)
'SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT' => array(
'css' => 'minwidth200',
'selectvalues' => array(
-1 => 'MailBodyFormatAutoDetect',
0 => 'MailBodyFormatPlainText',
1 => 'MailBodyFormatHtml',
),
),
);
/*
* Actions
*/
if ((float) DOL_VERSION >= 6)
{
include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
}
/*
* View
*/
$page_name = "sendrecurringinvoicebymailSetup";
llxHeader('', $langs->trans($page_name));
// Subheader
$linkback = '<a href="'.($backtopage?$backtopage:DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans($page_name), $linkback, 'object_mymodule@mymodule');
// Configuration header
//$head = mymoduleAdminPrepareHead();
$head = array();
dol_fiche_head($head, 'settings', '', -1, "sendrecurringinvoicebymail@sendrecurringinvoicebymail");
// Setup page goes here
echo '<span class="opacitymedium">'.$langs->trans("sendrecurringinvoicebymailSetupPage").'</span><br><br>';
if ($action == 'edit')
{
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="update">';
print '<table class="noborder" width="100%">';
print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
foreach($arrayofparameters as $key => $val)
{
print '<tr class="oddeven"><td>';
$tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : '');
print $form->textwithpicto($langs->trans($key), $tooltiphelp);
print "</td>\n";
print '<td>';
if (isset($val['selectvalues'])) {
// Select input
print '<select name="' . $key . '">';
foreach ($val['selectvalues'] as $k => $item) {
print '<option value="' . $k . '"';
if ($k == $conf->global->$key) {
print ' selected="selected"';
}
print '>' . $langs->trans($item) . "</option>\n";
}
print "</select>\n";
} else {
// Simple input
print '<input name="'.$key.'" class="flat '.(empty($val['css'])?'minwidth200':$val['css']).'" value="' . $conf->global->$key . '">';
}
print "</td></tr>\n";
}
print '</table>';
print '<br><div class="center">';
print '<input class="button" type="submit" value="'.$langs->trans("Save").'">';
print '</div>';
print '</form>';
print '<br>';
}
else
{
if (! empty($arrayofparameters))
{
print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
foreach($arrayofparameters as $key => $val)
{
print '<tr class="oddeven"><td>';
$tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : '');
print $form->textwithpicto($langs->trans($key), $tooltiphelp);
print '</td><td>' . $conf->global->$key . '</td></tr>';
}
print '</table>';
print '<div class="tabsAction">';
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>';
print '</div>';
}
else
{
print '<br>'.$langs->trans("NothingToSetup");
}
// Display a notice if the 'cron' module is not enabled
if (! in_array('cron', $conf->modules, true)) {
print '<div class="info"><p>' . $langs->trans('NoticeCronIsDisabled') . "</p></div>\n";
}
}
// Page end
dol_fiche_end();
llxFooter();
$db->close();

View file

@ -84,23 +84,15 @@ class Actionssendrecurringinvoicebymail
$error = 0; // Error counter
$facturerec = $parameters['facturerec'];
// Since Dolibarr 16, this hook is also used for the FactureFournisseurRec class.
if (! $facturerec instanceof FactureRec) {
return 0;
}
// Load our own object, linked to this facture
// (if it doesn't exist in database, fetch(,,true) will fill the object
// from the global mail template)
$mailObject = new SRIBMCustomMailInfo($this->db);
if ($mailObject->fetch(null, $facturerec->id, true) != 1) {
dol_syslog("Error loading SRIBMCustomMailInfo for facture rec " . (isset($facturerec->id) ? $facturerec->id : "(facturerec->id not set ??)"));
return -1;
}
// Abort sending when inactive
// (draft invoice or explictly disabled)
if (!$mailObject->active) {
// We only send the mail when the invoice is not a draft
// and the sending is enabled for the template.
if ($object->brouillon || !$mailObject->active) {
return 0;
}
@ -123,8 +115,7 @@ class Actionssendrecurringinvoicebymail
'errorsTo' => $conf->global->MAIN_MAIL_ERRORS_TO,
'replyTo' => $conf->global->MAIN_MAIL_ERRORS_TO,
'subject' => $mailObject->subject,
'message' => $mailObject->body,
'ishtml' => $mailObject->body_ishtml,
'message' => $mailObject->body_plaintext,
);
// Check that we have a recipient, to avoid some frequent error...
@ -163,7 +154,7 @@ class Actionssendrecurringinvoicebymail
$mail_data['cc'], // CC
$mail_data['bcc'], // BCC
0, //deliveryreceipt
$mail_data['ishtml'], //msgishtml
0, //msgishtml
$mail_data['errorsTo'],
'', // css
'', // trackid

View file

@ -109,12 +109,12 @@ class SRIBMCustomMailInfo extends CommonObject
/**
* @var string
*/
public $body;
public $body_plaintext;
/**
* @var int 0: plain text, 1: html, -1: auto (see CMailFile and dol_ishtml())
* @var string (not used at the moment)
*/
public $body_ishtml = 0;
public $body_html;
// End of database fields
@ -228,7 +228,7 @@ class SRIBMCustomMailInfo extends CommonObject
$sql .= " SET ";
$sql .= " fk_facture_rec = " . (int)$this->fk_facture_rec;
$sql .= ", active = " . (int)$this->active;
$sql .= ", addmaindocfile = " . (int)$this->addmaindocfile;
$sql .= ", addmaindocfile = '" . (int)$this->addmaindocfile . "'";
$sql .= ", fromtype = '" . $this->db->escape($this->fromtype) . "'";
$sql .= ", frommail = '" . $this->db->escape($this->frommail) . "'";
$sql .= ", sendto_thirdparty = " . (int)$this->db->escape($this->sendto_thirdparty);
@ -238,8 +238,8 @@ class SRIBMCustomMailInfo extends CommonObject
$sql .= ", sendbcc_thirdparty = " . (int)$this->db->escape($this->sendbcc_thirdparty);
$sql .= ", sendbcc_free = '" . $this->db->escape($this->sendbcc_free) . "'";
$sql .= ", subject = '" . $this->db->escape($this->subject) . "'";
$sql .= ", body = '" . $this->db->escape($this->body) . "'";
$sql .= ", body_ishtml = " . (int)$this->body_ishtml;
$sql .= ", body_plaintext = '" . $this->db->escape($this->body_plaintext) . "'";
$sql .= ", body_html = '" . $this->db->escape($this->body_html) . "'";
$sql .= " WHERE rowid = " . (int)$this->id;
$result = $this->db->query($sql);
@ -281,7 +281,7 @@ class SRIBMCustomMailInfo extends CommonObject
{
global $conf;
$sql = "SELECT rowid, fk_facture_rec, active, addmaindocfile, fromtype, frommail, sendto_thirdparty, sendto_free, sendcc_thirdparty, sendcc_free, sendbcc_thirdparty, sendbcc_free, subject, body, body_ishtml";
$sql = "SELECT rowid, fk_facture_rec, active, addmaindocfile, fromtype, frommail, sendto_thirdparty, sendto_free, sendcc_thirdparty, sendcc_free, sendbcc_thirdparty, sendbcc_free, subject, body_plaintext, body_html";
$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
$sql .= " WHERE " . (isset($ref) ? 'fk_facture_rec = ' . (int)$ref : "rowid = " . (int)$rowid);
@ -309,8 +309,8 @@ class SRIBMCustomMailInfo extends CommonObject
$this->sendbcc_thirdparty = $obj->sendbcc_thirdparty;
$this->sendbcc_free = $obj->sendbcc_free;
$this->subject = $obj->subject;
$this->body = $obj->body;
$this->body_ishtml = $obj->body_ishtml;
$this->body_plaintext = $obj->body_plaintext;
$this->body_html = $obj->body_html;
$ref = $obj->fk_facture_rec;
} elseif (!$fill_defaults_from_template) {
$this->error = "SRIBMCustomMailInfo not found (id: " . var_export($rowid, true) . ", ref: " . var_export($ref, true);
@ -366,15 +366,8 @@ class SRIBMCustomMailInfo extends CommonObject
}
$this->subject = $template->topic;
$this->body = $template->content;
$this->body_plaintext = $template->content;
$this->addmaindocfile = $template->joinfiles;
// By default, we don't send emails when the generated invoice is
// still a draft.
$this->active = $this->fac_rec_object->auto_validate;
// Retrieve the default body format from config.
$this->body_ishtml = $conf->global->SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT;
}
return 1;

View file

@ -52,7 +52,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules
// Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
// It is used to group modules by family in module setup page
$this->family = "financial";
$this->family = "crm";
// Module position in the family on 2 digits ('01', '10', '20', ...)
$this->module_position = '90';
// Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
@ -69,7 +69,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules
$this->editor_url = 'https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail';
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
$this->version = '0.3.4';
$this->version = '0.3.1';
//Url to the file with your last numberversion of this module
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
@ -103,7 +103,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules
$this->dirs = array("/sendrecurringinvoicebymail/temp");
// Config pages. Put here list of php page, stored into sendrecurringinvoicebymail/admin directory, to use to setup module.
$this->config_page_url = array("setup.php@sendrecurringinvoicebymail");
//$this->config_page_url = array("setup.php@sendrecurringinvoicebymail");
// Dependencies
$this->hidden = false; // A condition to hide module
@ -124,15 +124,6 @@ class modsendrecurringinvoicebymail extends DolibarrModules
// 1=>array('SENDRECURRINGINVOICEBYMAIL_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
// );
$this->const = array(
0 => array(
'SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT', // key
'chaine', // always 'chaine' ?
'0', // value
'default format for mail body : -1 for auto-detect, 0 for plain text, 1 for HTML.', // desc
1, // visible
'current', // current or allentities
0, // deleteonunactive
),
//1=>array('SENDRECURRINGINVOICEBYMAIL_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1)
);
@ -366,7 +357,7 @@ class modsendrecurringinvoicebymail extends DolibarrModules
$this->db->query("INSERT INTO " . MAIN_DB_PREFIX . "sribm_custom_mail_info (fk_facture_rec, fromtype, frommail) VALUES (" . (int)$row->rid . ", 'robot', '" . $this->db->escape($conf->global->MAIN_MAIL_EMAIL_FROM) . "')");
$sid = $this->db->last_insert_id(MAIN_DB_PREFIX . 'sribm_custom_mail_info');
}
foreach (array('subject' => 'subject', 'body' => 'body', 'sendto' => 'sendto_free') as $key => $item) {
foreach (array('subject' => 'subject', 'body' => 'body_plaintext', 'sendto' => 'sendto_free') as $key => $item) {
if (! empty($mail_data[$key])) {
// We loop on each field.
// Not optimized, I know.

View file

@ -56,14 +56,18 @@ do {
*/
// Load necessary data
$object = new FactureRec($db);
$mailObject = new SRIBMCustomMailInfo($db);
$form = new Form($db);
if ($mailObject->fetch(null, $id, true) <= 0) {
// Note : this should only happen when facture-rec doesn't exist or some database error.
// If sribmcustommailinfo doesn't exist in database, we should still get a instance of the template.
if ($object->fetch($id) <= 0 or !$object->id)
{
setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
break;
}
if ($mailObject->fetch(null, $object->id, true) <= 0) {
setEventMessages("Weird stuff, shouldn't happen : " . $mailObject->error);
break;
}
// List of senders (user, company, robot, ...)
$listFrom = array();
@ -88,7 +92,7 @@ do {
// Substitution array/string
$helpforsubstitution = $langs->trans('AvailableVariables').' :<br>'."\n";
$tmparray = getCommonSubstitutionArray($langs, 0, null, $mailObject->fac_rec_object);
$tmparray = getCommonSubstitutionArray($langs, 0, null, $object);
complete_substitutions_array($tmparray, $langs);
foreach($tmparray as $key => $val) {
$helpforsubstitution .= $key . ' -> ' . $langs->trans(dol_string_nohtmltag($val)) . '<br>';
@ -128,10 +132,6 @@ do {
setEventMessages("In some configuration, CMailFile doesn't allow empty subject. You should set one.", null, 'warnings');
//break;
}
if (! in_array(GETPOST('body_ishtml', 'int'), array('-1', '0', '1'), true)) {
setEventMessages("Unexpected body_ishtml value", null, 'errors');
break;
}
// Feed the input data to the model
$mailObject->active = GETPOST('active', 'int') ? 1 : 0;
@ -147,8 +147,7 @@ do {
$mailObject->sendcc_thirdparty = in_array('thirdparty', GETPOST('sendcc_socpeople', 'array'));
$mailObject->subject = GETPOST('subject', 'alpha');
$mailObject->body = GETPOST('body', 'alpha');
$mailObject->body_ishtml = (int)GETPOST('body_ishtml', 'int');
$mailObject->body_plaintext = GETPOST('body_plaintext', 'alpha');
// Save into database
if ($mailObject->id) {
@ -157,7 +156,7 @@ do {
break;
}
} else {
$mailObject->fk_facture_rec = $mailObject->fac_rec_object->id;
$mailObject->fk_facture_rec = $object->id;
if ($mailObject->create($user) < 0) {
setEventMessages($langs->trans("ErrorSQL") . ' : ' . $mailObject->error, null, 'errors');
break;
@ -226,7 +225,7 @@ do {
*/
// Same tabs than the main page
$head=invoice_rec_prepare_head($mailObject->fac_rec_object);
$head=invoice_rec_prepare_head($object);
$output .= dol_get_fiche_head($head, 'sendrecurringinvoicebymail', $langs->trans("RepeatableInvoice"), -1, 'bill'); // Add a div
$output .= '<div class="inline-block floatleft valignmiddle refid refidpadding">' . $mailObject->fac_rec_object->ref . "</div>\n";
$output .= '<div class="refidno">' . $langs->trans('ThirdParty') . ' : ' . $mailObject->fac_rec_object->thirdparty->getNomUrl(1) . "</div>\n";
@ -234,12 +233,6 @@ do {
$output .= '<div class="titre inline-block">' . $langs->trans("Options") . "</div>\n";
$output .= '<form id="sribmform" name="sribmform" method="POST" action="#sribmform">';
if (function_exists('newToken')) {
$output .= '<input type="hidden" name="token" value="'.newToken().'">'; // CSRF protection
} else {
// Used before Dolibar 13
$output .= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; // CSRF protection
}
$output .= '<table class="liste" summary="mail options"><tbody>';
$output .= '<tr class="oddeven">';
$output .= ' <td><label for="active">' . $langs->trans('OptionEnable') . "</label></td>\n";
@ -302,7 +295,7 @@ do {
$output .= '<td><input type="checkbox" name="addmaindocfile" value="1"' . ($tmp_addmaindocfile ? ' checked="checked"' : '') . ' /> ' . $langs->trans("JoinMainDoc") . "</td>\n";
// body
// body_plaintext
$output .= '<tr><td class="minwidth200" valign="top">';
$output .= $form->textwithpicto($langs->trans("MailText"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');
$output .= "</td>\n<td>";
@ -313,24 +306,11 @@ do {
$doleditor = new DolEditor('body_plaintext', (GETPOST('body_plaintext', 'alpha') ? GETPOST('body_plaintext', 'alpha') : $mailObject->body_plaintext), '', 280);
$output .= $doleditor->Create(1);
*/
$output .= '<textarea id="body" name="body" rows="14" cols="80" class="flat">';
$output .= htmlentities(GETPOST('body', 'alpha') ? GETPOST('body', 'alpha') : $mailObject->body);
$output .= '<textarea id="body_plaintext" name="body_plaintext" rows="14" cols="80" class="flat">';
$output .= htmlentities(GETPOST('body_plaintext', 'alpha') ? GETPOST('body_plaintext', 'alpha') : $mailObject->body_plaintext);
$output .= "</textarea>\n";
$output .= "</td></tr>\n";
// body_ishtml
$output .= '<tr><td>' . $langs->trans('MailBodyFormat') . "</td>\n";
$tmp_ishtml = (int)(GETPOSTISSET('body_ishtml') ? GETPOST('body_ishtml', 'int') : $mailObject->body_ishtml);
// selectarray() does funny things with -1 key, so we build it manually.
//$output .= $form->selectarray('body_ishtml', $listBodyIsHtml, $mailObject->body_ishtml);
$output .= '<td><select name="body_ishtml">';
foreach (array(-1 => 'MailBodyFormatAutoDetect', 0 => 'MailBodyFormatPlainText', 1 => 'MailBodyFormatHtml') as $key => $item) {
$output .= '<option value="' . $key . '"';
$output .= ($key === $tmp_ishtml) ? ' selected="selected"' : '';
$output .= '>' . $langs->trans($item) . "</option>\n";
}
$output .= "</select>\n</td>\n";
$output .= "</table>\n";
$output .= '<br><div class="center">';

View file

@ -28,9 +28,10 @@ ModulesendrecurringinvoicebymailDesc = Send FactureRec generated invoices by mai
sendrecurringinvoicebymailSetup = sendrecurringinvoicebymail setup
Settings = Settings
sendrecurringinvoicebymailSetupPage = sendrecurringinvoicebymail setup page
NoticeCronIsDisabled = Notice: the cron / Scheduled Jobs module seems disabled. Unless you know what you are doing, invoices won't be generated and emails won't be sent.
SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT = Default mail body's format
SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULTTooltip = -1 for auto-detect, 0 for plaintext, 1 for HTML
SENDRECURRINGINVOICEBYMAIL_MYPARAM1 = My param 1
SENDRECURRINGINVOICEBYMAIL_MYPARAM1Tooltip = My param 1 tooltip
SENDRECURRINGINVOICEBYMAIL_MYPARAM2=My param 2
SENDRECURRINGINVOICEBYMAIL_MYPARAM2Tooltip=My param 2 tooltip
#
@ -40,16 +41,10 @@ About = About
sendrecurringinvoicebymailAbout = About sendrecurringinvoicebymail
sendrecurringinvoicebymailAboutPage = sendrecurringinvoicebymail about page
#
# Tab title on the fiche-rec page
#
CustomizationTitle = Customization
CustomizationIntro = Below, you can override the global email template for this particular recurring invoice. To remove all customization, click on the %s button.
CustomizationLinkToGlobalTemplate = As a note, the global email template can be <a href="%s">configured here</a>, and the default sender address can be <a href="%s">configured there</a>.
MailBodyFormat = Message format
MailBodyFormatAutoDetect = Auto-detect
MailBodyFormatPlainText = Plain text
MailBodyFormatHtml = HTML
OptionEnable = Send mail when generating via cron (cf. module "Scheduled Jobs")
Reset = Reset
ResetDone = Reset done : customization deleted

View file

@ -28,10 +28,6 @@ ModulesendrecurringinvoicebymailDesc = Envoi par mail des factures générées p
sendrecurringinvoicebymailSetup = Configuration du module sendrecurringinvoicebymail
Settings = Réglages
sendrecurringinvoicebymailSetupPage = Page de configuration du module sendrecurringinvoicebymail
NoticeCronIsDisabled = Notice : le module cron / Travaux Planifiés semble désactivé. Sauf cas particulier, les factures ne seront pas générées et les mails ne seront pas envoyés.
SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULT = Format par défaut du corps du mail
SENDRECURRINGINVOICEBYMAIL_BODY_ISHTML_DEFAULTTooltip = -1: auto-détection, 0: texte pur, 1: HTML
#
# Page À propos
@ -46,10 +42,6 @@ sendrecurringinvoicebymailAboutPage = Page à propos de sendrecurringinvoicebyma
CustomizationTitle = Personnalisation
CustomizationIntro = Ci-dessous, vous pouvez personnaliser les emails pour cette facture-modèle. Pour annuler toute personnalisation, cliquez sur le bouton '%s'.
CustomizationLinkToGlobalTemplate = Pour mémoire, le template global est <a href="%s">configurable par ici</a>, et l'adresse de l'émetteur par défaut est <a href="%s">configurable par là</a>.
MailBodyFormat = Format du message
MailBodyFormatAutoDetect = Auto-detect
MailBodyFormatPlainText = Texte pur
MailBodyFormatHtml = HTML
OptionEnable = Envoyer par email lors d'une génération automatique via le module "Travaux planifiés"
Reset = Réinitialiser
ResetDone = Réinitialisation effectuée : personnalisation supprimée.

View file

@ -1,21 +0,0 @@
-- Copyright (C) 2021 Chl <chl-dev@bugness.org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see http://www.gnu.org/licenses/.
-- We designed the schema too quickly : CMailFile doesn't let us manage
-- independently the text and html parts. All we can do is set the mode.
ALTER TABLE llx_sribm_custom_mail_info CHANGE COLUMN body_plaintext body mediumtext;
ALTER TABLE llx_sribm_custom_mail_info DROP COLUMN body_html;
ALTER TABLE llx_sribm_custom_mail_info ADD COLUMN body_ishtml smallint DEFAULT 0 NOT NULL;