dolibarr 20.0.0
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
29require '../main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
31
32// security check
33if (!$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
47if (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
53if (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
60clearstatcache();
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
219if (!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
243llxHeader('', $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>';
246print load_fiche_titre($langs->trans("WorkflowSetup"), $linkback, 'title_setup');
247
248print '<span class="opacitymedium">'.$langs->trans("WorkflowDesc").'</span>';
249print '<br>';
250print '<br>';
251
252// current module setup don't support any automatic workflow of this module
253if (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
264print '<table class="noborder centpercent">';
265
266$oldfamily = '';
267
268foreach ($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
357print '</table>';
358
359// End of page
360llxFooter();
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).
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.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.