dolibarr  21.0.0-alpha
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  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
28 // Load Dolibarr environment
29 require '../main.inc.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
31 
32 // security check
33 if (!$user->admin) {
35 }
36 
37 // Load translation files required by the page
38 $langs->loadLangs(array("admin", "workflow", "propal", "workflow", "orders", "supplier_proposal", "receptions", "errors", 'sendings'));
39 
40 $action = GETPOST('action', 'aZ09');
41 
42 
43 /*
44  * Actions
45  */
46 
47 if (preg_match('/set(.*)/', $action, $reg)) {
48  if (!dolibarr_set_const($db, $reg[1], '1', 'chaine', 0, '', $conf->entity) > 0) {
49  dol_print_error($db);
50  }
51 }
52 
53 if (preg_match('/del(.*)/', $action, $reg)) {
54  if (!dolibarr_set_const($db, $reg[1], '0', 'chaine', 0, '', $conf->entity) > 0) {
55  dol_print_error($db);
56  }
57 }
58 
59 // List of workflow we can enable
60 clearstatcache();
61 
62 $workflowcodes = array(
63  // Automatic creation
64  'WORKFLOW_PROPAL_AUTOCREATE_ORDER' => array(
65  'family' => 'create',
66  'position' => 10,
67  'enabled' => (isModEnabled("propal") && isModEnabled('order')),
68  'picto' => 'order'
69  ),
70  'WORKFLOW_ORDER_AUTOCREATE_INVOICE' => array(
71  'family' => 'create',
72  'position' => 20,
73  'enabled' => (isModEnabled('order') && isModEnabled('invoice')),
74  'picto' => 'bill'
75  ),
76  'WORKFLOW_TICKET_CREATE_INTERVENTION' => array(
77  'family' => 'create',
78  'position' => 25,
79  'enabled' => (isModEnabled('ticket') && isModEnabled('intervention')),
80  'picto' => 'ticket'
81  ),
82 
83  'separator1' => array('family' => 'separator', 'position' => 25, 'title' => '', 'enabled' => ((isModEnabled("propal") && isModEnabled('order')) || (isModEnabled('order') && isModEnabled('invoice')) || (isModEnabled('ticket') && isModEnabled('intervention')))),
84 
85  // Automatic classification of proposal
86  'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL' => array(
87  'family' => 'classify_proposal',
88  'position' => 30,
89  'enabled' => (isModEnabled("propal") && isModEnabled('order')),
90  'picto' => 'propal',
91  'warning' => ''
92  ),
93  'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL' => array(
94  'family' => 'classify_proposal',
95  'position' => 31,
96  'enabled' => (isModEnabled("propal") && isModEnabled('invoice')),
97  'picto' => 'propal',
98  'warning' => ''
99  ),
100 
101  // Automatic classification of order
102  'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING' => array( // when shipping validated
103  'family' => 'classify_order',
104  'position' => 40,
105  'enabled' => (isModEnabled("shipping") && isModEnabled('order')),
106  'picto' => 'order'
107  ),
108  'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED' => array( // when shipping closed
109  'family' => 'classify_order',
110  'position' => 41,
111  'enabled' => (isModEnabled("shipping") && isModEnabled('order')),
112  'picto' => 'order'
113  ),
114  'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER' => array(
115  'family' => 'classify_order',
116  'position' => 42,
117  'enabled' => (isModEnabled('invoice') && isModEnabled('order')),
118  'picto' => 'order',
119  'warning' => ''
120  ), // For this option, if module invoice is disabled, it does not exists, so "Classify billed" for order must be done manually from order card.
121 
122  'WORKFLOW_SUM_INVOICES_AMOUNT_CLASSIFY_BILLED_ORDER' => array(
123  'family' => 'classify_order',
124  'position' => 43,
125  'enabled' => (isModEnabled('invoice') && isModEnabled('order')),
126  'picto' => 'order',
127  'warning' => ''
128  ), // For this option, if module invoice is disabled, it does not exists, so "Classify billed" for order must be done manually from order card.
129 
130  // Automatic classification supplier proposal
131  'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL' => array(
132  'family' => 'classify_supplier_proposal',
133  'position' => 60,
134  'enabled' => (isModEnabled('supplier_proposal') && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))),
135  'picto' => 'supplier_proposal',
136  'warning' => ''
137  ),
138 
139  // Automatic classification supplier order
140  'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION' => array(
141  'family' => 'classify_supplier_order',
142  'position' => 63,
143  'enabled' => (getDolGlobalString('MAIN_FEATURES_LEVEL') && isModEnabled("reception") && isModEnabled('supplier_order')),
144  'picto' => 'supplier_order',
145  'warning' => ''
146  ),
147 
148  'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED' => array(
149  'family' => 'classify_supplier_order',
150  'position' => 64,
151  'enabled' => (getDolGlobalString('MAIN_FEATURES_LEVEL') && isModEnabled("reception") && isModEnabled('supplier_order')),
152  'picto' => 'supplier_order',
153  'warning' => ''
154  ),
155 
156  'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER' => array(
157  'family' => 'classify_supplier_order',
158  'position' => 65,
159  'enabled' => (isModEnabled("supplier_order") || isModEnabled("supplier_invoice")),
160  'picto' => 'supplier_order',
161  'warning' => ''
162  ),
163 
164  // Automatic classification shipping
165  /* Replaced by next option
166  'WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE' => array(
167  'family' => 'classify_shipping',
168  'position' => 90,
169  'enabled' => isModEnabled("shipping") && isModEnabled("invoice"),
170  'picto' => 'shipment',
171  'deprecated' => 1
172  ),
173  */
174 
175  'WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE' => array(
176  'family' => 'classify_shipping',
177  'position' => 91,
178  'enabled' => isModEnabled("shipping") && isModEnabled("invoice") && getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT') !== '0',
179  'picto' => 'shipment'
180  ),
181 
182  // Automatic classification reception
183  /*
184  'WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE'=>array(
185  'family'=>'classify_reception',
186  'position'=>95,
187  'enabled'=>(isModEnabled("reception") && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))),
188  'picto'=>'reception'
189  ),
190  */
191 
192  'WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE' => array(
193  'family' => 'classify_reception',
194  'position' => 91,
195  'enabled' => isModEnabled("reception") && isModEnabled("supplier_invoice") && getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0',
196  'picto' => 'shipment'
197  ),
198 
199 
200  'separator2' => array('family' => 'separator', 'position' => 400, 'enabled' => (isModEnabled('ticket') && isModEnabled('contract'))),
201 
202  // Automatic link ticket -> contract
203  'WORKFLOW_TICKET_LINK_CONTRACT' => array(
204  'family' => 'link_ticket',
205  'position' => 500,
206  'enabled' => (isModEnabled('ticket') && isModEnabled('contract')),
207  'picto' => 'ticket',
208  'reloadpage' => 1 // So next option can be shown
209  ),
210  // This one depends on previous one WORKFLOW_TICKET_LINK_CONTRACT
211  'WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS' => array(
212  'family' => 'link_ticket',
213  'position' => 501,
214  'enabled' => (isModEnabled('ticket') && isModEnabled('contract') && getDolGlobalString('WORKFLOW_TICKET_LINK_CONTRACT')),
215  'picto' => 'ticket'
216  ),
217 );
218 
219 if (!empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts['workflow'])) {
220  foreach ($conf->modules_parts['workflow'] as $workflow) {
221  $workflowcodes = array_merge($workflowcodes, $workflow);
222  }
223 }
224 
225 // remove not available workflows (based on activated modules and global defined keys)
226 $workflowcodes = array_filter(
227  $workflowcodes,
232  static function ($var) {
233  return (bool) $var['enabled'];
234  }
235 );
236 
237 
238 
239 /*
240  * View
241  */
242 
243 llxHeader('', $langs->trans("WorkflowSetup"), "EN:Module_Workflow_En|FR:Module_Workflow|ES:Módulo_Workflow", '', 0, 0, '', '', '', 'mod-admin page-workflow');
244 
245 $linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
246 print load_fiche_titre($langs->trans("WorkflowSetup"), $linkback, 'title_setup');
247 
248 print '<span class="opacitymedium">'.$langs->trans("WorkflowDesc").'</span>';
249 print '<br>';
250 print '<br>';
251 
252 // current module setup don't support any automatic workflow of this module
253 if (count($workflowcodes) < 1) {
254  print $langs->trans("ThereIsNoWorkflowToModify");
255 
256  llxFooter();
257  $db->close();
258  return;
259 }
260 
261 // Sort on position
262 $workflowcodes = dol_sort_array($workflowcodes, 'position');
263 
264 print '<table class="noborder centpercent">';
265 
266 $oldfamily = '';
267 
268 foreach ($workflowcodes as $key => $params) {
269  if ($params['family'] == 'separator') {
270  print '</table>';
271  print '<br>';
272 
273  print '<table class="noborder centpercent">';
274 
275  continue;
276  }
277 
278  $reg = array();
279  if ($oldfamily != $params['family']) {
280  if ($params['family'] == 'create') {
281  $header = $langs->trans("AutomaticCreation");
282  } elseif (preg_match('/classify_(.*)/', $params['family'], $reg)) {
283  $header = $langs->trans("AutomaticClassification");
284  if ($reg[1] == 'proposal') {
285  $header .= ' - '.$langs->trans('Proposal');
286  }
287  if ($reg[1] == 'order') {
288  $header .= ' - '.$langs->trans('Order');
289  }
290  if ($reg[1] == 'supplier_proposal') {
291  $header .= ' - '.$langs->trans('SupplierProposal');
292  }
293  if ($reg[1] == 'supplier_order') {
294  $header .= ' - '.$langs->trans('SupplierOrder');
295  }
296  if ($reg[1] == 'reception') {
297  $header .= ' - '.$langs->trans('Reception');
298  }
299  if ($reg[1] == 'shipping') {
300  $header .= ' - '.$langs->trans('Shipment');
301  }
302  } elseif (preg_match('/link_(.*)/', $params['family'], $reg)) {
303  $header = $langs->trans("AutomaticLinking");
304  if ($reg[1] == 'ticket') {
305  $header .= ' - '.$langs->trans('Ticket');
306  }
307  } else {
308  $header = $langs->trans("Description");
309  }
310 
311  print '<tr class="liste_titre">';
312  print '<th>'.$header.'</th>';
313  print '<th class="right">'.$langs->trans("Status").'</th>';
314  print '</tr>';
315 
316  $oldfamily = $params['family'];
317  }
318 
319  print '<tr class="oddeven">';
320  print '<td>';
321  print img_object('', $params['picto'], 'class="pictofixedwidth"');
322  print ' '.$langs->trans('desc'.$key);
323 
324  if (!empty($params['warning'])) {
325  print ' '.img_warning($langs->transnoentitiesnoconv($params['warning']));
326  }
327  if (!empty($params['deprecated'])) {
328  print ' '.img_warning($langs->transnoentitiesnoconv("Deprecated"));
329  }
330 
331  print '</td>';
332 
333  print '<td class="right">';
334 
335  if (!empty($conf->use_javascript_ajax)) {
336  if (!empty($params['reloadpage'])) {
337  print ajax_constantonoff($key, array(), null, 0, 0, 1);
338  } else {
339  print ajax_constantonoff($key);
340  }
341  } else {
342  if (getDolGlobalString($key)) {
343  print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=del'.$key.'&token='.newToken().'">';
344  print img_picto($langs->trans("Activated"), 'switch_on');
345  print '</a>';
346  } else {
347  print '<a class="reposition" href="'.$_SERVER['PHP_SELF'].'?action=set'.$key.'&token='.newToken().'">';
348  print img_picto($langs->trans("Disabled"), 'switch_off');
349  print '</a>';
350  }
351  }
352 
353  print '</td>';
354  print '</tr>';
355 }
356 
357 print '</table>';
358 
359 // End of page
360 llxFooter();
361 $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).
Definition: admin.lib.php:656
ajax_constantonoff($code, $input=array(), $entity=null, $revertonoff=0, $strict=0, $forcereload=0, $marginleftonlyshort=2, $forcenoajax=0, $setzeroinsteadofdel=0, $suffix='', $mode='', $morecss='inline-block')
On/off button for constant.
Definition: ajax.lib.php:642
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:55
llxFooter()
Empty footer.
Definition: wrapper.php:69
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)
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 dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.