diff --git a/admin/setup.php b/admin/setup.php
index fcb3a43..4c49367 100644
--- a/admin/setup.php
+++ b/admin/setup.php
@@ -58,7 +58,7 @@
// Libraries
require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
require_once '../lib/diffusionplans.lib.php';
-require_once '../class/diffusion.class.php';
+require_once '../class/bordereaudoc.class.php';
/**
@@ -84,7 +84,7 @@
$value = GETPOST('value', 'alpha');
$label = GETPOST('label', 'alpha');
$scandir = GETPOST('scan_dir', 'alpha');
-$type = 'diffusion';
+$type = 'bordereaudoc';
$error = 0;
$setupnotempty = 0;
@@ -197,7 +197,7 @@
$moduledir = 'diffusionplans';
$myTmpObjects = array();
// TODO Scan list of objects to fill this array
-$myTmpObjects['diffusion'] = array('label' => 'Diffusion', 'includerefgeneration' => 1, 'includedocgeneration' => 1, 'class' => 'Diffusion');
+$myTmpObjects['bordereaudoc'] = array('label' => 'Bordereaudoc', 'includerefgeneration' => 1, 'includedocgeneration' => 1, 'class' => 'Bordereaudoc');
$tmpobjectkey = GETPOST('object', 'aZ09');
if ($tmpobjectkey && !array_key_exists($tmpobjectkey, $myTmpObjects)) {
@@ -237,7 +237,7 @@
$className = $myTmpObjects[$tmpobjectkey]['class'];
$tmpobject = new $className($db);
- '@phan-var-force Diffusion $tmpobject';
+ '@phan-var-force Bordereaudoc $tmpobject';
$tmpobject->initAsSpecimen();
// Search template files
@@ -245,7 +245,7 @@
$className = '';
$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
foreach ($dirmodels as $reldir) {
- $file = dol_buildpath($reldir."core/modules/diffusionplans/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0);
+ $file = dol_buildpath($reldir."core/modules/bordereaudoc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0);
if (file_exists($file)) {
$className = "pdf_".$modele."_".strtolower($tmpobjectkey);
break;
@@ -432,7 +432,7 @@
$className = $myTmpObjectArray['class'];
$mytmpinstance = new $className($db);
- '@phan-var-force Diffusion $mytmpinstance';
+ '@phan-var-force Bordereaudoc $mytmpinstance';
$mytmpinstance->initAsSpecimen();
// Info
diff --git a/bordereaudoc_agenda.php b/bordereaudoc_agenda.php
new file mode 100644
index 0000000..ec4dd99
--- /dev/null
+++ b/bordereaudoc_agenda.php
@@ -0,0 +1,147 @@
+
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+/**
+* \file bordereaudoc_agenda.php
+* \ingroup diffusionplans
+* \brief Tab of events for Bordereaudoc.
+*/
+
+// Load Dolibarr environment
+$res = 0;
+if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
+ $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
+}
+$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";
+}
+if (!$res && file_exists("../main.inc.php")) {
+ $res = @include "../main.inc.php";
+}
+if (!$res && file_exists("../../main.inc.php")) {
+ $res = @include "../../main.inc.php";
+}
+if (!$res && file_exists("../../../main.inc.php")) {
+ $res = @include "../../../main.inc.php";
+}
+if (!$res) {
+ die("Include of main fails");
+}
+
+require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+dol_include_once('/diffusionplans/class/bordereaudoc.class.php');
+dol_include_once('/diffusionplans/lib/diffusionplans_bordereaudoc.lib.php');
+
+// Load translation files required by the page
+$langs->loadLangs(array('diffusionplans@diffusionplans', 'other'));
+
+// Get parameters
+$id = GETPOSTINT('id');
+$ref = GETPOST('ref', 'alpha');
+$action = GETPOST('action', 'aZ09');
+$backtopage = GETPOST('backtopage', 'alpha');
+$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'bordereaudocagenda';
+
+$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
+$sortfield = GETPOST('sortfield', 'aZ09comma');
+$sortorder = GETPOST('sortorder', 'aZ09comma');
+$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
+if (empty($page) || $page == -1) {
+ $page = 0;
+}
+$offset = $limit * $page;
+if (!$sortorder) {
+ $sortorder = 'DESC';
+}
+if (!$sortfield) {
+ $sortfield = 'a.datep';
+}
+
+// Initialize objects
+$object = new Bordereaudoc($db);
+$form = new Form($db);
+$hookmanager->initHooks(array('bordereaudocagenda', 'globalcard'));
+
+// Permissions
+$permissiontoread = $user->hasRight('diffusionplans', 'bordereaudoc', 'read');
+$permissiontoadd = $user->hasRight('agenda', 'myactions', 'create');
+
+if (!$permissiontoread) {
+ accessforbidden();
+}
+
+// Load object
+include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php';
+if (empty($object->id)) {
+ accessforbidden();
+}
+
+$backtopage = $backtopage ?: dol_buildpath('/diffusionplans/bordereaudoc_card.php', 1).'?id='.$object->id;
+$param = '?id='.$object->id;
+
+// Actions
+$object->fetch_thirdparty();
+$permissiontoreadnote = $permissiontoread;
+$permissiontodeletenote = $permissiontoadd;
+include DOL_DOCUMENT_ROOT.'/core/actions_agenda.inc.php';
+
+// View
+$help_url = '';
+$title = $langs->trans('Agenda');
+llxHeader('', $title, $help_url);
+
+$head = bordereaudocPrepareHead($object);
+print dol_get_fiche_head($head, 'agenda', $langs->trans('Bordereaudoc'), -1, $object->picto);
+
+dol_banner_tab($object, 'ref', $backtopage, ($user->socid ? 0 : 1), 'ref', 'fk_project');
+
+print '
';
+print '
';
+
+$morehtmlright = '';
+$morehtmlcenter = $langs->trans('Project').': ';
+if (!empty($object->fk_project)) {
+ $projectstatic = new Project($db);
+ $projectstatic->fetch($object->fk_project);
+ $morehtmlcenter .= $projectstatic->getNomUrl(1);
+} else {
+ $morehtmlcenter .= $langs->trans('None');
+}
+
+include DOL_DOCUMENT_ROOT.'/core/tpl/agenda_view.tpl.php';
+
+print '
';
+print '
';
+
+print dol_get_fiche_end();
+
+// Footer
+llxFooter();
+$db->close();
diff --git a/bordereaudoc_card.php b/bordereaudoc_card.php
new file mode 100644
index 0000000..0c5bdb4
--- /dev/null
+++ b/bordereaudoc_card.php
@@ -0,0 +1,632 @@
+
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+/**
+* \file bordereaudoc_card.php
+* \ingroup diffusionplans
+* \brief Card page for Bordereaudoc object.
+*/
+
+// Load Dolibarr environment
+$res = 0;
+if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
+$res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
+}
+$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";
+}
+if (!$res && file_exists("../main.inc.php")) {
+$res = @include "../main.inc.php";
+}
+if (!$res && file_exists("../../main.inc.php")) {
+$res = @include "../../main.inc.php";
+}
+if (!$res && file_exists("../../../main.inc.php")) {
+$res = @include "../../../main.inc.php";
+}
+if (!$res) {
+die("Include of main fails");
+}
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
+require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
+require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
+dol_include_once('/diffusionplans/class/bordereaudoc.class.php');
+dol_include_once('/diffusionplans/core/modules/bordereaudoc/modules_bordereaudoc.php');
+
+// Load translations
+$langs->loadLangs(array('diffusionplans@diffusionplans', 'other', 'projects'));
+
+// Get parameters
+$id = GETPOSTINT('id');
+$ref = GETPOST('ref', 'alpha');
+$action = GETPOST('action', 'aZ09');
+$backtopage = GETPOST('backtopage', 'alpha');
+$cancel = GETPOST('cancel', 'alpha');
+$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'bordereaudoccard';
+$optioncss = GETPOST('optioncss', 'aZ');
+
+// Objects
+$object = new Bordereaudoc($db);
+$form = new Form($db);
+$formproject = new FormProjets($db);
+$formfile = new FormFile($db);
+$hookmanager = new HookManager($db);
+$hookmanager->initHooks(array('bordereaudoccard', 'globalcard'));
+
+// Permissions
+$permissiontoread = $user->hasRight('diffusionplans', 'bordereaudoc', 'read');
+$permissiontoadd = $user->hasRight('diffusionplans', 'bordereaudoc', 'write');
+$permissiontovalidate = $user->hasRight('diffusionplans', 'bordereaudoc', 'validate');
+$permissiontosend = $user->hasRight('diffusionplans', 'bordereaudoc', 'send');
+$permissiontoarchive = $user->hasRight('diffusionplans', 'bordereaudoc', 'archive');
+$permissiondelete = $user->hasRight('diffusionplans', 'bordereaudoc', 'delete');
+
+if (!$permissiontoread) {
+ accessforbidden();
+}
+
+if (empty($action) && empty($id) && empty($ref)) {
+$action = 'create';
+}
+
+// Fetch object
+if (!empty($id) || !empty($ref)) {
+$object->fetch($id, $ref);
+}
+
+$upload_dir = '';
+$modulepart = 'bordereaudoc';
+$relativepath = '';
+if ($object->id > 0) {
+ $upload_dir = $object->getDocumentsDirectory();
+ $relativepath = 'bordereaudoc/'.dol_sanitizeFileName($object->ref);
+}
+
+if ($object->id > 0) {
+ $permissiontoaddfile = $permissiontoadd;
+ $param = '?id='.$object->id;
+ $preheaderfile = DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_pre_headers.tpl.php';
+ if (is_readable($preheaderfile)) {
+ include $preheaderfile;
+}
+ $object->syncDocumentIndex($user);
+}
+
+// Actions
+if ($cancel && $backtopage) {
+ header("Location: ".$backtopage);
+ exit;
+ }
+
+$parameters = array('id' => $object->id, 'ref' => $object->ref);
+$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
+if ($reshook < 0) {
+ setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+}
+if (empty($reshook)) {
+ if ($action === 'add' && $permissiontoadd) {
+ $object->ref = GETPOST('ref', 'alpha');
+ $object->title = GETPOST('title', 'alpha');
+ $object->description = dol_htmlcleanlastbr(GETPOST('description', 'restricthtml'));
+ $object->fk_project = GETPOSTINT('fk_project');
+
+ $result = $object->create($user);
+ if ($result > 0) {
+ if (!empty($object->fk_project)) {
+ $object->addProjectExternalContacts($user);
+ }
+
+ if (!empty($backtopage)) {
+ header('Location: '.$backtopage);
+ exit;
+ }
+ header('Location: '.dol_buildpath('/diffusionplans/bordereaudoc_card.php', 1).'?id='.$object->id);
+ exit;
+ }
+ setEventMessages($object->error, $object->errors, 'errors');
+ $action = 'create';
+ }
+
+ if ($action === 'update' && $permissiontoadd && $object->id > 0) {
+ if ((int) $object->statut !== Bordereaudoc::STATUS_DRAFT) {
+ setEventMessages($langs->trans('ErrorForbidden'), null, 'errors');
+ $action = 'view';
+ } else {
+ $object->title = GETPOST('title', 'alpha');
+ $object->description = dol_htmlcleanlastbr(GETPOST('description', 'restricthtml'));
+ $object->fk_project = GETPOSTINT('fk_project');
+ $object->fk_user_modif = $user->id;
+ $result = $object->update($user);
+ if ($result > 0) {
+ setEventMessages($langs->trans('RecordModifiedSuccessfully'), null, 'mesgs');
+ $action = 'view';
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ $action = 'edit';
+ }
+ }
+ }
+
+if ($action === 'confirm_delete' && GETPOST('confirm', 'alpha') === 'yes' && $permissiondelete && $object->id > 0) {
+ $result = $object->delete($user);
+ if ($result > 0) {
+ header('Location: '.dol_buildpath('/diffusionplans/bordereaudoc_list.php', 1));
+ exit;
+ }
+ setEventMessages($object->error, $object->errors, 'errors');
+}
+
+ if ($action === 'confirm_validate' && GETPOST('confirm', 'alpha') === 'yes' && $permissiontovalidate && $object->id > 0) {
+ $result = $object->validate($user);
+ if ($result > 0) {
+ setEventMessages($langs->trans('BordereaudocValidated'), null, 'mesgs');
+ $action = 'view';
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ }
+
+ if ($action === 'confirm_delivered' && GETPOST('confirm', 'alpha') === 'yes' && $permissiontoarchive && $object->id > 0) {
+ $result = $object->setDelivered($user);
+ if ($result > 0) {
+ setEventMessages($langs->trans('BordereaudocDelivered'), null, 'mesgs');
+ $action = 'view';
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ }
+
+ if ($action === 'confirm_close' && GETPOST('confirm', 'alpha') === 'yes' && $permissiontoarchive && $object->id > 0) {
+ $result = $object->setClosed($user);
+ if ($result > 0) {
+ setEventMessages($langs->trans('BordereaudocClosed'), null, 'mesgs');
+ $action = 'view';
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ }
+
+ if ($action === 'builddoc' && $permissiontoread && $object->id > 0) {
+ $model = GETPOST('model', 'alpha');
+ if (empty($model)) {
+ $model = $object->model_pdf ? $object->model_pdf : 'standard';
+ }
+ if ($model !== $object->model_pdf) {
+ $object->model_pdf = $model;
+ $object->update($user);
+ }
+
+ $result = $object->generateDocument($model, $langs);
+ if ($result <= 0) {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ }
+
+ if ($action === 'addprojectcontacts' && $permissiontoadd && $object->id > 0) {
+ if ((int) $object->statut !== Bordereaudoc::STATUS_DRAFT) {
+ setEventMessages($langs->trans('ErrorForbidden'), null, 'errors');
+ } else {
+ $added = $object->addProjectExternalContacts($user);
+ if ($added >= 0) {
+ setEventMessages($langs->trans('BordereaudocAddRecipients'), null, 'mesgs');
+ } else {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ }
+ $action = 'view';
+ }
+
+if ($action === 'saverecipients' && $permissiontoadd && $object->id > 0) {
+if ((int) $object->statut !== Bordereaudoc::STATUS_DRAFT) {
+ setEventMessages($langs->trans('ErrorForbidden'), null, 'errors');
+} else {
+$sendEmail = GETPOST('send_email', 'array');
+$sendMail = GETPOST('send_mail', 'array');
+$sendHand = GETPOST('send_hand', 'array');
+$active = GETPOST('active', 'array');
+
+$lines = $object->getRecipients();
+foreach ($lines as $line) {
+$lineData = array(
+'send_email' => isset($sendEmail[$line->rowid]) ? 1 : 0,
+'send_mail' => isset($sendMail[$line->rowid]) ? 1 : 0,
+'send_hand' => isset($sendHand[$line->rowid]) ? 1 : 0,
+'active' => isset($active[$line->rowid]) ? 1 : 0,
+);
+$object->updateRecipientFlags($line->rowid, $lineData);
+}
+
+ setEventMessages($langs->trans('BordereaudocRecipientsUpdated'), null, 'mesgs');
+}
+
+$action = 'view';
+}
+
+if ($action === 'savefiles' && $permissiontoadd && $object->id > 0) {
+if ((int) $object->statut !== Bordereaudoc::STATUS_DRAFT) {
+ setEventMessages($langs->trans('ErrorForbidden'), null, 'errors');
+} else {
+$visible = GETPOST('is_visible', 'array');
+$lines = $object->getDocumentIndex();
+foreach ($lines as $line) {
+$flag = isset($visible[$line->rowid]) ? 1 : 0;
+$object->updateFileVisibility($line->rowid, $flag);
+}
+ setEventMessages($langs->trans('BordereaudocFilesUpdated'), null, 'mesgs');
+}
+
+$action = 'view';
+}
+
+if ($action === 'sendemail' && $permissiontosend && $object->id > 0) {
+require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
+
+$model = $object->model_pdf ? $object->model_pdf : 'standard';
+if (empty($object->last_main_doc)) {
+$object->generateDocument($model, $langs);
+}
+
+$objectref = dol_sanitizeFileName($object->ref);
+$basedir = !empty($conf->diffusionplans->multidir_output[$object->entity]) ? $conf->diffusionplans->multidir_output[$object->entity] : $conf->document_root[$object->entity];
+$fullpath = $basedir.'/'.$objectref.'/'.$objectref.'.pdf';
+if (!file_exists($fullpath)) {
+ setEventMessages($langs->trans('ErrorFailedToLoadFile'), null, 'errors');
+} else {
+$recipients = array();
+$lines = $object->getRecipients(1);
+foreach ($lines as $line) {
+if (!empty($line->send_email) && !empty($line->fk_contact)) {
+$contact = new Contact($db);
+if ($contact->fetch($line->fk_contact) > 0 && !empty($contact->email)) {
+$recipients[] = $contact->email;
+}
+}
+}
+
+$recipients = array_unique($recipients);
+if (empty($recipients)) {
+ setEventMessages($langs->trans('ErrorNoEMailRecipientSelected'), null, 'errors');
+} else {
+$subject = $langs->trans('BordereaudocMailSubject', $object->ref);
+$template = getDolGlobalString('DIFFUSIONPLANS_BORDEREAU_MAIL_TEMPLATE', '');
+$body = $template ? $template : $langs->trans('BordereaudocMailDefaultIntro', $object->ref);
+$body .= "\n\n".dol_string_nohtmltag($object->description, '', array(), 1);
+
+$docs = $object->getDocumentIndex(1);
+if (!empty($docs)) {
+$body .= "\n\n".$langs->trans('BordereaudocMailDocuments')."\n";
+foreach ($docs as $docline) {
+$link = dol_buildpath('/custom/diffusionplans/public/bordereaudocdownload.php?hash='.$docline->hash, 2);
+$body .= '- '.$docline->filename.' : '.$link."\n";
+}
+}
+
+$htmlbody = nl2br(dol_htmlentitiesbr($body));
+$mailfile = new CMailFile($subject, implode(',', $recipients), $user->email, $htmlbody, array($fullpath), array(basename($fullpath)), array('application/pdf'), '', '', 0, 1);
+if ($mailfile->sendfile()) {
+ setEventMessages($langs->trans('MailSuccessfulySent', implode(',', $recipients)), null, 'mesgs');
+} else {
+ setEventMessages($mailfile->error, $mailfile->errors, 'errors');
+}
+}
+}
+}
+}
+
+// View
+$help_url = '';
+llxHeader('', $langs->trans('BordereaudocCard'), $help_url);
+
+if ($action === 'create') {
+ print load_fiche_titre($langs->trans('BordereaudocNew'), '', 'fa fa-paper-plane');
+ print '';
+ llxFooter();
+ $db->close();
+ exit;
+ }
+
+
+if ($object->id > 0) {
+ if ($action === 'edit' && (((int) $object->statut) !== Bordereaudoc::STATUS_DRAFT || !$permissiontoadd)) {
+ $action = 'view';
+ }
+
+ $confirmform = '';
+ if ($action === 'valid' && $permissiontovalidate && $object->statut == Bordereaudoc::STATUS_DRAFT) {
+ $confirmform = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('ValidateBordereaudoc'), $langs->trans('ConfirmValidateBordereaudoc'), 'confirm_validate', '', 0, 1);
+ }
+ if ($action === 'deliver' && $permissiontoarchive && $object->statut == Bordereaudoc::STATUS_VALIDATED) {
+ $confirmform = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('DeliverBordereaudoc'), $langs->trans('ConfirmDeliverBordereaudoc'), 'confirm_delivered', '', 0, 1);
+ }
+ if ($action === 'close' && $permissiontoarchive && $object->statut == Bordereaudoc::STATUS_DELIVERED) {
+ $confirmform = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('CloseBordereaudoc'), $langs->trans('ConfirmCloseBordereaudoc'), 'confirm_close', '', 0, 1);
+ }
+
+ $head = array();
+ $head[0][0] = dol_buildpath('/diffusionplans/bordereaudoc_card.php', 1).'?id='.$object->id;
+ $head[0][1] = $langs->trans('Card');
+ $head[0][2] = 'card';
+
+ dol_fiche_head($head, 'card', $langs->trans('Bordereaudoc'), -1, 'fa-paper-plane');
+ if (!empty($confirmform)) {
+ print $confirmform;
+ }
+
+$linkback = ''.$langs->trans('BackToList').'';
+ $morehtmlref = '';
+ if (!empty($object->fk_project)) {
+ $projectstatic = new Project($db);
+ $projectstatic->fetch($object->fk_project);
+ $morehtmlref .= '
'.$projectstatic->getNomUrl(1);
+ }
+
+ $editmode = ($action === 'edit');
+ if ($editmode) {
+ print '';
+ } else {
+ $buttons = array();
+ if ($object->statut == Bordereaudoc::STATUS_DRAFT && $permissiontoadd) {
+ $buttons[] = ''.$langs->trans('Modify').'';
+ }
+ if ($object->statut == Bordereaudoc::STATUS_DRAFT && $permissiontovalidate) {
+ $buttons[] = ''.$langs->trans('Validate').'';
+ }
+ if ($object->statut == Bordereaudoc::STATUS_VALIDATED && $permissiontoarchive) {
+ $buttons[] = ''.$langs->trans('MarkDelivered').'';
+ }
+ if ($object->statut == Bordereaudoc::STATUS_DELIVERED && $permissiontoarchive) {
+ $buttons[] = ''.$langs->trans('Close').'';
+ }
+ if ($object->statut >= Bordereaudoc::STATUS_VALIDATED && $permissiontosend) {
+ $buttons[] = ''.$langs->trans('SendMail').'';
+ }
+ if ($permissiontoread) {
+ $buttons[] = ''.$langs->trans('GeneratePDF').'';
+ if (!empty($object->last_main_doc)) {
+$modulepart = 'bordereaudoc';
+ $filename = basename($object->last_main_doc);
+ $filelink = DOL_URL_ROOT.'/document.php?modulepart='.urlencode($modulepart).'&file='.urlencode($object->last_main_doc);
+ $buttons[] = ''.$langs->trans('Download').'';
+ }
+ }
+
+ print ''.implode(' ', $buttons).'
';
+ }
+
+ $recipients = $object->getRecipients();
+ $caneditrecipients = ((int) $object->statut === Bordereaudoc::STATUS_DRAFT && $permissiontoadd);
+
+ print '';
+ print load_fiche_titre($langs->trans('BordereaudocRecipients'), '', 'fa-address-book');
+
+ if ($caneditrecipients) {
+ print '
';
+ }
+
+ print '
';
+ print '
';
+
+ $caneditfiles = ((int) $object->statut === Bordereaudoc::STATUS_DRAFT && $permissiontoadd);
+ $filedir = $upload_dir;
+ $urlsource = $_SERVER['PHP_SELF'].'?id='.$object->id;
+
+ print '';
+ print load_fiche_titre($langs->trans('BordereaudocFiles'), '', 'fa-files-o');
+ print $formfile->showdocuments($modulepart, $relativepath, $filedir, $urlsource, $caneditfiles, $caneditfiles, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', 1);
+
+ $doclines = $object->getDocumentIndex();
+ if (!empty($doclines)) {
+ if ($caneditfiles) {
+ print '
';
+ }
+ } else {
+ print '
'.$langs->trans('BordereaudocNoFiles').'
';
+ }
+
+ print '
';
+
+dol_fiche_end();
+}
+
+// Footer
+ llxFooter();
+ $db->close();
+
diff --git a/bordereaudoc_document.php b/bordereaudoc_document.php
new file mode 100644
index 0000000..4db8e39
--- /dev/null
+++ b/bordereaudoc_document.php
@@ -0,0 +1,209 @@
+
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+/**
+* \file bordereaudoc_document.php
+* \ingroup diffusionplans
+* \brief Tab for documents linked to Bordereaudoc.
+*/
+
+// Load Dolibarr environment
+$res = 0;
+if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
+ $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
+}
+$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";
+}
+if (!$res && file_exists("../main.inc.php")) {
+ $res = @include "../main.inc.php";
+}
+if (!$res && file_exists("../../main.inc.php")) {
+ $res = @include "../../main.inc.php";
+}
+if (!$res && file_exists("../../../main.inc.php")) {
+ $res = @include "../../../main.inc.php";
+}
+if (!$res) {
+ die("Include of main fails");
+}
+
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
+dol_include_once('/diffusionplans/class/bordereaudoc.class.php');
+dol_include_once('/diffusionplans/core/modules/bordereaudoc/modules_bordereaudoc.php');
+dol_include_once('/diffusionplans/lib/diffusionplans_bordereaudoc.lib.php');
+
+/** @var Conf $conf */
+/** @var DoliDB $db */
+/** @var Translate $langs */
+/** @var User $user */
+
+// Load translation files required by the page
+$langs->loadLangs(array('diffusionplans@diffusionplans', 'companies', 'other', 'mails'));
+
+// Get parameters
+$action = GETPOST('action', 'aZ09');
+$id = GETPOSTINT('id');
+$ref = GETPOST('ref', 'alpha');
+
+$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
+$sortfield = GETPOST('sortfield', 'aZ09comma');
+$sortorder = GETPOST('sortorder', 'aZ09comma');
+$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
+if (empty($page) || $page == -1) {
+ $page = 0;
+}
+$offset = $limit * $page;
+if (!$sortorder) {
+ $sortorder = 'ASC';
+}
+if (!$sortfield) {
+ $sortfield = 'name';
+}
+
+// Initialize objects
+$object = new Bordereaudoc($db);
+$form = new Form($db);
+$formfile = new FormFile($db);
+$hookmanager->initHooks(array('bordereaudocdocument', 'globalcard'));
+
+// Permissions
+$permissiontoread = $user->hasRight('diffusionplans', 'bordereaudoc', 'read');
+$permissiontoadd = $user->hasRight('diffusionplans', 'bordereaudoc', 'write');
+
+if (!$permissiontoread) {
+ accessforbidden();
+}
+
+// Load object
+include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php';
+if (empty($object->id)) {
+ accessforbidden();
+}
+
+$upload_dir = $object->getDocumentsDirectory();
+$modulepart = 'bordereaudoc';
+$relativepath = 'bordereaudoc/'.dol_sanitizeFileName($object->ref);
+
+if ($object->id > 0) {
+ $permissiontoaddfile = $permissiontoadd;
+ $param = '?id='.$object->id;
+ include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_pre_headers.tpl.php';
+}
+
+/*
+* Actions
+*/
+
+if ($action === 'savevisibility' && $permissiontoadd && (int) $object->status === Bordereaudoc::STATUS_DRAFT) {
+ $visible = GETPOST('is_visible', 'array');
+ $doclines = $object->getDocumentIndex();
+ foreach ($doclines as $line) {
+ $isVisible = !empty($visible[$line->rowid]) ? 1 : 0;
+ $object->updateFileVisibility($line->rowid, $isVisible);
+ }
+ setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
+}
+
+include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
+
+// Refresh index to align database with filesystem and default visibility rules
+$object->syncDocumentIndex($user);
+
+/*
+* View
+*/
+
+$help_url = '';
+$title = $langs->trans('BordereaudocFiles');
+llxHeader('', $title, $help_url);
+
+$head = bordereaudocPrepareHead($object);
+print dol_get_fiche_head($head, 'documents', $langs->trans('Bordereaudoc'), -1, $object->picto);
+
+dol_banner_tab($object, 'ref', '', ($user->socid ? 0 : 1), 'ref', 'fk_project');
+
+print '';
+print '
';
+
+$urlsource = $_SERVER['PHP_SELF'].'?id='.$object->id;
+$caneditfiles = $permissiontoadd;
+print $formfile->showdocuments($modulepart, $relativepath, $upload_dir, $urlsource, $caneditfiles, $caneditfiles, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', 0);
+
+print '
';
+print '
';
+
+$doclines = $object->getDocumentIndex();
+if (!empty($doclines)) {
+ if ($caneditfiles && (int) $object->status === Bordereaudoc::STATUS_DRAFT) {
+ print '
';
+ }
+} else {
+ print '
'.$langs->trans('BordereaudocNoFiles').'
';
+}
+
+print '
';
+print '
';
+
+print dol_get_fiche_end();
+
+// Footer
+llxFooter();
+$db->close();
diff --git a/bordereaudoc_list.php b/bordereaudoc_list.php
new file mode 100644
index 0000000..01ef99e
--- /dev/null
+++ b/bordereaudoc_list.php
@@ -0,0 +1,346 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file bordereaudoc_list.php
+ * \ingroup diffusionplans
+ * \brief List page for Bordereaudoc objects.
+ */
+
+// Load Dolibarr environment
+$res = 0;
+if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
+ $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
+}
+$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";
+}
+if (!$res && file_exists("../main.inc.php")) {
+ $res = @include "../main.inc.php";
+}
+if (!$res && file_exists("../../main.inc.php")) {
+ $res = @include "../../main.inc.php";
+}
+if (!$res && file_exists("../../../main.inc.php")) {
+ $res = @include "../../../main.inc.php";
+}
+if (!$res) {
+ die("Include of main fails");
+}
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
+require_once __DIR__.'/class/bordereaudoc.class.php';
+
+// Load translation files required by the page
+$langs->loadLangs(array('diffusionplans@diffusionplans', 'projects'));
+
+// Security check
+if (empty($user->rights->diffusionplans->bordereaudoc->read)) {
+ accessforbidden();
+}
+
+$sortfield = GETPOST('sortfield', 'aZ09comma');
+$sortorder = GETPOST('sortorder', 'aZ09comma');
+$page = (int) GETPOST('page', 'int');
+if ($page < 0) {
+ $page = 0;
+}
+$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
+$offset = $limit * $page;
+
+$search_ref = GETPOST('search_ref', 'alpha');
+$search_title = GETPOST('search_title', 'alpha');
+$search_project = GETPOSTINT('search_project');
+$search_status = GETPOSTINT('search_status', -1);
+$search_date_startday = GETPOSTINT('search_date_startday');
+$search_date_startmonth = GETPOSTINT('search_date_startmonth');
+$search_date_startyear = GETPOSTINT('search_date_startyear');
+$search_date_endday = GETPOSTINT('search_date_endday');
+$search_date_endmonth = GETPOSTINT('search_date_endmonth');
+$search_date_endyear = GETPOSTINT('search_date_endyear');
+
+$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear);
+$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
+
+$action = GETPOST('action', 'aZ09');
+$massaction = GETPOST('massaction', 'alpha');
+$confirm = GETPOST('confirm', 'alpha');
+$toselect = GETPOST('toselect', 'array');
+
+// Objects
+$form = new Form($db);
+$formproject = new FormProjets($db);
+$projectstatic = new Project($db);
+$object = new Bordereaudoc($db);
+
+$formconfirm = '';
+
+$arrayofmassactions = array();
+if (!empty($user->rights->diffusionplans->bordereaudoc->delete)) {
+ $arrayofmassactions['delete'] = $langs->trans('Delete');
+}
+
+if ($action === 'confirm_delete' && $confirm === 'yes' && $massaction === 'delete' && !empty($toselect)) {
+ $error = 0;
+ foreach ($toselect as $selectedId) {
+ if (empty($selectedId)) {
+ continue;
+ }
+ $resFetch = $object->fetch((int) $selectedId);
+ if ($resFetch > 0) {
+if ((int) $object->statut === Bordereaudoc::STATUS_DRAFT) {
+ $resDel = $object->delete($user);
+ if ($resDel < 0) {
+ $error++;
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
+ } else {
+ $error++;
+ setEventMessages($langs->trans('ErrorBordereaudocDeleteDraftOnly', $object->ref), null, 'errors');
+ }
+ }
+ }
+
+ if (!$error) {
+ setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs');
+ header('Location: '.$_SERVER['PHP_SELF']);
+ exit;
+ }
+ }
+
+if ($massaction === 'delete' && !empty($arrayofmassactions) && !empty($toselect)) {
+$formconfirm = $form->formconfirm($_SERVER['PHP_SELF'], $langs->trans('Delete'), $langs->trans('ConfirmDelete'), 'confirm_delete', array('massaction' => 'delete', 'toselect' => $toselect));
+}
+
+if (empty($sortfield)) {
+ $sortfield = 't.ref';
+}
+if (empty($sortorder)) {
+ $sortorder = 'ASC';
+}
+
+$statusLabels = array(
+Bordereaudoc::STATUS_DRAFT => $langs->trans('Draft'),
+Bordereaudoc::STATUS_VALIDATED => $langs->trans('Validated'),
+Bordereaudoc::STATUS_DELIVERED => $langs->trans('Delivered'),
+Bordereaudoc::STATUS_CLOSED => $langs->trans('Closed')
+);
+
+$sql = 'SELECT t.rowid, t.ref, t.title, t.fk_project, t.statut, t.datec, t.tms, p.ref as project_ref, p.title as project_title,';
+$sql .= ' bc.cnt_contact as nb_contacts, bf.cnt_visible as nb_visible_files';
+$sql .= ' FROM '.MAIN_DB_PREFIX.'bordereaudoc as t';
+$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."projet as p ON p.rowid = t.fk_project";
+$sql .= ' LEFT JOIN (SELECT fk_bordereaudoc, COUNT(*) as cnt_contact FROM '.MAIN_DB_PREFIX."bordereaudoc_contact WHERE active = 1 AND entity IN (".getEntity('bordereaudoc').") GROUP BY fk_bordereaudoc) as bc ON bc.fk_bordereaudoc = t.rowid";
+$sql .= ' LEFT JOIN (SELECT fk_bordereaudoc, COUNT(*) as cnt_visible FROM '.MAIN_DB_PREFIX."bordereaudoc_file WHERE is_visible = 1 AND entity IN (".getEntity('bordereaudoc').") GROUP BY fk_bordereaudoc) as bf ON bf.fk_bordereaudoc = t.rowid";
+$sql .= ' WHERE t.entity IN ('.getEntity('bordereaudoc').')';
+if (!empty($search_ref)) {
+ $sql .= natural_search('t.ref', $search_ref);
+}
+if (!empty($search_title)) {
+ $sql .= natural_search('t.title', $search_title);
+}
+if (!empty($search_project)) {
+ $sql .= ' AND t.fk_project = '.((int) $search_project);
+}
+if ($search_status >= 0) {
+$sql .= ' AND t.statut = '.((int) $search_status);
+}
+if ($search_date_start > 0) {
+ $sql .= " AND t.datec >= '".$db->idate($search_date_start)."'";
+}
+if ($search_date_end > 0) {
+ $sql .= " AND t.datec <= '".$db->idate($search_date_end)."'";
+}
+
+$sql .= $db->order($sortfield, $sortorder ? $sortorder : 'DESC');
+$sql .= $db->plimit($limit + 1, $offset);
+
+$resql = $db->query($sql);
+if (!$resql) {
+ dol_print_error($db);
+ $num = 0;
+} else {
+ $num = $db->num_rows($resql);
+}
+
+$newcardbutton = '';
+if (!empty($user->rights->diffusionplans->bordereaudoc->write)) {
+ $newcardbutton = dolGetButtonTitle($langs->trans('NewBordereaudoc'), '', 'fa fa-plus-circle', dol_buildpath('/diffusionplans/bordereaudoc_card.php', 1).'?action=create');
+}
+
+$massactionbutton = '';
+if (!empty($arrayofmassactions)) {
+ $massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions);
+}
+
+$param = '';
+if (!empty($search_ref)) {
+ $param .= '&search_ref='.urlencode($search_ref);
+}
+if (!empty($search_title)) {
+ $param .= '&search_title='.urlencode($search_title);
+}
+if (!empty($search_project)) {
+ $param .= '&search_project='.(int) $search_project;
+}
+if ($search_status >= 0) {
+ $param .= '&search_status='.(int) $search_status;
+}
+if ($search_date_startday) {
+ $param .= '&search_date_startday='.(int) $search_date_startday;
+}
+if ($search_date_startmonth) {
+ $param .= '&search_date_startmonth='.(int) $search_date_startmonth;
+}
+if ($search_date_startyear) {
+ $param .= '&search_date_startyear='.(int) $search_date_startyear;
+}
+if ($search_date_endday) {
+ $param .= '&search_date_endday='.(int) $search_date_endday;
+}
+if ($search_date_endmonth) {
+ $param .= '&search_date_endmonth='.(int) $search_date_endmonth;
+}
+if ($search_date_endyear) {
+ $param .= '&search_date_endyear='.(int) $search_date_endyear;
+}
+
+llxHeader('', $langs->trans('BordereaudocList'));
+
+if (!empty($formconfirm)) {
+ print $formconfirm;
+}
+
+print '';
+
+llxFooter();
+$db->close();
diff --git a/class/bordereaudoc.class.php b/class/bordereaudoc.class.php
new file mode 100644
index 0000000..d78556a
--- /dev/null
+++ b/class/bordereaudoc.class.php
@@ -0,0 +1,739 @@
+
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+/**
+* \file class/bordereaudoc.class.php
+* \ingroup diffusionplans
+* \brief Business class for delivery slip of documents.
+*/
+
+// Dolibarr includes
+require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+
+/**
+* Class for Bordereaudoc
+*/
+class Bordereaudoc extends CommonObject
+{
+ /**
+ * @var string Module name
+ */
+ public $module = 'diffusionplans';
+
+ /**
+ * @var string Element name
+ */
+ public $element = 'bordereaudoc';
+
+ /**
+ * @var string Table without prefix
+ */
+ public $table_element = 'bordereaudoc';
+
+ /**
+ * @var string Picto code
+ */
+ public $picto = 'fa-paper-plane';
+
+ /**
+ * Status constants
+ */
+ const STATUS_DRAFT = 0;
+ const STATUS_VALIDATED = 1;
+ const STATUS_DELIVERED = 2;
+ const STATUS_CLOSED = 3;
+
+ /**
+ * @var array Fields definition
+ */
+public $fields = array(
+'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => '1', 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1),
+'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => '1', 'position' => 10, 'notnull' => 1, 'visible' => 1, 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'validate' => 1),
+'title' => array('type' => 'varchar(255)', 'label' => 'Title', 'enabled' => '1', 'position' => 20, 'notnull' => 0, 'visible' => 1, 'searchall' => 1, 'css' => 'minwidth300', 'cssview' => 'wordbreak', 'validate' => 1),
+'description' => array('type' => 'html', 'label' => 'Description', 'enabled' => '1', 'position' => 30, 'notnull' => 0, 'visible' => 3, 'validate' => 1),
+'fk_project' => array('type' => 'integer:Project:projet/class/project.class.php:1', 'label' => 'Project', 'picto' => 'project', 'enabled' => "isModEnabled('project')", 'position' => 40, 'notnull' => 1, 'visible' => 1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'validate' => 1),
+'statut' => array('type' => 'integer', 'label' => 'Status', 'enabled' => '1', 'position' => 50, 'notnull' => 1, 'visible' => 1, 'index' => 1, 'arrayofkeyval' => array('0' => 'Draft', '1' => 'Validated', '2' => 'Delivered', '3' => 'Closed'), 'validate' => 1),
+'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => '1', 'position' => 60, 'notnull' => 1, 'visible' => -2, 'index' => 1),
+'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => '1', 'position' => 70, 'notnull' => 1, 'visible' => -2),
+'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => '1', 'position' => 80, 'notnull' => 0, 'visible' => -2),
+'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'picto' => 'user', 'enabled' => '1', 'position' => 90, 'notnull' => 1, 'visible' => -2),
+'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'picto' => 'user', 'enabled' => '1', 'position' => 100, 'notnull' => -1, 'visible' => -2),
+'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => '1', 'position' => 110, 'notnull' => -1, 'visible' => -2),
+'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => '1', 'position' => 120, 'notnull' => 0, 'visible' => 0),
+'model_pdf' => array('type' => 'varchar(255)', 'label' => 'ModelPDF', 'enabled' => '1', 'position' => 130, 'notnull' => -1, 'visible' => 0),
+);
+
+ public $rowid;
+ public $ref;
+ public $title;
+ public $description;
+ public $fk_project;
+public $statut;
+ public $entity;
+ public $datec;
+ public $tms;
+ public $fk_user_creat;
+ public $fk_user_modif;
+ public $import_key;
+ public $last_main_doc;
+ public $model_pdf;
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct(DoliDB $db)
+ {
+ global $conf;
+
+ $this->db = $db;
+ $this->ismultientitymanaged = 1;
+ $this->isextrafieldmanaged = 1;
+
+ $this->fields['entity']['default'] = !empty($conf->entity) ? (int) $conf->entity : 1;
+ $this->fields['datec']['default'] = dol_now();
+ $this->fields['statut']['default'] = self::STATUS_DRAFT;
+ }
+
+ /**
+ * Load object by id or ref.
+ *
+ * @param int $id Object id
+ * @param string $ref Object ref
+ * @param bool $loadAll Load children data
+ * @return int <0 if KO, 0 not found, >0 if OK
+ */
+ public function fetch($id, $ref = '', $loadAll = true)
+ {
+ // EN: Ensure only one identifier is used to avoid malformed queries
+ $id = (int) $id;
+ $ref = trim((string) $ref);
+
+ if (!empty($id)) {
+ $result = $this->fetchCommon($id);
+ } elseif (!empty($ref)) {
+ $result = $this->fetchCommon(0, $ref, 'ref');
+ } else {
+ return 0;
+ }
+
+ if ($result > 0 && $loadAll) {
+ $this->fetchDocumentIndex();
+ }
+
+ return $result;
+ }
+ /**
+ * Get next reference for object
+ *
+ * @param User $user Current user
+ * @return string
+ */
+ public function getNextNumRef(User $user)
+ {
+ $prefix = getDolGlobalString('DIFFUSIONPLANS_BORDEREAU_REF_PREFIX', 'BRD');
+
+ return $this->getDefaultRef($this->db, $prefix, '', 'bordereaudoc', 'ref');
+ }
+
+ /**
+ * Create object in database
+ *
+ * @param User $user Current user
+ * @param bool $notrigger Disable triggers
+ * @return int
+ */
+ public function create(User $user, $notrigger = false)
+ {
+ if (empty($this->fk_project)) {
+ $this->error = 'ErrorFieldRequired';
+
+ return -1;
+ }
+
+ if (empty($this->ref)) {
+ $this->ref = '(PROV)';
+ }
+
+ $this->entity = !empty($this->entity) ? $this->entity : $user->entity;
+ $this->datec = dol_now();
+ $this->fk_user_creat = $user->id;
+ $this->statut = self::STATUS_DRAFT;
+
+ return $this->createCommon($user, $notrigger);
+ }
+
+ /**
+ * Update object in database.
+ *
+ * @param User $user Current user
+ * @param bool $notrigger Disable triggers
+ * @return int
+ */
+ public function update(User $user, $notrigger = false)
+ {
+ if (empty($this->id) && empty($this->rowid)) {
+ return -1;
+ }
+
+ if (empty($this->fk_project)) {
+ $this->error = 'ErrorFieldRequired';
+
+ return -1;
+ }
+
+ $this->fk_user_modif = $user->id;
+
+ return $this->updateCommon($user, $notrigger);
+ }
+
+ /**
+ * Validate object
+ *
+ * @param User $user Current user
+ * @return int
+ */
+ public function validate(User $user)
+ {
+ if (empty($this->fk_project)) {
+ $this->error = 'ErrorFieldRequired';
+
+ return -1;
+ }
+
+ if ($this->ref == '(PROV)') {
+ $this->ref = $this->getNextNumRef($user);
+ }
+
+ $this->statut = self::STATUS_VALIDATED;
+ $this->fk_user_modif = $user->id;
+
+ return $this->update($user);
+ }
+
+ /**
+ * Set status back to draft.
+ *
+ * @param User $user Current user
+ * @return int
+ */
+ public function setDraft(User $user)
+ {
+ $this->statut = self::STATUS_DRAFT;
+ $this->fk_user_modif = $user->id;
+
+ return $this->update($user);
+ }
+
+ /**
+ * Mark as delivered.
+ *
+ * @param User $user Current user
+ * @return int
+ */
+ public function setDelivered(User $user)
+ {
+ $this->statut = self::STATUS_DELIVERED;
+ $this->fk_user_modif = $user->id;
+
+ return $this->update($user);
+ }
+
+ /**
+ * Get status label with optional picto.
+ *
+ * @param int $mode Output mode
+ * @return string
+ */
+ public function getLibStatut($mode = 0)
+ {
+ return $this->LibStatut($this->statut, $mode);
+ }
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * Build status label for provided status.
+ *
+ * @param int $status Status code
+ * @param int $mode Output mode
+ * @return string
+ */
+ public function LibStatut($status, $mode = 0)
+ {
+ // phpcs:enable
+ global $langs;
+
+ if ($status === null) {
+ return '';
+ }
+
+ if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
+ $this->labelStatus = array(
+ self::STATUS_DRAFT => $langs->transnoentitiesnoconv('Draft'),
+ self::STATUS_VALIDATED => $langs->transnoentitiesnoconv('Validated'),
+ self::STATUS_DELIVERED => $langs->transnoentitiesnoconv('Delivered'),
+ self::STATUS_CLOSED => $langs->transnoentitiesnoconv('Closed'),
+ );
+ $this->labelStatusShort = array(
+ self::STATUS_DRAFT => $langs->transnoentitiesnoconv('Draft'),
+ self::STATUS_VALIDATED => $langs->transnoentitiesnoconv('Validated'),
+ self::STATUS_DELIVERED => $langs->transnoentitiesnoconv('Delivered'),
+ self::STATUS_CLOSED => $langs->transnoentitiesnoconv('Closed'),
+ );
+ }
+
+ $statusType = 'status0';
+ if ($status == self::STATUS_VALIDATED) {
+ $statusType = 'status4';
+ } elseif ($status == self::STATUS_DELIVERED) {
+ $statusType = 'status6';
+ } elseif ($status == self::STATUS_CLOSED) {
+ $statusType = 'status9';
+ }
+
+ return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
+ }
+
+ /**
+ * Add external project contacts as recipients
+ *
+ * @param User $user Current user
+ * @return int
+ */
+ public function addProjectExternalContacts(User $user)
+ {
+ if (empty($this->fk_project) || empty($this->id)) {
+ return 0;
+ }
+
+ $project = new Project($this->db);
+ if ($project->fetch($this->fk_project) <= 0) {
+ return -1;
+ }
+
+ $contacts = $project->liste_contact(-1, 'external');
+ if (empty($contacts)) {
+ return 0;
+ }
+
+ $added = 0;
+ foreach ($contacts as $contact) {
+ if ($this->recipientExists($contact['id'])) {
+ continue;
+ }
+
+ $this->addRecipient($user, $contact['socid'], $contact['id'], $contact['libelle_fonction'], 'External', 1, 0, 0);
+ $added++;
+ }
+
+ return $added;
+ }
+
+ /**
+ * Close object
+ *
+ * @param User $user Current user
+ * @return int
+ */
+ public function setClosed(User $user)
+ {
+ $this->statut = self::STATUS_CLOSED;
+ $this->fk_user_modif = $user->id;
+
+ return $this->update($user);
+ }
+
+ /**
+ * Get documents directory for the bordereaudoc.
+ *
+ * @return string
+ */
+ public function getDocumentsDirectory()
+ {
+ global $conf;
+
+ $entity = !empty($this->entity) ? (int) $this->entity : (int) $conf->entity;
+ if (empty($conf->diffusionplans->multidir_output[$entity])) {
+ return '';
+ }
+
+ $path = rtrim($conf->diffusionplans->multidir_output[$entity], '/').'/bordereaudoc/'.dol_sanitizeFileName($this->ref);
+ dol_mkdir($path);
+
+ return $path;
+ }
+
+ /**
+ * Synchronize filesystem files with database index.
+ *
+ * @param User $user Current user
+ * @return int
+ */
+ public function syncDocumentIndex(User $user)
+ {
+ $dir = $this->getDocumentsDirectory();
+ if (empty($dir)) {
+ return -1;
+ }
+
+ $fsFiles = dol_dir_list($dir, 'files', 0, '', '(\.meta|_preview.*\.png)$', '', '', 1);
+ $existing = $this->fetchDocumentIndex();
+ $existingMap = array();
+ $basepath = 'bordereaudoc/'.dol_sanitizeFileName($this->ref);
+
+ foreach ($existing as $line) {
+ $key = trim($line->filepath, '/').'/'.$line->filename;
+ $existingMap[$key] = $line;
+ }
+
+ $seen = array();
+ foreach ($fsFiles as $file) {
+ $relativeName = !empty($file['relativename']) ? $file['relativename'] : $file['name'];
+ $key = $basepath.'/'.ltrim($relativeName, '/');
+ $seen[$key] = 1;
+ if (!isset($existingMap[$key])) {
+$visible = ((int) $this->statut === self::STATUS_DRAFT) ? 1 : 0;
+ $this->addFileIndex($file['name'], $basepath, $visible, $user);
+ }
+ }
+
+ foreach ($existingMap as $key => $line) {
+ if (!isset($seen[$key])) {
+ $this->deleteFileIndex($line->rowid);
+ }
+ }
+
+ return 1;
+ }
+
+ /**
+ * Get indexed files for the bordereaudoc.
+ *
+ * @param int $onlyVisible Restrict to visible files
+ * @return array
+ */
+ public function getDocumentIndex($onlyVisible = 0)
+ {
+ $sql = 'SELECT rowid, fk_bordereaudoc, filename, filepath, hash, is_visible, entity';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'bordereaudoc_file';
+ $sql .= ' WHERE fk_bordereaudoc = '.((int) $this->id).' AND entity = '.((int) $this->entity);
+ if (!empty($onlyVisible)) {
+ $sql .= ' AND is_visible = 1';
+ }
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $this->error = $this->db->lasterror();
+
+ return array();
+ }
+
+ $lines = array();
+ while ($obj = $this->db->fetch_object($resql)) {
+ $lines[] = $obj;
+ }
+
+ return $lines;
+ }
+
+ /**
+ * Fetch document index without filtering.
+ *
+ * @return array
+ */
+ protected function fetchDocumentIndex()
+ {
+ return $this->getDocumentIndex(0);
+ }
+
+ /**
+ * Add index entry for a file.
+ *
+ * @param string $filename File name
+ * @param string $filepath Relative path
+ * @param int $visible Visibility flag
+ * @param User $user Current user
+ * @param string $hashValue Hash value
+ * @return int
+ */
+ public function addFileIndex($filename, $filepath, $visible, User $user, $hashValue = '')
+ {
+ if (empty($hashValue)) {
+ $hashValue = $this->generateFileHash();
+ }
+
+ $sql = 'INSERT INTO '.MAIN_DB_PREFIX."bordereaudoc_file (fk_bordereaudoc, filename, filepath, hash, is_visible, entity, datec, tms, fk_user_creat)";
+ $sql .= " VALUES (".((int) $this->id).", '".$this->db->escape($filename)."', '".$this->db->escape($filepath)."', '".$this->db->escape($hashValue)."', ".((int) $visible).", ".((int) $this->entity).", ".$this->db->idate(dol_now()).", ".$this->db->idate(dol_now()).", ".((int) $user->id).")";
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $this->error = $this->db->lasterror();
+
+ return -1;
+ }
+
+ return $this->db->last_insert_id(MAIN_DB_PREFIX.'bordereaudoc_file');
+ }
+
+ /**
+ * Delete index entry.
+ *
+ * @param int $rowid Line id
+ * @return int
+ */
+ public function deleteFileIndex($rowid)
+ {
+ $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'bordereaudoc_file WHERE rowid = '.((int) $rowid);
+ $sql .= ' AND fk_bordereaudoc = '.((int) $this->id).' AND entity = '.((int) $this->entity);
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $this->error = $this->db->lasterror();
+
+ return -1;
+ }
+
+ return 1;
+ }
+
+ /**
+ * Update visibility flag for an indexed file.
+ *
+ * @param int $rowid Line id
+ * @param int $visible Visibility flag
+ * @return int
+ */
+ public function updateFileVisibility($rowid, $visible)
+ {
+ $sql = 'UPDATE '.MAIN_DB_PREFIX+"bordereaudoc_file SET is_visible = "+((int) $visible);
+ $sql .= ' WHERE rowid = '.((int) $rowid).' AND fk_bordereaudoc = '.((int) $this->id).' AND entity = '.((int) $this->entity);
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $this->error = $this->db->lasterror();
+
+ return -1;
+ }
+
+ return 1;
+ }
+
+ /**
+ * Generate document from model.
+ *
+ * @param string $modele Model name
+ * @param Translate $outputlangs Output language
+ * @param int<0,1> $hidedetails Hide details flag
+ * @param int<0,1> $hidedesc Hide description flag
+ * @param int<0,1> $hideref Hide ref flag
+ * @param array $moreparams Additional parameters
+ * @return int <=0 if KO, >0 if OK
+ */
+ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = array())
+ {
+ global $langs;
+
+ $langs->load('diffusionplans@diffusionplans');
+
+ if (!dol_strlen($modele)) {
+ if (!empty($this->model_pdf)) {
+ $modele = $this->model_pdf;
+ } elseif (getDolGlobalString('DIFFUSIONPLANS_BORDEREAU_DEFAULT_MODEL')) {
+ $modele = getDolGlobalString('DIFFUSIONPLANS_BORDEREAU_DEFAULT_MODEL');
+ } else {
+ $modele = 'standard';
+ }
+ }
+
+ $modelpath = 'core/modules/bordereaudoc/';
+
+ if (method_exists(get_parent_class($this), 'generateDocument')) {
+ return parent::generateDocument($modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
+ }
+
+ return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
+ }
+
+
+ /**
+ * Generate secure hash for document link.
+ *
+ * @return string
+ */
+ protected function generateFileHash()
+ {
+ try {
+ return hash('sha256', bin2hex(random_bytes(32)).microtime(true).$this->id.dol_print_date(dol_now(), 'dayrfc'));
+ } catch (Exception $e) {
+ return hash('sha256', uniqid((string) $this->id, true));
+ }
+ }
+
+ /**
+ * Load project contacts into bordereaudoc contacts table
+ *
+ * @param User $user Current user
+ * @return int
+ */
+ public function loadProjectContacts(User $user)
+ {
+ if (empty($this->fk_project)) {
+ return 0;
+ }
+
+ $project = new Project($this->db);
+ $res = $project->fetch($this->fk_project);
+ if ($res <= 0) {
+ return -1;
+ }
+
+ $contacts = $project->liste_contact(0, 'external', '', 1, 'contact', 1);
+ if (empty($contacts)) {
+ return 0;
+ }
+
+ $count = 0;
+ foreach ($contacts as $contact) {
+ $already = $this->recipientExists($contact['id']);
+ if ($already) {
+ continue;
+ }
+
+ $this->addRecipient($user, $contact['socid'], $contact['id'], $contact['libelle_fonction'], 'External', 1, 0, 0);
+ $count++;
+ }
+
+ return $count;
+ }
+
+ /**
+ * Check if recipient already exists
+ *
+ * @param int $contactId Contact id
+ * @return bool
+ */
+ protected function recipientExists($contactId)
+ {
+ $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX."bordereaudoc_contact WHERE fk_bordereaudoc = ".((int) $this->id)." AND fk_contact =".((int) $contactId);
+ $sql .= " AND entity = ".((int) $this->entity);
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ return false;
+ }
+
+ return ($this->db->num_rows($resql) > 0);
+ }
+
+ /**
+ * Add a recipient
+ *
+ * @param User $user Current user
+ * @param int $socid Thirdparty id
+ * @param int $contactId Contact id
+ * @param string $typeContact Type label
+ * @param string $nature Nature label
+ * @param int $email Send email flag
+ * @param int $mail Send mail flag
+ * @param int $hand Hand delivery flag
+ * @return int
+ */
+ public function addRecipient(User $user, $socid, $contactId, $typeContact = '', $nature = '', $email = 1, $mail = 0, $hand = 0)
+ {
+ $sql = 'INSERT INTO '.MAIN_DB_PREFIX."bordereaudoc_contact (datec, tms, fk_bordereaudoc, fk_soc, fk_contact, nature_contact, type_contact, send_email, send_mail, send_hand, active, entity, fk_user_creat)";
+ $sql .= " VALUES (".$this->db->idate(dol_now()).", ".$this->db->idate(dol_now()).", ".((int) $this->id).", ".((int) $socid).", ".((int) $contactId).", ";
+ $sql .= "'".$this->db->escape($nature)."', '".$this->db->escape($typeContact)."', ".((int) $email).", ".((int) $mail).", ".((int) $hand).", 1, ".((int) $this->entity).", ".((int) $user->id).")";
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $this->error = $this->db->lasterror();
+
+ return -1;
+ }
+
+ return $this->db->last_insert_id(MAIN_DB_PREFIX.'bordereaudoc_contact');
+ }
+
+ /**
+ * Update recipient flags
+ *
+ * @param int $lineId Line id
+ * @param array $data Data to update
+ * @return int
+ */
+ public function updateRecipientFlags($lineId, array $data)
+ {
+ $fields = array();
+ foreach (array('send_email', 'send_mail', 'send_hand', 'active') as $key) {
+ if (isset($data[$key])) {
+ $fields[] = $key.' = '.((int) $data[$key]);
+ }
+ }
+
+ if (empty($fields)) {
+ return 0;
+ }
+
+ $sql = 'UPDATE '.MAIN_DB_PREFIX.'bordereaudoc_contact SET '.implode(', ', $fields).' WHERE rowid = '.((int) $lineId);
+ $sql .= " AND fk_bordereaudoc = ".((int) $this->id)." AND entity = ".((int) $this->entity);
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $this->error = $this->db->lasterror();
+
+ return -1;
+ }
+
+ return 1;
+ }
+
+ /**
+ * Get recipients list
+ *
+ * @param int $onlyActive Restrict to active
+ * @return array
+ */
+ public function getRecipients($onlyActive = 0)
+ {
+ $sql = 'SELECT bc.rowid, bc.fk_soc, bc.fk_contact, bc.nature_contact, bc.type_contact, bc.send_email, bc.send_mail, bc.send_hand, bc.active, s.nom as socname, c.lastname, c.firstname, c.civility as civility';
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'bordereaudoc_contact as bc';
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON bc.fk_soc = s.rowid';
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."socpeople as c ON bc.fk_contact = c.rowid";
+ $sql .= ' WHERE bc.fk_bordereaudoc = '.((int) $this->id).' AND bc.entity = '.((int) $this->entity);
+ if ($onlyActive) {
+ $sql .= ' AND bc.active = 1';
+ }
+
+ $resql = $this->db->query($sql);
+ if (!$resql) {
+ $this->error = $this->db->lasterror();
+
+ return array();
+ }
+
+ $lines = array();
+ while ($obj = $this->db->fetch_object($resql)) {
+ $lines[] = $obj;
+ }
+
+ return $lines;
+ }
+}
diff --git a/class/diffusion.class.php b/class/diffusion.class.php
index 5ef4b40..20689d3 100644
--- a/class/diffusion.class.php
+++ b/class/diffusion.class.php
@@ -914,7 +914,7 @@ public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss
$label = implode($this->getTooltipContentArray($params));
}
- $url = dol_buildpath('/diffusionplans/diffusion_card.php', 1).'?id='.$this->id;
+$url = dol_buildpath('/diffusionplans/bordereaudoc_card.php', 1).'?id='.$this->id;
if ($option !== 'nolink') {
// Add param to save lastsearch_values or not
diff --git a/core/modules/bordereaudoc/modules_bordereaudoc.php b/core/modules/bordereaudoc/modules_bordereaudoc.php
new file mode 100644
index 0000000..d069823
--- /dev/null
+++ b/core/modules/bordereaudoc/modules_bordereaudoc.php
@@ -0,0 +1,83 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file core/modules/bordereaudoc/modules_bordereaudoc.php
+ * \ingroup diffusionplans
+ * \brief Parent classes for bordereaudoc PDF and numbering models.
+ */
+
+require_once DOL_DOCUMENT_ROOT . '/core/class/commondocgenerator.class.php';
+require_once DOL_DOCUMENT_ROOT . '/core/class/commonnumrefgenerator.class.php';
+
+/**
+ * Parent class for bordereaudoc PDF models.
+ */
+abstract class ModelePDFBordereaudoc extends CommonDocGenerator
+ {
+ /**
+ * Return list of active generation modules.
+ *
+ * @param DoliDB $db Database handler
+ * @param int $maxfilenamelength Max length of value to show
+ * @return array|int
+ */
+ public static function liste_modeles($db, $maxfilenamelength = 0)
+ {
+ $type = 'bordereaudoc';
+ $list = array();
+
+ include_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
+ $list = getListOfModels($db, $type, $maxfilenamelength);
+
+ return $list;
+ }
+
+ /**
+ * Build document on disk.
+ *
+ * @param Bordereaudoc $object Object source to build document
+ * @param Translate $outputlangs Lang output object
+ * @param string $srctemplatepath Full path of source filename for generator using a template file
+ * @param int $hidedetails Do not show line details
+ * @param int $hidedesc Do not show desc
+ * @param int $hideref Do not show ref
+ * @return int
+ */
+ abstract public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0);
+ }
+
+ /**
+ * Parent class to manage numbering of Bordereaudoc.
+ */
+ abstract class ModeleNumRefBordereaudoc extends CommonNumRefGenerator
+ {
+ /**
+ * Return an example of numbering.
+ *
+ * @return string
+ */
+ abstract public function getExample();
+
+ /**
+ * Return next free value.
+ *
+ * @param Bordereaudoc $object Object we need next value for
+ * @return string|int
+ */
+ abstract public function getNextValue($object);
+ }
diff --git a/core/modules/bordereaudoc/pdf_bordereaudoc_standard.modules.php b/core/modules/bordereaudoc/pdf_bordereaudoc_standard.modules.php
new file mode 100644
index 0000000..fc065ea
--- /dev/null
+++ b/core/modules/bordereaudoc/pdf_bordereaudoc_standard.modules.php
@@ -0,0 +1,192 @@
+
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file core/modules/bordereaudoc/pdf_bordereaudoc_standard.modules.php
+ * \ingroup diffusionplans
+ * \brief PDF model for bordereaudoc.
+ */
+
+dol_include_once('/diffusionplans/core/modules/bordereaudoc/modules_bordereaudoc.php');
+require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
+require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+
+class pdf_bordereaudoc_standard extends ModelePDFBordereaudoc
+{
+ /**
+ * @var DoliDB Database handler
+ */
+ public $db;
+
+ /**
+ * @var string Model name
+ */
+ public $name;
+
+ /**
+ * @var string Model description
+ */
+ public $description;
+
+ /**
+ * @var string Document type
+ */
+ public $type = 'pdf';
+
+ /**
+ * @var string Document format
+ */
+ public $format;
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $langs;
+
+ $this->db = $db;
+ $this->name = 'standard';
+ $this->description = 'Standard';
+ $this->option_freetext = getDolGlobalString('DIFFUSIONPLANS_FREE_TEXT', '');
+ $this->format = array(210, 297);
+
+ $langs->loadLangs(array('main', 'companies', 'projects', 'diffusionplans@diffusionplans'));
+ }
+
+ /**
+ * Write bordereaudoc PDF file
+ *
+ * @param Bordereaudoc $object Bordereaudoc
+ * @param Translate $outputlangs Output langs
+ * @param string $srctemplatepath Not used
+ * @param int $hidedetails Not used
+ * @param int $hidedesc Not used
+ * @param int $hideref Not used
+ * @return int
+ */
+ public function write_file($object, $outputlangs, $srctemplatepath = '', $hidedetails = 0, $hidedesc = 0, $hideref = 0)
+ {
+ global $conf, $langs, $mysoc;
+
+ if (empty($outputlangs)) {
+ $outputlangs = $langs;
+ }
+ $outputlangs->loadLangs(array('main', 'companies', 'projects', 'diffusionplans@diffusionplans'));
+
+ if ($mysoc->country_code) {
+ $outputlangs->load('dict');
+ }
+
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+ $objectref = dol_sanitizeFileName($object->ref);
+ $dir = (!empty($conf->diffusionplans->multidir_output[$object->entity]) ? $conf->diffusionplans->multidir_output[$object->entity] : $conf->document_root[$object->entity]).'/'.$objectref;
+ dol_mkdir($dir);
+ $file = $dir.'/'.$objectref.'.pdf';
+
+ $pdf = pdf_getInstance($this->format);
+ $default_font = pdf_getPDFFont($outputlangs);
+ $pdf->SetTitle($outputlangs->transnoentities('Bordereaudoc').' '.$object->ref);
+ $pdf->SetSubject($outputlangs->transnoentities('Bordereaudoc'));
+ $pdf->SetCreator('Dolibarr');
+ $pdf->SetAuthor($outputlangs->transnoentities($mysoc->name));
+ pdf_setPrintHeader($pdf, $outputlangs);
+ pdf_setPrintFooter($pdf, $outputlangs);
+ $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
+ $pdf->SetAutoPageBreak(true, PDF_MARGIN_BOTTOM);
+ $pdf->AddPage();
+ $pdf->SetFont($default_font, 'B', $default_font_size + 2);
+ $pdf->SetTextColor(0, 0, 60);
+ $pdf->MultiCell(0, 6, $outputlangs->trans('Bordereaudoc').' '.$object->ref, 0, 'L', 0, 1);
+ $pdf->Ln(2);
+
+ if (!empty($object->title)) {
+ $pdf->SetFont($default_font, '', $default_font_size + 1);
+ $pdf->MultiCell(0, 5, $object->title, 0, 'L', 0, 1);
+ $pdf->Ln(1);
+ }
+
+ $pdf->SetFont($default_font, '', $default_font_size);
+ $pdf->MultiCell(0, 5, $outputlangs->trans('Project').': '.($object->fk_project ? $object->fk_project : ''), 0, 'L', 0, 1);
+ $pdf->Ln(1);
+
+ if (!empty($object->description)) {
+ $pdf->SetFont($default_font, 'B', $default_font_size);
+ $pdf->MultiCell(0, 5, $outputlangs->trans('Description'), 0, 'L', 0, 1);
+ $pdf->SetFont($default_font, '', $default_font_size);
+ $pdf->writeHTMLCell(0, 0, '', '', $object->description, 0, 1, 0, true, 'L', true);
+ $pdf->Ln(2);
+ }
+
+ $recipients = $object->getRecipients(1);
+ if (!empty($recipients)) {
+ $pdf->SetFont($default_font, 'B', $default_font_size);
+ $pdf->MultiCell(0, 5, $outputlangs->trans('BordereaudocRecipients'), 0, 'L', 0, 1);
+ $pdf->SetFont($default_font, '', $default_font_size);
+ $table = '';
+ $table .= '';
+ $table .= '| '.$outputlangs->trans('ThirdParty').' | ';
+ $table .= ''.$outputlangs->trans('Contact').' | ';
+ $table .= ''.$outputlangs->trans('Nature').' | ';
+ $table .= ''.$outputlangs->trans('Type').' | ';
+ $table .= ''.$outputlangs->trans('SendByEmail').' | ';
+ $table .= ''.$outputlangs->trans('SendByMail').' | ';
+ $table .= ''.$outputlangs->trans('SendByHand').' | ';
+ $table .= '
';
+ foreach ($recipients as $line) {
+ $table .= '';
+ $table .= '| '.dol_escape_htmltag($line->socname).' | ';
+ $table .= ''.dol_escape_htmltag(dolGetFirstLastname($line->firstname, $line->lastname)).' | ';
+ $table .= ''.dol_escape_htmltag($line->nature_contact).' | ';
+ $table .= ''.dol_escape_htmltag($line->type_contact).' | ';
+ $table .= ''.($line->send_email ? $outputlangs->trans('Yes') : $outputlangs->trans('No')).' | ';
+ $table .= ''.($line->send_mail ? $outputlangs->trans('Yes') : $outputlangs->trans('No')).' | ';
+ $table .= ''.($line->send_hand ? $outputlangs->trans('Yes') : $outputlangs->trans('No')).' | ';
+ $table .= '
';
+ }
+ $table .= '
';
+ $pdf->writeHTML($table, true, false, true, false, '');
+ $pdf->Ln(2);
+ }
+
+ $docs = $object->getDocumentIndex(1);
+ if (!empty($docs)) {
+ $pdf->SetFont($default_font, 'B', $default_font_size);
+ $pdf->MultiCell(0, 5, $outputlangs->trans('BordereaudocDocuments'), 0, 'L', 0, 1);
+ $pdf->SetFont($default_font, '', $default_font_size);
+ $list = '';
+ foreach ($docs as $doc) {
+ $link = dol_buildpath('/custom/diffusionplans/public/bordereaudocdownload.php?hash='.$doc->hash, 2);
+ $list .= '- '.dol_escape_htmltag($doc->filename).' - '.$link.'
';
+ }
+ $list .= '
';
+ $pdf->writeHTML($list, true, false, true, false, '');
+ }
+
+ $pdf->Close();
+ $pdf->Output($file, 'F');
+ $object->last_main_doc = 'diffusionplans/'.$objectref.'/'.$objectref.'.pdf';
+ $object->model_pdf = $this->name;
+
+ return 1;
+ }
+}
diff --git a/core/modules/modDiffusionPlans.class.php b/core/modules/modDiffusionPlans.class.php
index 12305e1..34f81d6 100644
--- a/core/modules/modDiffusionPlans.class.php
+++ b/core/modules/modDiffusionPlans.class.php
@@ -1,666 +1,707 @@
-
- * Copyright (C) 2018-2019 Nicolas ZABOURI
- * Copyright (C) 2019-2024 Frédéric France
- * Copyright (C) 2025 Pierre ARDOIN
- *
- * 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 .
- */
-
-/**
- * \defgroup diffusionplans Module DiffusionPlans
- * \brief DiffusionPlans module descriptor.
- *
- * \file htdocs/diffusionplans/core/modules/modDiffusionPlans.class.php
- * \ingroup diffusionplans
- * \brief Description and activation file for module DiffusionPlans
- */
-include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
-
-
-/**
- * Description and activation class for module DiffusionPlans
- */
-class modDiffusionPlans extends DolibarrModules
-{
- /**
- * Constructor. Define names, constants, directories, boxes, permissions
- *
- * @param DoliDB $db Database handler
- */
- public function __construct($db)
- {
- global $conf, $langs;
-
- $this->db = $db;
-
- // Id for module (must be unique).
- // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
- $this->numero = 450001; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve an id number for your module
-
- // Key text used to identify module (for permissions, menus, etc...)
- $this->rights_class = 'diffusionplans';
-
- // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
- // It is used to group modules by family in module setup page
- $this->family = "other";
-
- // Module position in the family on 2 digits ('01', '10', '20', ...)
- $this->module_position = '90';
-
- // Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
- //$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
- // Module label (no space allowed), used if translation string 'ModuleDiffusionPlansName' not found (DiffusionPlans is name of module).
- $this->name = preg_replace('/^mod/i', '', get_class($this));
-
- // DESCRIPTION_FLAG
- // Module description, used if translation string 'ModuleDiffusionPlansDesc' not found (DiffusionPlans is name of module).
- $this->description = 'ModuleDiffusionsPlansDesc';
- // Used only if file README.md and README-LL.md not found.
- $this->descriptionlong = "DiffusionPlansDescription";
-
- // Author
- $this->editor_name = 'Les Métiers du Bâtiment';
- $this->editor_url = 'lesmetiersdubatiment.fr'; // Must be an external online web site
- $this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@diffusionplans'
-
- // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z'
- $this->version = '1.0';
- // Url to the file with your last numberversion of this module
- //$this->url_last_version = 'http://www.example.com/versionmodule.txt';
-
- // Key used in llx_const table to save module status enabled/disabled (where DIFFUSIONPLANS is value of property name of module in uppercase)
- $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
-
- if (!isset($conf->diffusionplans) || !is_object($conf->diffusionplans)) {
- $conf->diffusionplans = new stdClass();
- }
-
- $entity = !empty($conf->entity) ? (int) $conf->entity : 1;
- $defaultDir = DOL_DATA_ROOT.($entity > 1 ? '/'.$entity : '').'/diffusionplans';
-
- if (empty($conf->diffusionplans->dir_output)) {
- $conf->diffusionplans->dir_output = $defaultDir;
- }
- if (empty($conf->diffusionplans->dir_temp)) {
- $conf->diffusionplans->dir_temp = $conf->diffusionplans->dir_output.'/temp';
- }
- if (empty($conf->diffusionplans->multidir_output) || !is_array($conf->diffusionplans->multidir_output)) {
- $conf->diffusionplans->multidir_output = array();
- }
- if (empty($conf->diffusionplans->multidir_output[$entity])) {
- $conf->diffusionplans->multidir_output[$entity] = $defaultDir;
- }
-
- $diffusionDir = $conf->diffusionplans->dir_output.'/diffusion';
- if (!isset($conf->diffusion) || !is_object($conf->diffusion)) {
- $conf->diffusion = new stdClass();
- }
- if (empty($conf->diffusion->dir_output)) {
- $conf->diffusion->dir_output = $diffusionDir;
- }
- if (empty($conf->diffusion->multidir_output) || !is_array($conf->diffusion->multidir_output)) {
- $conf->diffusion->multidir_output = array();
- }
- if (empty($conf->diffusion->multidir_output[$entity])) {
- $conf->diffusion->multidir_output[$entity] = $diffusionDir;
- }
-
- $diffusionContactDir = $conf->diffusionplans->dir_output.'/diffusioncontact';
- if (!isset($conf->diffusioncontact) || !is_object($conf->diffusioncontact)) {
- $conf->diffusioncontact = new stdClass();
- }
- if (empty($conf->diffusioncontact->dir_output)) {
- $conf->diffusioncontact->dir_output = $diffusionContactDir;
- }
- if (empty($conf->diffusioncontact->multidir_output) || !is_array($conf->diffusioncontact->multidir_output)) {
- $conf->diffusioncontact->multidir_output = array();
- }
- if (empty($conf->diffusioncontact->multidir_output[$entity])) {
- $conf->diffusioncontact->multidir_output[$entity] = $diffusionContactDir;
- }
-
- // 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 module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
- // To use a supported fa-xxx css style of font awesome, use this->picto='xxx'
- $this->picto = 'fa-paper-plane';
-
- // Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
- $this->module_parts = array(
- // Set this to 1 if module has its own trigger directory (core/triggers)
- 'triggers' => 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 substitution function file (core/substitutions)
- 'substitutions' => 0,
- // Set this to 1 if module has its own menus handler directory (core/menus)
- 'menus' => 0,
- // Set this to 1 if module overwrite template dir (core/tpl)
- 'tpl' => 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 models directory (core/modules/xxx)
- 'models' => 1,
- // Set this to 1 if module has its own printing directory (core/modules/printing)
- 'printing' => 0,
- // Set this to 1 if module has its own theme directory (theme)
- 'theme' => 0,
- // Set this to relative path of css file if module has its own css file
- 'css' => array(
- // '/diffusionplans/css/diffusionplans.css.php',
- ),
- // Set this to relative path of js file if module must load a js on all pages
- 'js' => array(
- '/diffusionplans/js/diffusionplans.js.php',
- ),
- // 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 to 'all'
- /* BEGIN MODULEBUILDER HOOKSCONTEXTS */
- 'hooks' => array(
- // 'data' => array(
- // 'hookcontext1',
- // 'hookcontext2',
- // ),
- // 'entity' => '0',
- ),
- /* END MODULEBUILDER HOOKSCONTEXTS */
- // Set this to 1 if features of module are opened to external users
- 'moduleforexternal' => 0,
- // Set this to 1 if the module provides a website template into doctemplates/websites/website_template-mytemplate
- 'websitetemplates' => 0,
- // Set this to 1 if the module provides a captcha driver
- 'captcha' => 0
- );
-
- // Data directories to create when module is enabled.
- // Example: this->dirs = array("/diffusionplans/temp","/diffusionplans/subdir");
- $this->dirs = array(
- "/diffusionplans/temp",
- "/diffusionplans/diffusion",
- "/diffusionplans/diffusioncontact",
- );
-
- // Config pages. Put here list of php page, stored into diffusionplans/admin directory, to use to setup module.
- $this->config_page_url = array("setup.php@diffusionplans");
-
- // Dependencies
- // A condition to hide module
- $this->hidden = getDolGlobalInt('MODULE_DIFFUSIONPLANS_DISABLED'); // A condition to disable module;
- // List of module class names that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR')...)
- $this->depends = array('always'=>array('modProjet','modSociete'));
- // List of module class names to disable if this one is disabled. Example: array('modModuleToDisable1', ...)
- $this->requiredby = array();
- // List of module class names this module is in conflict with. Example: array('modModuleToDisable1', ...)
- $this->conflictwith = array();
-
- // The language file dedicated to your module
- $this->langfiles = array("diffusionplans@diffusionplans");
-
- // Prerequisites
- $this->phpmin = array(7, 1); // Minimum version of PHP required by module
- $this->need_dolibarr_version = array(19, -3); // Minimum version of Dolibarr required by module
- $this->need_javascript_ajax = 0;
-
- // Messages at activation
- $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','MX'='textmx'...)
- $this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','MX'='textmx'...)
- //$this->automatic_activation = array('FR'=>'DiffusionPlansWasAutomaticallyActivatedBecauseOfYourCountryChoice');
- //$this->always_enabled = true; // If true, can't be disabled
-
- // Constants
- // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
- // Example: $this->const=array(1 => array('DIFFUSIONPLANS_MYNEWCONST1', 'chaine', 'myvalue', 'This is a constant to add', 1),
- // 2 => array('DIFFUSIONPLANS_MYNEWCONST2', 'chaine', 'myvalue', 'This is another constant to add', 0, 'current', 1)
- // );
- $i = 0;
- $this->const = array(
- $i++ => ['DIFFUSIONPLANS_DIFFUSION_ADDON', 'chaine', 'mod_diffusion_standard', '', 0, 'current'],
- $i++ => ['DIFFUSIONPLANS_DIFFUSION_ADDON_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/diffusionplans/diffusion/', '', 0, 'current'],
- $i++ => ['DIFFUSIONPLANS_DIFFUSION_DEFAULT_MODEL', 'chaine', 'standard_diffusion', '', 0, 'current'],
- );
-
- // Some keys to add into the overwriting translation tables
- /*$this->overwrite_translation = array(
- 'en_US:ParentCompany'=>'Parent company or reseller',
- 'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
- )*/
-
- if (!isModEnabled("diffusionplans")) {
- $conf->diffusionplans = new stdClass();
- $conf->diffusionplans->enabled = 0;
- }
-
- // Array to add new pages in new tabs
- /* BEGIN MODULEBUILDER TABS */
- $this->tabs = array();
- $this->tabs[] = array(
- 'data'=>'project:+diffusion:DiffusionDocuments:diffusionplans@diffusionplans:$user->hasRight(\'diffusionplans\', \'read\'):/diffusionplans/tabs/diffusionplans.php?id=__ID__',
- );
- /* END MODULEBUILDER TABS */
- // Example:
- // To add a new tab identified by code tabname1
- // $this->tabs[] = array('data' => 'objecttype:+tabname1:Title1:mylangfile@diffusionplans:$user->hasRight(\'diffusionplans\', \'read\'):/diffusionplans/mynewtab1.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:+tabname2:SUBSTITUTION_Title2:mylangfile@diffusionplans:$user->hasRight(\'othermodule\', \'read\'):/diffusionplans/mynewtab2.php?id=__ID__',
- // To remove an existing tab identified by code tabname
- // $this->tabs[] = array('data' => 'objecttype:-tabname:NU:conditiontoremove');
- //
- // 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)
- // 'contact' to add a tab in contact view
- // 'contract' to add a tab in contract view
- // 'delivery' to add a tab in delivery view
- // 'group' to add a tab in group view
- // 'intervention' to add a tab in intervention view
- // 'invoice' to add a tab in customer invoice view
- // 'invoice_supplier' to add a tab in supplier invoice view
- // 'member' to add a tab in foundation member view
- // 'opensurveypoll' to add a tab in opensurvey poll view
- // 'order' to add a tab in sale order view
- // 'order_supplier' to add a tab in supplier order view
- // 'payment' to add a tab in payment view
- // 'payment_supplier' to add a tab in supplier payment view
- // 'product' to add a tab in product view
- // 'propal' to add a tab in propal view
- // 'project' to add a tab in project view
- // 'stock' to add a tab in stock view
- // 'thirdparty' to add a tab in third party view
- // 'user' to add a tab in user view
-
-
- // Dictionaries
- /* Example:
- $this->dictionaries=array(
- 'langs' => 'diffusionplans@diffusionplans',
- // List of tables we want to see into dictionary editor
- 'tabname' => array("table1", "table2", "table3"),
- // Label of tables
- 'tablib' => array("Table1", "Table2", "Table3"),
- // 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'),
- // Sort order
- 'tabsqlsort' => array("label ASC", "label ASC", "label ASC"),
- // List of fields (result of select to show dictionary)
- 'tabfield' => 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 for insert)
- 'tabfieldinsert' => array("code,label", "code,label", "code,label"),
- // Name of columns with primary key (try to always name it 'rowid')
- 'tabrowid' => array("rowid", "rowid", "rowid"),
- // Condition to show each dictionary
- 'tabcond' => array(isModEnabled('diffusionplans'), isModEnabled('diffusionplans'), isModEnabled('diffusionplans')),
- // Tooltip for every fields of dictionaries: DO NOT PUT AN EMPTY ARRAY
- 'tabhelp' => array(array('code' => $langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip'), array('code' => $langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip'), ...),
- );
- */
- /* BEGIN MODULEBUILDER DICTIONARIES */
- $this->dictionaries = array();
- /* END MODULEBUILDER DICTIONARIES */
-
- // Boxes/Widgets
- // Add here list of php file(s) stored in diffusionplans/core/boxes that contains a class to show a widget.
- /* BEGIN MODULEBUILDER WIDGETS */
- $this->boxes = array(
- // 0 => array(
- // 'file' => 'diffusionplanswidget1.php@diffusionplans',
- // 'note' => 'Widget provided by DiffusionPlans',
- // 'enabledbydefaulton' => 'Home',
- // ),
- // ...
- );
- /* END MODULEBUILDER WIDGETS */
-
- // 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
- /* BEGIN MODULEBUILDER CRON */
- $this->cronjobs = array(
- // 0 => array(
- // 'label' => 'MyJob label',
- // 'jobtype' => 'method',
- // 'class' => '/diffusionplans/class/diffusion.class.php',
- // 'objectname' => 'Diffusion',
- // 'method' => 'doScheduledJob',
- // 'parameters' => '',
- // 'comment' => 'Comment',
- // 'frequency' => 2,
- // 'unitfrequency' => 3600,
- // 'status' => 0,
- // 'test' => 'isModEnabled("diffusionplans")',
- // 'priority' => 50,
- // ),
- );
- /* END MODULEBUILDER CRON */
- // 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'=>'isModEnabled("diffusionplans")', 'priority'=>50),
- // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'isModEnabled("diffusionplans")', 'priority'=>50)
- // );
-
- // Permissions provided by this module
- $this->rights = array();
- $r = 0;
- // Add here entries to declare new permissions
- /* BEGIN MODULEBUILDER PERMISSIONS */
- $this->rights[$r][0] = $this->numero . sprintf('%02d', (0 * 10) + 0 + 1);
- $this->rights[$r][1] = 'Read Diffusion object of DiffusionPlans';
- $this->rights[$r][4] = 'diffusion';
- $this->rights[$r][5] = 'read';
- $r++;
- $this->rights[$r][0] = $this->numero . sprintf('%02d', (0 * 10) + 1 + 1);
- $this->rights[$r][1] = 'Create/Update Diffusion object of DiffusionPlans';
- $this->rights[$r][4] = 'diffusion';
- $this->rights[$r][5] = 'write';
- $r++;
- $this->rights[$r][0] = $this->numero . sprintf('%02d', (0 * 10) + 2 + 1);
- $this->rights[$r][1] = 'Delete Diffusion object of DiffusionPlans';
- $this->rights[$r][4] = 'diffusion';
- $this->rights[$r][5] = 'delete';
- $r++;
- $this->rights[$r][0] = $this->numero . sprintf('%02d', (1 * 10) + 0 + 1);
- $this->rights[$r][1] = 'Read DiffusionContact object of DiffusionPlans';
- $this->rights[$r][4] = 'diffusioncontact';
- $this->rights[$r][5] = 'read';
- $r++;
- $this->rights[$r][0] = $this->numero . sprintf('%02d', (1 * 10) + 1 + 1);
- $this->rights[$r][1] = 'Create/Update DiffusionContact object of DiffusionPlans';
- $this->rights[$r][4] = 'diffusioncontact';
- $this->rights[$r][5] = 'write';
- $r++;
- $this->rights[$r][0] = $this->numero . sprintf('%02d', (1 * 10) + 2 + 1);
- $this->rights[$r][1] = 'Delete DiffusionContact object of DiffusionPlans';
- $this->rights[$r][4] = 'diffusioncontact';
- $this->rights[$r][5] = 'delete';
- $r++;
-
- /* END MODULEBUILDER PERMISSIONS */
-
-
- // Main menu entries to add
- $this->menu = array();
- $r = 0;
- // Add here entries to declare new menus
- /* BEGIN MODULEBUILDER TOPMENU */
- $this->menu[$r++] = array(
- 'fk_menu' => '', // Will be stored into mainmenu + leftmenu. Use '' 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
- 'titre' => 'ModuleDiffusionPlansName',
- 'prefix' => img_picto('', $this->picto, 'class="pictofixedwidth valignmiddle"'),
- 'mainmenu' => 'diffusionplans',
- 'leftmenu' => '',
- 'url' => '/diffusionplans/diffusionplansindex.php',
- 'langs' => 'diffusionplans@diffusionplans', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
- 'position' => 1000 + $r,
- 'enabled' => 'isModEnabled("diffusionplans")', // Define condition to show or hide menu entry. Use 'isModEnabled("diffusionplans")' if entry must be visible if module is enabled.
- 'perms' => '1', // Use 'perms'=>'$user->hasRight("diffusionplans", "diffusion", "read")' if you want your menu with a permission rules
- 'target' => '',
- 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
- );
- /* END MODULEBUILDER TOPMENU */
-
-
-
- /* BEGIN MODULEBUILDER LEFTMENU DIFFUSION */
- $this->menu[$r++] = array(
- 'fk_menu' => 'fk_mainmenu=diffusionplans',
- 'type' => 'left',
- 'titre' => 'Diffusion',
- 'mainmenu' => 'diffusionplans',
- 'leftmenu' => 'diffusion',
- 'url' => '/diffusionplans/diffusion_list.php',
- 'langs' => 'diffusionplans@diffusionplans',
- 'position' => 1001,
- 'enabled' => 'isModEnabled(\'diffusionplans\')',
- 'perms' => '$user->hasRight(\'diffusionplans\', \'diffusion\', \'read\')',
- 'target' => '',
- 'user' => 2,
- 'object' => 'Diffusion',
- );
- /* END MODULEBUILDER LEFTMENU DIFFUSION */
- /* BEGIN MODULEBUILDER LEFTMENU DIFFUSION */
- $this->menu[$r++] = array(
- 'fk_menu' => 'fk_mainmenu=diffusionplans,fk_leftmenu=diffusion',
- 'type' => 'left',
- 'titre' => 'List Diffusion',
- 'mainmenu' => 'diffusionplans',
- 'leftmenu' => 'diffusionplans_diffusion_list',
- 'url' => '/diffusionplans/diffusion_list.php',
- 'langs' => 'diffusionplans@diffusionplans',
- 'position' => 1002,
- 'enabled' => 'isModEnabled(\'diffusionplans\')',
- 'perms' => '$user->hasRight(\'diffusionplans\', \'diffusion\', \'read\')',
- 'target' => '',
- 'user' => 2,
- 'object' => 'Diffusion',
- );
- /* END MODULEBUILDER LEFTMENU DIFFUSION */
- /* BEGIN MODULEBUILDER LEFTMENU DIFFUSION */
- $this->menu[$r++] = array(
- 'fk_menu' => 'fk_mainmenu=diffusionplans,fk_leftmenu=diffusion',
- 'type' => 'left',
- 'titre' => 'New Diffusion',
- 'mainmenu' => 'diffusionplans',
- 'leftmenu' => 'diffusionplans_diffusion_new',
- 'url' => '/diffusionplans/diffusion_card.php?action=create',
- 'langs' => 'diffusionplans@diffusionplans',
- 'position' => 1003,
- 'enabled' => 'isModEnabled(\'diffusionplans\')',
- 'perms' => '$user->hasRight(\'diffusionplans\', \'diffusion\', \'write\')',
- 'target' => '',
- 'user' => 2,
- 'object' => 'Diffusion',
- );
- /* END MODULEBUILDER LEFTMENU DIFFUSION */
-
- /* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */
- /*
- $this->menu[$r++]=array(
- 'fk_menu' => 'fk_mainmenu=diffusionplans', // '' 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
- 'titre' => 'Diffusion',
- 'prefix' => img_picto('', $this->picto, 'class="pictofixedwidth valignmiddle paddingright"'),
- 'mainmenu' => 'diffusionplans',
- 'leftmenu' => 'diffusion',
- 'url' => '/diffusionplans/diffusionplansindex.php',
- 'langs' => 'diffusionplans@diffusionplans', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
- 'position' => 1000 + $r,
- 'enabled' => 'isModEnabled("diffusionplans")', // Define condition to show or hide menu entry. Use 'isModEnabled("diffusionplans")' if entry must be visible if module is enabled.
- 'perms' => '$user->hasRight("diffusionplans", "diffusion", "read")',
- 'target' => '',
- 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
- 'object' => 'Diffusion'
- );
- $this->menu[$r++]=array(
- 'fk_menu' => 'fk_mainmenu=diffusionplans,fk_leftmenu=diffusion', // '' 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
- 'titre' => 'New_Diffusion',
- 'mainmenu' => 'diffusionplans',
- 'leftmenu' => 'diffusionplans_diffusion_new',
- 'url' => '/diffusionplans/diffusion_card.php?action=create',
- 'langs' => 'diffusionplans@diffusionplans', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
- 'position' => 1000 + $r,
- 'enabled' => 'isModEnabled("diffusionplans")', // Define condition to show or hide menu entry. Use 'isModEnabled("diffusionplans")' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
- 'perms' => '$user->hasRight("diffusionplans", "diffusion", "write")'
- 'target' => '',
- 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
- 'object' => 'Diffusion'
- );
- $this->menu[$r++]=array(
- 'fk_menu' => 'fk_mainmenu=diffusionplans,fk_leftmenu=diffusion', // '' 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
- 'titre' => 'List_Diffusion',
- 'mainmenu' => 'diffusionplans',
- 'leftmenu' => 'diffusionplans_diffusion_list',
- 'url' => '/diffusionplans/diffusion_list.php',
- 'langs' => 'diffusionplans@diffusionplans', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
- 'position' => 1000 + $r,
- 'enabled' => 'isModEnabled("diffusionplans")', // Define condition to show or hide menu entry. Use 'isModEnabled("diffusionplans")' if entry must be visible if module is enabled.
- 'perms' => '$user->hasRight("diffusionplans", "diffusion", "read")'
- 'target' => '',
- 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
- 'object' => 'Diffusion'
- );
- */
- /* END MODULEBUILDER LEFTMENU MYOBJECT */
-
-
- // Exports profiles provided by this module
- $r = 0;
- /* BEGIN MODULEBUILDER EXPORT MYOBJECT */
- /*
- $langs->load("diffusionplans@diffusionplans");
- $this->export_code[$r] = $this->rights_class.'_'.$r;
- $this->export_label[$r] = 'DiffusionLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->export_icon[$r] = $this->picto;
- // Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array
- $keyforclass = 'Diffusion'; $keyforclassfile='/diffusionplans/class/diffusion.class.php'; $keyforelement='diffusion@diffusionplans';
- include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
- //$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text';
- //unset($this->export_fields_array[$r]['t.fieldtoremove']);
- //$keyforclass = 'DiffusionLine'; $keyforclassfile='/diffusionplans/class/diffusion.class.php'; $keyforelement='diffusionline@diffusionplans'; $keyforalias='tl';
- //include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
- $keyforselect='diffusion'; $keyforaliasextra='extra'; $keyforelement='diffusion@diffusionplans';
- include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- //$keyforselect='diffusionline'; $keyforaliasextra='extraline'; $keyforelement='diffusionline@diffusionplans';
- //include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
- //$this->export_dependencies_array[$r] = array('diffusionline' => array('tl.rowid','tl.ref')); // 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_special_array[$r] = array('t.field' => '...');
- //$this->export_examplevalues_array[$r] = array('t.field' => 'Example');
- //$this->export_help_array[$r] = array('t.field' => 'FieldDescHelp');
- $this->export_sql_start[$r]='SELECT DISTINCT ';
- $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'diffusionplans_diffusion as t';
- //$this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'diffusionplans_diffusion_line as tl ON tl.fk_diffusion = t.rowid';
- $this->export_sql_end[$r] .=' WHERE 1 = 1';
- $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('diffusion').')';
- $r++; */
- /* END MODULEBUILDER EXPORT MYOBJECT */
-
- // Imports profiles provided by this module
- $r = 0;
- /* BEGIN MODULEBUILDER IMPORT MYOBJECT */
- /*
- $langs->load("diffusionplans@diffusionplans");
- $this->import_code[$r] = $this->rights_class.'_'.$r;
- $this->import_label[$r] = 'DiffusionLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
- $this->import_icon[$r] = $this->picto;
- $this->import_tables_array[$r] = array('t' => MAIN_DB_PREFIX.'diffusionplans_diffusion', 'extra' => MAIN_DB_PREFIX.'diffusionplans_diffusion_extrafields');
- $this->import_tables_creator_array[$r] = array('t' => 'fk_user_author'); // Fields to store import user id
- $import_sample = array();
- $keyforclass = 'Diffusion'; $keyforclassfile='/diffusionplans/class/diffusion.class.php'; $keyforelement='diffusion@diffusionplans';
- include DOL_DOCUMENT_ROOT.'/core/commonfieldsinimport.inc.php';
- $import_extrafield_sample = array();
- $keyforselect='diffusion'; $keyforaliasextra='extra'; $keyforelement='diffusion@diffusionplans';
- include DOL_DOCUMENT_ROOT.'/core/extrafieldsinimport.inc.php';
- $this->import_fieldshidden_array[$r] = array('extra.fk_object' => 'lastrowid-'.MAIN_DB_PREFIX.'diffusionplans_diffusion');
- $this->import_regex_array[$r] = array();
- $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample);
- $this->import_updatekeys_array[$r] = array('t.ref' => 'Ref');
- $this->import_convertvalue_array[$r] = array(
- 't.ref' => array(
- 'rule'=>'getrefifauto',
- 'class'=>(!getDolGlobalString('DIFFUSIONPLANS_MYOBJECT_ADDON') ? 'mod_diffusion_standard' : getDolGlobalString('DIFFUSIONPLANS_MYOBJECT_ADDON')),
- 'path'=>"/core/modules/diffusionplans/".(!getDolGlobalString('DIFFUSIONPLANS_MYOBJECT_ADDON') ? 'mod_diffusion_standard' : getDolGlobalString('DIFFUSIONPLANS_MYOBJECT_ADDON')).'.php',
- 'classobject'=>'Diffusion',
- 'pathobject'=>'/diffusionplans/class/diffusion.class.php',
- ),
- 't.fk_soc' => array('rule' => 'fetchidfromref', 'file' => '/societe/class/societe.class.php', 'class' => 'Societe', 'method' => 'fetch', 'element' => 'ThirdParty'),
- 't.fk_user_valid' => array('rule' => 'fetchidfromref', 'file' => '/user/class/user.class.php', 'class' => 'User', 'method' => 'fetch', 'element' => 'user'),
- 't.fk_mode_reglement' => array('rule' => 'fetchidfromcodeorlabel', 'file' => '/compta/paiement/class/cpaiement.class.php', 'class' => 'Cpaiement', 'method' => 'fetch', 'element' => 'cpayment'),
- );
- $this->import_run_sql_after_array[$r] = array();
- $r++; */
- /* END MODULEBUILDER IMPORT MYOBJECT */
- }
-
- /**
- * Function called when module is enabled.
- * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
- * It also creates data directories
- *
- * @param string $options Options when enabling module ('', 'noboxes')
- * @return int<-1,1> 1 if OK, <=0 if KO
- */
- public function init($options = '')
- {
- global $conf, $langs;
-
- // Create tables of module at module activation
- //$result = $this->_load_tables('/install/mysql/', 'diffusionplans');
- $result = $this->_load_tables('/diffusionplans/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')
- }
-
- // Create extrafields during init
- //include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
- //$extrafields = new ExtraFields($this->db);
- //$result0=$extrafields->addExtraField('diffusionplans_separator1', "Separator 1", 'separator', 1, 0, 'thirdparty', 0, 0, '', array('options'=>array(1=>1)), 1, '', 1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
- //$result1=$extrafields->addExtraField('diffusionplans_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
- //$result2=$extrafields->addExtraField('diffusionplans_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
- //$result3=$extrafields->addExtraField('diffusionplans_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
- //$result4=$extrafields->addExtraField('diffusionplans_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
- //$result5=$extrafields->addExtraField('diffusionplans_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
-
- // Permissions
- $this->remove($options);
-
- $sql = array();
-
- // Document templates
- $moduledir = dol_sanitizeFileName('diffusionplans');
- $myTmpObjects = array();
- $myTmpObjects['Diffusion'] = array('includerefgeneration' => 1, 'includedocgeneration' => 1);
-
- foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
- if ($myTmpObjectArray['includerefgeneration']) {
- $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/'.$moduledir.'/template_diffusions.odt';
- $dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/'.$moduledir;
- $dest = $dirodt.'/template_diffusions.odt';
-
- if (file_exists($src) && !file_exists($dest)) {
- require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
- dol_mkdir($dirodt);
- $result = dol_copy($src, $dest, '0', 0);
- if ($result < 0) {
- $langs->load("errors");
- $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest);
- return 0;
- }
- }
-
- $sql = array_merge($sql, array(
- "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'standard_".strtolower($myTmpObjectKey)."' AND type = '".$this->db->escape(strtolower($myTmpObjectKey))."' AND entity = ".((int) $conf->entity),
- "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('standard_".strtolower($myTmpObjectKey)."', '".$this->db->escape(strtolower($myTmpObjectKey))."', ".((int) $conf->entity).")",
- "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'generic_".strtolower($myTmpObjectKey)."_odt' AND type = '".$this->db->escape(strtolower($myTmpObjectKey))."' AND entity = ".((int) $conf->entity),
- "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('generic_".strtolower($myTmpObjectKey)."_odt', '".$this->db->escape(strtolower($myTmpObjectKey))."', ".((int) $conf->entity).")"
- ));
- }
- }
-
- 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,1> 1 if OK, <=0 if KO
- */
- public function remove($options = '')
- {
- $sql = array();
- return $this->_remove($sql, $options);
- }
-}
+
+ * Copyright (C) 2018-2019 Nicolas ZABOURI
+ * Copyright (C) 2019-2024 Frédéric France
+ * Copyright (C) 2025 Pierre ARDOIN
+ *
+ * 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 .
+ */
+
+/**
+ * \defgroup diffusionplans Module DiffusionPlans
+ * \brief DiffusionPlans module descriptor.
+ *
+ * \file htdocs/diffusionplans/core/modules/modDiffusionPlans.class.php
+ * \ingroup diffusionplans
+ * \brief Description and activation file for module DiffusionPlans
+ */
+include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
+
+
+/**
+ * Description and activation class for module DiffusionPlans
+ */
+class modDiffusionPlans extends DolibarrModules
+{
+ /**
+ * Constructor. Define names, constants, directories, boxes, permissions
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $conf, $langs;
+
+ $this->db = $db;
+
+ // Id for module (must be unique).
+ // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
+ $this->numero = 450001; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve an id number for your module
+
+ // Key text used to identify module (for permissions, menus, etc...)
+ $this->rights_class = 'diffusionplans';
+
+ // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
+ // It is used to group modules by family in module setup page
+ $this->family = "other";
+
+ // Module position in the family on 2 digits ('01', '10', '20', ...)
+ $this->module_position = '90';
+
+ // Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
+ //$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
+ // Module label (no space allowed), used if translation string 'ModuleDiffusionPlansName' not found (DiffusionPlans is name of module).
+ $this->name = preg_replace('/^mod/i', '', get_class($this));
+
+ // DESCRIPTION_FLAG
+ // Module description, used if translation string 'ModuleDiffusionPlansDesc' not found (DiffusionPlans is name of module).
+ $this->description = 'ModuleDiffusionsPlansDesc';
+ // Used only if file README.md and README-LL.md not found.
+ $this->descriptionlong = "DiffusionPlansDescription";
+
+ // Author
+ $this->editor_name = 'Les Métiers du Bâtiment';
+ $this->editor_url = 'lesmetiersdubatiment.fr'; // Must be an external online web site
+ $this->editor_squarred_logo = ''; // Must be image filename into the module/img directory followed with @modulename. Example: 'myimage.png@diffusionplans'
+
+ // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated', 'experimental_deprecated' or a version string like 'x.y.z'
+ $this->version = '1.0';
+ // Url to the file with your last numberversion of this module
+ //$this->url_last_version = 'http://www.example.com/versionmodule.txt';
+
+ // Key used in llx_const table to save module status enabled/disabled (where DIFFUSIONPLANS is value of property name of module in uppercase)
+ $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
+
+ if (!isset($conf->diffusionplans) || !is_object($conf->diffusionplans)) {
+ $conf->diffusionplans = new stdClass();
+ }
+
+ $entity = !empty($conf->entity) ? (int) $conf->entity : 1;
+ $defaultDir = DOL_DATA_ROOT.($entity > 1 ? '/'.$entity : '').'/diffusionplans';
+
+ if (empty($conf->diffusionplans->dir_output)) {
+ $conf->diffusionplans->dir_output = $defaultDir;
+ }
+ if (empty($conf->diffusionplans->dir_temp)) {
+ $conf->diffusionplans->dir_temp = $conf->diffusionplans->dir_output.'/temp';
+ }
+ if (empty($conf->diffusionplans->multidir_output) || !is_array($conf->diffusionplans->multidir_output)) {
+ $conf->diffusionplans->multidir_output = array();
+ }
+ if (empty($conf->diffusionplans->multidir_output[$entity])) {
+ $conf->diffusionplans->multidir_output[$entity] = $defaultDir;
+ }
+
+ $diffusionDir = $conf->diffusionplans->dir_output.'/diffusion';
+ if (!isset($conf->diffusion) || !is_object($conf->diffusion)) {
+ $conf->diffusion = new stdClass();
+ }
+ if (empty($conf->diffusion->dir_output)) {
+ $conf->diffusion->dir_output = $diffusionDir;
+ }
+ if (empty($conf->diffusion->multidir_output) || !is_array($conf->diffusion->multidir_output)) {
+ $conf->diffusion->multidir_output = array();
+ }
+ if (empty($conf->diffusion->multidir_output[$entity])) {
+ $conf->diffusion->multidir_output[$entity] = $diffusionDir;
+ }
+
+ $diffusionContactDir = $conf->diffusionplans->dir_output.'/diffusioncontact';
+ if (!isset($conf->diffusioncontact) || !is_object($conf->diffusioncontact)) {
+ $conf->diffusioncontact = new stdClass();
+ }
+ if (empty($conf->diffusioncontact->dir_output)) {
+ $conf->diffusioncontact->dir_output = $diffusionContactDir;
+ }
+ if (empty($conf->diffusioncontact->multidir_output) || !is_array($conf->diffusioncontact->multidir_output)) {
+ $conf->diffusioncontact->multidir_output = array();
+ }
+ if (empty($conf->diffusioncontact->multidir_output[$entity])) {
+ $conf->diffusioncontact->multidir_output[$entity] = $diffusionContactDir;
+ }
+
+ // 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 module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
+ // To use a supported fa-xxx css style of font awesome, use this->picto='xxx'
+ $this->picto = 'fa-paper-plane';
+
+ // Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
+ $this->module_parts = array(
+ // Set this to 1 if module has its own trigger directory (core/triggers)
+ 'triggers' => 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 substitution function file (core/substitutions)
+ 'substitutions' => 0,
+ // Set this to 1 if module has its own menus handler directory (core/menus)
+ 'menus' => 0,
+ // Set this to 1 if module overwrite template dir (core/tpl)
+ 'tpl' => 0,
+ // Set this to 1 if module has its own barcode directory (core/modules/barcode)
+ 'barcode' => 0,
+ // Set custom models directories (core/modules/xxx)
+ 'models' => array(
+ 'bordereaudoc' => array('dir' => '/diffusionplans/core/modules/bordereaudoc/'),
+ ),
+ // Set this to 1 if module has its own printing directory (core/modules/printing)
+ 'printing' => 0,
+ // Set this to 1 if module has its own theme directory (theme)
+ 'theme' => 0,
+ // Set this to relative path of css file if module has its own css file
+ 'css' => array(
+ // '/diffusionplans/css/diffusionplans.css.php',
+ ),
+ // Set this to relative path of js file if module must load a js on all pages
+ 'js' => array(
+ '/diffusionplans/js/diffusionplans.js.php',
+ ),
+ // 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 to 'all'
+ /* BEGIN MODULEBUILDER HOOKSCONTEXTS */
+ 'hooks' => array(
+ // 'data' => array(
+ // 'hookcontext1',
+ // 'hookcontext2',
+ // ),
+ // 'entity' => '0',
+ ),
+ /* END MODULEBUILDER HOOKSCONTEXTS */
+ // Set this to 1 if features of module are opened to external users
+ 'moduleforexternal' => 0,
+ // Set this to 1 if the module provides a website template into doctemplates/websites/website_template-mytemplate
+ 'websitetemplates' => 0,
+ // Set this to 1 if the module provides a captcha driver
+ 'captcha' => 0
+ );
+
+ // Data directories to create when module is enabled.
+ // Example: this->dirs = array("/diffusionplans/temp","/diffusionplans/subdir");
+ $this->dirs = array(
+ "/diffusionplans/temp",
+ "/diffusionplans/diffusion",
+ "/diffusionplans/diffusioncontact",
+ );
+
+ // Config pages. Put here list of php page, stored into diffusionplans/admin directory, to use to setup module.
+ $this->config_page_url = array("setup.php@diffusionplans");
+
+ // Dependencies
+ // A condition to hide module
+ $this->hidden = getDolGlobalInt('MODULE_DIFFUSIONPLANS_DISABLED'); // A condition to disable module;
+ // List of module class names that must be enabled if this module is enabled. Example: array('always'=>array('modModuleToEnable1','modModuleToEnable2'), 'FR'=>array('modModuleToEnableFR')...)
+ $this->depends = array('always'=>array('modProjet','modSociete'));
+ // List of module class names to disable if this one is disabled. Example: array('modModuleToDisable1', ...)
+ $this->requiredby = array();
+ // List of module class names this module is in conflict with. Example: array('modModuleToDisable1', ...)
+ $this->conflictwith = array();
+
+ // The language file dedicated to your module
+ $this->langfiles = array("diffusionplans@diffusionplans");
+
+ // Prerequisites
+ $this->phpmin = array(7, 1); // Minimum version of PHP required by module
+ $this->need_dolibarr_version = array(19, -3); // Minimum version of Dolibarr required by module
+ $this->need_javascript_ajax = 0;
+
+ // Messages at activation
+ $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','MX'='textmx'...)
+ $this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','MX'='textmx'...)
+ //$this->automatic_activation = array('FR'=>'DiffusionPlansWasAutomaticallyActivatedBecauseOfYourCountryChoice');
+ //$this->always_enabled = true; // If true, can't be disabled
+
+ // Constants
+ // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
+ // Example: $this->const=array(1 => array('DIFFUSIONPLANS_MYNEWCONST1', 'chaine', 'myvalue', 'This is a constant to add', 1),
+ // 2 => array('DIFFUSIONPLANS_MYNEWCONST2', 'chaine', 'myvalue', 'This is another constant to add', 0, 'current', 1)
+ // );
+ $i = 0;
+ $this->const = array(
+ $i++ => array('DIFFUSIONPLANS_DIFFUSION_ADDON', 'chaine', 'mod_diffusion_standard', '', 0, 'current'),
+ $i++ => array('DIFFUSIONPLANS_DIFFUSION_ADDON_ODT_PATH', 'chaine', 'DOL_DATA_ROOT/diffusionplans/diffusion/', '', 0, 'current'),
+ $i++ => array('DIFFUSIONPLANS_DIFFUSION_DEFAULT_MODEL', 'chaine', 'standard_diffusion', '', 0, 'current'),
+ $i++ => array('DIFFUSIONPLANS_BORDEREAU_REF_PREFIX', 'chaine', 'BRD', 'Prefix for bordereaudoc references', 0, 'current'),
+ $i++ => array('DIFFUSIONPLANS_BORDEREAU_DEFAULT_MODEL', 'chaine', 'standard', 'Default PDF model for bordereaudoc', 0, 'current'),
+ $i++ => array('DIFFUSIONPLANS_BORDEREAU_MAIL_TEMPLATE', 'chaine', '', 'Mail template code for bordereaudoc emails', 0, 'current'),
+ );
+
+ // Some keys to add into the overwriting translation tables
+ /*$this->overwrite_translation = array(
+ 'en_US:ParentCompany'=>'Parent company or reseller',
+ 'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
+ )*/
+
+ if (!isModEnabled("diffusionplans")) {
+ $conf->diffusionplans = new stdClass();
+ $conf->diffusionplans->enabled = 0;
+ }
+
+ // Array to add new pages in new tabs
+ /* BEGIN MODULEBUILDER TABS */
+ $this->tabs = array();
+ $this->tabs[] = array(
+ 'data'=>'project:+bordereaudoc:Bordereaudoc:diffusionplans@diffusionplans:$user->hasRight(\'diffusionplans\', \'bordereaudoc\', \'read\'):/diffusionplans/bordereaudoc_list.php?fk_project=__ID__',
+ );
+ /* END MODULEBUILDER TABS */
+ // Example:
+ // To add a new tab identified by code tabname1
+ // $this->tabs[] = array('data' => 'objecttype:+tabname1:Title1:mylangfile@diffusionplans:$user->hasRight(\'diffusionplans\', \'read\'):/diffusionplans/mynewtab1.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:+tabname2:SUBSTITUTION_Title2:mylangfile@diffusionplans:$user->hasRight(\'othermodule\', \'read\'):/diffusionplans/mynewtab2.php?id=__ID__',
+ // To remove an existing tab identified by code tabname
+ // $this->tabs[] = array('data' => 'objecttype:-tabname:NU:conditiontoremove');
+ //
+ // 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)
+ // 'contact' to add a tab in contact view
+ // 'contract' to add a tab in contract view
+ // 'delivery' to add a tab in delivery view
+ // 'group' to add a tab in group view
+ // 'intervention' to add a tab in intervention view
+ // 'invoice' to add a tab in customer invoice view
+ // 'invoice_supplier' to add a tab in supplier invoice view
+ // 'member' to add a tab in foundation member view
+ // 'opensurveypoll' to add a tab in opensurvey poll view
+ // 'order' to add a tab in sale order view
+ // 'order_supplier' to add a tab in supplier order view
+ // 'payment' to add a tab in payment view
+ // 'payment_supplier' to add a tab in supplier payment view
+ // 'product' to add a tab in product view
+ // 'propal' to add a tab in propal view
+ // 'project' to add a tab in project view
+ // 'stock' to add a tab in stock view
+ // 'thirdparty' to add a tab in third party view
+ // 'user' to add a tab in user view
+
+
+ // Dictionaries
+ /* Example:
+ $this->dictionaries=array(
+ 'langs' => 'diffusionplans@diffusionplans',
+ // List of tables we want to see into dictionary editor
+ 'tabname' => array("table1", "table2", "table3"),
+ // Label of tables
+ 'tablib' => array("Table1", "Table2", "Table3"),
+ // 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'),
+ // Sort order
+ 'tabsqlsort' => array("label ASC", "label ASC", "label ASC"),
+ // List of fields (result of select to show dictionary)
+ 'tabfield' => 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 for insert)
+ 'tabfieldinsert' => array("code,label", "code,label", "code,label"),
+ // Name of columns with primary key (try to always name it 'rowid')
+ 'tabrowid' => array("rowid", "rowid", "rowid"),
+ // Condition to show each dictionary
+ 'tabcond' => array(isModEnabled('diffusionplans'), isModEnabled('diffusionplans'), isModEnabled('diffusionplans')),
+ // Tooltip for every fields of dictionaries: DO NOT PUT AN EMPTY ARRAY
+ 'tabhelp' => array(array('code' => $langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip'), array('code' => $langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip'), ...),
+ );
+ */
+ /* BEGIN MODULEBUILDER DICTIONARIES */
+ $this->dictionaries = array();
+ /* END MODULEBUILDER DICTIONARIES */
+
+ // Boxes/Widgets
+ // Add here list of php file(s) stored in diffusionplans/core/boxes that contains a class to show a widget.
+ /* BEGIN MODULEBUILDER WIDGETS */
+ $this->boxes = array(
+ // 0 => array(
+ // 'file' => 'diffusionplanswidget1.php@diffusionplans',
+ // 'note' => 'Widget provided by DiffusionPlans',
+ // 'enabledbydefaulton' => 'Home',
+ // ),
+ // ...
+ );
+ /* END MODULEBUILDER WIDGETS */
+
+ // 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
+ /* BEGIN MODULEBUILDER CRON */
+ $this->cronjobs = array(
+ // 0 => array(
+ // 'label' => 'MyJob label',
+ // 'jobtype' => 'method',
+ // 'class' => '/diffusionplans/class/diffusion.class.php',
+ // 'objectname' => 'Diffusion',
+ // 'method' => 'doScheduledJob',
+ // 'parameters' => '',
+ // 'comment' => 'Comment',
+ // 'frequency' => 2,
+ // 'unitfrequency' => 3600,
+ // 'status' => 0,
+ // 'test' => 'isModEnabled("diffusionplans")',
+ // 'priority' => 50,
+ // ),
+ );
+ /* END MODULEBUILDER CRON */
+ // 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'=>'isModEnabled("diffusionplans")', 'priority'=>50),
+ // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'isModEnabled("diffusionplans")', 'priority'=>50)
+ // );
+
+// Permissions provided by this module
+ $this->rights = array();
+ $r = 0;
+// Add here entries to declare new permissions
+ /* BEGIN MODULEBUILDER PERMISSIONS */
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (0 * 10) + 0 + 1);
+ $this->rights[$r][1] = 'Read Diffusion object of DiffusionPlans';
+ $this->rights[$r][4] = 'diffusion';
+ $this->rights[$r][5] = 'read';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (0 * 10) + 1 + 1);
+ $this->rights[$r][1] = 'Create/Update Diffusion object of DiffusionPlans';
+ $this->rights[$r][4] = 'diffusion';
+ $this->rights[$r][5] = 'write';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (0 * 10) + 2 + 1);
+ $this->rights[$r][1] = 'Delete Diffusion object of DiffusionPlans';
+ $this->rights[$r][4] = 'diffusion';
+ $this->rights[$r][5] = 'delete';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (1 * 10) + 0 + 1);
+ $this->rights[$r][1] = 'Read DiffusionContact object of DiffusionPlans';
+ $this->rights[$r][4] = 'diffusioncontact';
+ $this->rights[$r][5] = 'read';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (1 * 10) + 1 + 1);
+ $this->rights[$r][1] = 'Create/Update DiffusionContact object of DiffusionPlans';
+ $this->rights[$r][4] = 'diffusioncontact';
+ $this->rights[$r][5] = 'write';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (1 * 10) + 2 + 1);
+ $this->rights[$r][1] = 'Delete DiffusionContact object of DiffusionPlans';
+ $this->rights[$r][4] = 'diffusioncontact';
+ $this->rights[$r][5] = 'delete';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (2 * 10) + 0 + 1);
+ $this->rights[$r][1] = 'Read Bordereaudoc object of DiffusionPlans';
+ $this->rights[$r][4] = 'bordereaudoc';
+ $this->rights[$r][5] = 'read';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (2 * 10) + 1 + 1);
+ $this->rights[$r][1] = 'Create/Update Bordereaudoc object of DiffusionPlans';
+ $this->rights[$r][4] = 'bordereaudoc';
+ $this->rights[$r][5] = 'write';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (2 * 10) + 2 + 1);
+ $this->rights[$r][1] = 'Validate Bordereaudoc object of DiffusionPlans';
+ $this->rights[$r][4] = 'bordereaudoc';
+ $this->rights[$r][5] = 'validate';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (2 * 10) + 3 + 1);
+ $this->rights[$r][1] = 'Send Bordereaudoc object of DiffusionPlans';
+ $this->rights[$r][4] = 'bordereaudoc';
+ $this->rights[$r][5] = 'send';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (2 * 10) + 4 + 1);
+ $this->rights[$r][1] = 'Set delivered Bordereaudoc of DiffusionPlans';
+ $this->rights[$r][4] = 'bordereaudoc';
+ $this->rights[$r][5] = 'set_diffuse';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (2 * 10) + 5 + 1);
+ $this->rights[$r][1] = 'Archive Bordereaudoc object of DiffusionPlans';
+ $this->rights[$r][4] = 'bordereaudoc';
+ $this->rights[$r][5] = 'archive';
+ $r++;
+ $this->rights[$r][0] = $this->numero . sprintf('%02d', (2 * 10) + 6 + 1);
+ $this->rights[$r][1] = 'Delete Bordereaudoc object of DiffusionPlans';
+ $this->rights[$r][4] = 'bordereaudoc';
+ $this->rights[$r][5] = 'delete';
+ $r++;
+
+ /* END MODULEBUILDER PERMISSIONS */
+
+
+ // Main menu entries to add
+ $this->menu = array();
+ $r = 0;
+ // Add here entries to declare new menus
+ /* BEGIN MODULEBUILDER TOPMENU */
+ $this->menu[$r++] = array(
+ 'fk_menu' => '', // Will be stored into mainmenu + leftmenu. Use '' 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
+ 'titre' => 'ModuleDiffusionPlansName',
+ 'prefix' => img_picto('', $this->picto, 'class="pictofixedwidth valignmiddle"'),
+ 'mainmenu' => 'diffusionplans',
+ 'leftmenu' => '',
+ 'url' => '/diffusionplans/diffusionplansindex.php',
+ 'langs' => 'diffusionplans@diffusionplans', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position' => 1000 + $r,
+ 'enabled' => 'isModEnabled("diffusionplans")', // Define condition to show or hide menu entry. Use 'isModEnabled("diffusionplans")' if entry must be visible if module is enabled.
+ 'perms' => '1', // Use 'perms'=>'$user->hasRight("diffusionplans", "diffusion", "read")' if you want your menu with a permission rules
+ 'target' => '',
+ 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
+ );
+ /* END MODULEBUILDER TOPMENU */
+
+
+
+/* BEGIN MODULEBUILDER LEFTMENU DIFFUSION */
+$this->menu[$r++] = array(
+'fk_menu' => 'fk_mainmenu=diffusionplans',
+'type' => 'left',
+'titre' => 'Diffusion',
+'mainmenu' => 'diffusionplans',
+'leftmenu' => 'diffusion',
+'url' => '/diffusionplans/bordereaudoc_list.php',
+'langs' => 'diffusionplans@diffusionplans',
+'position' => 1001,
+'enabled' => 'isModEnabled(\'diffusionplans\')',
+'perms' => '$user->hasRight(\'diffusionplans\', \'bordereaudoc\', \'read\')',
+'target' => '',
+'user' => 2,
+'object' => 'Bordereaudoc',
+);
+/* END MODULEBUILDER LEFTMENU DIFFUSION */
+/* BEGIN MODULEBUILDER LEFTMENU DIFFUSION */
+$this->menu[$r++] = array(
+'fk_menu' => 'fk_mainmenu=diffusionplans,fk_leftmenu=diffusion',
+'type' => 'left',
+'titre' => 'List Diffusion',
+'mainmenu' => 'diffusionplans',
+'leftmenu' => 'diffusionplans_diffusion_list',
+'url' => '/diffusionplans/bordereaudoc_list.php',
+'langs' => 'diffusionplans@diffusionplans',
+'position' => 1002,
+'enabled' => 'isModEnabled(\'diffusionplans\')',
+'perms' => '$user->hasRight(\'diffusionplans\', \'bordereaudoc\', \'read\')',
+'target' => '',
+'user' => 2,
+'object' => 'Bordereaudoc',
+);
+/* END MODULEBUILDER LEFTMENU DIFFUSION */
+/* BEGIN MODULEBUILDER LEFTMENU DIFFUSION */
+$this->menu[$r++] = array(
+'fk_menu' => 'fk_mainmenu=diffusionplans,fk_leftmenu=diffusion',
+'type' => 'left',
+'titre' => 'New Diffusion',
+'mainmenu' => 'diffusionplans',
+'leftmenu' => 'diffusionplans_diffusion_new',
+'url' => '/diffusionplans/bordereaudoc_card.php?action=create',
+'langs' => 'diffusionplans@diffusionplans',
+'position' => 1003,
+'enabled' => 'isModEnabled(\'diffusionplans\')',
+'perms' => '$user->hasRight(\'diffusionplans\', \'bordereaudoc\', \'write\')',
+'target' => '',
+'user' => 2,
+'object' => 'Bordereaudoc',
+);
+/* END MODULEBUILDER LEFTMENU DIFFUSION */
+
+ /* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */
+ /*
+ $this->menu[$r++]=array(
+ 'fk_menu' => 'fk_mainmenu=diffusionplans', // '' 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
+ 'titre' => 'Diffusion',
+ 'prefix' => img_picto('', $this->picto, 'class="pictofixedwidth valignmiddle paddingright"'),
+ 'mainmenu' => 'diffusionplans',
+ 'leftmenu' => 'diffusion',
+ 'url' => '/diffusionplans/diffusionplansindex.php',
+ 'langs' => 'diffusionplans@diffusionplans', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position' => 1000 + $r,
+ 'enabled' => 'isModEnabled("diffusionplans")', // Define condition to show or hide menu entry. Use 'isModEnabled("diffusionplans")' if entry must be visible if module is enabled.
+ 'perms' => '$user->hasRight("diffusionplans", "diffusion", "read")',
+ 'target' => '',
+ 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
+ 'object' => 'Bordereaudoc'
+ );
+ $this->menu[$r++]=array(
+ 'fk_menu' => 'fk_mainmenu=diffusionplans,fk_leftmenu=diffusion', // '' 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
+ 'titre' => 'New_Diffusion',
+ 'mainmenu' => 'diffusionplans',
+ 'leftmenu' => 'diffusionplans_diffusion_new',
+'url' => '/diffusionplans/bordereaudoc_card.php?action=create',
+ 'langs' => 'diffusionplans@diffusionplans', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position' => 1000 + $r,
+ 'enabled' => 'isModEnabled("diffusionplans")', // Define condition to show or hide menu entry. Use 'isModEnabled("diffusionplans")' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
+ 'perms' => '$user->hasRight("diffusionplans", "diffusion", "write")'
+ 'target' => '',
+ 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
+ 'object' => 'Bordereaudoc'
+ );
+ $this->menu[$r++]=array(
+ 'fk_menu' => 'fk_mainmenu=diffusionplans,fk_leftmenu=diffusion', // '' 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
+ 'titre' => 'List_Diffusion',
+ 'mainmenu' => 'diffusionplans',
+ 'leftmenu' => 'diffusionplans_diffusion_list',
+ 'url' => '/diffusionplans/diffusion_list.php',
+ 'langs' => 'diffusionplans@diffusionplans', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position' => 1000 + $r,
+ 'enabled' => 'isModEnabled("diffusionplans")', // Define condition to show or hide menu entry. Use 'isModEnabled("diffusionplans")' if entry must be visible if module is enabled.
+ 'perms' => '$user->hasRight("diffusionplans", "diffusion", "read")'
+ 'target' => '',
+ 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
+ 'object' => 'Bordereaudoc'
+ );
+ */
+ /* END MODULEBUILDER LEFTMENU MYOBJECT */
+
+
+ // Exports profiles provided by this module
+ $r = 0;
+ /* BEGIN MODULEBUILDER EXPORT MYOBJECT */
+ /*
+ $langs->load("diffusionplans@diffusionplans");
+ $this->export_code[$r] = $this->rights_class.'_'.$r;
+ $this->export_label[$r] = 'DiffusionLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->export_icon[$r] = $this->picto;
+ // Define $this->export_fields_array, $this->export_TypeFields_array and $this->export_entities_array
+ $keyforclass = 'Diffusion'; $keyforclassfile='/diffusionplans/class/diffusion.class.php'; $keyforelement='diffusion@diffusionplans';
+ include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
+ //$this->export_fields_array[$r]['t.fieldtoadd']='FieldToAdd'; $this->export_TypeFields_array[$r]['t.fieldtoadd']='Text';
+ //unset($this->export_fields_array[$r]['t.fieldtoremove']);
+ //$keyforclass = 'DiffusionLine'; $keyforclassfile='/diffusionplans/class/diffusion.class.php'; $keyforelement='diffusionline@diffusionplans'; $keyforalias='tl';
+ //include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
+ $keyforselect='diffusion'; $keyforaliasextra='extra'; $keyforelement='diffusion@diffusionplans';
+ include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
+ //$keyforselect='diffusionline'; $keyforaliasextra='extraline'; $keyforelement='diffusionline@diffusionplans';
+ //include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
+ //$this->export_dependencies_array[$r] = array('diffusionline' => array('tl.rowid','tl.ref')); // 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_special_array[$r] = array('t.field' => '...');
+ //$this->export_examplevalues_array[$r] = array('t.field' => 'Example');
+ //$this->export_help_array[$r] = array('t.field' => 'FieldDescHelp');
+ $this->export_sql_start[$r]='SELECT DISTINCT ';
+ $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'diffusionplans_diffusion as t';
+ //$this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'diffusionplans_diffusion_line as tl ON tl.fk_diffusion = t.rowid';
+ $this->export_sql_end[$r] .=' WHERE 1 = 1';
+ $this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('diffusion').')';
+ $r++; */
+ /* END MODULEBUILDER EXPORT MYOBJECT */
+
+ // Imports profiles provided by this module
+ $r = 0;
+ /* BEGIN MODULEBUILDER IMPORT MYOBJECT */
+ /*
+ $langs->load("diffusionplans@diffusionplans");
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = 'DiffusionLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
+ $this->import_icon[$r] = $this->picto;
+ $this->import_tables_array[$r] = array('t' => MAIN_DB_PREFIX.'diffusionplans_diffusion', 'extra' => MAIN_DB_PREFIX.'diffusionplans_diffusion_extrafields');
+ $this->import_tables_creator_array[$r] = array('t' => 'fk_user_author'); // Fields to store import user id
+ $import_sample = array();
+ $keyforclass = 'Diffusion'; $keyforclassfile='/diffusionplans/class/diffusion.class.php'; $keyforelement='diffusion@diffusionplans';
+ include DOL_DOCUMENT_ROOT.'/core/commonfieldsinimport.inc.php';
+ $import_extrafield_sample = array();
+ $keyforselect='diffusion'; $keyforaliasextra='extra'; $keyforelement='diffusion@diffusionplans';
+ include DOL_DOCUMENT_ROOT.'/core/extrafieldsinimport.inc.php';
+ $this->import_fieldshidden_array[$r] = array('extra.fk_object' => 'lastrowid-'.MAIN_DB_PREFIX.'diffusionplans_diffusion');
+ $this->import_regex_array[$r] = array();
+ $this->import_examplevalues_array[$r] = array_merge($import_sample, $import_extrafield_sample);
+ $this->import_updatekeys_array[$r] = array('t.ref' => 'Ref');
+ $this->import_convertvalue_array[$r] = array(
+ 't.ref' => array(
+ 'rule'=>'getrefifauto',
+ 'class'=>(!getDolGlobalString('DIFFUSIONPLANS_MYOBJECT_ADDON') ? 'mod_diffusion_standard' : getDolGlobalString('DIFFUSIONPLANS_MYOBJECT_ADDON')),
+ 'path'=>"/core/modules/diffusionplans/".(!getDolGlobalString('DIFFUSIONPLANS_MYOBJECT_ADDON') ? 'mod_diffusion_standard' : getDolGlobalString('DIFFUSIONPLANS_MYOBJECT_ADDON')).'.php',
+ 'classobject'=>'Diffusion',
+ 'pathobject'=>'/diffusionplans/class/diffusion.class.php',
+ ),
+ 't.fk_soc' => array('rule' => 'fetchidfromref', 'file' => '/societe/class/societe.class.php', 'class' => 'Societe', 'method' => 'fetch', 'element' => 'ThirdParty'),
+ 't.fk_user_valid' => array('rule' => 'fetchidfromref', 'file' => '/user/class/user.class.php', 'class' => 'User', 'method' => 'fetch', 'element' => 'user'),
+ 't.fk_mode_reglement' => array('rule' => 'fetchidfromcodeorlabel', 'file' => '/compta/paiement/class/cpaiement.class.php', 'class' => 'Cpaiement', 'method' => 'fetch', 'element' => 'cpayment'),
+ );
+ $this->import_run_sql_after_array[$r] = array();
+ $r++; */
+ /* END MODULEBUILDER IMPORT MYOBJECT */
+ }
+
+ /**
+ * Function called when module is enabled.
+ * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
+ * It also creates data directories
+ *
+ * @param string $options Options when enabling module ('', 'noboxes')
+ * @return int<-1,1> 1 if OK, <=0 if KO
+ */
+ public function init($options = '')
+ {
+ global $conf, $langs;
+
+ // Create tables of module at module activation
+ //$result = $this->_load_tables('/install/mysql/', 'diffusionplans');
+ $result = $this->_load_tables('/diffusionplans/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')
+ }
+
+ // Create extrafields during init
+ //include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+ //$extrafields = new ExtraFields($this->db);
+ //$result0=$extrafields->addExtraField('diffusionplans_separator1', "Separator 1", 'separator', 1, 0, 'thirdparty', 0, 0, '', array('options'=>array(1=>1)), 1, '', 1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
+ //$result1=$extrafields->addExtraField('diffusionplans_myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
+ //$result2=$extrafields->addExtraField('diffusionplans_myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
+ //$result3=$extrafields->addExtraField('diffusionplans_myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
+ //$result4=$extrafields->addExtraField('diffusionplans_myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
+ //$result5=$extrafields->addExtraField('diffusionplans_myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', -1, 0, '', '', 'diffusionplans@diffusionplans', 'isModEnabled("diffusionplans")');
+
+ // Permissions
+ $this->remove($options);
+
+ $sql = array();
+
+ // Document templates
+ $moduledir = dol_sanitizeFileName('diffusionplans');
+ $myTmpObjects = array();
+ $myTmpObjects['Diffusion'] = array('includerefgeneration' => 1, 'includedocgeneration' => 1);
+ $myTmpObjects['Bordereaudoc'] = array('includerefgeneration' => 1, 'includedocgeneration' => 1);
+
+ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
+ if ($myTmpObjectArray['includerefgeneration']) {
+ $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/'.$moduledir.'/template_diffusions.odt';
+ $dirodt = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/doctemplates/'.$moduledir;
+ $dest = $dirodt.'/template_diffusions.odt';
+
+ if (file_exists($src) && !file_exists($dest)) {
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+ dol_mkdir($dirodt);
+ $result = dol_copy($src, $dest, '0', 0);
+ if ($result < 0) {
+ $langs->load("errors");
+ $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest);
+ return 0;
+ }
+ }
+
+ $sql = array_merge($sql, array(
+ "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'standard_".strtolower($myTmpObjectKey)."' AND type = '".$this->db->escape(strtolower($myTmpObjectKey))."' AND entity = ".((int) $conf->entity),
+ "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('standard_".strtolower($myTmpObjectKey)."', '".$this->db->escape(strtolower($myTmpObjectKey))."', ".((int) $conf->entity).")",
+ "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'generic_".strtolower($myTmpObjectKey)."_odt' AND type = '".$this->db->escape(strtolower($myTmpObjectKey))."' AND entity = ".((int) $conf->entity),
+ "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('generic_".strtolower($myTmpObjectKey)."_odt', '".$this->db->escape(strtolower($myTmpObjectKey))."', ".((int) $conf->entity).")"
+ ));
+ }
+ }
+
+ 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,1> 1 if OK, <=0 if KO
+ */
+ public function remove($options = '')
+ {
+ $sql = array();
+ return $this->_remove($sql, $options);
+ }
+}
diff --git a/diffusion_agenda.php b/diffusion_agenda.php
deleted file mode 100644
index 279a3cc..0000000
--- a/diffusion_agenda.php
+++ /dev/null
@@ -1,347 +0,0 @@
-
- * Copyright (C) 2024 Frédéric France
- * Copyright (C) 2025 Pierre ARDOIN
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-/**
- * \file diffusion_agenda.php
- * \ingroup diffusionplans
- * \brief Tab of events on Diffusion
- */
-
-//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db
-//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user
-//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs
-//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters
-//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data
-//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu
-//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php
-//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library
-//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too.
-//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value
-//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
-//if (! defined("MAIN_SECURITY_FORCECSP")) define('MAIN_SECURITY_FORCECSP', 'none'); // Disable all Content Security Policies
-//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
-//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
-
-// 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");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
-dol_include_once('/diffusionplans/class/diffusion.class.php');
-dol_include_once('/diffusionplans/lib/diffusionplans_diffusion.lib.php');
-
-/**
- * @var Conf $conf
- * @var DoliDB $db
- * @var HookManager $hookmanager
- * @var Translate $langs
- * @var User $user
- */
-
-// Load translation files required by the page
-$langs->loadLangs(array("diffusionplans@diffusionplans", "other"));
-
-// Get parameters
-$id = GETPOSTINT('id');
-$ref = GETPOST('ref', 'alpha');
-$action = GETPOST('action', 'aZ09');
-$cancel = GETPOST('cancel', 'aZ09');
-$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
-$backtopage = GETPOST('backtopage', 'alpha');
-
-if (GETPOST('actioncode', 'array')) {
- $actioncode = GETPOST('actioncode', 'array', 3);
- if (!count($actioncode)) {
- $actioncode = '0';
- }
-} else {
- $actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
-}
-$search_rowid = GETPOST('search_rowid');
-$search_agenda_label = GETPOST('search_agenda_label');
-
-$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
-if (empty($page) || $page == -1) {
- $page = 0;
-} // If $page is not defined, or '' or -1
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-if (!$sortfield) {
- $sortfield = 'a.datep,a.id';
-}
-if (!$sortorder) {
- $sortorder = 'DESC,DESC';
-}
-
-// Initialize a technical objects
-$object = new Diffusion($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->diffusionplans->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array($object->element.'agenda', 'globalcard')); // Note that conf->hooks_modules contains array
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-
-// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'. Include fetch and fetch_thirdparty but not fetch_optionals
-if ($id > 0 || !empty($ref)) {
- $upload_dir = $conf->diffusionplans->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity]."/".$object->id;
-}
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = getDolGlobalInt('DIFFUSIONPLANS_ENABLE_PERMISSION_CHECK');
-if ($enablepermissioncheck) {
- $permissiontoread = $user->hasRight('diffusionplans', 'diffusion', 'read');
- $permissiontoadd = $user->hasRight('diffusionplans', 'diffusion', 'write');
-} else {
- $permissiontoread = 1;
- $permissiontoadd = 1;
-}
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("diffusionplans")) {
- accessforbidden();
-}
-if (!$permissiontoread) {
- accessforbidden();
-}
-
-
-/*
- * Actions
- */
-
-$parameters = array('id' => $id);
-$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
-if ($reshook < 0) {
- setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-}
-
-if (empty($reshook)) {
- // Cancel
- if (GETPOST('cancel', 'alpha') && !empty($backtopage)) {
- header("Location: ".$backtopage);
- exit;
- }
-
- // Purge search criteria
- if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
- $actioncode = '';
- $search_agenda_label = '';
- }
-}
-
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-if ($object->id > 0) {
- $title = $langs->trans("Diffusion")." - ".$langs->trans('Agenda');
- //$title = $object->ref." - ".$langs->trans("Agenda");
- $help_url = 'EN:Module_Agenda_En|DE:Modul_Terminplanung';
-
- llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-diffusionplans page-card_agenda');
-
- if (isModEnabled('notification')) {
- $langs->load("mails");
- }
- $head = diffusionPrepareHead($object);
-
-
- print dol_get_fiche_head($head, 'agenda', $langs->trans("Diffusion"), -1, $object->picto);
-
- // Object card
- // ------------------------------------------------------------
- $linkback = ''.$langs->trans("BackToList").'';
-
- $morehtmlref = '';
- /*
- // Ref customer
- $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
- $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
- // Thirdparty
- $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
- // Project
- if (isModEnabled('project')) {
- $langs->load("projects");
- $morehtmlref.='
'.$langs->trans('Project') . ' ';
- if ($permissiontoadd) {
- if ($action != 'classify') {
- //$morehtmlref.='
' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : ';
- }
- $morehtmlref.=' : ';
- if ($action == 'classify') {
- //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
- $morehtmlref.='
';
- } else {
- $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
- }
- } else {
- if (!empty($object->fk_project)) {
- $proj = new Project($db);
- $proj->fetch($object->fk_project);
- $morehtmlref .= ': '.$proj->getNomUrl();
- } else {
- $morehtmlref .= '';
- }
- }
- }*/
- $morehtmlref .= '
';
-
-
- dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
- print '';
- print '
';
-
- $object->info($object->id);
- dol_print_object_info($object, 1);
-
- print '
';
-
- print dol_get_fiche_end();
-
-
-
- // Actions buttons
-
- $objthirdparty = $object;
- $objcon = new stdClass();
-
- $out = '&origin='.urlencode($object->element.(property_exists($object, 'module') ? '@'.$object->module : '')).'&originid='.urlencode((string) $object->id);
- $urlbacktopage = $_SERVER['PHP_SELF'].'?id='.$object->id;
- $out .= '&backtopage='.urlencode($urlbacktopage);
- $permok = $user->hasRight('agenda', 'myactions', 'create');
- if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) {
- //$out.='trans("AddAnAction"),'filenew');
- //$out.="";
- }
-
- $morehtmlright = '';
-
- //$messagingUrl = DOL_URL_ROOT.'/societe/messaging.php?socid='.$object->id;
- //$morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1);
- //$messagingUrl = DOL_URL_ROOT.'/societe/agenda.php?socid='.$object->id;
- //$morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 2);
-
- if (isModEnabled('agenda')) {
- if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
- $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out);
- } else {
- $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out, '', 0);
- }
- }
-
-
- if (isModEnabled('agenda') && ($user->hasRight('agenda', 'myactions', 'read') || $user->hasRight('agenda', 'allactions', 'read'))) {
- print '
';
-
- $param = '&id='.$object->id.(!empty($socid) ? '&socid='.$socid : '');
- if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
- $param .= '&contextpage='.urlencode($contextpage);
- }
- if ($limit > 0 && $limit != $conf->liste_limit) {
- $param .= '&limit='.((int) $limit);
- }
-
- // Try to know count of actioncomm from cache
- $nbEvent = 0;
- //require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
- //$cachekey = 'count_events_diffusion_'.$object->id;
- //$nbEvent = dol_getcache($cachekey);
- $titlelist = $langs->trans("Actions").(is_numeric($nbEvent) ? '('.$nbEvent.')' : '');
- if (!empty($conf->dol_optimize_smallscreen)) {
- $titlelist = $langs->trans("Actions").(is_numeric($nbEvent) ? '('.$nbEvent.')' : '');
- }
-
- print_barre_liste($titlelist, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 0);
-
- // List of all actions
- $filters = array();
- $filters['search_agenda_label'] = $search_agenda_label;
- $filters['search_rowid'] = $search_rowid;
-
- // TODO Replace this with same code than into list.php
- show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, property_exists($object, 'module') ? $object->module : '');
- }
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/diffusion_card.php b/diffusion_card.php
deleted file mode 100644
index 585b5ab..0000000
--- a/diffusion_card.php
+++ /dev/null
@@ -1,814 +0,0 @@
-
- * Copyright (C) 2024 Frédéric France
- * Copyright (C) 2025 Pierre ARDOIN
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-/**
- * \file diffusion_card.php
- * \ingroup diffusionplans
- * \brief Page to create/edit/view diffusion
- */
-
-
-// General defined Options
-//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
-//if (! defined('MAIN_AUTHENTICATION_MODE')) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
-//if (! defined('MAIN_LANG_DEFAULT')) define('MAIN_LANG_DEFAULT', 'auto'); // Force LANG (language) to a particular value
-//if (! defined('MAIN_SECURITY_FORCECSP')) define('MAIN_SECURITY_FORCECSP', 'none'); // Disable all Content Security Policies
-//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
-//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined('NOLOGIN')) define('NOLOGIN', '1'); // Do not use login - if this page is public (can be called outside logged session). This includes the NOIPCHECK too.
-//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library
-//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db
-//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // Do not load html.form.class.php
-//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // Do not load and show top and left menu
-//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs
-//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user
-//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters
-//if (! defined('NOSESSION')) define('NOSESSION', '1'); // On CLI mode, no need to use web sessions
-//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data
-//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-
-
-// 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");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
-require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-
-
-dol_include_once('/diffusionplans/class/diffusion.class.php');
-dol_include_once('/diffusionplans/class/diffusioncontact.class.php');
-dol_include_once('/diffusionplans/lib/diffusionplans_diffusion.lib.php');
-
-/**
- * @var Conf $conf
- * @var DoliDB $db
- * @var HookManager $hookmanager
- * @var Societe $mysoc
- * @var Translate $langs
- * @var User $user
- */
-
-// Load translation files required by the page
-$langs->loadLangs(array("diffusionplans@diffusionplans", "other"));
-
-// Get parameters
-$id = GETPOSTINT('id');
-$ref = GETPOST('ref', 'alpha');
-$lineid = GETPOSTINT('lineid');
-
-$action = GETPOST('action', 'aZ09');
-$confirm = GETPOST('confirm', 'alpha');
-$cancel = GETPOST('cancel', 'aZ09');
-$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
-$backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
-$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
-$backtopagejsfields = GETPOST('backtopagejsfields', 'alpha');
-$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
-$dol_openinpopup = GETPOST('dol_openinpopup', 'aZ09');
-
-
-if (!empty($backtopagejsfields)) {
- $tmpbacktopagejsfields = explode(':', $backtopagejsfields);
- $dol_openinpopup = preg_replace('/[^a-z0-9_]/i', '', $tmpbacktopagejsfields[0]);
-}
-
-// Initialize a technical objects
-$object = new Diffusion($db);
-
-$diffusion_project = new Project($db);
-
-$extrafields = new ExtraFields($db);
-
-$object->dir_output = $conf->monmodule->dir_output . '/' . dol_sanitizeFileName($object->ref);
-$diroutputmassaction = $conf->diffusionplans->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array($object->element.'card', 'globalcard')); // Note that conf->hooks_modules contains array
-$soc = null;
-
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-
-
-$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
-
-// Initialize array of search criteria
-$search_all = trim(GETPOST("search_all", 'alpha'));
-$search = array();
-foreach ($object->fields as $key => $val) {
- if (GETPOST('search_'.$key, 'alpha')) {
- $search[$key] = GETPOST('search_'.$key, 'alpha');
- }
-}
-
-if (empty($action) && empty($id) && empty($ref)) {
- $action = 'view';
-}
-
-// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'.
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = getDolGlobalInt('DIFFUSIONPLANS_ENABLE_PERMISSION_CHECK');
-if ($enablepermissioncheck) {
- $permissiontoread = $user->hasRight('diffusionplans', 'diffusion', 'read');
- $permissiontoadd = $user->hasRight('diffusionplans', 'diffusion', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
- $permissiontodelete = $user->hasRight('diffusionplans', 'diffusion', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
- $permissionnote = $user->hasRight('diffusionplans', 'diffusion', 'write'); // Used by the include of actions_setnotes.inc.php
- $permissiondellink = $user->hasRight('diffusionplans', 'diffusion', 'write'); // Used by the include of actions_dellink.inc.php
-} else {
- $permissiontoread = 1;
- $permissiontoadd = 1; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
- $permissiontodelete = 1;
- $permissionnote = 1;
- $permissiondellink = 1;
-}
-
-$upload_dir = $conf->diffusionplans->multidir_output[isset($object->entity) ? $object->entity : 1].'/diffusion';
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-$isdraft = (isset($object->status) && ($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled($object->module)) {
- accessforbidden("Module ".$object->module." not enabled");
-}
-if (!$permissiontoread) {
- accessforbidden();
-}
-
-$error = 0;
-
-
-/*
- * Actions
- */
-
-$parameters = array();
-$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
-if ($reshook < 0) {
- setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-}
-
-if (empty($reshook)) {
- $backurlforlist = dol_buildpath('/diffusionplans/diffusion_list.php', 1);
-
- if (empty($backtopage) || ($cancel && empty($id))) {
- if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
- if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
- $backtopage = $backurlforlist;
- } else {
- $backtopage = dol_buildpath('/diffusionplans/diffusion_card.php', 1).'?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
- }
- }
- }
-
- $triggermodname = 'DIFFUSIONPLANS_DIFFUSION_MODIFY'; // Name of trigger action code to execute when we modify record
-
- // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
- include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
-
- // Actions when linking object each other
- include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
-
- // Actions when printing a doc from card
- include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
-
- // Action to move up and down lines of object
- //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';
-
- // Action to build doc
- include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
-
- if ($action == 'set_thirdparty' && $permissiontoadd) {
- $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname);
- }
- if ($action == 'classin' && $permissiontoadd) {
- $object->setProject(GETPOSTINT('projectid'));
- }
-
- // Actions to send emails
- $triggersendname = 'DIFFUSIONPLANS_DIFFUSION_SENTBYMAIL';
- $autocopy = 'MAIN_MAIL_AUTOCOPY_DIFFUSION_TO';
- $trackid = 'diffusion'.$object->id;
- include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
-}
-
-/*
- * Add a new contact
- */
-
-if ($action == 'addcontact' && $permissiontoadd) {
- $contactid = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
- $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
- $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
- if ($result >= 0) {
- $diffusioncontactstatic = new DiffusionContact($db);
-
- $resql = $diffusioncontactstatic->create($object->id, $contactid, GETPOST("source", 'aZ09'));
- //var_dump("Contact ID : ".$result);
- header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
- exit;
- } else {
- if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
- $langs->load("errors");
- setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
- } else {
- setEventMessages($object->error, $object->errors, 'errors');
- }
- }
-} elseif ($action == 'swapstatut' && $permissiontoadd) {
- // Toggle the status of a contact
- $result = $object->swapContactStatus(GETPOSTINT('ligne'));
-} elseif ($action == 'deletecontact' && $permissiontoadd) { // Permission to add on object because this is an update of a link of object, not a deletion of data
- // Deletes a contact
- $contactid = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
- $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
- $result = $object->delete_contact($lineid);
-
- if ($result >= 0) {
-
- $diffusioncontactstatic = new DiffusionContact($db);
-
- $deletediffusioncontact = $diffusioncontactstatic->deleteLine($object->id, $contactid, GETPOST("source", 'aZ09'));
-
- header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
- exit;
- } else {
- dol_print_error($db);
- }
-} elseif ($action == 'add' && $usercancreate) {
- //$db->begin();
- $object->ref = GETPOST('ref');
- $object->label = GETPOST('label');
- $object->fk_project = GETPOSTINT('projectid');
- $object->description = GETPOST('description', 'restricthtml');
-
- var_dump($object->fk_project);
- //$id = $object->create($user, $db);
-}
-
-/*
- * View
- */
-
-$form = new Form($db);
-$formfile = new FormFile($db);
-$formproject = new FormProjets($db);
-
-//$title = $langs->trans("Diffusion")." - ".$langs->trans('Card');
-$title = $object->ref." - ".$langs->trans('Card');
-if ($action == 'create') {
- $title = $langs->trans("NewDiffusion", $langs->transnoentitiesnoconv("Diffusion"));
-}
-$help_url = '';
-
-llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-diffusionplans page-card');
-
-// Example : Adding jquery code
-// print '';
-
-
-// Part to create
-if ($action == 'create') {
- if (empty($permissiontoadd)) {
- accessforbidden('NotEnoughPermissions', 0, 1);
- }
-
- print load_fiche_titre($title, '', $object->picto);
-
- print '';
-
- //dol_set_focus('input[name="ref"]');
-}
-
-// Part to edit record
-if (($id || $ref) && $action == 'edit') {
- print load_fiche_titre($langs->trans("Diffusion"), '', $object->picto);
-
- print '';
-}
-
-// Part to show record
-if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
- $head = diffusionPrepareHead($object);
-
- print dol_get_fiche_head($head, 'card', $langs->trans("Diffusion"), -1, $object->picto, 0, '', '', 0, '', 1);
-
- $formconfirm = '';
-
- // Confirmation to delete (using preloaded confirm popup)
- if ($action == 'delete' || ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile))) {
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteDiffusion'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 'action-delete');
- }
- // Confirmation to delete line
- if ($action == 'deleteline') {
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
- }
-
- // Clone confirmation
- if ($action == 'clone') {
- // Create an array for form
- $formquestion = array();
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
- }
-
- // Confirmation of action xxxx (You can use it for xxx = 'close', xxx = 'reopen', ...)
- if ($action == 'xxx') {
- $text = $langs->trans('ConfirmActionXxx', $object->ref);
- /*if (isModEnabled('notification'))
- {
- require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
- $notify = new Notify($db);
- $text .= '
';
- $text .= $notify->confirmMessage('DIFFUSION_CLOSE', $object->socid, $object);
- }*/
-
- $formquestion = array();
-
- /*
- $forcecombo=0;
- if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
- $formquestion = array(
- // 'text' => $langs->trans("ConfirmClone"),
- // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
- // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
- // array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
- );
- */
- $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220);
- }
-
- // Call Hook formConfirm
- $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
- $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- if (empty($reshook)) {
- $formconfirm .= $hookmanager->resPrint;
- } elseif ($reshook > 0) {
- $formconfirm = $hookmanager->resPrint;
- }
-
- // Print form confirm
- print $formconfirm;
-
-
- // Object card
- // ------------------------------------------------------------
- $linkback = ''.$langs->trans("BackToList").'';
-
- $morehtmlref = '';
- /*
- // Ref customer
- $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', 0, 1);
- $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string'.(getDolGlobalInt('THIRDPARTY_REF_INPUT_SIZE') ? ':'.getDolGlobalInt('THIRDPARTY_REF_INPUT_SIZE') : ''), '', null, null, '', 1);
- // Thirdparty
- $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1, 'customer');
- if (!getDolGlobalInt('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
- $morehtmlref .= ' (
'.$langs->trans("OtherOrders").')';
- }
- // Project
- if (isModEnabled('project')) {
- $langs->load("projects");
- $morehtmlref .= '
';
- if ($permissiontoadd) {
- $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
- if ($action != 'classify') {
- $morehtmlref .= '
'.img_edit($langs->transnoentitiesnoconv('SetProject')).' ';
- }
- $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
- } else {
- if (!empty($object->fk_project)) {
- $proj = new Project($db);
- $proj->fetch($object->fk_project);
- $morehtmlref .= $proj->getNomUrl(1);
- if ($proj->title) {
- $morehtmlref .= '
- '.dol_escape_htmltag($proj->title).'';
- }
- }
- }
- }
- */
- $morehtmlref .= '
';
-
-
- dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
-
- print '';
- print '
';
- print '
';
- print '
'."\n";
-
- $fieldsBackup = $object->fields;
- $labelFieldDef = isset($object->fields['label']) ? $object->fields['label'] : null;
- $descriptionFieldDef = isset($object->fields['description']) ? $object->fields['description'] : null;
- if ($labelFieldDef !== null) {
- unset($object->fields['label']);
- }
- if ($descriptionFieldDef !== null) {
- unset($object->fields['description']);
- }
-
- $inlineEditable = ($permissiontoadd && $object->status == $object::STATUS_DRAFT);
-
- if ($labelFieldDef !== null) {
- $valueClasses = array('valuefield');
- if (!empty($labelFieldDef['cssview'])) {
- $valueClasses[] = $labelFieldDef['cssview'];
- }
- $valueClassAttr = implode(' ', array_unique(array_filter($valueClasses)));
-
- print ''; // Label row
- print '| '.$form->editfieldkey($labelFieldDef['label'], 'label', '', $object, $inlineEditable, 'string').' | ';
- print ''.$form->editfieldval($labelFieldDef['label'], 'label', $object->label, $object, $inlineEditable, 'string', '', null, null, '', 1).' | ';
- print '
';
- }
-
- if ($descriptionFieldDef !== null) {
- $descValueClasses = array('valuefield', 'wordbreak');
- if (!empty($descriptionFieldDef['cssview'])) {
- $descValueClasses[] = $descriptionFieldDef['cssview'];
- }
- $descValueClassAttr = implode(' ', array_unique(array_filter($descValueClasses)));
-
- print '';
- print '| '.$form->editfieldkey($descriptionFieldDef['label'], 'description', '', $object, $inlineEditable, 'textarea').' | ';
- print ''.$form->editfieldval($descriptionFieldDef['label'], 'description', $object->description, $object, $inlineEditable, 'textarea:100:6', '', null, null, '', 1).' | ';
- print '
';
- }
-
- // Common attributes
- //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field
- //unset($object->fields['fk_project']); // Hide field already shown in banner
- //unset($object->fields['fk_soc']); // Hide field already shown in banner
- include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
-
- $object->fields = $fieldsBackup;
-
- // Other attributes. Fields from hook formObjectOptions and Extrafields.
- include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
-
- print '
';
- print '
';
- print '
';
-
- print '';
-
- print dol_get_fiche_end();
-
-
- /*
- * Lines
- */
-
- include './tpl/diffusion_contacts.tpl.php';
-
- if (!empty($object->table_element_line)) {
- // Show object lines
- $result = $object->getLinesArray();
-
- print ' \n";
- }
-
-
- // Buttons for actions
-
- if ($action != 'presend' && $action != 'editline') {
- print ''."\n";
- $parameters = array();
- $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
- if ($reshook < 0) {
- setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
- }
-
- if (empty($reshook)) {
- // Send
- if (empty($user->socid) && $object->status == $object::STATUS_VALIDATED) {
- print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle');
- }
-
- // Back to draft
- if ($object->status == $object::STATUS_VALIDATED) {
- print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken(), '', $permissiontoadd);
- }
-
- // Modify
- //print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken(), '', $permissiontoadd);
-
- // Validate
- if ($object->status == $object::STATUS_DRAFT) {
- if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
- print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_validate&confirm=yes&token='.newToken(), '', $permissiontoadd);
- } else {
- $langs->load("errors");
- print dolGetButtonAction($langs->trans("ErrorAddAtLeastOneLineFirst"), $langs->trans("Validate"), 'default', '#', '', 0);
- }
- }
-
- // Clone
- if ($permissiontoadd) {
- print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.(!empty($object->socid) ? '&socid='.$object->socid : '').'&action=clone&token='.newToken(), '', $permissiontoadd);
- }
-
- /*
- // Disable / Enable
- if ($permissiontoadd) {
- if ($object->status == $object::STATUS_ENABLED) {
- print dolGetButtonAction('', $langs->trans('Disable'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=disable&token='.newToken(), '', $permissiontoadd);
- } else {
- print dolGetButtonAction('', $langs->trans('Enable'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=enable&token='.newToken(), '', $permissiontoadd);
- }
- }
- if ($permissiontoadd) {
- if ($object->status == $object::STATUS_VALIDATED) {
- print dolGetButtonAction('', $langs->trans('Cancel'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close&token='.newToken(), '', $permissiontoadd);
- } else {
- print dolGetButtonAction('', $langs->trans('Re-Open'), 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken(), '', $permissiontoadd);
- }
- }
- */
-
- // Delete (with preloaded confirm popup)
- $deleteUrl = $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken();
- $buttonId = 'action-delete-no-ajax';
- if ($conf->use_javascript_ajax && empty($conf->dol_use_jmobile)) { // We can use preloaded confirm if not jmobile
- $deleteUrl = '';
- $buttonId = 'action-delete';
- }
- $params = array();
- print dolGetButtonAction('', $langs->trans("Delete"), 'delete', $deleteUrl, $buttonId, $permissiontodelete, $params);
- }
- print '
'."\n";
- }
-
-
- // Select mail models is same action as presend
- if (GETPOST('modelselected')) {
- $action = 'presend';
- }
-
- if ($action != 'presend') {
- print '';
- print '
'; // ancre
-
- $includedocgeneration = 1;
-
- // Documents
-
- $object->element = "diffusion";
- if ($includedocgeneration) {
- $objref = dol_sanitizeFileName($object->ref);
- $relativepath = $objref.'/'.$objref.'.pdf';
- $filedir = $conf->diffusionplans->dir_output.'/'.$object->element.'/'.$objref;
- $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
- $genallowed = $permissiontoread; // If you can read, you can build the PDF to read content
- $delallowed = $permissiontoadd; // If you can create/edit, you can remove a file on card
- print $formfile->showdocuments('diffusionplans:Diffusion', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
- }
- /*
- // Show links to link elements
- $object->element = "diffusion";
- $tmparray = $form->showLinkToObjectBlock($object, array(), array('diffusion'), 1);
- if (is_array($tmparray)) {
- $linktoelem = $tmparray['linktoelem'];
- $htmltoenteralink = $tmparray['htmltoenteralink'];
- print $htmltoenteralink;
- $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
- } else {
- // backward compatibility
- $somethingshown = $form->showLinkedObjectBlock($object, $tmparray);
- }
- */
- print '
';
-
- $MAXEVENT = 10;
-
- $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/diffusionplans/diffusion_agenda.php', 1).'?id='.$object->id);
-
- $includeeventlist = 0;
-
- // List of actions on element
- if ($includeeventlist) {
- include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
- $formactions = new FormActions($db);
- $somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
- }
-
- print '
';
- }
-
- //Select mail models is same action as presend
- if (GETPOST('modelselected')) {
- $action = 'presend';
- }
-
- // Presend form
- $modelmail = 'diffusion';
- $defaulttopic = 'InformationMessage';
- $diroutput = $conf->diffusionplans->dir_output;
- $trackid = 'diffusion'.$object->id;
-
- include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/diffusion_document.php b/diffusion_document.php
deleted file mode 100644
index e77b90a..0000000
--- a/diffusion_document.php
+++ /dev/null
@@ -1,274 +0,0 @@
-
- * Copyright (C) 2024 Frédéric France
- * Copyright (C) 2025 Pierre ARDOIN
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-/**
- * \file diffusion_document.php
- * \ingroup diffusionplans
- * \brief Tab for documents linked to Diffusion
- */
-
-// General defined Options
-//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
-//if (! defined('MAIN_AUTHENTICATION_MODE')) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
-//if (! defined('MAIN_LANG_DEFAULT')) define('MAIN_LANG_DEFAULT', 'auto'); // Force LANG (language) to a particular value
-//if (! defined('MAIN_SECURITY_FORCECSP')) define('MAIN_SECURITY_FORCECSP', 'none'); // Disable all Content Security Policies
-//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
-//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined('NOLOGIN')) define('NOLOGIN', '1'); // Do not use login - if this page is public (can be called outside logged session). This includes the NOIPCHECK too.
-//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library
-//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db
-//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // Do not load html.form.class.php
-//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // Do not load and show top and left menu
-//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs
-//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user
-//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters
-//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data
-//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-
-
-// 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");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
-dol_include_once('/diffusionplans/class/diffusion.class.php');
-dol_include_once('/diffusionplans/lib/diffusionplans_diffusion.lib.php');
-
-/**
- * @var Conf $conf
- * @var DoliDB $db
- * @var HookManager $hookmanager
- * @var Translate $langs
- * @var User $user
- */
-
-// Load translation files required by the page
-$langs->loadLangs(array("diffusionplans@diffusionplans", "companies", "other", "mails"));
-
-// Get parameters
-$action = GETPOST('action', 'aZ09');
-$confirm = GETPOST('confirm');
-$id = (GETPOSTINT('socid') ? GETPOSTINT('socid') : GETPOSTINT('id'));
-$ref = GETPOST('ref', 'alpha');
-
-$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
-if (empty($page) || $page == -1) {
- $page = 0;
-} // If $page is not defined, or '' or -1
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-if (!$sortorder) {
- $sortorder = "ASC";
-}
-if (!$sortfield) {
- $sortfield = "name";
-}
-//if (! $sortfield) $sortfield="position_name";
-
-// Initialize a technical objects
-$object = new Diffusion($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->diffusionplans->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array($object->element.'document', 'globalcard')); // Note that conf->hooks_modules contains array
-
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-
-// Load object
-include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'. Include fetch and fetch_thirdparty but not fetch_optionals
-
-if ($id > 0 || !empty($ref)) {
- $upload_dir = $conf->diffusionplans->multidir_output[$object->entity ? $object->entity : $conf->entity]."/diffusion/".get_exdir(0, 0, 0, 1, $object);
-}
-
-// Permissions
-// (There are several ways to check permission.)
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = getDolGlobalInt('DIFFUSIONPLANS_ENABLE_PERMISSION_CHECK');
-if ($enablepermissioncheck) {
- $permissiontoread = $user->hasRight('diffusionplans', 'diffusion', 'read');
- $permissiontoadd = $user->hasRight('diffusionplans', 'diffusion', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php
-} else {
- $permissiontoread = 1;
- $permissiontoadd = 1;
-}
-
-// Security check (enable the most restrictive one)
-//if ($user->socid > 0) accessforbidden();
-//if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("diffusionplans")) {
- accessforbidden();
-}
-if (!$permissiontoread) {
- accessforbidden();
-}
-if (empty($object->id)) {
- accessforbidden();
-}
-
-
-
-/*
- * Actions
- */
-
-include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-// Header
-// ------
-$title = $langs->trans("Diffusion")." - ".$langs->trans("Files");
-//$title = $object->ref." - ".$langs->trans("Files");
-$help_url = '';
-//Example $help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
-llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-diffusionplans page-card_document');
-
-// Show tabs
-$head = diffusionPrepareHead($object);
-
-print dol_get_fiche_head($head, 'document', $langs->trans("Diffusion"), -1, $object->picto);
-
-
-// Build file list
-$filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1);
-$totalsize = 0;
-foreach ($filearray as $key => $file) {
- $totalsize += $file['size'];
-}
-
-// Object card
-// ------------------------------------------------------------
-$linkback = ''.$langs->trans("BackToList").'';
-
-$morehtmlref = '';
-/*
- // Ref customer
- $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
- $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
- // Thirdparty
- $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : '');
- // Project
- if (isModEnabled('project')) {
- $langs->load("projects");
- $morehtmlref.='
'.$langs->trans('Project') . ' ';
- if ($permissiontoadd)
- {
- if ($action != 'classify')
- //$morehtmlref.='
' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : ';
- $morehtmlref.=' : ';
- if ($action == 'classify') {
- //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
- $morehtmlref.='
';
- } else {
- $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
- }
- } else {
- if (!empty($object->fk_project)) {
- $proj = new Project($db);
- $proj->fetch($object->fk_project);
- $morehtmlref .= ': '.$proj->getNomUrl();
- } else {
- $morehtmlref .= '';
- }
- }
- }*/
-$morehtmlref .= '
';
-
-dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
-
-print '';
-
-print '
';
-print '
';
-
-// Number of files
-print '| '.$langs->trans("NbOfAttachedFiles").' | '.count($filearray).' |
';
-
-// Total size
-print '| '.$langs->trans("TotalSizeOfAttachedFiles").' | '.$totalsize.' '.$langs->trans("bytes").' |
';
-
-print '
';
-
-print '
';
-
-print dol_get_fiche_end();
-
-$modulepart = 'diffusionplans';
-$param = '&id='.$object->id;
-//$relativepathwithnofile='diffusion/' . dol_sanitizeFileName($object->id).'/';
-$relativepathwithnofile = 'diffusion/'.dol_sanitizeFileName($object->ref).'/';
-
-include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php';
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/diffusion_list.php b/diffusion_list.php
deleted file mode 100644
index 7219fa3..0000000
--- a/diffusion_list.php
+++ /dev/null
@@ -1,941 +0,0 @@
-
- * Copyright (C) 2024 Frédéric France
- * Copyright (C) 2025 Pierre ARDOIN
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-/**
- * \file diffusion_list.php
- * \ingroup diffusionplans
- * \brief List page for diffusion
- */
-
-
-// General defined Options
-//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
-//if (! defined('MAIN_AUTHENTICATION_MODE')) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler
-//if (! defined('MAIN_LANG_DEFAULT')) define('MAIN_LANG_DEFAULT', 'auto'); // Force LANG (language) to a particular value
-//if (! defined('MAIN_SECURITY_FORCECSP')) define('MAIN_SECURITY_FORCECSP', 'none'); // Disable all Content Security Policies
-//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
-//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
-//if (! defined('NOLOGIN')) define('NOLOGIN', '1'); // Do not use login - if this page is public (can be called outside logged session). This includes the NOIPCHECK too.
-//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library
-//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db
-//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // Do not load html.form.class.php
-//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // Do not load and show top and left menu
-//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc
-//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs
-//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user
-//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters
-//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters
-//if (! defined('NOSESSION')) define('NOSESSION', '1'); // On CLI mode, no need to use web sessions
-//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data
-//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on)
-
-
-// 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");
-}
-
-require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
-// load module libraries
-require_once __DIR__.'/class/diffusion.class.php';
-// for other modules
-//dol_include_once('/othermodule/class/otherobject.class.php');
-
-/**
- * @var Conf $conf
- * @var DoliDB $db
- * @var HookManager $hookmanager
- * @var Translate $langs
- * @var User $user
- */
-
-// Load translation files required by the page
-$langs->loadLangs(array("diffusionplans@diffusionplans", "other"));
-
-// Get parameters
-$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'create'/'add', 'edit'/'update', 'view', ...
-$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
-$show_files = GETPOSTINT('show_files'); // Show files area generated by bulk actions ?
-$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
-$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
-$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
-$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
-$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
-$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
-$mode = GETPOST('mode', 'aZ'); // The display mode ('list', 'kanban', 'hierarchy', 'calendar', 'gantt', ...)
-$groupby = GETPOST('groupby', 'aZ09'); // Example: $groupby = 'p.fk_opp_status' or $groupby = 'p.fk_statut'
-
-$id = GETPOSTINT('id');
-$ref = GETPOST('ref', 'alpha');
-
-// Load variable for pagination
-$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
-$sortfield = GETPOST('sortfield', 'aZ09comma');
-$sortorder = GETPOST('sortorder', 'aZ09comma');
-$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
-if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
- // If $page is not defined, or '' or -1 or if we click on clear filters
- $page = 0;
-}
-$offset = $limit * $page;
-$pageprev = $page - 1;
-$pagenext = $page + 1;
-
-// Initialize technical objects
-$object = new Diffusion($db);
-$extrafields = new ExtraFields($db);
-$diroutputmassaction = $conf->diffusionplans->dir_output.'/temp/massgeneration/'.$user->id;
-$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array of activated contexes
-
-// Fetch optionals attributes and labels
-$extrafields->fetch_name_optionals_label($object->table_element);
-//$extrafields->fetch_name_optionals_label($object->table_element_line);
-
-$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
-
-// Default sort order (if not yet defined by previous GETPOST)
-if (!$sortfield) {
- reset($object->fields); // Reset is required to avoid key() to return null.
- $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition.
-}
-if (!$sortorder) {
- $sortorder = "ASC";
-}
-
-// Initialize array of search criteria
-$search_all = trim(GETPOST('search_all', 'alphanohtml'));
-$search = array();
-foreach ($object->fields as $key => $val) {
- if (GETPOST('search_'.$key, 'alpha') !== '') {
- $search[$key] = GETPOST('search_'.$key, 'alpha');
- }
- if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
- $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOSTINT('search_'.$key.'_dtstartmonth'), GETPOSTINT('search_'.$key.'_dtstartday'), GETPOSTINT('search_'.$key.'_dtstartyear'));
- $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOSTINT('search_'.$key.'_dtendmonth'), GETPOSTINT('search_'.$key.'_dtendday'), GETPOSTINT('search_'.$key.'_dtendyear'));
- }
-}
-
-$fieldstosearchall = array();
-// List of fields to search into when doing a "search in all"
-// foreach ($object->fields as $key => $val) {
-// if (!empty($val['searchall'])) {
-// $fieldstosearchall['t.'.$key] = $val['label'];
-// }
-// }
-// $parameters = array('fieldstosearchall'=>$fieldstosearchall);
-// $reshook = $hookmanager->executeHooks('completeFieldsToSearchAll', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
-// if ($reshook > 0) {
-// $fieldstosearchall = empty($hookmanager->resArray['fieldstosearchall']) ? array() : $hookmanager->resArray['fieldstosearchall'];
-// } elseif ($reshook == 0) {
-// $fieldstosearchall = array_merge($fieldstosearchall, empty($hookmanager->resArray['fieldstosearchall']) ? array() : $hookmanager->resArray['fieldstosearchall']);
-// }
-
-// Definition of array of fields for columns
-$tableprefix = 't';
-$arrayfields = array();
-foreach ($object->fields as $key => $val) {
- // If $val['visible']==0, then we never show the field
- if (!empty($val['visible'])) {
- $visible = (int) dol_eval((string) $val['visible'], 1);
- $arrayfields[$tableprefix.'.'.$key] = array(
- 'label' => $val['label'],
- 'checked' => (($visible < 0) ? 0 : 1),
- 'enabled' => (abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)),
- 'position' => $val['position'],
- 'help' => isset($val['help']) ? $val['help'] : ''
- );
- }
-}
-// Extra fields
-include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
-
-$object->fields = dol_sort_array($object->fields, 'position');
-//$arrayfields['anotherfield'] = array('type'=>'integer', 'label'=>'AnotherField', 'checked'=>1, 'enabled'=>1, 'position'=>90, 'csslist'=>'right');
-$arrayfields = dol_sort_array($arrayfields, 'position');
-
-// There is several ways to check permission.
-// Set $enablepermissioncheck to 1 to enable a minimum low level of checks
-$enablepermissioncheck = getDolGlobalInt('DIFFUSIONPLANS_ENABLE_PERMISSION_CHECK');
-if ($enablepermissioncheck) {
- $permissiontoread = $user->hasRight('diffusionplans', 'diffusion', 'read');
- $permissiontoadd = $user->hasRight('diffusionplans', 'diffusion', 'write');
- $permissiontodelete = $user->hasRight('diffusionplans', 'diffusion', 'delete');
-} else {
- $permissiontoread = 1;
- $permissiontoadd = 1;
- $permissiontodelete = 1;
-}
-
-// Security check (enable the most restrictive one)
-if ($user->socid > 0) {
- accessforbidden();
-}
-//if ($user->socid > 0) accessforbidden();
-//$socid = 0; if ($user->socid > 0) $socid = $user->socid;
-//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
-//restrictedArea($user, $object->module, 0, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
-if (!isModEnabled("diffusionplans")) {
- accessforbidden('Module diffusionplans not enabled');
-}
-if (!$permissiontoread) {
- accessforbidden();
-}
-
-
-/*
- * Actions
- */
-
-if (GETPOST('cancel', 'alpha')) {
- $action = 'list';
- $massaction = '';
-}
-if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
- $massaction = '';
-}
-
-$parameters = array('arrayfields' => &$arrayfields);
-$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
-if ($reshook < 0) {
- setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
-}
-
-if (empty($reshook)) {
- // Selection of new fields
- include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
-
- // Purge search criteria
- if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
- foreach ($object->fields as $key => $val) {
- $search[$key] = '';
- if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
- $search[$key.'_dtstart'] = '';
- $search[$key.'_dtend'] = '';
- }
- }
- $search_all = '';
- $toselect = array();
- $search_array_options = array();
- }
- if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
- || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
- $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
- }
-
- // Mass actions
- $objectclass = 'Diffusion';
- $objectlabel = 'Diffusion';
- $uploaddir = $conf->diffusionplans->dir_output;
-
- global $error;
- include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
-
- // You can add more action here
- // if ($action == 'xxx' && $permissiontoxxx) ...
-}
-
-
-
-/*
- * View
- */
-
-$form = new Form($db);
-
-$now = dol_now();
-
-$title = $langs->trans("Diffusions");
-//$help_url = "EN:Module_Diffusion|FR:Module_Diffusion_FR|ES:Módulo_Diffusion";
-$help_url = '';
-$morejs = array();
-$morecss = array();
-
-
-// Build and execute select
-// --------------------------------------------------------------------
-$sql = "SELECT";
-$sql .= " ".$object->getFieldList('t');
-// Add fields from extrafields
-if (!empty($extrafields->attributes[$object->table_element]['label'])) {
- foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
- $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : "");
- }
-}
-// Add fields from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-$sql = preg_replace('/,\s*$/', '', $sql);
-
-$sqlfields = $sql; // $sql fields to remove for count total
-
-$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
-//$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."anothertable as rc ON rc.parent = t.rowid";
-if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
- $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
-}
-// Add table from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-if ($object->ismultientitymanaged == 1) {
- $sql .= " WHERE t.entity IN (".getEntity($object->element, (GETPOSTINT('search_current_entity') ? 0 : 1)).")";
-} else {
- $sql .= " WHERE 1 = 1";
-}
-foreach ($search as $key => $val) {
- if (array_key_exists($key, $object->fields)) {
- if ($key == 'status' && $search[$key] == -1) {
- continue;
- }
- $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
- if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
- if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
- $search[$key] = '';
- }
- $mode_search = 2;
- }
- if (empty($object->fields[$key]['searchmulti'])) {
- if (!is_array($search[$key]) && $search[$key] != '') {
- $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
- }
- } else {
- if (is_array($search[$key]) && !empty($search[$key])) {
- $sql .= natural_search("t.".$db->escape($key), implode(',', $search[$key]), (($key == 'status') ? 2 : $mode_search));
- }
- }
- } else {
- if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
- $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
- if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
- if (preg_match('/_dtstart$/', $key)) {
- $sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
- }
- if (preg_match('/_dtend$/', $key)) {
- $sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
- }
- }
- }
- }
-}
-if ($search_all) {
- $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
-}
-/*
-// If the internal user must only see his customers, force searching by him
-$search_sale = 0;
-if (!$user->hasRight('societe', 'client', 'voir')) {
- $search_sale = $user->id;
-}
-// Search on sale representative
-if ($search_sale && $search_sale != '-1') {
- if ($search_sale == -2) {
- $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
- } elseif ($search_sale > 0) {
- $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc AND sc.fk_user = ".((int) $search_sale).")";
- }
-}
-// Search on socid
-if ($socid) {
- $sql .= " AND t.fk_soc = ".((int) $socid);
-}
-*/
-//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear);
-// Add where from extra fields
-include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
-// Add where from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-
-/* If a group by is required
-$sql .= " GROUP BY ";
-foreach($object->fields as $key => $val) {
- $sql .= "t.".$db->sanitize($key).", ";
-}
-// Add fields from extrafields
-if (!empty($extrafields->attributes[$object->table_element]['label'])) {
- foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
- $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : '');
- }
-}
-// Add groupby from hooks
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-$sql .= $hookmanager->resPrint;
-$sql = preg_replace('/,\s*$/', '', $sql);
-*/
-
-// Add HAVING from hooks
-/*
-$parameters = array();
-$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-$sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPrint;
-*/
-
-// Count total nb of records
-$nbtotalofrecords = '';
-if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
- /* The fast and low memory method to get and count full list converts the sql into a sql count */
- $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
- $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
-
- $resql = $db->query($sqlforcount);
- if ($resql) {
- $objforcount = $db->fetch_object($resql);
- $nbtotalofrecords = $objforcount->nbtotalofrecords;
- } else {
- dol_print_error($db);
- }
-
- if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
- $page = 0;
- $offset = 0;
- }
- $db->free($resql);
-}
-
-// Complete request and execute it with limit
-$sql .= $db->order($sortfield, $sortorder);
-if ($limit) {
- $sql .= $db->plimit($limit + 1, $offset);
-}
-
-$resql = $db->query($sql);
-if (!$resql) {
- dol_print_error($db);
- exit;
-}
-
-$num = $db->num_rows($resql);
-
-
-// Direct jump if only one record found
-if ($num == 1 && getDolGlobalInt('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all && !$page) {
- $obj = $db->fetch_object($resql);
- $id = $obj->rowid;
- header("Location: ".dol_buildpath('/diffusionplans/diffusion_card.php', 1).'?id='.((int) $id));
- exit;
-}
-
-
-// Output page
-// --------------------------------------------------------------------
-
-llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'mod-diffusionplans page-list bodyforlist'); // Can use also classforhorizontalscrolloftabs instead of bodyforlist for a horizontal scroll in the table instead of page
-
-// Example : Adding jquery code
-// print '';
-
-$arrayofselected = is_array($toselect) ? $toselect : array();
-
-$param = '';
-if (!empty($mode)) {
- $param .= '&mode='.urlencode($mode);
-}
-if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
- $param .= '&contextpage='.urlencode($contextpage);
-}
-if ($limit > 0 && $limit != $conf->liste_limit) {
- $param .= '&limit='.((int) $limit);
-}
-if ($optioncss != '') {
- $param .= '&optioncss='.urlencode($optioncss);
-}
-if ($groupby != '') {
- $param .= '&groupby='.urlencode($groupby);
-}
-foreach ($search as $key => $val) {
- if (is_array($search[$key])) {
- foreach ($search[$key] as $skey) {
- if ($skey != '') {
- $param .= '&search_'.$key.'[]='.urlencode($skey);
- }
- }
- } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
- $param .= '&search_'.$key.'month='.GETPOSTINT('search_'.$key.'month');
- $param .= '&search_'.$key.'day='.GETPOSTINT('search_'.$key.'day');
- $param .= '&search_'.$key.'year='.GETPOSTINT('search_'.$key.'year');
- } elseif ($search[$key] != '') {
- $param .= '&search_'.$key.'='.urlencode($search[$key]);
- }
-}
-// Add $param from extra fields
-include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
-// Add $param from hooks
-$parameters = array('param' => &$param);
-$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
-$param .= $hookmanager->resPrint;
-
-// List of mass actions available
-$arrayofmassactions = array(
- //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"),
- //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
- //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
- //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
-);
-if (!empty($permissiontodelete)) {
- $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
-}
-if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
- $arrayofmassactions = array();
-}
-$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
-
-print ''."\n";
-
-if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
- $hidegeneratedfilelistifempty = 1;
- if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
- $hidegeneratedfilelistifempty = 0;
- }
-
- require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
- $formfile = new FormFile($db);
-
- // Show list of available documents
- $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
- $urlsource .= str_replace('&', '&', $param);
-
- $filedir = $diroutputmassaction;
- $genallowed = $permissiontoread;
- $delallowed = $permissiontoadd;
-
- print $formfile->showdocuments('massfilesarea_'.$object->module, '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
-}
-
-// End of page
-llxFooter();
-$db->close();
diff --git a/langs/en_US/diffusionplans.lang b/langs/en_US/diffusionplans.lang
index f6a2200..9802e43 100644
--- a/langs/en_US/diffusionplans.lang
+++ b/langs/en_US/diffusionplans.lang
@@ -19,6 +19,7 @@ ConfirmClone = Confirm cloning
Contact = Contact
ContactType = Contact type
Contacts = Contacts
+ContactsCount = Contacts
CopyOf = Copy of
Currency = Currency
CustomerAccountancyCode = Customer accountancy code
@@ -29,18 +30,18 @@ DateModificationShort = Modified
Default = Default
Delete = Delete
Description = Description
-Diffusion = Diffusion
+Diffusion = Delivery slip
DiffusionAttachmentLine = %s (%s)
-DiffusionAttachmentsTitle = Attached documents
-DiffusionContact = Diffusion contact
-DiffusionContacts = Diffusion contacts
-DiffusionContactsTitle = Diffusion contacts
-DiffusionNoContacts = No contact is linked to this diffusion.
-DiffusionNoDocuments = No document is attached to this diffusion.
-DiffusionPlansArea = DiffusionPlans area
-DiffusionPlansSetup = DiffusionPlans setup
-DiffusionPlansSetupPage = DiffusionPlans setup page
-Diffusions = Diffusions
+DiffusionAttachmentsTitle = Delivery slip documents
+DiffusionContact = Delivery slip contact
+DiffusionContacts = Delivery slip contacts
+DiffusionContactsTitle = Delivery slip contacts
+DiffusionNoContacts = No contact is linked to this delivery slip.
+DiffusionNoDocuments = No document is attached to this delivery slip.
+DiffusionPlansArea = Delivery slip area
+DiffusionPlansSetup = Delivery slip setup
+DiffusionPlansSetupPage = Delivery slip setup page
+Diffusions = Delivery slips
Disable = Disable
Disabled = Disabled
DocumentModelOdt = OpenDocument templates
@@ -67,6 +68,7 @@ ExtraFields = Extra fields
FeaturesSupported = Supported features
FieldEdition = Field edition
Files = Files
+VisibleDocuments = Listed documents
FilterOnInto = Filter on
FollowingSubstitutionKeysCanBeUsed = You can use the following substitution keys:
FullListOnOnlineDocumentation = See the online documentation for the complete list.
@@ -85,15 +87,15 @@ Logo = Logo
Mask = Mask
Method = Method
Modify = Modify
-ModuleDiffusionPlansDesc = Module to create plan or document diffusions.
-ModuleDiffusionPlansName = Diffusion plans
+ModuleDiffusionPlansDesc = Module to manage delivery slips for project documents.
+ModuleDiffusionPlansName = Document delivery slips
MultiLanguage = Multi-language
MyOwnFamily = My own family
Name = Name
NatureOfContact = Nature of contact
NbOfAttachedFiles = Number of attached files
NewAttribute = New attribute
-NewDiffusion = New diffusion
+NewDiffusion = New delivery slip
NewObject = New object
NextValue = Next value
No = No
@@ -110,7 +112,7 @@ NumberingModules = Numbering modules
OtherOrders = Other orders
PDFMerge = Merge PDF
Path = Path
-PdfTitle = Diffusion
+PdfTitle = Delivery slip
Phone = Phone
Preview = Preview
PreviewNotAvailable = Preview not available
@@ -126,8 +128,8 @@ SendByMail = Send by email
Settings = Settings
SetupSaved = Setup saved
ShortInfo = Short information
-ShowDiffusion = Show diffusion
-ShowDiffusionContact = Show diffusion contact
+ShowDiffusion = Show delivery slip
+ShowDiffusionContact = Show delivery slip contact
SimpleNumRefModelDesc = Simple automatic numbering
Status = Status
ThirdParty = Third party
@@ -151,3 +153,51 @@ methodHand = Hand delivered
methodLetter = Send by letter
methodMail = Send by email
or = or
+BordereaudocDocuments = Delivery slip documents
+Bordereaudoc = Delivery slip
+Bordereaudocs = Delivery slips
+BordereaudocCard = Delivery slip card
+BordereaudocNew = New delivery slip
+BordereaudocList = List of delivery slips
+BordereaudocTitle = Title
+BordereaudocRecipients = Recipients
+BordereaudocSendEmail = Send by email
+BordereaudocSendMail = Send by mail
+BordereaudocSendHand = Hand delivery
+BordereaudocActive = Attached
+BordereaudocContactNature = Contact nature
+BordereaudocContactType = Contact type
+BordereaudocDetach = Detach
+BordereaudocRecipientsUpdated = Recipients updated
+BordereaudocProjectRequired = A project is mandatory to validate the delivery slip.
+BordereaudocAddRecipients = Add project recipients
+BordereaudocFiles = Delivery slip files
+BordereaudocValidated = Delivery slip validated
+BordereaudocDelivered = Delivery slip marked as delivered
+BordereaudocClosed = Delivery slip archived
+ValidateBordereaudoc = Validate the delivery slip
+ConfirmValidateBordereaudoc = Do you confirm validation of this delivery slip?
+DeliverBordereaudoc = Mark delivery slip as delivered
+ConfirmDeliverBordereaudoc = Do you confirm to mark this delivery slip as delivered?
+CloseBordereaudoc = Archive the delivery slip
+ConfirmCloseBordereaudoc = Do you confirm to archive this delivery slip?
+MarkDelivered = Mark as delivered
+BordereaudocListed = Listed in the delivery slip
+BordereaudocDownloadLink = Public download link
+BordereaudocNoFiles = No file is indexed for this delivery slip.
+BordereaudocFilesUpdated = File list updated
+BordereaudocMailSubject=Delivery slip %s
+BordereaudocMailDefaultIntro=Please find below the delivery slip %s and the related documents.
+BordereaudocMailDocuments=Documents available
+ErrorBordereaudocDeleteDraftOnly=Only draft delivery slips can be deleted
+SendByEmail = Sent by email
+SendByMail = Sent by mail
+SendByHand = Hand delivered
+Nature = Nature
+Delivered = Delivered
+Closed = Closed
+GeneratePDF = Generate PDF
+SendMail = Send by email
+DateCreation = Date created
+ErrorFailedToLoadFile = Failed to load file
+ErrorNoEMailRecipientSelected = No recipient selected for email
diff --git a/langs/fr_FR/diffusionplans.lang b/langs/fr_FR/diffusionplans.lang
index c3bea5c..7ba9a04 100644
--- a/langs/fr_FR/diffusionplans.lang
+++ b/langs/fr_FR/diffusionplans.lang
@@ -19,6 +19,7 @@ ConfirmClone = Confirmer le clonage
Contact = Contact
ContactType = Type de contact
Contacts = Contacts
+ContactsCount = Contacts
CopyOf = Copie de
Currency = Devise
CustomerAccountancyCode = Code comptable client
@@ -29,18 +30,18 @@ DateModificationShort = Modifié
Default = Par défaut
Delete = Supprimer
Description = Description
-Diffusion = Diffusion
+Diffusion = Bordereau
DiffusionAttachmentLine = %s (%s)
-DiffusionAttachmentsTitle = Documents joints
-DiffusionContact = Contact de diffusion
-DiffusionContacts = Contacts de diffusion
-DiffusionContactsTitle = Contacts de la diffusion
-DiffusionNoContacts = Aucun contact n'est lié à cette diffusion.
-DiffusionNoDocuments = Aucun document n'est joint à cette diffusion.
-DiffusionPlansArea = Accueil DiffusionPlans
-DiffusionPlansSetup = Configuration DiffusionPlans
-DiffusionPlansSetupPage = Page de configuration DiffusionPlans
-Diffusions = Diffusions
+DiffusionAttachmentsTitle = Documents du bordereau
+DiffusionContact = Contact du bordereau
+DiffusionContacts = Contacts du bordereau
+DiffusionContactsTitle = Contacts du bordereau
+DiffusionNoContacts = Aucun contact n'est lié à ce bordereau.
+DiffusionNoDocuments = Aucun document n'est joint à ce bordereau.
+DiffusionPlansArea = Accueil Bordereaux
+DiffusionPlansSetup = Configuration Bordereau d'envoi
+DiffusionPlansSetupPage = Page de configuration des bordereaux
+Diffusions = Bordereaux
Disable = Désactiver
Disabled = Désactivé
DocumentModelOdt = Modèles OpenDocument
@@ -67,6 +68,7 @@ ExtraFields = Champs supplémentaires
FeaturesSupported = Fonctionnalités prises en charge
FieldEdition = Édition du champ
Files = Fichiers
+VisibleDocuments = Documents listés
FilterOnInto = Filtrer sur
FollowingSubstitutionKeysCanBeUsed = Vous pouvez utiliser les clés de substitution suivantes :
FullListOnOnlineDocumentation = Voir la documentation en ligne pour la liste complète.
@@ -85,15 +87,15 @@ Logo = Logo
Mask = Masque
Method = Méthode
Modify = Modifier
-ModuleDiffusionPlansDesc = Module permettant de créer des diffusions de plans ou de documents.
-ModuleDiffusionPlansName = Diffusion de plans
+ModuleDiffusionPlansDesc = Module permettant de gérer des bordereaux d'envoi de documents projet.
+ModuleDiffusionPlansName = Bordereaux d'envoi de documents
MultiLanguage = Multilingue
MyOwnFamily = Ma propre famille
Name = Nom
NatureOfContact = Nature du contact
NbOfAttachedFiles = Nombre de fichiers joints
NewAttribute = Nouvel attribut
-NewDiffusion = Nouvelle diffusion
+NewDiffusion = Nouveau bordereau
NewObject = Nouvel objet
NextValue = Valeur suivante
No = Non
@@ -110,7 +112,7 @@ NumberingModules = Modules de numérotation
OtherOrders = Autres commandes
PDFMerge = Fusionner le PDF
Path = Chemin
-PdfTitle = Diffusion
+PdfTitle = Bordereau
Phone = Téléphone
Preview = Prévisualisation
PreviewNotAvailable = Prévisualisation indisponible
@@ -126,8 +128,8 @@ SendByMail = Envoyer par mail
Settings = Paramètres
SetupSaved = Configuration enregistrée
ShortInfo = Information courte
-ShowDiffusion = Afficher la diffusion
-ShowDiffusionContact = Afficher le contact de diffusion
+ShowDiffusion = Afficher le bordereau
+ShowDiffusionContact = Afficher le contact du bordereau
SimpleNumRefModelDesc = Numérotation automatique simple
Status = Statut
ThirdParty = Tiers
@@ -151,3 +153,51 @@ methodHand = Remis en main propre
methodLetter = Envoyer par courrier
methodMail = Envoyer par e-mail
or = ou
+BordereaudocDocuments = Documents du bordereau
+Bordereaudoc = Bordereau d'envoi
+Bordereaudocs = Bordereaux d'envoi
+BordereaudocCard = Fiche bordereau d'envoi
+BordereaudocNew = Nouveau bordereau d'envoi
+BordereaudocList = Liste des bordereaux d'envoi
+BordereaudocTitle = Titre
+BordereaudocRecipients = Destinataires
+BordereaudocSendEmail = Envoi par e-mail
+BordereaudocSendMail = Envoi par courrier
+BordereaudocSendHand = Remis en main propre
+BordereaudocActive = Lié au bordereau
+BordereaudocContactNature = Nature du contact
+BordereaudocContactType = Type de contact
+BordereaudocDetach = Dissocier
+BordereaudocRecipientsUpdated = Destinataires mis à jour
+BordereaudocProjectRequired = Un projet est obligatoire pour valider le bordereau.
+BordereaudocAddRecipients = Ajouter les contacts du projet
+BordereaudocFiles = Fichiers du bordereau
+BordereaudocValidated = Bordereau validé
+BordereaudocDelivered = Bordereau marqué comme diffusé/remis
+BordereaudocClosed = Bordereau archivé
+ValidateBordereaudoc = Valider le bordereau
+ConfirmValidateBordereaudoc = Confirmez-vous la validation de ce bordereau ?
+DeliverBordereaudoc = Marquer le bordereau comme remis
+ConfirmDeliverBordereaudoc = Confirmez-vous le passage de ce bordereau en remis ?
+CloseBordereaudoc = Archiver le bordereau
+ConfirmCloseBordereaudoc = Confirmez-vous l'archivage de ce bordereau ?
+BordereaudocListed = Listé dans le bordereau
+BordereaudocDownloadLink = Lien public de téléchargement
+BordereaudocNoFiles = Aucun fichier indexé pour ce bordereau.
+BordereaudocFilesUpdated = Liste des fichiers mise à jour
+MarkDelivered = Marquer comme remis
+BordereaudocMailSubject=Bordereau %s
+BordereaudocMailDefaultIntro=Veuillez trouver ci-joint le bordereau %s et les documents associés.
+BordereaudocMailDocuments=Documents disponibles
+ErrorBordereaudocDeleteDraftOnly=Seuls les bordereaux en brouillon peuvent être supprimés
+SendByEmail = Envoyé par e-mail
+SendByMail = Envoyé par courrier
+SendByHand = Remis en main propre
+Nature = Nature
+Delivered = Diffusé/Remis
+Closed = Archivé
+GeneratePDF = Générer le PDF
+SendMail = Envoyer par e-mail
+DateCreation = Date de création
+ErrorFailedToLoadFile = Échec de chargement du fichier
+ErrorNoEMailRecipientSelected = Aucun destinataire sélectionné pour l'e-mail
diff --git a/lib/diffusionplans_bordereaudoc.lib.php b/lib/diffusionplans_bordereaudoc.lib.php
new file mode 100644
index 0000000..3d64e75
--- /dev/null
+++ b/lib/diffusionplans_bordereaudoc.lib.php
@@ -0,0 +1,79 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * \file lib/diffusionplans_bordereaudoc.lib.php
+ * \ingroup diffusionplans
+ * \brief Library file with common functions for Bordereaudoc cards.
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
+
+/**
+ * Prepare array of tabs for Bordereaudoc cards.
+ *
+ * @param Bordereaudoc $object Bordereaudoc object
+ * @return array
+ */
+function bordereaudocPrepareHead($object)
+{
+ global $db, $langs, $conf;
+
+ $langs->load('diffusionplans@diffusionplans');
+
+ $h = 0;
+ $head = array();
+
+ $head[$h][0] = dol_buildpath('/diffusionplans/bordereaudoc_card.php', 1).'?id='.$object->id;
+ $head[$h][1] = $langs->trans('Bordereaudoc');
+ $head[$h][2] = 'card';
+ $h++;
+
+ $uploadDir = $object->getDocumentsDirectory();
+ $nbFiles = count(dol_dir_list($uploadDir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
+ $nbLinks = Link::count($db, $object->element, $object->id);
+ $head[$h][0] = dol_buildpath('/diffusionplans/bordereaudoc_document.php', 1).'?id='.$object->id;
+ $head[$h][1] = $langs->trans('Documents');
+ if (($nbFiles + $nbLinks) > 0) {
+ $head[$h][1] .= (!getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') ? ''.($nbFiles + $nbLinks).'' : '');
+ }
+ $head[$h][2] = 'documents';
+ $h++;
+
+ $head[$h][0] = dol_buildpath('/diffusionplans/bordereaudoc_agenda.php', 1).'?id='.$object->id;
+ $head[$h][1] = $langs->trans('Events');
+ $head[$h][2] = 'agenda';
+ $h++;
+
+ complete_head_from_modules($conf, $langs, $object, $head, $h, 'bordereaudoc@diffusionplans');
+ complete_head_from_modules($conf, $langs, $object, $head, $h, 'bordereaudoc@diffusionplans', 'remove');
+
+ return $head;
+}
+
+/**
+ * Compatibility wrapper for legacy includes.
+ *
+ * @param Bordereaudoc $object Bordereaudoc object
+ * @return array
+ */
+function diffusionPrepareHead($object)
+{
+ return bordereaudocPrepareHead($object);
+}
+
diff --git a/lib/diffusionplans_diffusion.lib.php b/lib/diffusionplans_diffusion.lib.php
index 01dbc9a..9675a93 100644
--- a/lib/diffusionplans_diffusion.lib.php
+++ b/lib/diffusionplans_diffusion.lib.php
@@ -1,5 +1,5 @@
*
* 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
@@ -18,93 +18,7 @@
/**
* \file lib/diffusionplans_diffusion.lib.php
* \ingroup diffusionplans
- * \brief Library files with common functions for Diffusion
+ * \brief Legacy include kept for backward compatibility.
*/
-/**
- * Prepare array of tabs for Diffusion
- *
- * @param Diffusion $object Diffusion
- * @return array Array of tabs
- */
-function diffusionPrepareHead($object)
-{
- global $db, $langs, $conf;
-
- $langs->load("diffusionplans@diffusionplans");
-
- $showtabofpagecontact = 0;
- $showtabofpagenote = 0;
- $showtabofpagedocument = 1;
- $showtabofpageagenda = 1;
-
- $h = 0;
- $head = array();
-
- $head[$h][0] = dol_buildpath("/diffusionplans/diffusion_card.php", 1).'?id='.$object->id;
- $head[$h][1] = $langs->trans("Diffusion");
- $head[$h][2] = 'card';
- $h++;
-
- if ($showtabofpagecontact) {
- $head[$h][0] = dol_buildpath("/diffusionplans/diffusion_contact.php", 1).'?id='.$object->id;
- $head[$h][1] = $langs->trans("Contacts");
- $head[$h][2] = 'contact';
- $h++;
- }
-
- if ($showtabofpagenote) {
- if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) {
- $nbNote = 0;
- if (!empty($object->note_private)) {
- $nbNote++;
- }
- if (!empty($object->note_public)) {
- $nbNote++;
- }
- $head[$h][0] = dol_buildpath('/diffusionplans/diffusion_note.php', 1).'?id='.$object->id;
- $head[$h][1] = $langs->trans('Notes');
- if ($nbNote > 0) {
- $head[$h][1] .= (!getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') ? ''.$nbNote.'' : '');
- }
- $head[$h][2] = 'note';
- $h++;
- }
- }
-
- if ($showtabofpagedocument) {
- require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
- require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
- $upload_dir = $conf->diffusionplans->dir_output."/diffusion/".dol_sanitizeFileName($object->ref);
- $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
- $nbLinks = Link::count($db, $object->element, $object->id);
- $head[$h][0] = dol_buildpath("/diffusionplans/diffusion_document.php", 1).'?id='.$object->id;
- $head[$h][1] = $langs->trans('Documents');
- if (($nbFiles + $nbLinks) > 0) {
- $head[$h][1] .= ''.($nbFiles + $nbLinks).'';
- }
- $head[$h][2] = 'document';
- $h++;
- }
-
- if ($showtabofpageagenda) {
- $head[$h][0] = dol_buildpath("/diffusionplans/diffusion_agenda.php", 1).'?id='.$object->id;
- $head[$h][1] = $langs->trans("Events");
- $head[$h][2] = 'agenda';
- $h++;
- }
-
- // Show more tabs from modules
- // Entries must be declared in modules descriptor with line
- //$this->tabs = array(
- // 'entity:+tabname:Title:@diffusionplans:/diffusionplans/mypage.php?id=__ID__'
- //); // to add new tab
- //$this->tabs = array(
- // 'entity:-tabname:Title:@diffusionplans:/diffusionplans/mypage.php?id=__ID__'
- //); // to remove a tab
- complete_head_from_modules($conf, $langs, $object, $head, $h, 'diffusion@diffusionplans');
-
- complete_head_from_modules($conf, $langs, $object, $head, $h, 'diffusion@diffusionplans', 'remove');
-
- return $head;
-}
+require_once __DIR__.'/diffusionplans_bordereaudoc.lib.php';
diff --git a/public/bordereaudocdownload.php b/public/bordereaudocdownload.php
new file mode 100644
index 0000000..4d70bea
--- /dev/null
+++ b/public/bordereaudocdownload.php
@@ -0,0 +1,106 @@
+
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+/**
+* \file public/bordereaudocdownload.php
+* \ingroup diffusionplans
+* \brief Public download entry for Bordereaudoc files using hash tokens.
+*/
+
+if (!defined('NOREQUIREMENU')) {
+ define('NOREQUIREMENU', '1');
+}
+if (!defined('NOREQUIREHTML')) {
+ define('NOREQUIREHTML', '1');
+}
+if (!defined('NOREQUIREAJAX')) {
+ define('NOREQUIREAJAX', '1');
+}
+if (!defined('NOLOGIN')) {
+ define('NOLOGIN', '1');
+}
+if (!defined('NOCSRFCHECK')) {
+ define('NOCSRFCHECK', '1');
+}
+if (!defined('NOIPCHECK')) {
+ define('NOIPCHECK', '1');
+}
+
+// Load Dolibarr environment
+$res = 0;
+if (!$res && !empty($_SERVER['CONTEXT_DOCUMENT_ROOT'])) {
+ $res = @include $_SERVER['CONTEXT_DOCUMENT_ROOT'].'/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 && file_exists('../../../main.inc.php')) {
+ $res = @include '../../../main.inc.php';
+}
+if (!$res) {
+ die('Include of main fails');
+}
+
+require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+dol_include_once('/diffusionplans/class/bordereaudoc.class.php');
+
+$hash = GETPOST('hash', 'alphanohtml');
+if (empty($hash)) {
+ http_response_code(400);
+ echo 'Missing hash';
+ exit;
+}
+
+$sql = 'SELECT f.rowid, f.filename, f.filepath, f.entity, b.ref';
+$sql .= ' FROM '.MAIN_DB_PREFIX.'bordereaudoc_file as f';
+$sql .= ' JOIN '.MAIN_DB_PREFIX.'bordereaudoc as b ON b.rowid = f.fk_bordereaudoc';
+$sql .= " WHERE f.hash = '".$db->escape($hash)."'";
+$sql .= ' AND f.entity IN ('.getEntity('bordereaudoc', 1).')';
+
+$resql = $db->query($sql);
+if (!$resql) {
+ http_response_code(500);
+ echo 'Error';
+ exit;
+}
+
+$obj = $db->fetch_object($resql);
+if (!$obj) {
+ http_response_code(404);
+ echo 'File not found';
+ exit;
+}
+
+$entity = (int) $obj->entity;
+$baseDir = !empty($conf->diffusionplans->multidir_output[$entity]) ? $conf->diffusionplans->multidir_output[$entity] : $conf->diffusionplans->dir_output;
+$fullpath = rtrim($baseDir, '/').'/'.trim($obj->filepath, '/').'/'.$obj->filename;
+
+if (!is_readable($fullpath)) {
+ http_response_code(404);
+ echo 'File not found';
+ exit;
+}
+
+$mime = dol_mimetype($fullpath);
+$filename = basename($fullpath);
+top_httphead($mime, 0, 0, 0);
+header('Content-Disposition: attachment; filename="'.dol_escape_htmltag($filename).'"');
+readfile($fullpath);
+exit;
diff --git a/sql/llx_bordereaudoc.key.sql b/sql/llx_bordereaudoc.key.sql
new file mode 100644
index 0000000..a690529
--- /dev/null
+++ b/sql/llx_bordereaudoc.key.sql
@@ -0,0 +1,7 @@
+-- Copyright (C) 2025 Pierre ARDOIN
+--
+-- GNU GPL v3
+
+ALTER TABLE llx_bordereaudoc ADD INDEX idx_bordereaudoc_entity (entity);
+ALTER TABLE llx_bordereaudoc ADD INDEX idx_bordereaudoc_project (fk_project);
+ALTER TABLE llx_bordereaudoc ADD UNIQUE INDEX uk_bordereaudoc_ref (ref, entity);
diff --git a/sql/llx_bordereaudoc.sql b/sql/llx_bordereaudoc.sql
new file mode 100644
index 0000000..fd819e0
--- /dev/null
+++ b/sql/llx_bordereaudoc.sql
@@ -0,0 +1,31 @@
+-- Copyright (C) 2025 Pierre ARDOIN
+--
+-- 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 https://www.gnu.org/licenses/.
+
+CREATE TABLE llx_bordereaudoc(
+rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ref varchar(128) DEFAULT '(PROV)' NOT NULL,
+title varchar(255),
+description longtext,
+fk_project integer NOT NULL,
+statut integer NOT NULL DEFAULT 0,
+entity integer NOT NULL DEFAULT 1,
+datec datetime,
+tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+fk_user_creat integer,
+fk_user_modif integer,
+import_key varchar(14),
+last_main_doc varchar(255),
+model_pdf varchar(255)
+) ENGINE=innodb;
diff --git a/sql/llx_bordereaudoc_contact.key.sql b/sql/llx_bordereaudoc_contact.key.sql
new file mode 100644
index 0000000..c5c74ca
--- /dev/null
+++ b/sql/llx_bordereaudoc_contact.key.sql
@@ -0,0 +1,7 @@
+-- Copyright (C) 2025 Pierre ARDOIN
+--
+-- GNU GPL v3
+
+ALTER TABLE llx_bordereaudoc_contact ADD INDEX idx_bordereaudoc_contact_entity (entity);
+ALTER TABLE llx_bordereaudoc_contact ADD INDEX idx_bordereaudoc_contact_parent (fk_bordereaudoc);
+ALTER TABLE llx_bordereaudoc_contact ADD INDEX idx_bordereaudoc_contact_contact (fk_contact);
diff --git a/sql/llx_bordereaudoc_contact.sql b/sql/llx_bordereaudoc_contact.sql
new file mode 100644
index 0000000..261795b
--- /dev/null
+++ b/sql/llx_bordereaudoc_contact.sql
@@ -0,0 +1,31 @@
+-- Copyright (C) 2025 Pierre ARDOIN
+--
+-- 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 https://www.gnu.org/licenses/.
+
+CREATE TABLE llx_bordereaudoc_contact(
+rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+fk_bordereaudoc integer NOT NULL,
+fk_soc integer,
+fk_contact integer,
+nature_contact varchar(64),
+type_contact varchar(64),
+send_email integer NOT NULL DEFAULT 1,
+send_mail integer NOT NULL DEFAULT 0,
+send_hand integer NOT NULL DEFAULT 0,
+active integer NOT NULL DEFAULT 1,
+entity integer NOT NULL DEFAULT 1,
+datec datetime,
+tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+fk_user_creat integer
+) ENGINE=innodb;
diff --git a/sql/llx_bordereaudoc_file.key.sql b/sql/llx_bordereaudoc_file.key.sql
new file mode 100644
index 0000000..bcf9dd1
--- /dev/null
+++ b/sql/llx_bordereaudoc_file.key.sql
@@ -0,0 +1,7 @@
+-- Copyright (C) 2025 Pierre ARDOIN
+--
+-- GNU GPL v3
+
+ALTER TABLE llx_bordereaudoc_file ADD INDEX idx_bordereaudoc_file_entity (entity);
+ALTER TABLE llx_bordereaudoc_file ADD INDEX idx_bordereaudoc_file_parent (fk_bordereaudoc);
+ALTER TABLE llx_bordereaudoc_file ADD UNIQUE INDEX uk_bordereaudoc_file_hash (hash, entity);
diff --git a/sql/llx_bordereaudoc_file.sql b/sql/llx_bordereaudoc_file.sql
new file mode 100644
index 0000000..6b77445
--- /dev/null
+++ b/sql/llx_bordereaudoc_file.sql
@@ -0,0 +1,27 @@
+-- Copyright (C) 2025 Pierre ARDOIN
+--
+-- 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 https://www.gnu.org/licenses/.
+
+CREATE TABLE llx_bordereaudoc_file(
+rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+fk_bordereaudoc integer NOT NULL,
+filename varchar(255) NOT NULL,
+filepath varchar(255) NOT NULL,
+hash varchar(64) NOT NULL,
+is_visible integer NOT NULL DEFAULT 1,
+entity integer NOT NULL DEFAULT 1,
+datec datetime,
+tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+fk_user_creat integer
+) ENGINE=innodb;