dolibarr 21.0.0-beta
workflow.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
4 * Copyright (C) 2005-2021 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
7 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
29// Load Dolibarr environment
30require '../main.inc.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
32
41// security check
42if (!$user->admin) {
44}
45
46// Load translation files required by the page
47$langs->loadLangs(array("admin", "workflow", "propal", "workflow", "orders", "supplier_proposal", "receptions", "errors", 'sendings'));
48
49$action = GETPOST('action', 'aZ09');
50
51
52/*
53 * Actions
54 */
55
56if (preg_match('/set(.*)/', $action, $reg)) {
57 if (!dolibarr_set_const($db, $reg[1], '1', 'chaine', 0, '', $conf->entity) > 0) {
58 dol_print_error($db);
59 }
60}
61
62if (preg_match('/del(.*)/', $action, $reg)) {
63 if (!dolibarr_set_const($db, $reg[1], '0', 'chaine', 0, '', $conf->entity) > 0) {
64 dol_print_error($db);
65 }
66}
67
68// List of workflow we can enable
69clearstatcache();
70
71$workflowcodes = array(
72 // Automatic creation
73 'WORKFLOW_PROPAL_AUTOCREATE_ORDER' => array(
74 'family' => 'create',
75 'position' => 10,
76 'enabled' => (isModEnabled("propal") && isModEnabled('order')),
77 'picto' => 'order'
78 ),
79 'WORKFLOW_ORDER_AUTOCREATE_INVOICE' => array(
80 'family' => 'create',
81 'position' => 20,
82 'enabled' => (isModEnabled('order') && isModEnabled('invoice')),
83 'picto' => 'bill'
84 ),
85 'WORKFLOW_TICKET_CREATE_INTERVENTION' => array(
86 'family' => 'create',
87 'position' => 25,
88 'enabled' => (isModEnabled('ticket') && isModEnabled('intervention')),
89 'picto' => 'ticket'
90 ),
91
92 'separator1' => array('family' => 'separator', 'position' => 25, 'title' => '', 'enabled' => ((isModEnabled("propal") && isModEnabled('order')) || (isModEnabled('order') && isModEnabled('invoice')) || (isModEnabled('ticket') && isModEnabled('intervention')))),
93
94 // Automatic classification of proposal
95 'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL' => array(
96 'family' => 'classify_proposal',
97 'position' => 30,
98 'enabled' => (isModEnabled("propal") && isModEnabled('order')),
99 'picto' => 'propal',
100 'warning' => ''
101 ),
102 'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL' => array(
103 'family' => 'classify_proposal',
104 'position' => 31,
105 'enabled' => (isModEnabled("propal") && isModEnabled('invoice')),
106 'picto' => 'propal',
107 'warning' => ''
108 ),
109
110 // Automatic classification of order
111 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING' => array( // when shipping validated
112 'family' => 'classify_order',
113 'position' => 40,
114 'enabled' => (isModEnabled("shipping") && isModEnabled('order')),
115 'picto' => 'order'
116 ),
117 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED' => array( // when shipping closed
118 'family' => 'classify_order',
119 'position' => 41,
120 'enabled' => (isModEnabled("shipping") && isModEnabled('order')),
121 'picto' => 'order'
122 ),
123 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER' => array(
124 'family' => 'classify_order',
125 'position' => 42,
126 'enabled' => (isModEnabled('invoice') && isModEnabled('order')),
127 'picto' => 'order',
128 'warning' => ''
129 ), // For this option, if module invoice is disabled, it does not exists, so "Classify billed" for order must be done manually from order card.
130
131 'WORKFLOW_SUM_INVOICES_AMOUNT_CLASSIFY_BILLED_ORDER' => array(
132 'family' => 'classify_order',
133 'position' => 43,
134 'enabled' => (isModEnabled('invoice') && isModEnabled('order')),
135 'picto' => 'order',
136 'warning' => ''
137 ), // For this option, if module invoice is disabled, it does not exists, so "Classify billed" for order must be done manually from order card.
138
139 // Automatic classification supplier proposal
140 'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL' => array(
141 'family' => 'classify_supplier_proposal',
142 'position' => 60,
143 'enabled' => (isModEnabled('supplier_proposal') && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))),
144 'picto' => 'supplier_proposal',
145 'warning' => ''
146 ),
147
148 // Automatic classification supplier order
149 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION' => array(
150 'family' => 'classify_supplier_order',
151 'position' => 63,
152 'enabled' => (getDolGlobalString('MAIN_FEATURES_LEVEL') && isModEnabled("reception") && isModEnabled('supplier_order')),
153 'picto' => 'supplier_order',
154 'warning' => ''
155 ),
156
157 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED' => array(
158 'family' => 'classify_supplier_order',
159 'position' => 64,
160 'enabled' => (getDolGlobalString('MAIN_FEATURES_LEVEL') && isModEnabled("reception") && isModEnabled('supplier_order')),
161 'picto' => 'supplier_order',
162 'warning' => ''
163 ),
164
165 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER' => array(
166 'family' => 'classify_supplier_order',
167 'position' => 65,
168 'enabled' => (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")),
169 'picto' => 'supplier_order',
170 'warning' => ''
171 ),
172
173 // Automatic classification shipping
174 /* Replaced by next option
175 'WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE' => array(
176 'family' => 'classify_shipping',
177 'position' => 90,
178 'enabled' => isModEnabled("shipping") && isModEnabled("invoice"),
179 'picto' => 'shipment',
180 'deprecated' => 1
181 ),
182 */
183
184 'WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE' => array(
185 'family' => 'classify_shipping',
186 'position' => 91,
187 'enabled' => isModEnabled("shipping") && isModEnabled("invoice") && getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT') !== '0',
188 'picto' => 'shipment'
189 ),
190
191 // Automatic classification reception
192 /*
193 'WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE'=>array(
194 'family'=>'classify_reception',
195 'position'=>95,
196 'enabled'=>(isModEnabled("reception") && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))),
197 'picto'=>'reception'
198 ),
199 */
200
201 'WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE' => array(
202 'family' => 'classify_reception',
203 'position' => 91,
204 'enabled' => isModEnabled("reception") && isModEnabled("supplier_invoice") && getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0',
205 'picto' => 'shipment'
206 ),
207
208
209 'separator2' => array('family' => 'separator', 'position' => 400, 'enabled' => (isModEnabled('ticket') && isModEnabled('contract'))),
210
211 // Automatic link ticket -> contract
212 'WORKFLOW_TICKET_LINK_CONTRACT' => array(
213 'family' => 'link_ticket',
214 'position' => 500,
215 'enabled' => (isModEnabled('ticket') && isModEnabled('contract')),
216 'picto' => 'ticket',
217 'reloadpage' => 1 // So next option can be shown
218 ),
219 // This one depends on previous one WORKFLOW_TICKET_LINK_CONTRACT
220 'WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS' => array(
221 'family' => 'link_ticket',
222 'position' => 501,
223 'enabled' => (isModEnabled('ticket') && isModEnabled('contract') && getDolGlobalString('WORKFLOW_TICKET_LINK_CONTRACT')),
224 'picto' => 'ticket'
225 ),
226);
227
228if (!empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts['workflow'])) {
229 foreach ($conf->modules_parts['workflow'] as $workflow) {
230 $workflowcodes = array_merge($workflowcodes, $workflow);
231 }
232}
233
234// remove not available workflows (based on activated modules and global defined keys)
235$workflowcodes = array_filter(
236 $workflowcodes,
241 static function ($var) {
242 return (bool) $var['enabled'];
243 }
244);
245
246if ($action == 'setvarworkflow') { // Test on permission already done
247 if (GETPOSTISSET('product_category_id')) {
248 $param_ticket_product_category = GETPOSTINT('product_category_id');
249 $res = dolibarr_set_const($db, 'TICKET_PRODUCT_CATEGORY', $param_ticket_product_category, 'chaine', 0, '', $conf->entity);
250 }
251}
252
253
254/*
255 * View
256 */
257
258llxHeader('', $langs->trans("WorkflowSetup"), "EN:Module_Workflow_En|FR:Module_Workflow|ES:Módulo_Workflow", '', 0, 0, '', '', '', 'mod-admin page-workflow');
259
260$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
261print load_fiche_titre($langs->trans("WorkflowSetup"), $linkback, 'title_setup');
262
263print '<span class="opacitymedium">'.$langs->trans("WorkflowDesc").'</span>';
264print '<br>';
265print '<br>';
266
267// current module setup don't support any automatic workflow of this module
268if (count($workflowcodes) < 1) {
269 print $langs->trans("ThereIsNoWorkflowToModify");
270
271 llxFooter();
272 $db->close();
273 return;
274}
275
276// Sort on position
277$workflowcodes = dol_sort_array($workflowcodes, 'position');
278
279print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'" enctype="multipart/form-data" >';
280print '<input type="hidden" name="token" value="'.newToken().'">';
281print '<input type="hidden" name="action" value="setvarworkflow">';
282print '<input type="hidden" name="page_y" value="">';
283
284$oldfamily = '';
285$tableopen = 0;
286$atleastoneline = 0;
287
288foreach ($workflowcodes as $key => $params) {
289 if ($params['family'] == 'separator') {
290 if ($atleastoneline) {
291 print '</table>';
292 print '<br>';
293
294 $oldfamily = '';
295 $atleastoneline = 0;
296 }
297 continue;
298 }
299
300 $reg = array();
301 if ($oldfamily != $params['family']) {
302 // New group
303 if ($params['family'] == 'create') {
304 $header = $langs->trans("AutomaticCreation");
305 } elseif (preg_match('/classify_(.*)/', $params['family'], $reg)) {
306 $header = $langs->trans("AutomaticClassification");
307 if ($reg[1] == 'proposal') {
308 $header .= ' - '.$langs->trans('Proposal');
309 }
310 if ($reg[1] == 'order') {
311 $header .= ' - '.$langs->trans('Order');
312 }
313 if ($reg[1] == 'supplier_proposal') {
314 $header .= ' - '.$langs->trans('SupplierProposal');
315 }
316 if ($reg[1] == 'supplier_order') {
317 $header .= ' - '.$langs->trans('SupplierOrder');
318 }
319 if ($reg[1] == 'reception') {
320 $header .= ' - '.$langs->trans('Reception');
321 }
322 if ($reg[1] == 'shipping') {
323 $header .= ' - '.$langs->trans('Shipment');
324 }
325 } elseif (preg_match('/link_(.*)/', $params['family'], $reg)) {
326 $header = $langs->trans("AutomaticLinking");
327 if ($reg[1] == 'ticket') {
328 $header .= ' - '.$langs->trans('Ticket');
329 }
330 } else {
331 $header = $langs->trans("Description");
332 }
333
334 print '<table class="noborder centpercent">';
335 $tableopen = 1;
336
337 print '<tr class="liste_titre">';
338 print '<th>'.$header.'</th>';
339 print '<th class="right">'.$langs->trans("Status").'</th>';
340 print '</tr>';
341
342 $oldfamily = $params['family'];
343 }
344
345 $atleastoneline = 1;
346
347 print '<tr class="oddeven">';
348 print '<td>';
349 print img_object('', $params['picto'], 'class="pictofixedwidth"');
350 print ' '.$langs->trans('desc'.$key);
351
352 if (!empty($params['warning'])) {
353 print ' '.img_warning($langs->transnoentitiesnoconv($params['warning']));
354 }
355 if (!empty($params['deprecated'])) {
356 print ' '.img_warning($langs->transnoentitiesnoconv("Deprecated"));
357 }
358
359 if ($key == 'WORKFLOW_TICKET_LINK_CONTRACT' && getDolGlobalString('WORKFLOW_TICKET_LINK_CONTRACT')) {
360 require_once DOL_DOCUMENT_ROOT."/core/class/html.formcategory.class.php";
361
362 $formcategory = new FormCategory($db);
363
364 $htmlname = "product_category_id";
365 print '<br>';
366 print $formcategory->textwithpicto($langs->trans("TicketChooseProductCategory"), $langs->trans("TicketChooseProductCategoryHelp"), 1, 'help');
367 if (isModEnabled('category')) {
368 print ' &nbsp; '.img_picto('', 'category', 'class="pictofixedwidth"');
369 $formcategory->selectProductCategory(getDolGlobalInt('TICKET_PRODUCT_CATEGORY'), $htmlname, 1);
370 if ($conf->use_javascript_ajax) {
371 print ajax_combobox('select_'.$htmlname);
372 }
373 print '<input class="button smallpaddingimp" type="submit" value="'.$langs->trans("Save").'">';
374 } else {
375 print 'Module category must be enabled';
376 }
377 }
378
379 print '</td>';
380
381 print '<td class="right">';
382
383 if (!empty($conf->use_javascript_ajax)) {
384 if (!empty($params['reloadpage'])) {
385 print ajax_constantonoff($key, array(), null, 0, 0, 1);
386 } else {
387 print ajax_constantonoff($key);
388 }
389 } else {
390 if (getDolGlobalString($key)) {
391 print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=del'.$key.'&token='.newToken().'">';
392 print img_picto($langs->trans("Activated"), 'switch_on');
393 print '</a>';
394 } else {
395 print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=set'.$key.'&token='.newToken().'">';
396 print img_picto($langs->trans("Disabled"), 'switch_off');
397 print '</a>';
398 }
399 }
400
401 print '</td>';
402 print '</tr>';
403}
404
405if ($tableopen) {
406 print '</table>';
407}
408
409print '</form>';
410
411
412// End of page
413llxFooter();
414$db->close();
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:459
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
Class to manage forms for categories.
llxFooter()
Footer empty.
Definition document.php:107
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.