Merge pull request #24236 from OPEN-DSI/develop_generate_document_on_product_batch_files

NEW: Generate documents on product batch (Files)
This commit is contained in:
Laurent Destailleur 2023-03-17 18:19:10 +01:00 committed by GitHub
commit 8dcba9151f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 245 additions and 3 deletions

View File

@ -522,6 +522,7 @@ GoIntoTranslationMenuToChangeThis=A translation has been found for the key with
WarningSettingSortOrder=Warning, setting a default sort order may result in a technical error when going on the list page if field is an unknown field. If you experience such an error, come back to this page to remove the default sort order and restore default behavior.
Field=Field
ProductDocumentTemplates=Document templates to generate product document
ProductBatchDocumentTemplates=Document templates to generate product lots document
FreeLegalTextOnExpenseReports=Free legal text on expense reports
WatermarkOnDraftExpenseReports=Watermark on draft expense reports
ProjectIsRequiredOnExpenseReports=The project is mandatory for entering an expense report

View File

@ -36,6 +36,9 @@ if (!$user->admin || (empty($conf->productbatch->enabled)))
$action = GETPOST('action', 'alpha');
$value = GETPOST('value', 'alpha');
$label = GETPOST('label', 'alpha');
$scandir = GETPOST('scan_dir', 'alpha');
$type = 'product_batch';
$error = 0;
@ -88,6 +91,65 @@ if ($action == 'updateMaskLot') {
if ($value == '1' && $conf->global->PRODUCTBATCH_SN_ADDONS !== 'mod_sn_advanced') {
dolibarr_set_const($db, "PRODUCTBATCH_SN_ADDON", 'mod_sn_advanced', 'chaine', 0, '', $conf->entity);
}
} elseif ($action == 'set') {
// Activate a model
$ret = addDocumentModel($value, $type, $label, $scandir);
} elseif ($action == 'del') {
$ret = delDocumentModel($value, $type);
if ($ret > 0) {
if ($conf->global->FACTURE_ADDON_PDF == "$value") {
dolibarr_del_const($db, 'FACTURE_ADDON_PDF', $conf->entity);
}
}
} elseif ($action == 'specimen') {
$modele = GETPOST('module', 'alpha');
$product_batch = new Productlot($db);
$product_batch->initAsSpecimen();
// Search template files
$file = '';
$classname = '';
$filefound = 0;
$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
foreach ($dirmodels as $reldir) {
$file = dol_buildpath($reldir . "core/modules/product_batch/doc/pdf_" . $modele . ".modules.php", 0);
if (file_exists($file)) {
$filefound = 1;
$classname = "pdf_" . $modele;
break;
}
}
if ($filefound) {
require_once $file;
$module = new $classname($db);
if ($module->write_file($product_batch, $langs) > 0) {
header("Location: " . DOL_URL_ROOT . "/document.php?modulepart=product_batch&file=SPECIMEN.pdf");
return;
} else {
setEventMessages($module->error, $module->errors, 'errors');
dol_syslog($module->error, LOG_ERR);
}
} else {
setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
}
} elseif ($action == 'setdoc') {
// Set default model
if (dolibarr_set_const($db, "PRODUCT_BATCH_ADDON_PDF", $value, 'chaine', 0, '', $conf->entity)) {
// La constante qui a ete lue en avant du nouveau set
// on passe donc par une variable pour avoir un affichage coherent
$conf->global->PRODUCT_BATCH_ADDON_PDF = $value;
}
// On active le modele
$ret = delDocumentModel($value, $type);
if ($ret > 0) {
$ret = addDocumentModel($value, $type, $label, $scandir);
}
}
/*
@ -299,6 +361,141 @@ if ($conf->global->MAIN_FEATURES_LEVEL < 2) {
print "</table><br>\n";
}
// Module to build doc
$def = array();
$sql = "SELECT nom";
$sql .= " FROM " . MAIN_DB_PREFIX . "document_model";
$sql .= " WHERE type = '" . $db->escape($type) . "'";
$sql .= " AND entity = " . $conf->entity;
$resql = $db->query($sql);
if ($resql) {
$i = 0;
$num_rows = $db->num_rows($resql);
while ($i < $num_rows) {
$array = $db->fetch_array($resql);
array_push($def, $array[0]);
$i++;
}
} else {
dol_print_error($db);
}
print '<br>';
print load_fiche_titre($langs->trans("ProductBatchDocumentTemplates"), '', '');
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>' . $langs->trans("Name") . '</td>';
print '<td>' . $langs->trans("Description") . '</td>';
print '<td class="center" width="60">' . $langs->trans("Status") . "</td>\n";
print '<td class="center" width="60">' . $langs->trans("Default") . "</td>\n";
print '<td class="center"></td>';
print '<td class="center" width="80">' . $langs->trans("Preview") . '</td>';
print "</tr>\n";
clearstatcache();
foreach ($dirmodels as $reldir) {
foreach (array('', '/doc') as $valdir) {
$dir = dol_buildpath($reldir . "core/modules/product_batch" . $valdir);
if (is_dir($dir)) {
$handle = opendir($dir);
if (is_resource($handle)) {
while (($file = readdir($handle)) !== false) {
$filelist[] = $file;
}
closedir($handle);
arsort($filelist);
foreach ($filelist as $file) {
if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) {
if (file_exists($dir . '/' . $file)) {
$name = substr($file, 4, dol_strlen($file) - 16);
$classname = substr($file, 0, dol_strlen($file) - 12);
require_once $dir . '/' . $file;
$module = new $classname($db);
$modulequalified = 1;
if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) {
$modulequalified = 0;
}
if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) {
$modulequalified = 0;
}
if ($modulequalified) {
print '<tr class="oddeven"><td width="100">';
print (empty($module->name) ? $name : $module->name);
print "</td><td>\n";
if (method_exists($module, 'info')) {
print $module->info($langs);
} else {
print $module->description;
}
print '</td>';
// Active
if (in_array($name, $def)) {
print '<td class="center">' . "\n";
print '<a href="' . $_SERVER["PHP_SELF"] . '?action=del&token=' . newToken() . '&value=' . urlencode($name) . '">';
print img_picto($langs->trans("Enabled"), 'switch_on');
print '</a>';
print '</td>';
} else {
print '<td class="center">' . "\n";
print '<a href="' . $_SERVER["PHP_SELF"] . '?action=set&token=' . newToken() . '&value=' . urlencode($name) . '&scan_dir=' . urlencode($module->scandir) . '&label=' . urlencode($module->name) . '">' . img_picto($langs->trans("Disabled"), 'switch_off') . '</a>';
print "</td>";
}
// Defaut
print '<td class="center">';
if (getDolGlobalString('PRODUCT_BATCH_ADDON_PDF') == $name) {
print img_picto($langs->trans("Default"), 'on');
} else {
print '<a href="' . $_SERVER["PHP_SELF"] . '?action=setdoc&token=' . newToken() . '&value=' . urlencode($name) . '&scan_dir=' . urlencode($module->scandir) . '&label=' . urlencode($module->name) . '" alt="' . $langs->trans("Default") . '">' . img_picto($langs->trans("Disabled"), 'off') . '</a>';
}
print '</td>';
// Info
$htmltooltip = '' . $langs->trans("Name") . ': ' . $module->name;
$htmltooltip .= '<br>' . $langs->trans("Type") . ': ' . ($module->type ? $module->type : $langs->trans("Unknown"));
if ($module->type == 'pdf') {
$htmltooltip .= '<br>' . $langs->trans("Width") . '/' . $langs->trans("Height") . ': ' . $module->page_largeur . '/' . $module->page_hauteur;
}
$htmltooltip .= '<br><br><u>' . $langs->trans("FeaturesSupported") . ':</u>';
$htmltooltip .= '<br>' . $langs->trans("Logo") . ': ' . yn($module->option_logo, 1, 1);
$htmltooltip .= '<br>' . $langs->trans("MultiLanguage") . ': ' . yn($module->option_multilang, 1, 1);
print '<td class="center">';
print $form->textwithpicto('', $htmltooltip, 1, 0);
print '</td>';
// Preview
print '<td class="center">';
if ($module->type == 'pdf') {
print '<a href="' . $_SERVER["PHP_SELF"] . '?action=specimen&module=' . $name . '">' . img_object($langs->trans("Preview"), 'contract') . '</a>';
} else {
print img_object($langs->trans("PreviewNotAvailable"), 'generic');
}
print '</td>';
print "</tr>\n";
}
}
}
}
}
}
}
}
print '</table>';
print '</div>';
// End of page
llxFooter();
$db->close();

View File

@ -98,6 +98,8 @@ class Productlot extends CommonObject
//'commissionning_date' => array('type'=>'date', 'label'=>'FirstUseDate', 'enabled'=>'empty($conf->global->PRODUCT_ENABLE_TRACEABILITY)?0:1', 'visible'=>5, 'position'=>100),
//'qc_frequency' => array('type'=>'varchar(6)', 'label'=>'QCFrequency', 'enabled'=>'empty($conf->global->PRODUCT_ENABLE_QUALITYCONTROL)?1:0', 'visible'=>5, 'position'=>110),
'eatby' => array('type'=>'date', 'label'=>'EatByDate', 'enabled'=>'empty($conf->global->PRODUCT_DISABLE_EATBY)?1:0', 'visible'=>5, 'position'=>62),
'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 215),
'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'visible' => -1, 'position' => 310),
'datec' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>500),
'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501),
'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>510, 'foreignkey'=>'llx_user.rowid'),
@ -295,6 +297,8 @@ class Productlot extends CommonObject
$sql .= " t.scrapping_date,";
//$sql .= " t.commissionning_date,";
//$sql .= " t.qc_frequency,";
$sql .= " t.model_pdf,";
$sql .= " t.last_main_doc,";
$sql .= " t.datec,";
$sql .= " t.tms,";
$sql .= " t.fk_user_creat,";
@ -329,6 +333,8 @@ class Productlot extends CommonObject
$this->scrapping_date = $this->db->jdate($obj->scrapping_date);
//$this->commissionning_date = $this->db->jdate($obj->commissionning_date);
//$this->qc_frequency = $obj->qc_frequency;
$this->model_pdf = $obj->model_pdf;
$this->last_main_doc = $obj->last_main_doc;
$this->datec = $this->db->jdate($obj->datec);
$this->tms = $this->db->jdate($obj->tms);
@ -999,9 +1005,14 @@ class Productlot extends CommonObject
*/
public function initAsSpecimen()
{
$this->id = 0;
global $conf;
$this->entity = null;
// Initialise parametres
$this->id = 0;
$this->ref = 'SPECIMEN';
$this->specimen = 1;
$this->entity = $conf->entity;
$this->fk_product = null;
$this->batch = '';
$this->eatby = '';
@ -1012,4 +1023,37 @@ class Productlot extends CommonObject
$this->fk_user_modif = null;
$this->import_key = '';
}
/**
* Create a document onto disk according to template module.
*
* @param string $modele Force model to use ('' to not force)
* @param Translate $outputlangs Object langs to use for output
* @param int $hidedetails Hide details of lines
* @param int $hidedesc Hide description
* @param int $hideref Hide ref
* @return int 0 if KO, 1 if OK
*/
public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
{
global $conf, $user, $langs;
$langs->loadLangs(array('stocks', 'productbatch', "products"));
$outputlangs->loadLangs(array('stocks', 'productbatch', "products"));
// Positionne le modele sur le nom du modele a utiliser
if (!dol_strlen($modele)) {
$modele = '';
if (!empty($this->model_pdf)) {
$modele = $this->model_pdf;
} elseif (!empty($conf->global->PRODUCT_BATCH_ADDON_PDF)) {
$modele = $conf->global->PRODUCT_BATCH_ADDON_PDF;
}
}
$modelpath = "core/modules/product_batch/doc/";
return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
}
}

View File

@ -568,7 +568,7 @@ if ($action != 'presend') {
$urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
$genallowed = $usercanread; // If you can read, you can build the PDF to read content
$delallowed = $usercancreate; // If you can create/edit, you can remove a file on card
print $formfile->showdocuments('product_batch', $objref, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', 0, '', $langs->default_lang, '', $object);
print $formfile->showdocuments('product_batch', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 0, 0, 0, 28, 0, '', 0, '', $langs->default_lang, '', $object);
}
print '</div><div class="fichehalfright">';