v. 0.3.0 : customization form for each recurring invoice
This commit is contained in:
parent
3f14164994
commit
b5bc4bca93
12 changed files with 1470 additions and 524 deletions
|
@ -1,5 +1,8 @@
|
||||||
# CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR <a href="https://www.dolibarr.org">DOLIBARR ERP CRM</a>
|
# CHANGELOG SENDRECURRINGINVOICEBYMAIL FOR <a href="https://www.dolibarr.org">DOLIBARR ERP CRM</a>
|
||||||
|
|
||||||
|
## 0.3.0
|
||||||
|
Dedicated tab on the template invoice's page, to be able to customize more cleanly the recipients, and the email content.
|
||||||
|
|
||||||
## 0.2.7
|
## 0.2.7
|
||||||
Add the possibility to overwrite some email fields (recipients, subject, body) for each template.
|
Add the possibility to overwrite some email fields (recipients, subject, body) for each template.
|
||||||
|
|
||||||
|
|
61
README.md
61
README.md
|
@ -2,62 +2,31 @@
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
This module send the PDF generated with recurring invoices by email to the client.
|
(en) This module send the invoice generated with recurring invoices by email to the client.
|
||||||
|
|
||||||
You can customize the mail template in Home > Setup > Emails > Email templates.
|
(fr) Ce module envoie par mail les factures générées automatiquement par les travaux planifiés et les factures modèles.
|
||||||
|
|
||||||
Beta - test in progress : you can also customize for each template invoice, by adding some of those blocks in the private notes of the template.
|
You can customize the mail globally or by recurring invoice.
|
||||||
```
|
|
||||||
This is a good client (this is outside of the %%% blocks so it won't appear in the mails :)
|
|
||||||
|
|
||||||
%%% sendrecurringinvoicebymail::body
|
![Screenshot n° 1](img/screenshot1.png?raw=true)
|
||||||
Hello dear client,
|
|
||||||
|
|
||||||
Please find attached... invoice __REF__...
|
To edit the default global mail template, go to Home > Setup > Emails > Email templates, and modify the `SendRecurringInvoiceByMail : original template`. If you don't want to attach the PDF of the invoice to the mails, set the `Attach file` input to 0 (default: 1, PDF attached).
|
||||||
|
|
||||||
__(Sincerely)__,
|
To edit the default sender address, go to Home > Setup > Emails, and edit the `Sender email for automatic emails` field.
|
||||||
|
|
||||||
__MYCOMPANY_NAME__
|
This module is triggered by the cron (Scheduled jobs module) and will not send emails when manually generating an invoice.
|
||||||
%%%
|
|
||||||
|
|
||||||
%%% sendrecurringinvoicebymail::subject
|
|
||||||
My custom subject
|
|
||||||
%%%
|
|
||||||
%%% sendrecurringinvoicebymail::sendto
|
|
||||||
test1@example.org, "Mr. Test2" <test2@example.com>
|
|
||||||
%%%
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
It requires Dolibarr version 10.0 at least (first version with the 'cron/afterCreationOfRecurringInvoice()' hook).
|
It requires Dolibarr version 10.0 at least (first version with the `cron/afterCreationOfRecurringInvoice()` hook).
|
||||||
|
|
||||||
<!--
|
Don't forget to also activate the **Scheduled jobs** module.
|
||||||
![Screenshot sendrecurringinvoicebymail](img/screenshot_sendrecurringinvoicebymail.png?raw=true "sendrecurringinvoicebymail"){imgmd}
|
|
||||||
-->
|
|
||||||
|
|
||||||
Other modules are available on <a href="https://www.dolistore.com" target="_new">Dolistore.com</a>.
|
Other modules are available on <a href="https://www.dolistore.com" target="_new">Dolistore.com</a>.
|
||||||
|
|
||||||
|
|
||||||
|
## Install
|
||||||
<!--
|
|
||||||
### Translations
|
|
||||||
|
|
||||||
Translations can be define manually by editing files into directories *langs*.
|
|
||||||
|
|
||||||
This module contains also a sample configuration for Transifex, under the hidden directory [.tx](.tx), so it is possible to manage translation using this service.
|
|
||||||
|
|
||||||
For more informations, see the [translator's documentation](https://wiki.dolibarr.org/index.php/Translator_documentation).
|
|
||||||
|
|
||||||
There is a [Transifex project](https://transifex.com/projects/p/dolibarr-module-template) for this module.
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
Install
|
|
||||||
-------
|
|
||||||
|
|
||||||
### From the ZIP file and GUI interface
|
### From the ZIP file and GUI interface
|
||||||
|
|
||||||
|
@ -99,7 +68,7 @@ cd ....../custom
|
||||||
git clone git@github.com:bugness-chl/sendrecurringinvoicebymail.git sendrecurringinvoicebymail
|
git clone git@github.com:bugness-chl/sendrecurringinvoicebymail.git sendrecurringinvoicebymail
|
||||||
```
|
```
|
||||||
|
|
||||||
### <a name="final_steps"></a>Final steps
|
### Final steps
|
||||||
|
|
||||||
From your browser:
|
From your browser:
|
||||||
|
|
||||||
|
@ -108,12 +77,14 @@ From your browser:
|
||||||
- You should now be able to find and enable the module
|
- You should now be able to find and enable the module
|
||||||
|
|
||||||
|
|
||||||
|
## Updating instructions
|
||||||
|
|
||||||
-->
|
* Disable the module,
|
||||||
|
* Update the files (see Install),
|
||||||
|
* Re-enable the module.
|
||||||
|
|
||||||
|
|
||||||
Licenses
|
## Licenses
|
||||||
--------
|
|
||||||
|
|
||||||
### Main code
|
### Main code
|
||||||
|
|
||||||
|
|
|
@ -23,224 +23,174 @@
|
||||||
* Put detailed description here.
|
* Put detailed description here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Load needed classes/lib
|
||||||
|
require_once 'sribmcustommailinfo.class.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Actionssendrecurringinvoicebymail
|
* Class Actionssendrecurringinvoicebymail
|
||||||
*/
|
*/
|
||||||
class Actionssendrecurringinvoicebymail
|
class Actionssendrecurringinvoicebymail
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var DoliDB Database handler.
|
* @var DoliDB Database handler.
|
||||||
*/
|
*/
|
||||||
public $db;
|
public $db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string Error code (or message)
|
* @var string Error code (or message)
|
||||||
*/
|
*/
|
||||||
public $error = '';
|
public $error = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array Errors
|
* @var array Errors
|
||||||
*/
|
*/
|
||||||
public $errors = array();
|
public $errors = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array Hook results. Propagated to $hookmanager->resArray for later reuse
|
* @var array Hook results. Propagated to $hookmanager->resArray for later reuse
|
||||||
*/
|
*/
|
||||||
public $results = array();
|
public $results = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string String displayed by executeHook() immediately after return
|
* @var string String displayed by executeHook() immediately after return
|
||||||
*/
|
*/
|
||||||
public $resprints;
|
public $resprints;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param DoliDB $db Database handler
|
* @param DoliDB $db Database handler
|
||||||
*/
|
*/
|
||||||
public function __construct($db)
|
public function __construct($db)
|
||||||
{
|
{
|
||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloading the doActions function : replacing the parent's function with the one below
|
* Overloading the doActions function : replacing the parent's function with the one below
|
||||||
*
|
*
|
||||||
* @param array $parameters Hook metadatas (context, etc...)
|
* @param array $parameters Hook metadatas (context, etc...)
|
||||||
* @param CommonObject $object The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
|
* @param CommonObject $object The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
|
||||||
* @param string $action Current action (if set). Generally create or edit or null
|
* @param string $action Current action (if set). Generally create or edit or null
|
||||||
* @param HookManager $hookmanager Hook manager propagated to allow calling another hook
|
* @param HookManager $hookmanager Hook manager propagated to allow calling another hook
|
||||||
* @return int < 0 on error, 0 on success, 1 to replace standard code
|
* @return int < 0 on error, 0 on success, 1 to replace standard code
|
||||||
*/
|
*/
|
||||||
public function afterCreationOfRecurringInvoice($parameters, &$object, &$action, $hookmanager)
|
public function afterCreationOfRecurringInvoice($parameters, &$object, &$action, $hookmanager)
|
||||||
{
|
{
|
||||||
global $conf, $user, $langs;
|
global $conf, $user, $langs;
|
||||||
$langs->load('mails');
|
$langs->load('mails');
|
||||||
|
|
||||||
$error = 0; // Error counter
|
$error = 0; // Error counter
|
||||||
|
|
||||||
$facturerec = $parameters['facturerec'];
|
$facturerec = $parameters['facturerec'];
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
// We only send the mail when the invoice is not a draft
|
// We only send the mail when the invoice is not a draft
|
||||||
if ($object->brouillon) {
|
// and the sending is enabled for the template.
|
||||||
return 0;
|
if ($object->brouillon || !$mailObject->active) {
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch the mail template
|
// Prepare the substitions for mail's subject and message (ex-body)
|
||||||
// (pas très précise mais je commence à en avoir marre de creuser tout dolibarr pour trouver les bonnes fonctions...)
|
$substitutionarray = getCommonSubstitutionArray($langs, 0, null, $object);
|
||||||
$result = $this->db->query("SELECT * FROM " . MAIN_DB_PREFIX . "c_email_templates WHERE module = 'sendrecurringinvoicebymail' AND active = 1 AND enabled = '1' ORDER BY tms DESC LIMIT 1");
|
complete_substitutions_array($substitutionarray, $langs, $object); // lourd et n'a rien ajouté lors de mes tests
|
||||||
if ( ! $result or ! ($template = $this->db->fetch_object($result))) {
|
|
||||||
$this->error = "Can't find mail template for sendrecurringinvoicebymail";
|
|
||||||
$this->errors[] = $this->error;
|
|
||||||
$error++;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare the substitions for mail's subject and body
|
// Adding some useful substitions of our own...
|
||||||
$substitutionarray = getCommonSubstitutionArray($langs, 0, null, $object);
|
if ( ! empty($object->linkedObjects['contrat'])) {
|
||||||
complete_substitutions_array($substitutionarray, $langs, $object); // lourd et n'a rien ajouté lors de mes tests
|
$contrat = reset($object->linkedObjects['contrat']); // no deep search, we take the first linked contract
|
||||||
|
$substitutionarray['__CONTRACT_REF__'] = $contrat->ref;
|
||||||
|
}
|
||||||
|
|
||||||
// Adding some useful substitions of our own...
|
// Initialisations
|
||||||
if ( ! empty($object->linkedObjects['contrat'])) {
|
$mail_data = array(
|
||||||
$contrat = reset($object->linkedObjects['contrat']); // no deep search, we take the first linked contract
|
'from' => $mailObject->frommail,
|
||||||
$substitutionarray['__CONTRACT_REF__'] = $contrat->ref;
|
'to' => implode(', ', $mailObject->compileEmails('to', true)),
|
||||||
}
|
'cc' => implode(', ', $mailObject->compileEmails('cc', true)),
|
||||||
|
'bcc' => implode(', ', $mailObject->compileEmails('bcc', true)),
|
||||||
|
'errorsTo' => $conf->global->MAIN_MAIL_ERRORS_TO,
|
||||||
|
'replyTo' => $conf->global->MAIN_MAIL_ERRORS_TO,
|
||||||
|
'subject' => $mailObject->subject,
|
||||||
|
'message' => $mailObject->body_plaintext,
|
||||||
|
);
|
||||||
|
|
||||||
// Initialisations
|
// Check that we have a recipient, to avoid some frequent error...
|
||||||
$mail_data = array(
|
if (empty($mail_data['to'] . $mail_data['cc'] . $mail_data['bcc'])) {
|
||||||
'sendto' => $object->thirdparty->name . ' <' . $object->thirdparty->email . '>',
|
dol_syslog("Empty recipient for thirdparty " . $object->thirdparty->id . ". Not sending facturerec " . $facturerec->ref . " (id:" . $facturerec->id . ").");
|
||||||
'from' => $conf->global->MAIN_MAIL_EMAIL_FROM,
|
return 0;
|
||||||
'errorsTo' => $conf->global->MAIN_MAIL_ERRORS_TO,
|
}
|
||||||
'replyTo' => $conf->global->MAIN_MAIL_ERRORS_TO,
|
|
||||||
'subject' => $template->topic,
|
|
||||||
'body' => $template->content,
|
|
||||||
);
|
|
||||||
|
|
||||||
// If the invoice has some custom parameters (subject, body, sendto, ...)
|
// Make the substitutions
|
||||||
$mail_data = array_merge($mail_data, $this->getCustomFieldsMail($object));
|
foreach (array('subject', 'message') as $key) {
|
||||||
|
$mail_data[$key] = make_substitutions($mail_data[$key], $substitutionarray, $langs);
|
||||||
|
if (method_exists($object, 'makeSubstitution')) {
|
||||||
|
$mail_data[$key] = $object->makeSubstitution($mail_data[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check that we have a recipient, to avoid some frequent error...
|
// Check if we have to attach the file
|
||||||
if (empty($mail_data['sendto'])) {
|
$filePath = array();
|
||||||
dol_syslog("Empty recipient for thirdparty " . $object->thirdparty->id . ". Not sending facturerec " . $facturerec->ref . " (id:" . $facturerec->id . ").");
|
$fileMime = array();
|
||||||
return 0;
|
$fileName = array();
|
||||||
}
|
if ($mailObject->addmaindocfile) {
|
||||||
|
$filePath = array(DOL_DATA_ROOT . '/' . $object->last_main_doc);
|
||||||
|
$fileMime = array('application/pdf'); // FIXME: à rendre dynamique, même si ce sera toujours du PDF ?
|
||||||
|
$fileName = array(basename($object->last_main_doc));
|
||||||
|
}
|
||||||
|
|
||||||
// Make the substitutions
|
// At last, send the mail
|
||||||
foreach (array('subject', 'body') as $key) {
|
$mailfile = new CMailFile(
|
||||||
$mail_data[$key] = make_substitutions($mail_data[$key], $substitutionarray, $langs);
|
$mail_data['subject'],
|
||||||
if (method_exists($object, 'makeSubstitution')) {
|
$mail_data['to'],
|
||||||
$mail_data[$key] = $object->makeSubstitution($mail_data[$key]);
|
$mail_data['from'],
|
||||||
}
|
$mail_data['message'],
|
||||||
}
|
$filePath,
|
||||||
|
$fileMime,
|
||||||
|
$fileName,
|
||||||
|
$mail_data['cc'], // CC
|
||||||
|
$mail_data['bcc'], // BCC
|
||||||
|
0, //deliveryreceipt
|
||||||
|
0, //msgishtml
|
||||||
|
$mail_data['errorsTo'],
|
||||||
|
'', // css
|
||||||
|
'', // trackid
|
||||||
|
'', // moreinheader
|
||||||
|
'standard', // sendcontext
|
||||||
|
$mail_data['replyTo']);
|
||||||
|
|
||||||
// Check if we have to attach the file
|
if ($mailfile->sendfile()) {
|
||||||
$filePath = array();
|
dol_syslog("Success sending email for " . $facturerec->ref . " (id:" . $facturerec->id . ").");
|
||||||
$fileMime = array();
|
|
||||||
$fileName = array();
|
|
||||||
if ($template->joinfiles) {
|
|
||||||
$filePath = array(DOL_DATA_ROOT . '/' . $object->last_main_doc);
|
|
||||||
$fileMime = array('application/pdf'); // FIXME: à rendre dynamique, même si ce sera toujours du PDF ?
|
|
||||||
$fileName = array(basename($object->last_main_doc));
|
|
||||||
}
|
|
||||||
|
|
||||||
// At last, send the mail
|
// Adds info to object for trigger
|
||||||
$mailfile = new CMailFile(
|
// (maybe make a copy of the object instead of modifying it directly ?)
|
||||||
$mail_data['subject'],
|
$object->email_msgid = $mailfile->msgid;
|
||||||
$mail_data['sendto'],
|
$object->email_from = $mail_data['from'];
|
||||||
$mail_data['from'],
|
$object->email_subject = $mail_data['subject'];
|
||||||
$mail_data['body'],
|
$object->email_to = $mail_data['to'];
|
||||||
$filePath,
|
$object->email_tocc = $mail_data['cc'];
|
||||||
$fileMime,
|
$object->email_tobcc = $mail_data['bcc'];
|
||||||
$fileName,
|
$object->actiontypecode = 'AC_OTH_AUTO';
|
||||||
'', // CC
|
$object->actionmsg2=$langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($mail_data['from'],4,0,1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($mail_data['to'],4,0,1);
|
||||||
'', // BCC
|
$object->actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($mail_data['from']);
|
||||||
0, //deliveryreceipt
|
$object->actionmsg = dol_concatdesc($object->actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($mail_data['to']));
|
||||||
0, //msgishtml
|
$object->actionmsg = dol_concatdesc($object->actionmsg, $langs->transnoentities('MailTopic') . ": " . $mail_data['subject']);
|
||||||
$mail_data['errorsTo'],
|
$object->actionmsg = dol_concatdesc($object->actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
|
||||||
'', // css
|
$object->actionmsg = dol_concatdesc($object->actionmsg, $mail_data['message']);
|
||||||
'', // trackid
|
|
||||||
'', // moreinheader
|
|
||||||
'standard', // sendcontext
|
|
||||||
$mail_data['replyTo']);
|
|
||||||
|
|
||||||
if ($mailfile->sendfile()) {
|
// Launch triggers
|
||||||
dol_syslog("Success sending email for " . $facturerec->ref . " (id:" . $facturerec->id . ").");
|
$interface = new Interfaces($this->db);
|
||||||
|
$resultTrigger = $interface->run_triggers('BILL_SENTBYMAIL', $object, $user, $langs, $conf);
|
||||||
// Adds info to object for trigger
|
} else {
|
||||||
// (maybe make a copy of the object instead of modifying it directly ?)
|
$this->error = "Error sending email for " . $facturerec->ref . " (id:" . $facturerec->id . ").";
|
||||||
$object->email_msgid = $mailfile->msgid;
|
$this->errors[] = $this->error;
|
||||||
$object->email_from = $mail_data['from'];
|
dol_syslog($this->error);
|
||||||
$object->email_subject = $mail_data['subject'];
|
$error++;
|
||||||
$object->email_to = $mail_data['sendto'];
|
}
|
||||||
//$object->email_tocc = $sendtocc;
|
|
||||||
//$object->email_tobcc = $sendtobcc;
|
|
||||||
$object->actiontypecode = 'AC_OTH_AUTO';
|
|
||||||
$object->actionmsg2=$langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($mail_data['from'],4,0,1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($mail_data['sendto'],4,0,1);
|
|
||||||
$object->actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($mail_data['from']);
|
|
||||||
$object->actionmsg = dol_concatdesc($object->actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($mail_data['sendto']));
|
|
||||||
$object->actionmsg = dol_concatdesc($object->actionmsg, $langs->transnoentities('MailTopic') . ": " . $mail_data['subject']);
|
|
||||||
$object->actionmsg = dol_concatdesc($object->actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
|
|
||||||
$object->actionmsg = dol_concatdesc($object->actionmsg, $mail_data['body']);
|
|
||||||
|
|
||||||
// Launch triggers
|
|
||||||
$interface = new Interfaces($this->db);
|
|
||||||
$resultTrigger = $interface->run_triggers('BILL_SENTBYMAIL', $object, $user, $langs, $conf);
|
|
||||||
} else {
|
|
||||||
$this->error = "Error sending email for " . $facturerec->ref . " (id:" . $facturerec->id . ").";
|
|
||||||
$this->errors[] = $this->error;
|
|
||||||
dol_syslog($this->error);
|
|
||||||
$error++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ($error ? -1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: For the time being, we abuse of note_private to store our customizations
|
|
||||||
*/
|
|
||||||
public function getCustomFieldsMail($object)
|
|
||||||
{
|
|
||||||
return $this->parseCustomFieldsMail($object->note_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: For the time being, we abuse of note_private to store our customizations
|
|
||||||
*
|
|
||||||
* This expect something like this in note_private:
|
|
||||||
* This is a good client... (other private infos)
|
|
||||||
* %%% sendrecurringinvoicebymail::subject
|
|
||||||
* New invoice __REF__
|
|
||||||
* %%%
|
|
||||||
* %%% sendrecurringinvoicebymail::sendto
|
|
||||||
* recipient1@example.org, recipient2@example.org
|
|
||||||
* %%%
|
|
||||||
* %%% sendrecurringinvoicebymail::body
|
|
||||||
* Hello dear client,
|
|
||||||
* Please find attached...
|
|
||||||
* %%%
|
|
||||||
*/
|
|
||||||
public function parseCustomFieldsMail($data)
|
|
||||||
{
|
|
||||||
$output = [];
|
|
||||||
|
|
||||||
// Remove eventual windows' "\r"
|
|
||||||
$data = str_replace("\r", "", $data);
|
|
||||||
|
|
||||||
$regexps = array(
|
|
||||||
'subject' => '/(^|\n)%%% sendrecurringinvoicebymail::subject\n(?<subject>.*)%%%(\n|$)/sU',
|
|
||||||
'body' => '/(^|\n)%%% sendrecurringinvoicebymail::body\n(?<body>.*)%%%(\n|$)/sU',
|
|
||||||
'sendto' => '/(^|\n)%%% sendrecurringinvoicebymail::sendto\n(?<sendto>.*)%%%(\n|$)/sU',
|
|
||||||
);
|
|
||||||
foreach ($regexps as $key => $r) {
|
|
||||||
$result_regexp = [];
|
|
||||||
if (preg_match_all($r, $data, $result_regexp)) {
|
|
||||||
$output[$key] = trim($result_regexp[$key][0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return ($error ? -1 : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
516
class/sribmcustommailinfo.class.php
Normal file
516
class/sribmcustommailinfo.class.php
Normal file
|
@ -0,0 +1,516 @@
|
||||||
|
<?php
|
||||||
|
/* Cpoyright (C) 2021 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 class/sribmcustommailinfo.class.php
|
||||||
|
* \brief File of class for objects storing custom mail informations (module SRIBM : SendRecurringInvoiceByMail)
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
|
||||||
|
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture-rec.class.php';
|
||||||
|
require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for objects storing custom mail informations.
|
||||||
|
*
|
||||||
|
* Part of module SRIBM : SendRecurringInvoiceByMail
|
||||||
|
*/
|
||||||
|
class SRIBMCustomMailInfo extends CommonObject
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string Id to identify managed objects
|
||||||
|
*/
|
||||||
|
public $element = 'sribmcustommailinfo';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Name of table without prefix where object is stored
|
||||||
|
*/
|
||||||
|
public $table_element = 'sribm_custom_mail_info';
|
||||||
|
|
||||||
|
// Database fields
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $fk_facture_rec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $active = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $addmaindocfile = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Type of sender, could be 'robot', 'user' or 'company',
|
||||||
|
* usually meaning the mail sender is determined by the
|
||||||
|
* PHP/Dolibarr config (cf. admin/mails.php?mainmenu=home ),
|
||||||
|
* this object's creator email or the company email.
|
||||||
|
*/
|
||||||
|
public $fromtype = 'robot';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $frommail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int 1: Send to societe main's email, 0: don't.
|
||||||
|
*/
|
||||||
|
public $sendto_thirdparty = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Format expected: "Foo <foo@example.com>, bar@example.net"
|
||||||
|
*/
|
||||||
|
public $sendto_free;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int 1: Send to societe main's email, 0: don't.
|
||||||
|
*/
|
||||||
|
public $sendcc_thirdparty = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Format expected: "Foo <foo@example.com>, bar@example.net"
|
||||||
|
*/
|
||||||
|
public $sendcc_free;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int 1: Send to societe main's email, 0: don't.
|
||||||
|
*/
|
||||||
|
public $sendbcc_thirdparty = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Format expected: "Foo <foo@example.com>, bar@example.net"
|
||||||
|
*/
|
||||||
|
public $sendbcc_free;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $subject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $body_plaintext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string (not used at the moment)
|
||||||
|
*/
|
||||||
|
public $body_html;
|
||||||
|
|
||||||
|
// End of database fields
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FactureRec object linked to this object
|
||||||
|
*
|
||||||
|
* Note : the class Facture use $fac_rec and fk_fac_rec_source which both
|
||||||
|
* seem to be integer (I don't really see the distinction), so we suffix
|
||||||
|
* with '_object' to avoid future conflict.
|
||||||
|
*
|
||||||
|
* @var FactureRec
|
||||||
|
*/
|
||||||
|
public $fac_rec_object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array SocPeoples linked via table llx_sribm_custom_mail_info_socpeople (FIXME: describe format)
|
||||||
|
*/
|
||||||
|
public $linkToSocPeoples = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param DoliDb $db Database handler
|
||||||
|
*/
|
||||||
|
public function __construct(DoliDB $db)
|
||||||
|
{
|
||||||
|
global $conf;
|
||||||
|
|
||||||
|
$this->db = $db;
|
||||||
|
|
||||||
|
// Fill default values
|
||||||
|
$this->frommail = $conf->global->MAIN_MAIL_EMAIL_FROM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create object into database
|
||||||
|
*
|
||||||
|
* Since only one mail can exist for each invoice template, this method
|
||||||
|
* only insert a row with the id of the template and delegate all the work
|
||||||
|
* on the rest of the data to the update() method.
|
||||||
|
*
|
||||||
|
* @param User $user User that creates (at the moment, we don't use it)
|
||||||
|
* @param int $notrigger 1=do not execute triggers, 0 otherwise
|
||||||
|
* @return int >0 if OK, < 0 if KO
|
||||||
|
*/
|
||||||
|
public function create(User $user, $notrigger = 0)
|
||||||
|
{
|
||||||
|
$error=0;
|
||||||
|
|
||||||
|
$this->db->begin();
|
||||||
|
|
||||||
|
$sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element;
|
||||||
|
$sql .= " (fk_facture_rec, fromtype, frommail)";
|
||||||
|
$sql .= sprintf(
|
||||||
|
" VALUES (%d, '%s', '%s')",
|
||||||
|
(int)$this->fk_facture_rec,
|
||||||
|
$this->db->escape($this->fromtype),
|
||||||
|
$this->db->escape($this->frommail)
|
||||||
|
);
|
||||||
|
|
||||||
|
dol_syslog("SRIBMCustomMailInfo::create", LOG_DEBUG);
|
||||||
|
|
||||||
|
$result = $this->db->query($sql);
|
||||||
|
if ($result) {
|
||||||
|
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
|
||||||
|
$result = $this->update($user, 1);
|
||||||
|
if ($result < 0) {
|
||||||
|
$this->db->rollback();
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $notrigger)
|
||||||
|
{
|
||||||
|
// Call trigger
|
||||||
|
$result=$this->call_trigger('SRIBM_CUSTOM_MAIL_INFO_CREATE', $user);
|
||||||
|
if ($result < 0) {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
// End call triggers
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->commit();
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update object in database
|
||||||
|
*
|
||||||
|
* @param User $user User that creates (at the moment, we don't use it)
|
||||||
|
* @param int $notrigger 1=do not execute triggers, 0 otherwise
|
||||||
|
* @return int >0 if OK, < 0 if KO
|
||||||
|
*/
|
||||||
|
public function update(User $user, $notrigger = 0)
|
||||||
|
{
|
||||||
|
$error=0;
|
||||||
|
|
||||||
|
//$this->db->begin();
|
||||||
|
|
||||||
|
$sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
|
||||||
|
$sql .= " SET ";
|
||||||
|
$sql .= " fk_facture_rec = " . (int)$this->fk_facture_rec;
|
||||||
|
$sql .= ", active = " . (int)$this->active;
|
||||||
|
$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);
|
||||||
|
$sql .= ", sendto_free = '" . $this->db->escape($this->sendto_free) . "'";
|
||||||
|
$sql .= ", sendcc_thirdparty = " . (int)$this->db->escape($this->sendcc_thirdparty);
|
||||||
|
$sql .= ", sendcc_free = '" . $this->db->escape($this->sendcc_free) . "'";
|
||||||
|
$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_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);
|
||||||
|
if ($result) {
|
||||||
|
if (! $notrigger)
|
||||||
|
{
|
||||||
|
// Call trigger
|
||||||
|
$result=$this->call_trigger('SRIBM_CUSTOM_MAIL_INFO_MODIFY', $user);
|
||||||
|
if ($result < 0) {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
// End call triggers
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
dol_syslog(get_class($this) . "::update " . $this->error, LOG_ERR);
|
||||||
|
$this->db->rollback();
|
||||||
|
return -$error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->error = $this->db->lasterror();
|
||||||
|
$this->db->rollback();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//$this->db->commit();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate object with data from DB
|
||||||
|
*
|
||||||
|
* @param int $rowid Id of the SRIBMCustomMailInfo to load
|
||||||
|
* @param int $ref Id of the fac_rec_object
|
||||||
|
* @param bool $fill_defaults_from_template If true and the model doesn't exist in DB, fill attributes using the template
|
||||||
|
* @return int < 0 if KO, > 0 if OK
|
||||||
|
*/
|
||||||
|
public function fetch($rowid, $ref=null, $fill_defaults_from_template = false)
|
||||||
|
{
|
||||||
|
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_plaintext, body_html";
|
||||||
|
$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
|
||||||
|
$sql .= " WHERE " . (isset($ref) ? 'fk_facture_rec = ' . (int)$ref : "rowid = " . (int)$rowid);
|
||||||
|
|
||||||
|
dol_syslog("SRIBMCustomMailInfo::fetch", LOG_DEBUG);
|
||||||
|
|
||||||
|
$result = $this->db->query($sql);
|
||||||
|
if (! $result) {
|
||||||
|
$this->error=$this->db->lasterror();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->db->num_rows($result)) {
|
||||||
|
$obj = $this->db->fetch_object($result);
|
||||||
|
|
||||||
|
$this->id = $obj->rowid;
|
||||||
|
$this->fk_facture_rec = $obj->fk_facture_rec;
|
||||||
|
$this->active = $obj->active;
|
||||||
|
$this->addmaindocfile = $obj->addmaindocfile;
|
||||||
|
$this->fromtype = $obj->fromtype;
|
||||||
|
$this->frommail = $obj->frommail;
|
||||||
|
$this->sendto_thirdparty = $obj->sendto_thirdparty;
|
||||||
|
$this->sendto_free = $obj->sendto_free;
|
||||||
|
$this->sendcc_thirdparty = $obj->sendcc_thirdparty;
|
||||||
|
$this->sendcc_free = $obj->sendcc_free;
|
||||||
|
$this->sendbcc_thirdparty = $obj->sendbcc_thirdparty;
|
||||||
|
$this->sendbcc_free = $obj->sendbcc_free;
|
||||||
|
$this->subject = $obj->subject;
|
||||||
|
$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);
|
||||||
|
dol_syslog("SRIBMCustomMailInfo::fetch error " . $this->error, LOG_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// It seems to be usual to fully fetch by default (cf. Facture source
|
||||||
|
// code with fetch_optionals()) so we copy the Dolibarr behaviour
|
||||||
|
// Link to the facture_rec
|
||||||
|
$this->fac_rec_object = new FactureRec($this->db);
|
||||||
|
if ($this->fac_rec_object->fetch($ref) <= 0) {
|
||||||
|
$this->error = "Unable to fetch FactureRec $ref.";
|
||||||
|
dol_syslog("FactureRec::Fetch error " . $this->error, LOG_ERR);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
if ($this->fac_rec_object->fetch_thirdparty() <= 0) {
|
||||||
|
$this->error = "Unable to fetch ThirdParty for FactureRec $ref.";
|
||||||
|
dol_syslog("FactureRec::FetchThirdParty error " . $this->error, LOG_ERR);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
$result = $this->fac_rec_object->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0); // This load $_facrec->linkedObjectsIds
|
||||||
|
|
||||||
|
// link to socpeople
|
||||||
|
if ($this->id) {
|
||||||
|
// FIXME: create a dedicated PHP class?
|
||||||
|
$sql = "SELECT fk_socpeople, sendtype";
|
||||||
|
$sql .= " FROM " . MAIN_DB_PREFIX . "sribm_custom_mail_info_socpeople";
|
||||||
|
$sql .= " WHERE fk_sribm_cmi = " . (int)$this->id;
|
||||||
|
$result = $this->db->query($sql);
|
||||||
|
if (! $result) {
|
||||||
|
$this->error=$this->db->lasterror();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset the attribute
|
||||||
|
$this->linkToSocPeoples = array();
|
||||||
|
while ($obj = $this->db->fetch_object($result)) {
|
||||||
|
$tmp = new Contact($this->db);
|
||||||
|
if ($tmp->fetch($obj->fk_socpeople) > 0) {
|
||||||
|
$tmp->pivot = $obj;
|
||||||
|
$this->linkToSocPeoples[] = $tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally, if the model hasn't been found (no id), we fill with the template's data
|
||||||
|
if (!$this->id && $fill_defaults_from_template) {
|
||||||
|
$result = $this->db->query("SELECT topic, content, joinfiles FROM " . MAIN_DB_PREFIX . "c_email_templates WHERE module = 'sendrecurringinvoicebymail' AND active = 1 AND enabled = '1' ORDER BY tms DESC LIMIT 1");
|
||||||
|
if ( ! $result or ! ($template = $this->db->fetch_object($result))) {
|
||||||
|
$this->error = "Can't find mail template for sendrecurringinvoicebymail";
|
||||||
|
dol_syslog("SRIBMCustomMailInfo::fetch error " . $this->error, LOG_ERR);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->subject = $template->topic;
|
||||||
|
$this->body_plaintext = $template->content;
|
||||||
|
$this->addmaindocfile = $template->joinfiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete this object's record in database
|
||||||
|
*
|
||||||
|
* @return int <0 on error, >0 if OK
|
||||||
|
*/
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
$error=0;
|
||||||
|
|
||||||
|
//$this->db->begin();
|
||||||
|
|
||||||
|
$sql = "DELETE FROM " . MAIN_DB_PREFIX . $this->table_element;
|
||||||
|
$sql .= " WHERE rowid = " . (int)$this->id;
|
||||||
|
|
||||||
|
$result = $this->db->query($sql);
|
||||||
|
if (! $result) {
|
||||||
|
//$this->db->rollback();
|
||||||
|
$this->error = $this->db->lasterror();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call trigger
|
||||||
|
$result = $this->call_trigger('SRIBM_CUSTOM_MAIL_INFO_DELETE', $user);
|
||||||
|
if ($result < 0) {
|
||||||
|
$error++;
|
||||||
|
}
|
||||||
|
// End call triggers
|
||||||
|
|
||||||
|
if ($error) {
|
||||||
|
dol_syslog(get_class($this) . "::delete " . $this->error, LOG_ERR);
|
||||||
|
//$this->db->rollback();
|
||||||
|
return -$error;
|
||||||
|
}
|
||||||
|
|
||||||
|
//$this->db->commit();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quick function to synchronize the links between this object and its contacts
|
||||||
|
*
|
||||||
|
* Format of the data :
|
||||||
|
* array(
|
||||||
|
* array('id' => id_contact_1, 'sendtype' => 'to'),
|
||||||
|
* array('id' => id_contact_2, 'sendtype' => 'cc'),
|
||||||
|
* ...
|
||||||
|
*
|
||||||
|
* @param array $data Format : see above
|
||||||
|
* @return int <0 on error, >0 if OK
|
||||||
|
*/
|
||||||
|
public function updateLinkSocPeople($data)
|
||||||
|
{
|
||||||
|
$this->db->begin();
|
||||||
|
|
||||||
|
$result = $this->db->query("DELETE FROM " . MAIN_DB_PREFIX . "sribm_custom_mail_info_socpeople where fk_sribm_cmi = " . (int)$this->id);
|
||||||
|
if (! $result) {
|
||||||
|
$this->error=$this->db->lasterror();
|
||||||
|
$this->db->rollback();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($data) {
|
||||||
|
$sql = "INSERT INTO " . MAIN_DB_PREFIX . "sribm_custom_mail_info_socpeople";
|
||||||
|
$sql .= " (fk_sribm_cmi, fk_socpeople, sendtype) VALUES (%d, %d, '%s')";
|
||||||
|
foreach ($data as $item) {
|
||||||
|
// We insert one by one to maximize compatibility
|
||||||
|
// (if there happens to be thousands of links, I'll rework it :)
|
||||||
|
$result = $this->db->query(sprintf(
|
||||||
|
$sql,
|
||||||
|
$this->id,
|
||||||
|
$item['id'],
|
||||||
|
$this->db->escape($item['sendtype'])
|
||||||
|
));
|
||||||
|
if (! $result) {
|
||||||
|
$this->error=$this->db->lasterror();
|
||||||
|
$this->db->rollback();
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->commit();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to compile the recipients in one string from sendto_thirdparty,
|
||||||
|
* sendto_free and socpeople.
|
||||||
|
*
|
||||||
|
* @param string $sendtype One of 'to', 'cc', 'bcc'
|
||||||
|
* @param bool $filterBadEmail If true, don't include recipients with empty/bad email address
|
||||||
|
* @return string String compiling emails in the format 'Foo <foo@example.com>, bar@example.com'
|
||||||
|
*/
|
||||||
|
public function compileEmails($sendtype, $filterBadEmails = false)
|
||||||
|
{
|
||||||
|
$output = array();
|
||||||
|
|
||||||
|
$listContacts = $this->fac_rec_object->thirdparty->thirdparty_and_contact_email_array(1);
|
||||||
|
|
||||||
|
switch ($sendtype) {
|
||||||
|
case 'to':
|
||||||
|
if ($this->sendto_free) {
|
||||||
|
$output[] = $this->sendto_free;
|
||||||
|
}
|
||||||
|
if ($this->sendto_thirdparty) {
|
||||||
|
$output[] = $listContacts['thirdparty'];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'cc':
|
||||||
|
if ($this->sendcc_free) {
|
||||||
|
$output[] = $this->sendcc_free;
|
||||||
|
}
|
||||||
|
if ($this->sendcc_thirdparty) {
|
||||||
|
$output[] = $listContacts['thirdparty'];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'bcc':
|
||||||
|
if ($this->sendbcc_free) {
|
||||||
|
$output[] = $this->sendbcc_free;
|
||||||
|
}
|
||||||
|
if ($this->sendbcc_thirdparty) {
|
||||||
|
$output[] = $listContacts['thirdparty'];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->linkToSocPeoples as $contact) {
|
||||||
|
if ($contact->pivot->sendtype == $sendtype) {
|
||||||
|
$output[] = $listContacts[$contact->id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($filterBadEmails) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
/* Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
|
/* Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||||
* Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
|
* Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
|
||||||
* Copyright (C) 2018 SuperAdmin
|
* Copyright (C) 2018 SuperAdmin
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup sendrecurringinvoicebymail Module sendrecurringinvoicebymail
|
* \defgroup sendrecurringinvoicebymail Module sendrecurringinvoicebymail
|
||||||
* \brief sendrecurringinvoicebymail module descriptor.
|
* \brief sendrecurringinvoicebymail module descriptor.
|
||||||
*
|
*
|
||||||
* \file htdocs/sendrecurringinvoicebymail/core/modules/modsendrecurringinvoicebymail.class.php
|
* \file htdocs/sendrecurringinvoicebymail/core/modules/modsendrecurringinvoicebymail.class.php
|
||||||
|
@ -33,324 +33,412 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
|
||||||
*/
|
*/
|
||||||
class modsendrecurringinvoicebymail extends DolibarrModules
|
class modsendrecurringinvoicebymail extends DolibarrModules
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor. Define names, constants, directories, boxes, permissions
|
* Constructor. Define names, constants, directories, boxes, permissions
|
||||||
*
|
*
|
||||||
* @param DoliDB $db Database handler
|
* @param DoliDB $db Database handler
|
||||||
*/
|
*/
|
||||||
public function __construct($db)
|
public function __construct($db)
|
||||||
{
|
{
|
||||||
global $langs,$conf;
|
global $langs,$conf;
|
||||||
|
|
||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
|
|
||||||
// Id for module (must be unique).
|
// Id for module (must be unique).
|
||||||
// Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
|
// Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
|
||||||
$this->numero = 468101; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve id number for your module
|
$this->numero = 468101; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve id number for your module
|
||||||
// Key text used to identify module (for permissions, menus, etc...)
|
// Key text used to identify module (for permissions, menus, etc...)
|
||||||
$this->rights_class = 'sendrecurringinvoicebymail';
|
$this->rights_class = 'sendrecurringinvoicebymail';
|
||||||
|
|
||||||
// Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
|
// 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
|
// It is used to group modules by family in module setup page
|
||||||
$this->family = "crm";
|
$this->family = "crm";
|
||||||
// Module position in the family on 2 digits ('01', '10', '20', ...)
|
// Module position in the family on 2 digits ('01', '10', '20', ...)
|
||||||
$this->module_position = '90';
|
$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)
|
// 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)
|
||||||
//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
|
//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
|
||||||
|
|
||||||
// Module label (no space allowed), used if translation string 'ModulesendrecurringinvoicebymailName' not found (sendrecurringinvoicebymail is name of module).
|
// Module label (no space allowed), used if translation string 'ModulesendrecurringinvoicebymailName' not found (sendrecurringinvoicebymail is name of module).
|
||||||
$this->name = preg_replace('/^mod/i','',get_class($this));
|
$this->name = preg_replace('/^mod/i','',get_class($this));
|
||||||
// Module description, used if translation string 'ModulesendrecurringinvoicebymailDesc' not found (sendrecurringinvoicebymail is name of module).
|
// Module description, used if translation string 'ModulesendrecurringinvoicebymailDesc' not found (sendrecurringinvoicebymail is name of module).
|
||||||
$this->description = "Send generated invoice by email";
|
$this->description = "Send generated invoice by email";
|
||||||
// Used only if file README.md and README-LL.md not found.
|
// Used only if file README.md and README-LL.md not found.
|
||||||
$this->descriptionlong = "This module hooks onto the recurring invoice generation to automatically send the generated PDF.";
|
$this->descriptionlong = "This module hooks onto the recurring invoice generation to automatically send the generated PDF.";
|
||||||
|
|
||||||
$this->editor_name = 'Bugness';
|
$this->editor_name = 'Bugness';
|
||||||
$this->editor_url = 'https://code.bugness.org/Dolibarr/sendrecurringinvoicebymail';
|
$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'
|
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
|
||||||
$this->version = '0.2.7';
|
$this->version = '0.3.0';
|
||||||
|
|
||||||
//Url to the file with your last numberversion of this module
|
//Url to the file with your last numberversion of this module
|
||||||
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
|
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
|
||||||
// Key used in llx_const table to save module status enabled/disabled (where SENDRECURRINGINVOICEBYMAIL is value of property name of module in uppercase)
|
// Key used in llx_const table to save module status enabled/disabled (where SENDRECURRINGINVOICEBYMAIL is value of property name of module in uppercase)
|
||||||
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
|
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
|
||||||
// Name of image file used for this module.
|
// Name of image file used for this module.
|
||||||
// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
|
// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
|
||||||
// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
|
// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
|
||||||
$this->picto = 'sendrecurringinvoicebymail@sendrecurringinvoicebymail';
|
$this->picto = 'sendrecurringinvoicebymail@sendrecurringinvoicebymail';
|
||||||
|
|
||||||
// Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
|
// Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
|
||||||
$this->module_parts = array(
|
$this->module_parts = array(
|
||||||
'triggers' => 0, // Set this to 1 if module has its own trigger directory (core/triggers)
|
'triggers' => 0, // Set this to 1 if module has its own trigger directory (core/triggers)
|
||||||
'login' => 0, // Set this to 1 if module has its own login method file (core/login)
|
'login' => 0, // Set this to 1 if module has its own login method file (core/login)
|
||||||
'substitutions' => 0, // Set this to 1 if module has its own substitution function file (core/substitutions)
|
'substitutions' => 0, // Set this to 1 if module has its own substitution function file (core/substitutions)
|
||||||
'menus' => 0, // Set this to 1 if module has its own menus handler directory (core/menus)
|
'menus' => 0, // Set this to 1 if module has its own menus handler directory (core/menus)
|
||||||
'theme' => 0, // Set this to 1 if module has its own theme directory (theme)
|
'theme' => 0, // Set this to 1 if module has its own theme directory (theme)
|
||||||
'tpl' => 0, // Set this to 1 if module overwrite template dir (core/tpl)
|
'tpl' => 0, // Set this to 1 if module overwrite template dir (core/tpl)
|
||||||
'barcode' => 0, // Set this to 1 if module has its own barcode directory (core/modules/barcode)
|
'barcode' => 0, // Set this to 1 if module has its own barcode directory (core/modules/barcode)
|
||||||
'models' => 0, // Set this to 1 if module has its own models directory (core/modules/xxx)
|
'models' => 0, // Set this to 1 if module has its own models directory (core/modules/xxx)
|
||||||
//'css' => array('/sendrecurringinvoicebymail/css/sendrecurringinvoicebymail.css.php'), // Set this to relative path of css file if module has its own css file
|
'css' => array(),
|
||||||
//'js' => array('/sendrecurringinvoicebymail/js/sendrecurringinvoicebymail.js.php'), // Set this to relative path of js file if module must load a js on all pages
|
//'css' => array('/sendrecurringinvoicebymail/css/sendrecurringinvoicebymail.css.php'), // Set this to relative path of css file if module has its own css file
|
||||||
'hooks' => array('cron'), // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context 'all'
|
'js' => array(),
|
||||||
'moduleforexternal' => 0 // Set this to 1 if feature of module are opened to external users
|
//'js' => array('/sendrecurringinvoicebymail/js/sendrecurringinvoicebymail.js.php'), // Set this to relative path of js file if module must load a js on all pages
|
||||||
);
|
'hooks' => array('cron'), // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context 'all'
|
||||||
|
'moduleforexternal' => 0 // Set this to 1 if feature of module are opened to external users
|
||||||
|
);
|
||||||
|
|
||||||
// Data directories to create when module is enabled.
|
// Data directories to create when module is enabled.
|
||||||
// Example: this->dirs = array("/sendrecurringinvoicebymail/temp","/sendrecurringinvoicebymail/subdir");
|
// Example: this->dirs = array("/sendrecurringinvoicebymail/temp","/sendrecurringinvoicebymail/subdir");
|
||||||
$this->dirs = array("/sendrecurringinvoicebymail/temp");
|
$this->dirs = array("/sendrecurringinvoicebymail/temp");
|
||||||
|
|
||||||
// Config pages. Put here list of php page, stored into sendrecurringinvoicebymail/admin directory, to use to setup module.
|
// 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
|
// Dependencies
|
||||||
$this->hidden = false; // A condition to hide module
|
$this->hidden = false; // A condition to hide module
|
||||||
$this->depends = array('modFacture'); // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...)
|
$this->depends = array('modFacture'); // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...)
|
||||||
$this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...)
|
$this->requiredby = array(); // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...)
|
||||||
$this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...)
|
$this->conflictwith = array(); // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...)
|
||||||
$this->langfiles = array("sendrecurringinvoicebymail@sendrecurringinvoicebymail");
|
$this->langfiles = array("sendrecurringinvoicebymail@sendrecurringinvoicebymail");
|
||||||
//$this->phpmin = array(5,4); // Minimum version of PHP required by module
|
//$this->phpmin = array(5,4); // Minimum version of PHP required by module
|
||||||
$this->need_dolibarr_version = array(10,0); // Minimum version of Dolibarr required by module
|
$this->need_dolibarr_version = array(10,0); // Minimum version of Dolibarr required by module
|
||||||
$this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
|
$this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
|
||||||
$this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
|
$this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
|
||||||
//$this->automatic_activation = array('FR'=>'sendrecurringinvoicebymailWasAutomaticallyActivatedBecauseOfYourCountryChoice');
|
//$this->automatic_activation = array('FR'=>'sendrecurringinvoicebymailWasAutomaticallyActivatedBecauseOfYourCountryChoice');
|
||||||
//$this->always_enabled = true; // If true, can't be disabled
|
//$this->always_enabled = true; // If true, can't be disabled
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
// List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
|
// List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
|
||||||
// Example: $this->const=array(0=>array('SENDRECURRINGINVOICEBYMAIL_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
|
// Example: $this->const=array(0=>array('SENDRECURRINGINVOICEBYMAIL_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
|
||||||
// 1=>array('SENDRECURRINGINVOICEBYMAIL_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
|
// 1=>array('SENDRECURRINGINVOICEBYMAIL_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
|
||||||
// );
|
// );
|
||||||
$this->const = array(
|
$this->const = array(
|
||||||
//1=>array('SENDRECURRINGINVOICEBYMAIL_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1)
|
//1=>array('SENDRECURRINGINVOICEBYMAIL_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Some keys to add into the overwriting translation tables
|
// Some keys to add into the overwriting translation tables
|
||||||
/*$this->overwrite_translation = array(
|
/*$this->overwrite_translation = array(
|
||||||
'en_US:ParentCompany'=>'Parent company or reseller',
|
'en_US:ParentCompany'=>'Parent company or reseller',
|
||||||
'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
|
'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
|
||||||
)*/
|
)*/
|
||||||
|
|
||||||
if (! isset($conf->sendrecurringinvoicebymail) || ! isset($conf->sendrecurringinvoicebymail->enabled))
|
if (! isset($conf->sendrecurringinvoicebymail) || ! isset($conf->sendrecurringinvoicebymail->enabled))
|
||||||
{
|
{
|
||||||
$conf->sendrecurringinvoicebymail=new stdClass();
|
$conf->sendrecurringinvoicebymail=new stdClass();
|
||||||
$conf->sendrecurringinvoicebymail->enabled=0;
|
$conf->sendrecurringinvoicebymail->enabled=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Array to add new pages in new tabs
|
// Array to add new pages in new tabs
|
||||||
$this->tabs = array();
|
$this->tabs = array();
|
||||||
// Example:
|
$this->tabs[] = array('data'=>'invoice-rec:+sendrecurringinvoicebymail:SendingByMail:sendrecurringinvoicebymail@sendrecurringinvoicebymail:sendrecurringinvoicebymail/fiche-rec-tab1.php?id=__ID__'); // To add a new tab identified by code tabname1
|
||||||
// $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@sendrecurringinvoicebymail:$user->rights->sendrecurringinvoicebymail->read:/sendrecurringinvoicebymail/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1
|
// Example:
|
||||||
// $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@sendrecurringinvoicebymail:$user->rights->othermodule->read:/sendrecurringinvoicebymail/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
|
// $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@sendrecurringinvoicebymail:$user->rights->sendrecurringinvoicebymail->read:/sendrecurringinvoicebymail/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1
|
||||||
// $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname
|
// $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@sendrecurringinvoicebymail:$user->rights->othermodule->read:/sendrecurringinvoicebymail/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
|
||||||
|
// $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname
|
||||||
//
|
//
|
||||||
// Where objecttype can be
|
// Where objecttype can be
|
||||||
// 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
|
// 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
|
||||||
// 'contact' to add a tab in contact view
|
// 'contact' to add a tab in contact view
|
||||||
// 'contract' to add a tab in contract view
|
// 'contract' to add a tab in contract view
|
||||||
// 'group' to add a tab in group view
|
// 'group' to add a tab in group view
|
||||||
// 'intervention' to add a tab in intervention view
|
// 'intervention' to add a tab in intervention view
|
||||||
// 'invoice' to add a tab in customer invoice view
|
// 'invoice' to add a tab in customer invoice view
|
||||||
// 'invoice_supplier' to add a tab in supplier invoice view
|
// 'invoice_supplier' to add a tab in supplier invoice view
|
||||||
// 'member' to add a tab in fundation member view
|
// 'member' to add a tab in fundation member view
|
||||||
// 'opensurveypoll' to add a tab in opensurvey poll view
|
// 'opensurveypoll' to add a tab in opensurvey poll view
|
||||||
// 'order' to add a tab in customer order view
|
// 'order' to add a tab in customer order view
|
||||||
// 'order_supplier' to add a tab in supplier order view
|
// 'order_supplier' to add a tab in supplier order view
|
||||||
// 'payment' to add a tab in payment view
|
// 'payment' to add a tab in payment view
|
||||||
// 'payment_supplier' to add a tab in supplier payment view
|
// 'payment_supplier' to add a tab in supplier payment view
|
||||||
// 'product' to add a tab in product view
|
// 'product' to add a tab in product view
|
||||||
// 'propal' to add a tab in propal view
|
// 'propal' to add a tab in propal view
|
||||||
// 'project' to add a tab in project view
|
// 'project' to add a tab in project view
|
||||||
// 'stock' to add a tab in stock view
|
// 'stock' to add a tab in stock view
|
||||||
// 'thirdparty' to add a tab in third party view
|
// 'thirdparty' to add a tab in third party view
|
||||||
// 'user' to add a tab in user view
|
// 'user' to add a tab in user view
|
||||||
|
|
||||||
|
|
||||||
// Dictionaries
|
// Dictionaries
|
||||||
$this->dictionaries=array();
|
$this->dictionaries=array();
|
||||||
/* Example:
|
/* Example:
|
||||||
$this->dictionaries=array(
|
$this->dictionaries=array(
|
||||||
'langs'=>'mylangfile@sendrecurringinvoicebymail',
|
'langs'=>'mylangfile@sendrecurringinvoicebymail',
|
||||||
'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"), // List of tables we want to see into dictonnary editor
|
'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"), // List of tables we want to see into dictonnary editor
|
||||||
'tablib'=>array("Table1","Table2","Table3"), // Label of tables
|
'tablib'=>array("Table1","Table2","Table3"), // Label of tables
|
||||||
'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'), // Request to select fields
|
'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'), // Request to select fields
|
||||||
'tabsqlsort'=>array("label ASC","label ASC","label ASC"), // Sort order
|
'tabsqlsort'=>array("label ASC","label ASC","label ASC"), // Sort order
|
||||||
'tabfield'=>array("code,label","code,label","code,label"), // List of fields (result of select to show dictionary)
|
'tabfield'=>array("code,label","code,label","code,label"), // List of fields (result of select to show dictionary)
|
||||||
'tabfieldvalue'=>array("code,label","code,label","code,label"), // List of fields (list of fields to edit a record)
|
'tabfieldvalue'=>array("code,label","code,label","code,label"), // List of fields (list of fields to edit a record)
|
||||||
'tabfieldinsert'=>array("code,label","code,label","code,label"), // List of fields (list of fields for insert)
|
'tabfieldinsert'=>array("code,label","code,label","code,label"), // List of fields (list of fields for insert)
|
||||||
'tabrowid'=>array("rowid","rowid","rowid"), // Name of columns with primary key (try to always name it 'rowid')
|
'tabrowid'=>array("rowid","rowid","rowid"), // Name of columns with primary key (try to always name it 'rowid')
|
||||||
'tabcond'=>array($conf->sendrecurringinvoicebymail->enabled,$conf->sendrecurringinvoicebymail->enabled,$conf->sendrecurringinvoicebymail->enabled) // Condition to show each dictionary
|
'tabcond'=>array($conf->sendrecurringinvoicebymail->enabled,$conf->sendrecurringinvoicebymail->enabled,$conf->sendrecurringinvoicebymail->enabled) // Condition to show each dictionary
|
||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Boxes/Widgets
|
// Boxes/Widgets
|
||||||
// Add here list of php file(s) stored in sendrecurringinvoicebymail/core/boxes that contains class to show a widget.
|
// Add here list of php file(s) stored in sendrecurringinvoicebymail/core/boxes that contains class to show a widget.
|
||||||
$this->boxes = array(
|
$this->boxes = array(
|
||||||
//0=>array('file'=>'sendrecurringinvoicebymailwidget1.php@sendrecurringinvoicebymail','note'=>'Widget provided by sendrecurringinvoicebymail','enabledbydefaulton'=>'Home'),
|
//0=>array('file'=>'sendrecurringinvoicebymailwidget1.php@sendrecurringinvoicebymail','note'=>'Widget provided by sendrecurringinvoicebymail','enabledbydefaulton'=>'Home'),
|
||||||
//1=>array('file'=>'sendrecurringinvoicebymailwidget2.php@sendrecurringinvoicebymail','note'=>'Widget provided by sendrecurringinvoicebymail'),
|
//1=>array('file'=>'sendrecurringinvoicebymailwidget2.php@sendrecurringinvoicebymail','note'=>'Widget provided by sendrecurringinvoicebymail'),
|
||||||
//2=>array('file'=>'sendrecurringinvoicebymailwidget3.php@sendrecurringinvoicebymail','note'=>'Widget provided by sendrecurringinvoicebymail')
|
//2=>array('file'=>'sendrecurringinvoicebymailwidget3.php@sendrecurringinvoicebymail','note'=>'Widget provided by sendrecurringinvoicebymail')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Cronjobs (List of cron jobs entries to add when module is enabled)
|
// Cronjobs (List of cron jobs entries to add when module is enabled)
|
||||||
// unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
|
// unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
|
||||||
$this->cronjobs = array(
|
$this->cronjobs = array(
|
||||||
//0=>array('label'=>'MyJob label', 'jobtype'=>'method', 'class'=>'/sendrecurringinvoicebymail/class/myobject.class.php', 'objectname'=>'MyObject', 'method'=>'doScheduledJob', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->sendrecurringinvoicebymail->enabled', 'priority'=>50)
|
//0=>array('label'=>'MyJob label', 'jobtype'=>'method', 'class'=>'/sendrecurringinvoicebymail/class/myobject.class.php', 'objectname'=>'MyObject', 'method'=>'doScheduledJob', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->sendrecurringinvoicebymail->enabled', 'priority'=>50)
|
||||||
);
|
);
|
||||||
// Example: $this->cronjobs=array(0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->sendrecurringinvoicebymail->enabled', 'priority'=>50),
|
// Example: $this->cronjobs=array(0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->sendrecurringinvoicebymail->enabled', 'priority'=>50),
|
||||||
// 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->sendrecurringinvoicebymail->enabled', 'priority'=>50)
|
// 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->sendrecurringinvoicebymail->enabled', 'priority'=>50)
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
|
||||||
// Permissions
|
// Permissions
|
||||||
$this->rights = array(); // Permission array used by this module
|
$this->rights = array(); // Permission array used by this module
|
||||||
/*
|
/*
|
||||||
$r=0;
|
$r=0;
|
||||||
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
|
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
|
||||||
$this->rights[$r][1] = 'Read myobject of sendrecurringinvoicebymail'; // Permission label
|
$this->rights[$r][1] = 'Read myobject of sendrecurringinvoicebymail'; // Permission label
|
||||||
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
|
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
|
||||||
$this->rights[$r][4] = 'read'; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
$this->rights[$r][4] = 'read'; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
||||||
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
||||||
|
|
||||||
$r++;
|
$r++;
|
||||||
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
|
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
|
||||||
$this->rights[$r][1] = 'Create/Update myobject of sendrecurringinvoicebymail'; // Permission label
|
$this->rights[$r][1] = 'Create/Update myobject of sendrecurringinvoicebymail'; // Permission label
|
||||||
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
|
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
|
||||||
$this->rights[$r][4] = 'write'; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
$this->rights[$r][4] = 'write'; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
||||||
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
||||||
|
|
||||||
$r++;
|
$r++;
|
||||||
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
|
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
|
||||||
$this->rights[$r][1] = 'Delete myobject of sendrecurringinvoicebymail'; // Permission label
|
$this->rights[$r][1] = 'Delete myobject of sendrecurringinvoicebymail'; // Permission label
|
||||||
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
|
$this->rights[$r][3] = 1; // Permission by default for new user (0/1)
|
||||||
$this->rights[$r][4] = 'delete'; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
$this->rights[$r][4] = 'delete'; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
||||||
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
$this->rights[$r][5] = ''; // In php code, permission will be checked by test if ($user->rights->sendrecurringinvoicebymail->level1->level2)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Main menu entries
|
// Main menu entries
|
||||||
$this->menu = array(); // List of menus to add
|
$this->menu = array(); // List of menus to add
|
||||||
$r=0;
|
$r=0;
|
||||||
|
|
||||||
// Add here entries to declare new menus
|
// Add here entries to declare new menus
|
||||||
|
|
||||||
/* BEGIN MODULEBUILDER TOPMENU */
|
/* BEGIN MODULEBUILDER TOPMENU */
|
||||||
/*
|
/*
|
||||||
$this->menu[$r++]=array('fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
|
$this->menu[$r++]=array('fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
|
||||||
'type'=>'top', // This is a Top menu entry
|
'type'=>'top', // This is a Top menu entry
|
||||||
'titre'=>'sendrecurringinvoicebymail',
|
'titre'=>'sendrecurringinvoicebymail',
|
||||||
'mainmenu'=>'sendrecurringinvoicebymail',
|
'mainmenu'=>'sendrecurringinvoicebymail',
|
||||||
'leftmenu'=>'',
|
'leftmenu'=>'',
|
||||||
'url'=>'/sendrecurringinvoicebymail/sendrecurringinvoicebymailindex.php',
|
'url'=>'/sendrecurringinvoicebymail/sendrecurringinvoicebymailindex.php',
|
||||||
'langs'=>'sendrecurringinvoicebymail@sendrecurringinvoicebymail', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
|
'langs'=>'sendrecurringinvoicebymail@sendrecurringinvoicebymail', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
|
||||||
'position'=>1000+$r,
|
'position'=>1000+$r,
|
||||||
'enabled'=>'$conf->sendrecurringinvoicebymail->enabled', // Define condition to show or hide menu entry. Use '$conf->sendrecurringinvoicebymail->enabled' if entry must be visible if module is enabled.
|
'enabled'=>'$conf->sendrecurringinvoicebymail->enabled', // Define condition to show or hide menu entry. Use '$conf->sendrecurringinvoicebymail->enabled' if entry must be visible if module is enabled.
|
||||||
'perms'=>'1', // Use 'perms'=>'$user->rights->sendrecurringinvoicebymail->level1->level2' if you want your menu with a permission rules
|
'perms'=>'1', // Use 'perms'=>'$user->rights->sendrecurringinvoicebymail->level1->level2' if you want your menu with a permission rules
|
||||||
'target'=>'',
|
'target'=>'',
|
||||||
'user'=>2); // 0=Menu for internal users, 1=external users, 2=both
|
'user'=>2); // 0=Menu for internal users, 1=external users, 2=both
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* END MODULEBUILDER TOPMENU */
|
/* END MODULEBUILDER TOPMENU */
|
||||||
|
|
||||||
/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT
|
/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT
|
||||||
$this->menu[$r++]=array( 'fk_menu'=>'fk_mainmenu=sendrecurringinvoicebymail', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
|
$this->menu[$r++]=array( 'fk_menu'=>'fk_mainmenu=sendrecurringinvoicebymail', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
|
||||||
'type'=>'left', // This is a Left menu entry
|
'type'=>'left', // This is a Left menu entry
|
||||||
'titre'=>'List MyObject',
|
'titre'=>'List MyObject',
|
||||||
'mainmenu'=>'sendrecurringinvoicebymail',
|
'mainmenu'=>'sendrecurringinvoicebymail',
|
||||||
'leftmenu'=>'sendrecurringinvoicebymail_myobject_list',
|
'leftmenu'=>'sendrecurringinvoicebymail_myobject_list',
|
||||||
'url'=>'/sendrecurringinvoicebymail/myobject_list.php',
|
'url'=>'/sendrecurringinvoicebymail/myobject_list.php',
|
||||||
'langs'=>'sendrecurringinvoicebymail@sendrecurringinvoicebymail', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
|
'langs'=>'sendrecurringinvoicebymail@sendrecurringinvoicebymail', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
|
||||||
'position'=>1000+$r,
|
'position'=>1000+$r,
|
||||||
'enabled'=>'$conf->sendrecurringinvoicebymail->enabled', // Define condition to show or hide menu entry. Use '$conf->sendrecurringinvoicebymail->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
|
'enabled'=>'$conf->sendrecurringinvoicebymail->enabled', // Define condition to show or hide menu entry. Use '$conf->sendrecurringinvoicebymail->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
|
||||||
'perms'=>'1', // Use 'perms'=>'$user->rights->sendrecurringinvoicebymail->level1->level2' if you want your menu with a permission rules
|
'perms'=>'1', // Use 'perms'=>'$user->rights->sendrecurringinvoicebymail->level1->level2' if you want your menu with a permission rules
|
||||||
'target'=>'',
|
'target'=>'',
|
||||||
'user'=>2); // 0=Menu for internal users, 1=external users, 2=both
|
'user'=>2); // 0=Menu for internal users, 1=external users, 2=both
|
||||||
$this->menu[$r++]=array( 'fk_menu'=>'fk_mainmenu=sendrecurringinvoicebymail,fk_leftmenu=sendrecurringinvoicebymail', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
|
$this->menu[$r++]=array( 'fk_menu'=>'fk_mainmenu=sendrecurringinvoicebymail,fk_leftmenu=sendrecurringinvoicebymail', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
|
||||||
'type'=>'left', // This is a Left menu entry
|
'type'=>'left', // This is a Left menu entry
|
||||||
'titre'=>'New MyObject',
|
'titre'=>'New MyObject',
|
||||||
'mainmenu'=>'sendrecurringinvoicebymail',
|
'mainmenu'=>'sendrecurringinvoicebymail',
|
||||||
'leftmenu'=>'sendrecurringinvoicebymail_myobject_new',
|
'leftmenu'=>'sendrecurringinvoicebymail_myobject_new',
|
||||||
'url'=>'/sendrecurringinvoicebymail/myobject_page.php?action=create',
|
'url'=>'/sendrecurringinvoicebymail/myobject_page.php?action=create',
|
||||||
'langs'=>'sendrecurringinvoicebymail@sendrecurringinvoicebymail', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
|
'langs'=>'sendrecurringinvoicebymail@sendrecurringinvoicebymail', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
|
||||||
'position'=>1000+$r,
|
'position'=>1000+$r,
|
||||||
'enabled'=>'$conf->sendrecurringinvoicebymail->enabled', // Define condition to show or hide menu entry. Use '$conf->sendrecurringinvoicebymail->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
|
'enabled'=>'$conf->sendrecurringinvoicebymail->enabled', // Define condition to show or hide menu entry. Use '$conf->sendrecurringinvoicebymail->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
|
||||||
'perms'=>'1', // Use 'perms'=>'$user->rights->sendrecurringinvoicebymail->level1->level2' if you want your menu with a permission rules
|
'perms'=>'1', // Use 'perms'=>'$user->rights->sendrecurringinvoicebymail->level1->level2' if you want your menu with a permission rules
|
||||||
'target'=>'',
|
'target'=>'',
|
||||||
'user'=>2); // 0=Menu for internal users, 1=external users, 2=both
|
'user'=>2); // 0=Menu for internal users, 1=external users, 2=both
|
||||||
END MODULEBUILDER LEFTMENU MYOBJECT */
|
END MODULEBUILDER LEFTMENU MYOBJECT */
|
||||||
|
|
||||||
|
|
||||||
// Exports
|
// Exports
|
||||||
$r=1;
|
$r=1;
|
||||||
|
|
||||||
/* BEGIN MODULEBUILDER EXPORT MYOBJECT */
|
/* BEGIN MODULEBUILDER EXPORT MYOBJECT */
|
||||||
/*
|
/*
|
||||||
$langs->load("sendrecurringinvoicebymail@sendrecurringinvoicebymail");
|
$langs->load("sendrecurringinvoicebymail@sendrecurringinvoicebymail");
|
||||||
$this->export_code[$r]=$this->rights_class.'_'.$r;
|
$this->export_code[$r]=$this->rights_class.'_'.$r;
|
||||||
$this->export_label[$r]='MyObjectLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
|
$this->export_label[$r]='MyObjectLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
|
||||||
$this->export_icon[$r]='myobject@sendrecurringinvoicebymail';
|
$this->export_icon[$r]='myobject@sendrecurringinvoicebymail';
|
||||||
$keyforclass = 'MyObject'; $keyforclassfile='/mymobule/class/myobject.class.php'; $keyforelement='myobject';
|
$keyforclass = 'MyObject'; $keyforclassfile='/mymobule/class/myobject.class.php'; $keyforelement='myobject';
|
||||||
include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
|
include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
|
||||||
$keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject';
|
$keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject';
|
||||||
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
|
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
|
||||||
//$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
|
//$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
|
||||||
$this->export_sql_start[$r]='SELECT DISTINCT ';
|
$this->export_sql_start[$r]='SELECT DISTINCT ';
|
||||||
$this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'myobject as t';
|
$this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'myobject as t';
|
||||||
$this->export_sql_end[$r] .=' WHERE 1 = 1';
|
$this->export_sql_end[$r] .=' WHERE 1 = 1';
|
||||||
$this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')';
|
$this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')';
|
||||||
$r++; */
|
$r++; */
|
||||||
/* END MODULEBUILDER EXPORT MYOBJECT */
|
/* END MODULEBUILDER EXPORT MYOBJECT */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called when module is enabled.
|
* Function called when module is enabled.
|
||||||
* The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
|
* The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
|
||||||
* It also creates data directories
|
* It also creates data directories
|
||||||
*
|
*
|
||||||
* @param string $options Options when enabling module ('', 'noboxes')
|
* @param string $options Options when enabling module ('', 'noboxes')
|
||||||
* @return int 1 if OK, 0 if KO
|
* @return int 1 if OK, 0 if KO
|
||||||
*/
|
*/
|
||||||
public function init($options='')
|
public function init($options='')
|
||||||
{
|
{
|
||||||
$sql = array();
|
// Launch SQL files
|
||||||
|
$result=$this->_load_tables('/' . basename(dirname(dirname(dirname(__FILE__)))) . '/sql/');
|
||||||
|
if ($result < 0) return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default')
|
||||||
|
|
||||||
// we check if our model already exists
|
// Launch small and conditional SQL queries
|
||||||
$result = $this->db->query("SELECT COUNT(*) AS cpt FROM " . MAIN_DB_PREFIX."c_email_templates WHERE module = 'sendrecurringinvoicebymail'");
|
$sql = array();
|
||||||
if ($result) {
|
// we check if our model already exists
|
||||||
$row = $this->db->fetch_object($result);
|
$result = $this->db->query("SELECT COUNT(*) AS cpt FROM " . MAIN_DB_PREFIX . "c_email_templates WHERE module = 'sendrecurringinvoicebymail'");
|
||||||
if ($row->cpt == 0) {
|
if ($result) {
|
||||||
$sql[] = "INSERT INTO " . MAIN_DB_PREFIX."c_email_templates
|
$row = $this->db->fetch_object($result);
|
||||||
(module, type_template, lang, label, joinfiles, topic, content)
|
if ($row->cpt == 0) {
|
||||||
VALUES (
|
$sql[] = "INSERT INTO " . MAIN_DB_PREFIX."c_email_templates
|
||||||
'sendrecurringinvoicebymail',
|
(module, type_template, lang, label, joinfiles, topic, content)
|
||||||
'facture_send',
|
VALUES (
|
||||||
'',
|
'sendrecurringinvoicebymail',
|
||||||
'SendRecurringInvoiceByMail : original template',
|
'facture_send',
|
||||||
'1',
|
'',
|
||||||
'[__MYCOMPANY_NAME__] __(NewBill)__ __REF__',
|
'SendRecurringInvoiceByMail : original template',
|
||||||
'__(Hello)__,\n\nPlease find attached your new invoice.\n\nIn case of payment via bank transfer (our bank infos added at the bottom of the invoice), remember to add some references :\n- invoice number __REF__ for a one-time transfer,\n- or the contract/subscription reference __CONTRACT_REF__ for periodic transfers.\n\n__(Sincerely)__,\n\n__MYCOMPANY_NAME__')";
|
'1',
|
||||||
}
|
'[__MYCOMPANY_NAME__] __(NewBill)__ __REF__',
|
||||||
}
|
'__(Hello)__,\n\nPlease find attached your new invoice.\n\nIn case of payment via bank transfer (our bank infos added at the bottom of the invoice), remember to add some references :\n- invoice number __REF__ for a one-time transfer,\n- or the contract/subscription reference __CONTRACT_REF__ for periodic transfers.\n\n__(Sincerely)__,\n\n__MYCOMPANY_NAME__')";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $this->_init($sql, $options);
|
// Reactivate the template in case the module has been
|
||||||
}
|
// uninstalled which should have disabled the template.
|
||||||
|
$sql[] = "UPDATE " . MAIN_DB_PREFIX . "c_email_templates SET enabled = 1 WHERE module = 'sendrecurringinvoicebymail'";
|
||||||
|
|
||||||
/**
|
// Cleaning up old (and ugly) system which
|
||||||
* Function called when module is disabled.
|
// used note_private to store overriding data.
|
||||||
* Remove from database constants, boxes and permissions from Dolibarr database.
|
// TODO : Remove this block at next version.
|
||||||
* Data directories are not deleted
|
$result = $this->db->query("SELECT r.rowid AS rid, r.note_private, s.rowid AS sid FROM " . MAIN_DB_PREFIX . "facture_rec AS r LEFT JOIN " . MAIN_DB_PREFIX . "sribm_custom_mail_info AS s ON r.rowid = s.fk_facture_rec WHERE r.note_private LIKE '%sendrecurringinvoicebymail::%'");
|
||||||
*
|
if ($result) {
|
||||||
* @param string $options Options when enabling module ('', 'noboxes')
|
while($row = $this->db->fetch_object($result)) {
|
||||||
* @return int 1 if OK, 0 if KO
|
$mail_data = $this->parseCustomFieldsMail($row->note_private);
|
||||||
*/
|
$sid = $row->sid;
|
||||||
public function remove($options = '')
|
if (! $sid) {
|
||||||
{
|
$this->db->query("INSERT INTO " . MAIN_DB_PREFIX . "sribm_custom_mail_info (fk_facture_rec) VALUES (" . (int)$row->rid . ")");
|
||||||
$sql = array();
|
$sid = $this->db->last_insert_id(MAIN_DB_PREFIX . 'sribm_custom_mail_info');
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
$this->db->query("UPDATE " . MAIN_DB_PREFIX . "sribm_custom_mail_info SET " . $item . " = '" . $this->db->escape($mail_data[$key]) . "' WHERE rowid = " . (int)$sid);
|
||||||
|
if ($key == 'sendto') {
|
||||||
|
// If the note_private specified a recipient, we disable sending to the
|
||||||
|
// main societe's mail.
|
||||||
|
$this->db->query("UPDATE " . MAIN_DB_PREFIX . "sribm_custom_mail_info SET sendto_thirdparty = 0 WHERE rowid = " . (int)$row->rid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$regexps = array(
|
||||||
|
'/%%% sendrecurringinvoicebymail::subject.*%%%/sU',
|
||||||
|
'/%%% sendrecurringinvoicebymail::body.*%%%/sU',
|
||||||
|
'/%%% sendrecurringinvoicebymail::sendto.*%%%/sU',
|
||||||
|
);
|
||||||
|
$row->note_private = preg_replace($regexps, array('', '', ''), $row->note_private);
|
||||||
|
$this->db->query("UPDATE " . MAIN_DB_PREFIX . "facture_rec SET note_private = '" . $this->db->escape($row->note_private) . "' WHERE rowid = " . (int)$row->rid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$sql[] = "DELETE FROM " . MAIN_DB_PREFIX."c_email_templates WHERE module = 'sendrecurringinvoicebymail'";
|
return $this->_init($sql, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called when module is disabled.
|
||||||
|
* Remove from database constants, boxes and permissions from Dolibarr database.
|
||||||
|
* Data directories are not deleted
|
||||||
|
*
|
||||||
|
* @param string $options Options when enabling module ('', 'noboxes')
|
||||||
|
* @return int 1 if OK, 0 if KO
|
||||||
|
*/
|
||||||
|
public function remove($options = '')
|
||||||
|
{
|
||||||
|
$sql = array();
|
||||||
|
|
||||||
|
// Disable the template
|
||||||
|
// (instead of deleting it, which may cause unwanted work loss)
|
||||||
|
// (Yeah, counterside is data bloat... sorry...)
|
||||||
|
$sql[] = "UPDATE " . MAIN_DB_PREFIX . "c_email_templates SET enabled = 0 WHERE module = 'sendrecurringinvoicebymail'";
|
||||||
|
|
||||||
|
return $this->_remove($sql, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: Obsolete. Replaced by SRIBMCustomMailInfo. To be removed.
|
||||||
|
* For the time being, we abuse of note_private to store our customizations
|
||||||
|
*
|
||||||
|
* This expect something like this in note_private:
|
||||||
|
* This is a good client... (other private infos)
|
||||||
|
* %%% sendrecurringinvoicebymail::subject
|
||||||
|
* New invoice __REF__
|
||||||
|
* %%%
|
||||||
|
* %%% sendrecurringinvoicebymail::sendto
|
||||||
|
* recipient1@example.org, recipient2@example.org
|
||||||
|
* %%%
|
||||||
|
* %%% sendrecurringinvoicebymail::body
|
||||||
|
* Hello dear client,
|
||||||
|
* Please find attached...
|
||||||
|
* %%%
|
||||||
|
*/
|
||||||
|
public function parseCustomFieldsMail($data)
|
||||||
|
{
|
||||||
|
$output = [];
|
||||||
|
|
||||||
|
// Remove eventual windows' "\r"
|
||||||
|
$data = str_replace("\r", "", $data);
|
||||||
|
|
||||||
|
$regexps = array(
|
||||||
|
'subject' => '/(^|\n)%%% sendrecurringinvoicebymail::subject\n(?<subject>.*)%%%(\n|$)/sU',
|
||||||
|
'body' => '/(^|\n)%%% sendrecurringinvoicebymail::body\n(?<body>.*)%%%(\n|$)/sU',
|
||||||
|
'sendto' => '/(^|\n)%%% sendrecurringinvoicebymail::sendto\n(?<sendto>.*)%%%(\n|$)/sU',
|
||||||
|
);
|
||||||
|
foreach ($regexps as $key => $r) {
|
||||||
|
$result_regexp = [];
|
||||||
|
if (preg_match_all($r, $data, $result_regexp)) {
|
||||||
|
$output[$key] = trim($result_regexp[$key][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->_remove($sql, $options);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
326
fiche-rec-tab1.php
Normal file
326
fiche-rec-tab1.php
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
<?php
|
||||||
|
/* Copyright (C) 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Initially copied from modulebuilder/template/myobject_card.php
|
||||||
|
|
||||||
|
// 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 && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
|
||||||
|
if (! $res) die("Include of main fails");
|
||||||
|
|
||||||
|
// Load needed classes/lib
|
||||||
|
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture-rec.class.php';
|
||||||
|
require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php';
|
||||||
|
require_once 'class/sribmcustommailinfo.class.php';
|
||||||
|
|
||||||
|
// Get parameters
|
||||||
|
$id = GETPOST('id', 'int');
|
||||||
|
$output = '';
|
||||||
|
|
||||||
|
// Check security (take care of everything, even page layout, if something goes wrong)
|
||||||
|
restrictedArea($user, 'facture', $id, 'facture_rec');
|
||||||
|
|
||||||
|
// Load translation files required by the page
|
||||||
|
$langs->loadLangs(array('bills', 'compta', 'other', 'mails', 'products', 'companies', 'sendrecurringinvoicebymail@sendrecurringinvoicebymail'));
|
||||||
|
|
||||||
|
// Wrap everything in a do-while(false) as a try-catch mecanisme
|
||||||
|
// in order to print llxFooter whatever happens.
|
||||||
|
do {
|
||||||
|
/**
|
||||||
|
* Part 0 : Preparations
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Load necessary data
|
||||||
|
$object = new FactureRec($db);
|
||||||
|
$mailObject = new SRIBMCustomMailInfo($db);
|
||||||
|
$form = new Form($db);
|
||||||
|
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();
|
||||||
|
$listFrom['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM;
|
||||||
|
$listFrom['company'] = $conf->global->MAIN_INFO_SOCIETE_NOM .' <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>';
|
||||||
|
if (!empty($user->email)) {
|
||||||
|
$listFrom['user'] = $user->getFullName($langs) . ' <' . $user->email . '>';
|
||||||
|
}
|
||||||
|
// If the address in the SRIBM object is not the same as the user (basically,
|
||||||
|
// the user has changed its email address or the address has been set by another
|
||||||
|
// user), we add an 'old' = 'no modification' option.
|
||||||
|
if ($mailObject->id
|
||||||
|
&& $mailObject->fromtype == 'user'
|
||||||
|
&& isset($listFrom['user'])
|
||||||
|
&& $listFrom['user'] != $mailObject->frommail
|
||||||
|
) {
|
||||||
|
$listFrom['old'] = $mailObject->frommail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of contacts of the third party
|
||||||
|
$listContacts = $mailObject->fac_rec_object->thirdparty->thirdparty_and_contact_email_array(1);
|
||||||
|
|
||||||
|
// Substitution array/string
|
||||||
|
$helpforsubstitution = $langs->trans('AvailableVariables').' :<br>'."\n";
|
||||||
|
$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>';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part 1 : Treatment of form submission
|
||||||
|
*/
|
||||||
|
|
||||||
|
// If the mail form has been submitted, check and record the data
|
||||||
|
if (GETPOST('save')) {
|
||||||
|
do {
|
||||||
|
// Validate input data
|
||||||
|
if (! array_key_exists(GETPOST('fromtype', 'alpha'), $listFrom)) {
|
||||||
|
setEventMessages('Unexpected from value', null, 'errors');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (GETPOST('sendto_socpeople', 'array') != array_intersect(GETPOST('sendto_socpeople', 'array'), array_keys($listContacts))) {
|
||||||
|
setEventMessages("Unexpected contact value in 'to'", null, 'errors');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (GETPOST('sendcc_socpeople', 'array') != array_intersect(GETPOST('sendcc_socpeople', 'array'), array_keys($listContacts))) {
|
||||||
|
setEventMessages("Unexpected contact value in 'cc'", null, 'errors');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Validate some non-breaking stuff after feeding
|
||||||
|
if (empty(GETPOST('sendto_free', 'alpha')) && empty(GETPOST('sendto_socpeople', 'array'))) {
|
||||||
|
// Kinda weird behaviour from CMailFile but better alert the user beforehand
|
||||||
|
// FIXME: check if there is a workaround ?
|
||||||
|
setEventMessages("In some configuration, CMailFile doesn't allow empty 'to' recipient. You should set at least one.", null, 'warnings');
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
if (! strlen(GETPOST('subject', 'alpha'))) {
|
||||||
|
// Kinda weird behaviour from CMailFile but better alert the user beforehand
|
||||||
|
// FIXME: check if there is a workaround ?
|
||||||
|
setEventMessages("In some configuration, CMailFile doesn't allow empty subject. You should set one.", null, 'warnings');
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feed the input data to the model
|
||||||
|
$mailObject->active = GETPOST('active', 'int') ? 1 : 0;
|
||||||
|
$mailObject->addmaindocfile = GETPOST('addmaindocfile', 'int') ? 1 : 0;
|
||||||
|
|
||||||
|
$mailObject->fromtype = GETPOST('fromtype', 'alpha');
|
||||||
|
$mailObject->frommail = $listFrom[$mailObject->fromtype];
|
||||||
|
|
||||||
|
$mailObject->sendto_free = GETPOST('sendto_free', 'alpha');
|
||||||
|
$mailObject->sendto_thirdparty = in_array('thirdparty', GETPOST('sendto_socpeople', 'array'));
|
||||||
|
|
||||||
|
$mailObject->sendcc_free = GETPOST('sendcc_free', 'alpha');
|
||||||
|
$mailObject->sendcc_thirdparty = in_array('thirdparty', GETPOST('sendcc_socpeople', 'array'));
|
||||||
|
|
||||||
|
$mailObject->subject = GETPOST('subject', 'alpha');
|
||||||
|
$mailObject->body_plaintext = GETPOST('body_plaintext', 'alpha');
|
||||||
|
|
||||||
|
// Save into database
|
||||||
|
if ($mailObject->id) {
|
||||||
|
if ($mailObject->update($user) != 1) {
|
||||||
|
setEventMessages($langs->trans("ErrorSQL") . ' : ' . $mailObject->error, null, 'errors');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$mailObject->fk_facture_rec = $object->id;
|
||||||
|
if ($mailObject->create($user) < 0) {
|
||||||
|
setEventMessages($langs->trans("ErrorSQL") . ' : ' . $mailObject->error, null, 'errors');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update the linked contacts
|
||||||
|
$data = array_merge(
|
||||||
|
array_map(
|
||||||
|
function ($id) { return array('id' => $id, 'sendtype' => 'to'); },
|
||||||
|
array_filter(GETPOST('sendto_socpeople', 'array'), 'is_numeric')
|
||||||
|
),
|
||||||
|
array_map(
|
||||||
|
function ($id) { return array('id' => $id, 'sendtype' => 'cc'); },
|
||||||
|
array_filter(GETPOST('sendcc_socpeople', 'array'), 'is_numeric')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if ($mailObject->updateLinkSocPeople($data) != 1) {
|
||||||
|
setEventMessages($langs->trans("ErrorSQL") . ' : ' . $mailObject->error, null, 'errors');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything seems ok
|
||||||
|
setEventMessages($langs->trans("CorrectlyUpdated"), null, 'mesgs');
|
||||||
|
// ... + redirect to cleanly reload all data and avoid some F5 misbehaviour
|
||||||
|
header("Location: fiche-rec-tab1.php?id=" . (int) $id, true, 302);
|
||||||
|
return;
|
||||||
|
} while(false);
|
||||||
|
} else if (GETPOST('reset') && $mailObject->id) {
|
||||||
|
if ($mailObject->delete() == 1) {
|
||||||
|
// Success message...
|
||||||
|
setEventMessages($langs->trans("ResetDone"), null, 'mesgs');
|
||||||
|
|
||||||
|
// ... + redirect to cleanly reload all data
|
||||||
|
header("Location: fiche-rec-tab1.php?id=" . (int) $id, true, 302);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
setEventMessages($langs->trans("ErrorSQL") . " : " . $mailObject->error , null, 'errors');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the pre-selected id for To/Cc select inputs
|
||||||
|
$preselected = array(
|
||||||
|
'to' => array(),
|
||||||
|
'cc' => array(),
|
||||||
|
);
|
||||||
|
if (GETPOSTISSET('sendto_socpeople') || GETPOSTISSET('sendcc_socpeople')) {
|
||||||
|
// Retrieve data from last form submission
|
||||||
|
$preselected['to'] = GETPOST('sendto_socpeople');
|
||||||
|
$preselected['cc'] = GETPOST('sendcc_socpeople');
|
||||||
|
} else {
|
||||||
|
// Retrieve data from model
|
||||||
|
foreach ($mailObject->linkToSocPeoples as $contact) {
|
||||||
|
$preselected[$contact->pivot->sendtype][] = $contact->id;
|
||||||
|
}
|
||||||
|
// add the third-party's email in case sendXX_thirdparty is true
|
||||||
|
if ($mailObject->sendto_thirdparty) {
|
||||||
|
$preselected['to'][] = 'thirdparty';
|
||||||
|
}
|
||||||
|
if ($mailObject->sendcc_thirdparty) {
|
||||||
|
$preselected['cc'][] = 'thirdparty';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part 2 : Display
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Same tabs than the main page
|
||||||
|
$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";
|
||||||
|
$output .= "</div><!-- Closing div class='tabBar' -->\n\n";
|
||||||
|
|
||||||
|
$output .= '<div class="titre inline-block">' . $langs->trans("Options") . "</div>\n";
|
||||||
|
$output .= '<form id="sribmform" name="sribmform" method="POST" action="#sribmform">';
|
||||||
|
$output .= '<table class="liste" summary="mail options"><tbody>';
|
||||||
|
$output .= '<tr class="oddeven">';
|
||||||
|
$output .= ' <td><label for="active">' . $langs->trans('OptionEnable') . "</label></td>\n";
|
||||||
|
$output .= ' <td><input type="checkbox" id="active" name="active" value="1"' . ((empty($_POST) && $mailObject->active || GETPOSTISSET('active')) ? ' checked="checked"' : '') . " /></td>\n";
|
||||||
|
$output .= "</tr>\n";
|
||||||
|
$output .= "</tbody></table>\n";
|
||||||
|
|
||||||
|
// Little explanations
|
||||||
|
$output .= '<div class="titre inline-block" style="margin-top: 1.5em;">' . $langs->trans("CustomizationTitle") . "</div>\n";
|
||||||
|
// TODO: translation
|
||||||
|
$output .= "<p>" . $langs->trans('CustomizationIntro', $langs->trans('Reset')) . "<br />\n";
|
||||||
|
$output .= $langs->trans('CustomizationLinkToGlobalTemplate', DOL_URL_ROOT . '/admin/mails_templates.php?search_label=sendrecurring') . "</p>\n\n";
|
||||||
|
|
||||||
|
$output .= '<table class="tableforemailform boxtablenotop" width="100%">';
|
||||||
|
$output .= '<tr><td class="fieldrequired minwidth200">'.$langs->trans("MailFrom").'</td><td>';
|
||||||
|
$defaultFrom = 'robot';
|
||||||
|
if (isset($listFrom['old'])) {
|
||||||
|
$defaultFrom = 'old';
|
||||||
|
} elseif ($mailObject->id) {
|
||||||
|
$defaultFrom = $mailObject->fromtype;
|
||||||
|
}
|
||||||
|
$output .= $form->selectarray('fromtype', $listFrom, GETPOST('fromtype', 'alpha') ? GETPOST('fromtype', 'alpha') : $defaultFrom);
|
||||||
|
$output .= "</td></tr>\n";
|
||||||
|
|
||||||
|
|
||||||
|
// Recipient(s)
|
||||||
|
$output .= '<tr><td class="minwidth200 fieldrequired">';
|
||||||
|
$output .= $form->textwithpicto($langs->trans("MailTo"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
|
||||||
|
$output .= "</td>\n<td>";
|
||||||
|
$output .= '<input class="minwidth200" id="sendto_free" name="sendto_free" value="'.(GETPOST("sendto_free", "alpha") ? GETPOST("sendto_free", "alpha") : htmlentities($mailObject->sendto_free)) . '" />';
|
||||||
|
$output .= " " . $langs->trans("and") . "/" . $langs->trans("or") . " ";
|
||||||
|
$output .= $form->multiselectarray('sendto_socpeople', $listContacts, $preselected['to']);
|
||||||
|
$output .= "</td></tr>\n";
|
||||||
|
|
||||||
|
|
||||||
|
// CC
|
||||||
|
$output .= '<tr><td class="minwidth200">';
|
||||||
|
$output .= $form->textwithpicto($langs->trans("MailCC"), $langs->trans("YouCanUseCommaSeparatorForSeveralRecipients"));
|
||||||
|
$output .= "</td>\n<td>";
|
||||||
|
$output .= '<input class="minwidth200" id="sendto_free" name="sendcc_free" value="'.(GETPOST("sendcc_free", "alpha") ? GETPOST("sendcc_free", "alpha") : htmlentities($mailObject->sendcc_free)) . '" />';
|
||||||
|
$output .= " " . $langs->trans("and") . "/" . $langs->trans("or") . " ";
|
||||||
|
$output .= $form->multiselectarray('sendcc_socpeople', $listContacts, $preselected['cc']);
|
||||||
|
$output .= "</td></tr>\n";
|
||||||
|
|
||||||
|
|
||||||
|
// Subject
|
||||||
|
$output .= '<tr><td class="minwidth200 fieldrequired">';
|
||||||
|
$output .= $form->textwithpicto($langs->trans("MailTopic"), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfromtopic');
|
||||||
|
$output .= "</td>\n<td>";
|
||||||
|
$output .= '<input type="text" class="quatrevingtpercent" id="subject" name="subject" value="'. (GETPOST('subject', 'alpha') ? GETPOST('subject', 'alpha') : htmlentities($mailObject->subject)) . '" />';
|
||||||
|
$output .= "</td></tr>\n";
|
||||||
|
|
||||||
|
|
||||||
|
// addmaindocfile
|
||||||
|
$output .= '<tr><td>' . $langs->trans('MailFile') . "</td>\n";
|
||||||
|
$tmp_addmaindocfile = $mailObject->addmaindocfile;
|
||||||
|
if (! empty($_POST)) {
|
||||||
|
$tmp_addmaindocfile = GETPOSTISSET('addmaindocfile') ? 1 : 0;
|
||||||
|
}
|
||||||
|
$output .= '<td><input type="checkbox" name="addmaindocfile" value="1"' . ($tmp_addmaindocfile ? ' checked="checked"' : '') . ' /> ' . $langs->trans("JoinMainDoc") . "</td>\n";
|
||||||
|
|
||||||
|
|
||||||
|
// 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>";
|
||||||
|
/*
|
||||||
|
// doleditor does some weird stuff, adding <br> and newlines, I'll get more into it when I have time.
|
||||||
|
// fallback to simple <textarea> for the time being.
|
||||||
|
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
|
||||||
|
$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_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";
|
||||||
|
|
||||||
|
$output .= "</table>\n";
|
||||||
|
|
||||||
|
$output .= '<br><div class="center">';
|
||||||
|
$output .= '<input class="button" type="submit" id="save" name="save" value="'.$langs->trans("Save").'" />';
|
||||||
|
$output .= '<input class="button warning" type="submit" id="reset" name="reset" value="'.$langs->trans("Reset").'"';
|
||||||
|
$output .= ($mailObject->id ? '' : ' title="' . $langs->trans('ResetTooltipNoCustomisationToReset') . '" disabled="disabled"') . ' />';
|
||||||
|
$output .= "</div>\n";
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
// Print everything
|
||||||
|
llxHeader('', $langs->trans('RepeatableInvoice') . ' - ' . $langs->trans('SendingByMail'), '');
|
||||||
|
print $output;
|
||||||
|
llxFooter();
|
BIN
img/screenshot1.png
Normal file
BIN
img/screenshot1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 128 KiB |
|
@ -41,13 +41,12 @@ About = About
|
||||||
sendrecurringinvoicebymailAbout = About sendrecurringinvoicebymail
|
sendrecurringinvoicebymailAbout = About sendrecurringinvoicebymail
|
||||||
sendrecurringinvoicebymailAboutPage = sendrecurringinvoicebymail about page
|
sendrecurringinvoicebymailAboutPage = sendrecurringinvoicebymail about page
|
||||||
|
|
||||||
#
|
# Tab title on the fiche-rec page
|
||||||
# Sample 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.
|
||||||
MyPageName = My page name
|
CustomizationLinkToGlobalTemplate = As a note, the global email template can be found <a href="%s">here</a>.
|
||||||
|
OptionEnable = Send mail when generating via cron (cf. module "Scheduled Jobs")
|
||||||
#
|
Reset = Reset
|
||||||
# Sample widget
|
ResetDone = Reset done : customization deleted
|
||||||
#
|
ResetTooltipNoCustomisationToReset = No customization to delete.
|
||||||
MyWidget = My widget
|
SendingByMail = Sending by email
|
||||||
MyWidgetDescription = My widget description
|
|
||||||
|
|
|
@ -37,12 +37,13 @@ sendrecurringinvoicebymailAbout = À propos de sendrecurringinvoicebymail
|
||||||
sendrecurringinvoicebymailAboutPage = Page à propos de sendrecurringinvoicebymail
|
sendrecurringinvoicebymailAboutPage = Page à propos de sendrecurringinvoicebymail
|
||||||
|
|
||||||
#
|
#
|
||||||
# Page d'exemple
|
# Page de personnalisation par modèle
|
||||||
#
|
#
|
||||||
MyPageName = Nom de ma page
|
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 configurable par <a href="%s">ici</a>.
|
||||||
# Box d'exemple
|
OptionEnable = Envoyer par email lors d'une génération automatique via le module "Travaux planifiés"
|
||||||
#
|
Reset = Réinitialiser
|
||||||
MyWidget = Mon widget
|
ResetDone = Réinitialisation effectuée : personnalisation supprimée.
|
||||||
MyWidgetDescription = Description de mon widget
|
ResetTooltipNoCustomisationToReset = Aucune personnalisation à supprimer.
|
||||||
|
SendingByMail = Envoi par courriel
|
||||||
|
|
14
sql/data.sql
Normal file
14
sql/data.sql
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
-- 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/>.
|
29
sql/llx_sribm_custom_mail_info.key.sql
Normal file
29
sql/llx_sribm_custom_mail_info.key.sql
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
-- 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/.
|
||||||
|
|
||||||
|
|
||||||
|
-- BEGIN MODULEBUILDER INDEXES
|
||||||
|
--ALTER TABLE llx_mymodule_myobject ADD INDEX idx_fieldobject (fieldobject);
|
||||||
|
-- END MODULEBUILDER INDEXES
|
||||||
|
|
||||||
|
--ALTER TABLE llx_mymodule_myobject ADD UNIQUE INDEX uk_mymodule_myobject_fieldxy(fieldx, fieldy);
|
||||||
|
|
||||||
|
--ALTER TABLE llx_mymodule_myobject ADD CONSTRAINT llx_mymodule_myobject_fk_field FOREIGN KEY (fk_field) REFERENCES llx_mymodule_myotherobject(rowid);
|
||||||
|
|
||||||
|
ALTER TABLE llx_sribm_custom_mail_info ADD UNIQUE INDEX llx_sribm_custom_mail_info_uniq_frec (fk_facture_rec);
|
||||||
|
ALTER TABLE llx_sribm_custom_mail_info ADD CONSTRAINT llx_sribm_custom_mail_info_fk_rowid FOREIGN KEY (fk_facture_rec) REFERENCES llx_facture_rec(rowid) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
ALTER TABLE llx_sribm_custom_mail_info_socpeople ADD CONSTRAINT llx_sribm_custom_mail_info_socpeople_c_fk FOREIGN KEY (fk_sribm_cmi) REFERENCES llx_sribm_custom_mail_info(rowid) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
ALTER TABLE llx_sribm_custom_mail_info_socpeople ADD CONSTRAINT llx_sribm_custom_mail_info_socpeople_s_fk FOREIGN KEY (fk_socpeople) REFERENCES llx_socpeople(rowid) ON DELETE CASCADE ON UPDATE CASCADE;
|
49
sql/llx_sribm_custom_mail_info.sql
Normal file
49
sql/llx_sribm_custom_mail_info.sql
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
-- 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/.
|
||||||
|
|
||||||
|
|
||||||
|
-- Sorry for the schema's complexity, but we have to manage 3 types
|
||||||
|
-- of recipients :
|
||||||
|
-- * the email in the societe/company's profile (default for the module)
|
||||||
|
-- * the contacts (table 'llx_socpeople')
|
||||||
|
-- * the email from the free text input
|
||||||
|
-- The From can also be a little difficult since, for the time being,
|
||||||
|
-- we avoid a free text input for the source email.
|
||||||
|
CREATE TABLE llx_sribm_custom_mail_info(
|
||||||
|
rowid INTEGER AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
fk_facture_rec INTEGER NOT NULL,
|
||||||
|
active smallint DEFAULT 1 NOT NULL,
|
||||||
|
addmaindocfile smallint DEFAULT 1 NOT NULL,
|
||||||
|
fromtype text NOT NULL,
|
||||||
|
frommail text NOT NULL,
|
||||||
|
sendto_thirdparty smallint DEFAULT 1 NOT NULL,
|
||||||
|
sendto_free text,
|
||||||
|
sendcc_thirdparty smallint DEFAULT 0 NOT NULL,
|
||||||
|
sendcc_free text,
|
||||||
|
sendbcc_thirdparty smallint DEFAULT 0 NOT NULL,
|
||||||
|
sendbcc_free text,
|
||||||
|
subject text,
|
||||||
|
body_plaintext mediumtext,
|
||||||
|
body_html mediumtext
|
||||||
|
) ENGINE=innodb;
|
||||||
|
|
||||||
|
|
||||||
|
-- sendtype should only be one of 'to', 'cc' and 'bcc' but
|
||||||
|
-- I'm kinda afraid to do an ENUM with Dolibarr black magic on SQL.
|
||||||
|
CREATE TABLE llx_sribm_custom_mail_info_socpeople(
|
||||||
|
fk_sribm_cmi INTEGER NOT NULL,
|
||||||
|
fk_socpeople INTEGER NOT NULL,
|
||||||
|
sendtype text NOT NULL
|
||||||
|
) ENGINE=innodb;
|
Loading…
Reference in a new issue