dolibarr  9.0.0
card.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
6  * Copyright (C) 2010-2017 Juanjo Menent <jmenent@2byte.es>
7  * Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr>
8  * Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
9  * Copyright (C) 2014-2018 Ferran Marcet <fmarcet@2byte.es>
10  * Copyright (C) 2014-2016 Marcos García <marcosgdf@gmail.com>
11  * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
12  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <http://www.gnu.org/licenses/>.
26  */
27 
34 require "../main.inc.php";
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
41 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
42 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
43 if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
44 if (! empty($conf->projet->enabled)) {
45  require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
46  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
47 }
48 require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
49 
50 // Load translation files required by the page
51 $langs->loadLangs(array("contracts","orders","companies","bills","products",'compta'));
52 
53 $action=GETPOST('action','alpha');
54 $confirm=GETPOST('confirm','alpha');
55 $socid = GETPOST('socid','int');
56 $id = GETPOST('id','int');
57 $ref=GETPOST('ref','alpha');
58 $origin=GETPOST('origin','alpha');
59 $originid=GETPOST('originid','int');
60 
61 $datecontrat='';
62 $usehm=(! empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE:0);
63 
64 // Security check
65 if ($user->societe_id) $socid=$user->societe_id;
66 $result=restrictedArea($user,'contrat',$id);
67 
68 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
69 $hookmanager->initHooks(array('contractcard','globalcard'));
70 
71 $object = new Contrat($db);
72 $extrafields = new ExtraFields($db);
73 
74 // Load object
75 if ($id > 0 || ! empty($ref) && $action!='add') {
76  $ret = $object->fetch($id, $ref);
77  if ($ret > 0)
78  $ret = $object->fetch_thirdparty();
79  if ($ret < 0)
80  dol_print_error('', $object->error);
81 }
82 
83 // fetch optionals attributes and labels
84 $extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
85 
86 // fetch optionals attributes lines and labels
87 $extrafieldsline = new ExtraFields($db);
88 $extralabelslines=$extrafieldsline->fetch_name_optionals_label($object->table_element_line);
89 
90 $permissionnote=$user->rights->contrat->creer; // Used by the include of actions_setnotes.inc.php
91 $permissiondellink=$user->rights->contrat->creer; // Used by the include of actions_dellink.inc.php
92 
93 
94 
95 /*
96  * Actions
97  */
98 
99 $parameters = array('socid' => $socid);
100 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
101 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
102 if (empty($reshook))
103 {
104  include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once
105 
106  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
107 
108  if ($action == 'confirm_active' && $confirm == 'yes' && $user->rights->contrat->activer)
109  {
110  $result = $object->active_line($user, GETPOST('ligne'), GETPOST('date'), GETPOST('dateend'), GETPOST('comment'));
111 
112  if ($result > 0)
113  {
114  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
115  exit;
116  }
117  else {
118  setEventMessages($object->error, $object->errors, 'errors');
119  }
120  }
121 
122  else if ($action == 'confirm_closeline' && $confirm == 'yes' && $user->rights->contrat->activer)
123  {
124  if (! GETPOST('dateend'))
125  {
126  $error++;
127  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), null, 'errors');
128  }
129  if (! $error)
130  {
131  $result = $object->close_line($user, GETPOST('ligne'), GETPOST('dateend'), urldecode(GETPOST('comment')));
132  if ($result > 0)
133  {
134  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
135  exit;
136  }
137  else
138  {
139  setEventMessages($object->error, $object->errors, 'errors');
140  }
141  }
142  }
143 
144  // Si ajout champ produit predefini
145  if (GETPOST('mode')=='predefined')
146  {
147  $date_start='';
148  $date_end='';
149  if (GETPOST('date_startmonth') && GETPOST('date_startday') && GETPOST('date_startyear'))
150  {
151  $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
152  }
153  if (GETPOST('date_endmonth') && GETPOST('date_endday') && GETPOST('date_endyear'))
154  {
155  $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
156  }
157  }
158 
159  // Si ajout champ produit libre
160  if (GETPOST('mode')=='libre')
161  {
162  $date_start_sl='';
163  $date_end_sl='';
164  if (GETPOST('date_start_slmonth') && GETPOST('date_start_slday') && GETPOST('date_start_slyear'))
165  {
166  $date_start_sl=dol_mktime(GETPOST('date_start_slhour'), GETPOST('date_start_slmin'), 0, GETPOST('date_start_slmonth'), GETPOST('date_start_slday'), GETPOST('date_start_slyear'));
167  }
168  if (GETPOST('date_end_slmonth') && GETPOST('date_end_slday') && GETPOST('date_end_slyear'))
169  {
170  $date_end_sl=dol_mktime(GETPOST('date_end_slhour'), GETPOST('date_end_slmin'), 0, GETPOST('date_end_slmonth'), GETPOST('date_end_slday'), GETPOST('date_end_slyear'));
171  }
172  }
173 
174  // Param dates
175  $date_contrat='';
176  $date_start_update='';
177  $date_end_update='';
178  $date_start_real_update='';
179  $date_end_real_update='';
180  if (GETPOST('date_start_updatemonth') && GETPOST('date_start_updateday') && GETPOST('date_start_updateyear'))
181  {
182  $date_start_update=dol_mktime(GETPOST('date_start_updatehour'), GETPOST('date_start_updatemin'), 0, GETPOST('date_start_updatemonth'), GETPOST('date_start_updateday'), GETPOST('date_start_updateyear'));
183  }
184  if (GETPOST('date_end_updatemonth') && GETPOST('date_end_updateday') && GETPOST('date_end_updateyear'))
185  {
186  $date_end_update=dol_mktime(GETPOST('date_end_updatehour'), GETPOST('date_end_updatemin'), 0, GETPOST('date_end_updatemonth'), GETPOST('date_end_updateday'), GETPOST('date_end_updateyear'));
187  }
188  if (GETPOST('date_start_real_updatemonth') && GETPOST('date_start_real_updateday') && GETPOST('date_start_real_updateyear'))
189  {
190  $date_start_real_update=dol_mktime(GETPOST('date_start_real_updatehour'), GETPOST('date_start_real_updatemin'), 0, GETPOST('date_start_real_updatemonth'), GETPOST('date_start_real_updateday'), GETPOST('date_start_real_updateyear'));
191  }
192  if (GETPOST('date_end_real_updatemonth') && GETPOST('date_end_real_updateday') && GETPOST('date_end_real_updateyear'))
193  {
194  $date_end_real_update=dol_mktime(GETPOST('date_end_real_updatehour'), GETPOST('date_end_real_updatemin'), 0, GETPOST('date_end_real_updatemonth'), GETPOST('date_end_real_updateday'), GETPOST('date_end_real_updateyear'));
195  }
196  if (GETPOST('remonth') && GETPOST('reday') && GETPOST('reyear'))
197  {
198  $datecontrat = dol_mktime(GETPOST('rehour'), GETPOST('remin'), 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
199  }
200 
201  // Add contract
202  if ($action == 'add' && $user->rights->contrat->creer)
203  {
204  // Check
205  if (empty($datecontrat))
206  {
207  $error++;
208  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
209  $action='create';
210  }
211 
212  if ($socid<1)
213  {
214  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ThirdParty")), null, 'errors');
215  $action='create';
216  $error++;
217  }
218 
219  // Fill array 'array_options' with data from add form
220  $ret = $extrafields->setOptionalsFromPost($extralabels, $object);
221  if ($ret < 0) {
222  $error ++;
223  $action = 'create';
224  }
225 
226  if (! $error)
227  {
228  $object->socid = $socid;
229  $object->date_contrat = $datecontrat;
230 
231  $object->commercial_suivi_id = GETPOST('commercial_suivi_id','int');
232  $object->commercial_signature_id = GETPOST('commercial_signature_id','int');
233 
234  $object->note_private = GETPOST('note_private','alpha');
235  $object->note_public = GETPOST('note_public','alpha');
236  $object->fk_project = GETPOST('projectid','int');
237  $object->remise_percent = GETPOST('remise_percent','alpha');
238  $object->ref = GETPOST('ref','alpha');
239  $object->ref_customer = GETPOST('ref_customer','alpha');
240  $object->ref_supplier = GETPOST('ref_supplier','alpha');
241 
242  // If creation from another object of another module (Example: origin=propal, originid=1)
243  if (! empty($origin) && ! empty($originid))
244  {
245  // Parse element/subelement (ex: project_task)
246  $element = $subelement = $origin;
247  if (preg_match('/^([^_]+)_([^_]+)/i',$origin,$regs))
248  {
249  $element = $regs[1];
250  $subelement = $regs[2];
251  }
252 
253  // For compatibility
254  if ($element == 'order') { $element = $subelement = 'commande'; }
255  if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; }
256 
257  $object->origin = $origin;
258  $object->origin_id = $originid;
259 
260  // Possibility to add external linked objects with hooks
261  $object->linked_objects[$object->origin] = $object->origin_id;
262  if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects']))
263  {
264  $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
265  }
266 
267  $id = $object->create($user);
268  if ($id < 0) {
269  setEventMessages($object->error, $object->errors, 'errors');
270  }
271 
272  if ($id > 0)
273  {
274  dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
275 
276  $classname = ucfirst($subelement);
277  $srcobject = new $classname($db);
278 
279  dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines");
280  $result=$srcobject->fetch($object->origin_id);
281  if ($result > 0)
282  {
283  $srcobject->fetch_thirdparty();
284  $lines = $srcobject->lines;
285  if (empty($lines) && method_exists($srcobject,'fetch_lines'))
286  {
287  $srcobject->fetch_lines();
288  $lines = $srcobject->lines;
289  }
290 
291  $fk_parent_line=0;
292  $num=count($lines);
293 
294  for ($i=0;$i<$num;$i++)
295  {
296  $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0);
297 
298  if ($product_type == 1 || (! empty($conf->global->CONTRACT_SUPPORT_PRODUCTS) && in_array($product_type, array(0,1)))) { // TODO Exclude also deee
299  // service prédéfini
300  if ($lines[$i]->fk_product > 0)
301  {
302  $product_static = new Product($db);
303 
304  // Define output language
305  if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE))
306  {
307  $prod = new Product($db);
308  $prod->id=$lines[$i]->fk_product;
309  $prod->getMultiLangs();
310 
311  $outputlangs = $langs;
312  $newlang='';
313  if (empty($newlang) && GETPOST('lang_id','aZ09')) $newlang=GETPOST('lang_id','aZ09');
314  if (empty($newlang)) $newlang=$srcobject->thirdparty->default_lang;
315  if (! empty($newlang))
316  {
317  $outputlangs = new Translate("",$conf);
318  $outputlangs->setDefaultLang($newlang);
319  }
320 
321  $label = (! empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label;
322  }
323  else
324  {
325  $label = $lines[$i]->product_label;
326  }
327  $desc = ($lines[$i]->desc && $lines[$i]->desc!=$lines[$i]->libelle)?dol_htmlentitiesbr($lines[$i]->desc):'';
328  }
329  else {
330  $desc = dol_htmlentitiesbr($lines[$i]->desc);
331  }
332 
333  // Extrafields
334  $array_options = array();
335  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) // For avoid conflicts if
336  // trigger used
337  {
338  $lines[$i]->fetch_optionals($lines[$i]->rowid);
339  $array_options = $lines[$i]->array_options;
340  }
341 
342  $txtva = $lines[$i]->vat_src_code ? $lines[$i]->tva_tx . ' (' . $lines[$i]->vat_src_code . ')' : $lines[$i]->tva_tx;
343 
344  // View third's localtaxes for now
345  $localtax1_tx = get_localtax($txtva, 1, $object->thirdparty);
346  $localtax2_tx = get_localtax($txtva, 2, $object->thirdparty);
347 
348  $result = $object->addline(
349  $desc,
350  $lines[$i]->subprice,
351  $lines[$i]->qty,
352  $txtva,
353  $localtax1_tx,
354  $localtax2_tx,
355  $lines[$i]->fk_product,
356  $lines[$i]->remise_percent,
357  $lines[$i]->date_start,
358  $lines[$i]->date_end,
359  'HT',
360  0,
361  $lines[$i]->info_bits,
362  $lines[$i]->fk_fournprice,
363  $lines[$i]->pa_ht,
364  $array_options,
365  $lines[$i]->fk_unit
366  );
367 
368  if ($result < 0)
369  {
370  $error++;
371  break;
372  }
373  }
374  }
375  }
376  else
377  {
378  setEventMessages($srcobject->error, $srcobject->errors, 'errors');
379  $error++;
380  }
381 
382  // Hooks
383  $parameters = array('objFrom' => $srcobject);
384  $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
385  // modified by hook
386  if ($reshook < 0)
387  $error++;
388  }
389  else
390  {
391  setEventMessages($object->error, $object->errors, 'errors');
392  $error++;
393  }
394  }
395  else
396  {
397  $result = $object->create($user);
398  if ($result > 0)
399  {
400  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
401  exit;
402  }
403  else {
404  setEventMessages($object->error, $object->errors, 'errors');
405  }
406  $action='create';
407  }
408  }
409  }
410 
411  else if ($action == 'classin' && $user->rights->contrat->creer)
412  {
413  $object->setProject(GETPOST('projectid'));
414  }
415 
416  // Add a new line
417  else if ($action == 'addline' && $user->rights->contrat->creer)
418  {
419  // Set if we used free entry or predefined product
420  $predef='';
421  $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
422  $price_ht = GETPOST('price_ht');
423  $price_ht_devise = GETPOST('multicurrency_price_ht');
424  if (GETPOST('prod_entry_mode') == 'free')
425  {
426  $idprod=0;
427  $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
428  }
429  else
430  {
431  $idprod=GETPOST('idprod', 'int');
432  $tva_tx = '';
433  }
434 
435  $qty = GETPOST('qty'.$predef);
436  $remise_percent = GETPOST('remise_percent'.$predef);
437 
438  if ($qty == '')
439  {
440  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
441  $error++;
442  }
443  if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc))
444  {
445  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors');
446  $error++;
447  }
448 
449  $date_start = dol_mktime(GETPOST('date_start' . $predef . 'hour'), GETPOST('date_start' . $predef . 'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start' . $predef . 'month'), GETPOST('date_start' . $predef . 'day'), GETPOST('date_start' . $predef . 'year'));
450  $date_end = dol_mktime(GETPOST('date_end' . $predef . 'hour'), GETPOST('date_end' . $predef . 'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end' . $predef . 'month'), GETPOST('date_end' . $predef . 'day'), GETPOST('date_end' . $predef . 'year'));
451  if (!empty($date_start) && !empty($date_end) && $date_start > $date_end)
452  {
453  setEventMessages($langs->trans("Error").': '.$langs->trans("DateStartPlanned").' > '.$langs->trans("DateEndPlanned"), null, 'errors');
454  $error++;
455  }
456 
457  // Extrafields
458  $extrafieldsline = new ExtraFields($db);
459  $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
460  $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
461  // Unset extrafield
462  if (is_array($extralabelsline)) {
463  // Get extra fields
464  foreach ($extralabelsline as $key => $value) {
465  unset($_POST["options_" . $key]);
466  }
467  }
468 
469  if (! $error)
470  {
471  // Clean parameters
472  $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
473  $date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year'));
474  $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT');
475 
476  // Ecrase $pu par celui du produit
477  // Ecrase $desc par celui du produit
478  // Ecrase $tva_tx par celui du produit
479  // Ecrase $base_price_type par celui du produit
480  if ($idprod > 0)
481  {
482  $prod = new Product($db);
483  $prod->fetch($idprod);
484 
485  // Update if prices fields are defined
486  $tva_tx = get_default_tva($mysoc,$object->thirdparty,$prod->id);
487  $tva_npr = get_default_npr($mysoc,$object->thirdparty,$prod->id);
488  if (empty($tva_tx)) $tva_npr=0;
489 
490  $pu_ht = $prod->price;
491  $pu_ttc = $prod->price_ttc;
492  $price_min = $prod->price_min;
493  $price_base_type = $prod->price_base_type;
494 
495  // On defini prix unitaire
496  if ($conf->global->PRODUIT_MULTIPRICES && $object->thirdparty->price_level)
497  {
498  $pu_ht = $prod->multiprices[$object->thirdparty->price_level];
499  $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
500  $price_min = $prod->multiprices_min[$object->thirdparty->price_level];
501  $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
502  }
503  elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
504  {
505  require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
506 
507  $prodcustprice = new Productcustomerprice($db);
508 
509  $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
510 
511  $result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
512  if ($result) {
513  if (count($prodcustprice->lines) > 0) {
514  $pu_ht = price($prodcustprice->lines [0]->price);
515  $pu_ttc = price($prodcustprice->lines [0]->price_ttc);
516  $price_base_type = $prodcustprice->lines [0]->price_base_type;
517  $tva_tx = $prodcustprice->lines [0]->tva_tx;
518  if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')';
519  $tva_npr = $prodcustprice->lines[0]->recuperableonly;
520  if (empty($tva_tx)) $tva_npr=0;
521  }
522  }
523  }
524 
525  $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx));
526  $tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx));
527 
528  // On reevalue prix selon taux tva car taux tva transaction peut etre different
529  // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
530  if ($tmpvat != $tmpprodvat)
531  {
532  if ($price_base_type != 'HT')
533  {
534  $pu_ht = price2num($pu_ttc / (1 + ($tmpvat/100)), 'MU');
535  }
536  else
537  {
538  $pu_ttc = price2num($pu_ht * (1 + ($tmpvat/100)), 'MU');
539  }
540  }
541 
542  $desc=$prod->description;
543  $desc=dol_concatdesc($desc,$product_desc);
544  $fk_unit = $prod->fk_unit;
545  }
546  else
547  {
548  $pu_ht=GETPOST('price_ht');
549  $price_base_type = 'HT';
550  $tva_tx=GETPOST('tva_tx')?str_replace('*','',GETPOST('tva_tx')):0; // tva_tx field may be disabled, so we use vat rate 0
551  $tva_npr=preg_match('/\*/',GETPOST('tva_tx'))?1:0;
552  $desc=$product_desc;
553  $fk_unit= GETPOST('units', 'alpha');
554  }
555 
556  $localtax1_tx=get_localtax($tva_tx,1,$object->thirdparty,$mysoc,$tva_npr);
557  $localtax2_tx=get_localtax($tva_tx,2,$object->thirdparty,$mysoc,$tva_npr);
558 
559  // ajout prix achat
560  $fk_fournprice = $_POST['fournprice'];
561  if ( ! empty($_POST['buying_price']) )
562  $pa_ht = $_POST['buying_price'];
563  else
564  $pa_ht = null;
565 
566  $info_bits=0;
567  if ($tva_npr) $info_bits |= 0x01;
568 
569  if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& ($price_min && (price2num($pu_ht)*(1-price2num($remise_percent)/100) < price2num($price_min))))
570  {
571  $object->error = $langs->trans("CantBeLessThanMinPrice",price(price2num($price_min,'MU'),0,$langs,0,0,-1,$conf->currency));
572  $result = -1 ;
573  }
574  else
575  {
576  // Insert line
577  $result = $object->addline(
578  $desc,
579  $pu_ht,
580  $qty,
581  $tva_tx,
582  $localtax1_tx,
583  $localtax2_tx,
584  $idprod,
585  $remise_percent,
586  $date_start,
587  $date_end,
588  $price_base_type,
589  $pu_ttc,
590  $info_bits,
591  $fk_fournprice,
592  $pa_ht,
593  $array_options,
594  $fk_unit
595  );
596  }
597 
598  if ($result > 0)
599  {
600  // Define output language
601  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE) && ! empty($conf->global->CONTRACT_ADDON_PDF)) // No generation if default type not defined
602  {
603  $outputlangs = $langs;
604  $newlang = '';
605  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
606  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
607  if (! empty($newlang)) {
608  $outputlangs = new Translate("", $conf);
609  $outputlangs->setDefaultLang($newlang);
610  }
611 
612  $ret = $object->fetch($id); // Reload to get new records
613 
614  $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
615  }
616 
617  unset($_POST ['prod_entry_mode']);
618 
619  unset($_POST['qty']);
620  unset($_POST['type']);
621  unset($_POST['remise_percent']);
622  unset($_POST['price_ht']);
623  unset($_POST['multicurrency_price_ht']);
624  unset($_POST['price_ttc']);
625  unset($_POST['tva_tx']);
626  unset($_POST['product_ref']);
627  unset($_POST['product_label']);
628  unset($_POST['product_desc']);
629  unset($_POST['fournprice']);
630  unset($_POST['buying_price']);
631  unset($_POST ['np_marginRate']);
632  unset($_POST ['np_markRate']);
633  unset($_POST['dp_desc']);
634  unset($_POST['idprod']);
635 
636  unset($_POST['date_starthour']);
637  unset($_POST['date_startmin']);
638  unset($_POST['date_startsec']);
639  unset($_POST['date_startday']);
640  unset($_POST['date_startmonth']);
641  unset($_POST['date_startyear']);
642  unset($_POST['date_endhour']);
643  unset($_POST['date_endmin']);
644  unset($_POST['date_endsec']);
645  unset($_POST['date_endday']);
646  unset($_POST['date_endmonth']);
647  unset($_POST['date_endyear']);
648  }
649  else
650  {
651  setEventMessages($object->error, $object->errors, 'errors');
652  }
653  }
654  }
655 
656  else if ($action == 'updateline' && $user->rights->contrat->creer && ! GETPOST('cancel','alpha'))
657  {
658  $error = 0;
659 
660  if (!empty($date_start_update) && !empty($date_end_update) && $date_start_update > $date_end_update)
661  {
662  setEventMessages($langs->trans("Error").': '.$langs->trans("DateStartPlanned").' > '.$langs->trans("DateEndPlanned"), null, 'errors');
663  $action = 'editline';
664  $_GET['rowid'] = GETPOST('elrowid');
665  $error++;
666  }
667 
668  if (! $error)
669  {
670  $objectline = new ContratLigne($db);
671  if ($objectline->fetch(GETPOST('elrowid')) < 0)
672  {
673  setEventMessages($objectline->error, $objectline->errors, 'errors');
674  $error++;
675  }
676  }
677 
678  $db->begin();
679 
680  if (! $error)
681  {
682  if ($date_start_real_update == '') $date_start_real_update=$objectline->date_ouverture;
683  if ($date_end_real_update == '') $date_end_real_update=$objectline->date_cloture;
684 
685  $vat_rate = GETPOST('eltva_tx');
686  // Define info_bits
687  $info_bits = 0;
688  if (preg_match('/\*/', $vat_rate))
689  $info_bits |= 0x01;
690 
691  // Define vat_rate
692  $vat_rate = str_replace('*', '', $vat_rate);
693  $localtax1_tx=get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
694  $localtax2_tx=get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
695 
696  $txtva = $vat_rate;
697 
698  // Clean vat code
699  $vat_src_code='';
700  if (preg_match('/\((.*)\)/', $txtva, $reg))
701  {
702  $vat_src_code = $reg[1];
703  $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate.
704  }
705 
706  // ajout prix d'achat
707  $fk_fournprice = $_POST['fournprice'];
708  if ( ! empty($_POST['buying_price']) )
709  $pa_ht = $_POST['buying_price'];
710  else
711  $pa_ht = null;
712 
713  $fk_unit = GETPOST('unit', 'alpha');
714 
715  $objectline->description=GETPOST('product_desc','none');
716  $objectline->price_ht=GETPOST('elprice');
717  $objectline->subprice=GETPOST('elprice');
718  $objectline->qty=GETPOST('elqty');
719  $objectline->remise_percent=GETPOST('elremise_percent');
720  $objectline->tva_tx=($txtva?$txtva:0); // Field may be disabled, so we use vat rate 0
721  $objectline->vat_src_code=$vat_src_code;
722  $objectline->localtax1_tx=is_numeric($localtax1_tx)?$localtax1_tx:0;
723  $objectline->localtax2_tx=is_numeric($localtax2_tx)?$localtax2_tx:0;
724  $objectline->date_ouverture_prevue=$date_start_update;
725  $objectline->date_ouverture=$date_start_real_update;
726  $objectline->date_fin_validite=$date_end_update;
727  $objectline->date_cloture=$date_end_real_update;
728  $objectline->fk_user_cloture=$user->id;
729  $objectline->fk_fournprice=$fk_fournprice;
730  $objectline->pa_ht=$pa_ht;
731 
732  if ($fk_unit > 0) {
733  $objectline->fk_unit = GETPOST('unit');
734  } else {
735  $objectline->fk_unit = null;
736  }
737 
738  // Extrafields
739  $extrafieldsline = new ExtraFields($db);
740  $extralabelsline = $extrafieldsline->fetch_name_optionals_label($objectline->table_element);
741  $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
742  $objectline->array_options=$array_options;
743 
744  // TODO verifier price_min si fk_product et multiprix
745 
746  $result=$objectline->update($user);
747  if ($result < 0)
748  {
749  $error++;
750  setEventMessages($objectline->error, $objectline->errors, 'errors');
751  }
752  }
753 
754  if (! $error)
755  {
756  $db->commit();
757  }
758  else
759  {
760  $db->rollback();
761  }
762  }
763 
764  else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->contrat->creer)
765  {
766  $result = $object->deleteline(GETPOST('lineid'),$user);
767 
768  if ($result >= 0)
769  {
770  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
771  exit;
772  }
773  else
774  {
775  setEventMessages($object->error, $object->errors, 'errors');
776  }
777  }
778 
779  else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->contrat->creer)
780  {
781  $result = $object->validate($user);
782 
783  if ($result > 0)
784  {
785  // Define output language
786  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
787  {
788  $outputlangs = $langs;
789  $newlang = '';
790  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
791  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
792  if (! empty($newlang)) {
793  $outputlangs = new Translate("", $conf);
794  $outputlangs->setDefaultLang($newlang);
795  }
796  $model=$object->modelpdf;
797  $ret = $object->fetch($id); // Reload to get new records
798 
799  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
800  }
801  }
802  else
803  {
804  setEventMessages($object->error, $object->errors, 'errors');
805  }
806  }
807 
808  else if ($action == 'reopen' && $user->rights->contrat->creer)
809  {
810  $result = $object->reopen($user);
811  if ($result < 0)
812  {
813  setEventMessages($object->error, $object->errors, 'errors');
814  }
815  }
816 
817  // Close all lines
818  else if ($action == 'confirm_close' && $confirm == 'yes' && $user->rights->contrat->creer)
819  {
820  $result = $object->closeAll($user);
821  if ($result < 0)
822  {
823  setEventMessages($object->error, $object->errors, 'errors');
824  }
825  }
826 
827  // Close all lines
828  else if ($action == 'confirm_activate' && $confirm == 'yes' && $user->rights->contrat->creer)
829  {
830  $result = $object->activateAll($user);
831  if ($result < 0)
832  {
833  setEventMessages($object->error, $object->errors, 'errors');
834  }
835  }
836 
837  else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->contrat->supprimer)
838  {
839  $result=$object->delete($user);
840  if ($result >= 0)
841  {
842  header("Location: list.php?restore_lastsearch_values=1");
843  return;
844  }
845  else
846  {
847  setEventMessages($object->error, $object->errors, 'errors');
848  }
849  }
850 
851  else if ($action == 'confirm_move' && $confirm == 'yes' && $user->rights->contrat->creer)
852  {
853  if (GETPOST('newcid') > 0)
854  {
855  $contractline = new ContratLigne($db);
856  $result=$contractline->fetch(GETPOST('lineid'));
857  $contractline->fk_contrat = GETPOST('newcid');
858  $result=$contractline->update($user,1);
859  if ($result >= 0)
860  {
861  header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
862  return;
863  }
864  else
865  {
866  setEventMessages($object->error, $object->errors, 'errors');
867  }
868  }
869  else
870  {
871  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("RefNewContract")), null, 'errors');
872  }
873  }
874  else if ($action == 'update_extras')
875  {
876  $object->oldcopy = dol_clone($object);
877 
878  // Fill array 'array_options' with data from update form
879  $extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
880  $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute','none'));
881  if ($ret < 0) $error++;
882 
883  if (! $error) {
884  $result = $object->insertExtraFields('CONTRACT_MODIFY');
885  if ($result < 0)
886  {
887  setEventMessages($object->error, $object->errors, 'errors');
888  $error++;
889  }
890  }
891 
892  if ($error) {
893  $action = 'edit_extras';
894  }
895  }
896  elseif ($action=='setref_supplier')
897  {
898  $cancelbutton = GETPOST('cancel','alpha');
899  if (!$cancelbutton) {
900 
901  $object->oldcopy = dol_clone($object);
902 
903  $result = $object->setValueFrom('ref_supplier', GETPOST('ref_supplier','alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
904  if ($result < 0) {
905  setEventMessages($object->error, $object->errors, 'errors');
906  $action = 'editref_supplier';
907  } else {
908  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
909  exit;
910  }
911  }
912  else {
913  header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
914  exit;
915  }
916  }
917  elseif ($action=='setref_customer')
918  {
919  $cancelbutton = GETPOST('cancel','alpha');
920 
921  if (!$cancelbutton)
922  {
923  $object->oldcopy = dol_clone($object);
924 
925  $result = $object->setValueFrom('ref_customer', GETPOST('ref_customer','alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
926  if ($result < 0) {
927  setEventMessages($object->error, $object->errors, 'errors');
928  $action = 'editref_customer';
929  } else {
930  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
931  exit;
932  }
933  }
934  else {
935  header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
936  exit;
937  }
938  }
939  elseif ($action=='setref')
940  {
941  $cancelbutton = GETPOST('cancel','alpha');
942 
943  if (!$cancelbutton) {
944  $result = $object->fetch($id);
945  if ($result < 0) {
946  setEventMessages($object->error, $object->errors, 'errors');
947  }
948 
949  $old_ref = $object->ref;
950 
951  $result = $object->setValueFrom('ref', GETPOST('ref','alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
952  if ($result < 0) {
953  setEventMessages($object->error, $object->errors, 'errors');
954  $action = 'editref';
955  } else {
956  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
957  $old_filedir = $conf->contrat->dir_output . '/' . dol_sanitizeFileName($old_ref);
958  $new_filedir = $conf->contrat->dir_output . '/' . dol_sanitizeFileName($object->ref);
959 
960  $files = dol_dir_list($old_filedir);
961  if (!empty($files))
962  {
963  if (!is_dir($new_filedir)) dol_mkdir($new_filedir);
964  foreach ($files as $file)
965  {
966  dol_move($file['fullname'], $new_filedir.'/'.$file['name']);
967  }
968  }
969 
970  header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
971  exit;
972  }
973  }
974  else {
975  header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
976  exit;
977  }
978  }
979  elseif ($action=='setdate_contrat')
980  {
981  $cancelbutton = GETPOST('cancel','alpha');
982 
983  if (!$cancelbutton) {
984  $result = $object->fetch($id);
985  if ($result < 0) {
986  setEventMessages($object->error, $object->errors, 'errors');
987  }
988  $datacontrat=dol_mktime(GETPOST('date_contrathour'), GETPOST('date_contratmin'), 0, GETPOST('date_contratmonth'), GETPOST('date_contratday'), GETPOST('date_contratyear'));
989  $result = $object->setValueFrom('date_contrat', $datacontrat, '', null, 'date', '', $user, 'CONTRACT_MODIFY');
990  if ($result < 0) {
991  setEventMessages($object->error, $object->errors, 'errors');
992  $action = 'editdate_contrat';
993  } else {
994  header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
995  exit;
996  }
997  }
998  else {
999  header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
1000  exit;
1001  }
1002  }
1003 
1004 
1005  // Actions to build doc
1006  $upload_dir = $conf->contrat->dir_output;
1007  $permissioncreate = $user->rights->contrat->creer;
1008  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1009 
1010  // Actions to send emails
1011  $trigger_name='CONTRACT_SENTBYMAIL';
1012  $paramname='id';
1013  $mode='emailfromcontract';
1014  $trackid='con'.$object->id;
1015  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1016 
1017 
1018  if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->contrat->creer)
1019  {
1020  if ($action == 'addcontact')
1021  {
1022  $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
1023  $result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source'));
1024 
1025  if ($result >= 0)
1026  {
1027  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1028  exit;
1029  }
1030  else
1031  {
1032  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS')
1033  {
1034  $langs->load("errors");
1035  setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
1036  }
1037  else
1038  {
1039  setEventMessages($object->error, $object->errors, 'errors');
1040  }
1041  }
1042  }
1043 
1044  // bascule du statut d'un contact
1045  else if ($action == 'swapstatut')
1046  {
1047  $result=$object->swapContactStatus(GETPOST('ligne'));
1048  }
1049 
1050  // Efface un contact
1051  else if ($action == 'deletecontact')
1052  {
1053  $result = $object->delete_contact(GETPOST('lineid'));
1054 
1055  if ($result >= 0)
1056  {
1057  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1058  exit;
1059  }
1060  else {
1061  setEventMessages($object->error, $object->errors, 'errors');
1062  }
1063  }
1064  }
1065 
1066  // Action clone object
1067  if ($action == 'confirm_clone' && $confirm == 'yes')
1068  {
1069  if (! GETPOST('socid', 3))
1070  {
1071  setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
1072  }
1073  else
1074  {
1075  if ($object->id > 0) {
1076  $result = $object->createFromClone($socid);
1077  if ($result > 0) {
1078  header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result);
1079  exit();
1080  } else {
1081  if (count($object->errors) > 0) setEventMessages($object->error, $object->errors, 'errors');
1082  $action = '';
1083  }
1084  }
1085  }
1086  }
1087 }
1088 
1089 
1090 /*
1091  * View
1092  */
1093 
1094 llxHeader('',$langs->trans("Contract"),"");
1095 
1096 $form = new Form($db);
1097 $formfile = new FormFile($db);
1098 if (! empty($conf->projet->enabled)) $formproject = new FormProjets($db);
1099 
1100 $objectlignestatic=new ContratLigne($db);
1101 
1102 // Load object modContract
1103 $module=(! empty($conf->global->CONTRACT_ADDON)?$conf->global->CONTRACT_ADDON:'mod_contract_serpis');
1104 if (substr($module, 0, 13) == 'mod_contract_' && substr($module, -3) == 'php')
1105 {
1106  $module = substr($module, 0, dol_strlen($module)-4);
1107 }
1108 $result=dol_include_once('/core/modules/contract/'.$module.'.php');
1109 if ($result > 0)
1110 {
1111  $modCodeContract = new $module();
1112 }
1113 
1114 // Create
1115 if ($action == 'create')
1116 {
1117  print load_fiche_titre($langs->trans('AddContract'),'','title_commercial.png');
1118 
1119  $soc = new Societe($db);
1120  if ($socid>0) $soc->fetch($socid);
1121 
1122  if (GETPOST('origin') && GETPOST('originid'))
1123  {
1124  // Parse element/subelement (ex: project_task)
1125  $element = $subelement = GETPOST('origin');
1126  if (preg_match('/^([^_]+)_([^_]+)/i',GETPOST('origin'),$regs))
1127  {
1128  $element = $regs[1];
1129  $subelement = $regs[2];
1130  }
1131 
1132  if ($element == 'project')
1133  {
1134  $projectid=GETPOST('originid');
1135  }
1136  else
1137  {
1138  // For compatibility
1139  if ($element == 'order' || $element == 'commande') { $element = $subelement = 'commande'; }
1140  if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; }
1141 
1142  dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1143 
1144  $classname = ucfirst($subelement);
1145  $objectsrc = new $classname($db);
1146  $objectsrc->fetch(GETPOST('originid'));
1147  if (empty($objectsrc->lines) && method_exists($objectsrc,'fetch_lines')) $objectsrc->fetch_lines();
1148  $objectsrc->fetch_thirdparty();
1149 
1150  // Replicate extrafields
1151  $objectsrc->fetch_optionals($originid);
1152  $object->array_options = $objectsrc->array_options;
1153 
1154  $projectid = (!empty($objectsrc->fk_project)?$objectsrc->fk_project:'');
1155 
1156  $soc = $objectsrc->thirdparty;
1157 
1158  $note_private = (! empty($objectsrc->note_private) ? $objectsrc->note_private : '');
1159  $note_public = (! empty($objectsrc->note_public) ? $objectsrc->note_public : '');
1160 
1161  // Object source contacts list
1162  $srccontactslist = $objectsrc->liste_contact(-1,'external',1);
1163  }
1164  }
1165  else {
1166  $projectid = GETPOST('projectid','int');
1167  $note_private = GETPOST("note_private");
1168  $note_public = GETPOST("note_public");
1169  }
1170 
1171  $object->date_contrat = dol_now();
1172 
1173  print '<form name="form_contract" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1174  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1175 
1176  print '<input type="hidden" name="action" value="add">';
1177  print '<input type="hidden" name="socid" value="'.$soc->id.'">'."\n";
1178  print '<input type="hidden" name="remise_percent" value="0">';
1179 
1180  dol_fiche_head();
1181 
1182  print '<table class="border" width="100%">';
1183 
1184  // Ref
1185  print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Ref').'</td><td>';
1186  if (! empty($modCodeContract->code_auto)) {
1187  $tmpcode=$langs->trans("Draft");
1188  } else {
1189  $tmpcode='<input name="ref" class="maxwidth100" maxlength="128" value="'.dol_escape_htmltag(GETPOST('ref')?GETPOST('ref'):$tmpcode).'">';
1190  }
1191  print $tmpcode;
1192  print '</td></tr>';
1193 
1194  // Ref customer
1195  print '<tr><td>'.$langs->trans('RefCustomer').'</td>';
1196  print '<td><input type="text" class="maxwidth150" name="ref_customer" id="ref_customer" value="'.dol_escape_htmltag(GETPOST('ref_customer','alpha')).'"></td></tr>';
1197 
1198  // Ref supplier
1199  print '<tr><td>'.$langs->trans('RefSupplier').'</td>';
1200  print '<td><input type="text" class="maxwidth150" name="ref_supplier" id="ref_supplier" value="'.dol_escape_htmltag(GETPOST('ref_supplier','alpha')).'"></td></tr>';
1201 
1202  // Thirdparty
1203  print '<tr>';
1204  print '<td class="fieldrequired">'.$langs->trans('ThirdParty').'</td>';
1205  if ($socid>0)
1206  {
1207  print '<td>';
1208  print $soc->getNomUrl(1);
1209  print '<input type="hidden" name="socid" value="'.$soc->id.'">';
1210  print '</td>';
1211  }
1212  else
1213  {
1214  print '<td>';
1215  print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300');
1216  print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">'.$langs->trans("AddThirdParty").'</a>';
1217  print '</td>';
1218  }
1219  print '</tr>'."\n";
1220 
1221  if($socid>0)
1222  {
1223  // Ligne info remises tiers
1224  print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
1225  if ($soc->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$soc->remise_percent);
1226  else print $langs->trans("CompanyHasNoRelativeDiscount");
1227  print '. ';
1228  $absolute_discount=$soc->getAvailableDiscounts();
1229  if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->trans("Currency".$conf->currency));
1230  else print $langs->trans("CompanyHasNoAbsoluteDiscount");
1231  print '.';
1232  print '</td></tr>';
1233  }
1234 
1235  // Commercial suivi
1236  print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("TypeContact_contrat_internal_SALESREPFOLL").'</span></td><td>';
1237  print $form->select_dolusers(GETPOST("commercial_suivi_id")?GETPOST("commercial_suivi_id"):$user->id,'commercial_suivi_id',1,'');
1238  print '</td></tr>';
1239 
1240  // Commercial signature
1241  print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("TypeContact_contrat_internal_SALESREPSIGN").'</span></td><td>';
1242  print $form->select_dolusers(GETPOST("commercial_signature_id")?GETPOST("commercial_signature_id"):$user->id,'commercial_signature_id',1,'');
1243  print '</td></tr>';
1244 
1245  print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td>';
1246  print $form->selectDate($datecontrat, '', 0, 0, '', "contrat");
1247  print "</td></tr>";
1248 
1249  // Project
1250  if (! empty($conf->projet->enabled))
1251  {
1252  $langs->load('projects');
1253 
1254  $formproject=new FormProjets($db);
1255 
1256  print '<tr><td>'.$langs->trans("Project").'</td><td>';
1257  $formproject->select_projects(($soc->id>0?$soc->id:-1),$projectid,"projectid",0,0,1,1);
1258  print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid=' . $soc->id . '&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'">' . $langs->trans("AddProject") . '</a>';
1259  print "</td></tr>";
1260  }
1261 
1262  print '<tr><td>'.$langs->trans("NotePublic").'</td><td class="tdtop">';
1263  $doleditor=new DolEditor('note_public', $note_public, '', '100', 'dolibarr_notes', 'In', 1, true, true, ROWS_3, '90%');
1264  print $doleditor->Create(1);
1265  print '</td></tr>';
1266 
1267  if (empty($user->societe_id))
1268  {
1269  print '<tr><td>'.$langs->trans("NotePrivate").'</td><td class="tdtop">';
1270  $doleditor=new DolEditor('note_private', $note_private, '', '100', 'dolibarr_notes', 'In', 1, true, true, ROWS_3, '90%');
1271  print $doleditor->Create(1);
1272  print '</td></tr>';
1273  }
1274 
1275  // Other attributes
1276  $parameters=array('objectsrc' => $objectsrc,'colspan' => ' colspan="3"', 'cols'=>3);
1277  $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
1278  print $hookmanager->resPrint;
1279 
1280  // Other attributes
1281  if (empty($reshook)) {
1282  print $object->showOptionals($extrafields, 'edit');
1283  }
1284 
1285  print "</table>\n";
1286 
1287  dol_fiche_end();
1288 
1289  print '<div class="center">';
1290  print '<input type="submit" class="button" value="'.$langs->trans("Create").'">';
1291  print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
1292  print '<input type="button" class="button" value="' . $langs->trans("Cancel") . '" onClick="javascript:history.go(-1)">';
1293  print '</div>';
1294 
1295  if (is_object($objectsrc))
1296  {
1297  print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
1298  print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
1299 
1300  if (empty($conf->global->CONTRACT_SUPPORT_PRODUCTS))
1301  {
1302  print '<br>'.$langs->trans("Note").': '.$langs->trans("OnlyLinesWithTypeServiceAreUsed");
1303  }
1304  }
1305 
1306  print "</form>\n";
1307 }
1308 else
1309 /* *************************************************************************** */
1310 /* */
1311 /* Mode vue et edition */
1312 /* */
1313 /* *************************************************************************** */
1314 {
1315  $now=dol_now();
1316 
1317  if ($object->id > 0)
1318  {
1319  $object->fetch_thirdparty();
1320 
1321  $result=$object->fetch_lines(); // This also init $this->nbofserviceswait, $this->nbofservicesopened, $this->nbofservicesexpired=, $this->nbofservicesclosed
1322  if ($result < 0) {
1323  dol_print_error($db,$object->error);
1324  }
1325 
1326  $nbofservices=count($object->lines);
1327 
1328  $author = new User($db);
1329  $author->fetch($object->user_author_id);
1330 
1331  $commercial_signature = new User($db);
1332  $commercial_signature->fetch($object->commercial_signature_id);
1333 
1334  $commercial_suivi = new User($db);
1335  $commercial_suivi->fetch($object->commercial_suivi_id);
1336 
1337  $head = contract_prepare_head($object);
1338 
1339  $hselected = 0;
1340  $formconfirm = '';
1341 
1342  dol_fiche_head($head, $hselected, $langs->trans("Contract"), -1, 'contract');
1343 
1344 
1345  if ($action == 'delete') {
1346  //Confirmation de la suppression du contrat
1347  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("DeleteAContract"),$langs->trans("ConfirmDeleteAContract"),"confirm_delete",'',0,1);
1348  } elseif ($action == 'valid') {
1349  //Confirmation de la validation
1350  $ref = substr($object->ref, 1, 4);
1351  if ($ref == 'PROV' && !empty($modCodeContract->code_auto)) {
1352  $numref = $object->getNextNumRef($object->thirdparty);
1353  } else {
1354  $numref = $object->ref;
1355  }
1356  $text = $langs->trans('ConfirmValidateContract',$numref);
1357  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("ValidateAContract"),$text,"confirm_valid",'',0,1);
1358  } elseif ($action == 'close') {
1359  // Confirmation de la fermeture
1360  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("CloseAContract"),$langs->trans("ConfirmCloseContract"),"confirm_close",'',0,1);
1361  } elseif ($action == 'activate') {
1362  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("ActivateAllOnContract"),$langs->trans("ConfirmActivateAllOnContract"),"confirm_activate",'',0,1);
1363  } elseif ($action == 'clone') {
1364  // Clone confirmation
1365  $formquestion = array(array('type' => 'other','name' => 'socid','label' => $langs->trans("SelectThirdParty"),'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')));
1366  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('CloneContract'), $langs->trans('ConfirmCloneContract', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
1367  }
1368 
1369 
1370  // Call Hook formConfirm
1371  $parameters = array(
1372  'id' => $id,
1373  //'lineid' => $lineid,
1374  );
1375  // Note that $action and $object may have been modified by hook
1376  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
1377  if (empty($reshook)) {
1378  $formconfirm .= $hookmanager->resPrint;
1379  } elseif ($reshook > 0) {
1380  $formconfirm = $hookmanager->resPrint;
1381  }
1382 
1383  // Print form confirm
1384  print $formconfirm;
1385 
1386  /*
1387  * Contrat
1388  */
1389  if (! empty($object->brouillon) && $user->rights->contrat->creer)
1390  {
1391  print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST">';
1392  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1393  print '<input type="hidden" name="action" value="setremise">';
1394  }
1395 
1396  // Contract card
1397 
1398  $linkback = '<a href="'.DOL_URL_ROOT.'/contrat/list.php?restore_lastsearch_values=1'.(! empty($socid)?'&socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
1399 
1400 
1401  $morehtmlref='';
1402  if (! empty($modCodeContract->code_auto)) {
1403  $morehtmlref.=$object->ref;
1404  } else {
1405  $morehtmlref.=$form->editfieldkey("",'ref',$object->ref,$object,$user->rights->contrat->creer,'string','',0,3);
1406  $morehtmlref.=$form->editfieldval("",'ref',$object->ref,$object,$user->rights->contrat->creer,'string','',0,2);
1407  }
1408 
1409  $morehtmlref.='<div class="refidno">';
1410  // Ref customer
1411  $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_customer', $object->ref_customer, $object, $user->rights->contrat->creer, 'string', '', 0, 1);
1412  $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_customer', $object->ref_customer, $object, $user->rights->contrat->creer, 'string', '', null, null, '', 1);
1413  // Ref supplier
1414  $morehtmlref.='<br>';
1415  $morehtmlref.=$form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->rights->contrat->creer, 'string', '', 0, 1);
1416  $morehtmlref.=$form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->rights->contrat->creer, 'string', '', null, null, '', 1);
1417  // Thirdparty
1418  $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
1419  if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) $morehtmlref.=' (<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.$object->thirdparty->id.'&search_name='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherContracts").'</a>)';
1420  // Project
1421  if (! empty($conf->projet->enabled))
1422  {
1423  $langs->load("projects");
1424  $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
1425  if ($user->rights->contrat->creer)
1426  {
1427  if ($action != 'classify')
1428  $morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
1429  if ($action == 'classify') {
1430  //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
1431  $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
1432  $morehtmlref.='<input type="hidden" name="action" value="classin">';
1433  $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1434  $morehtmlref.=$formproject->select_projects($object->thirdparty->id, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
1435  $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
1436  $morehtmlref.='</form>';
1437  } else {
1438  $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->thirdparty->id, $object->fk_project, 'none', 0, 0, 0, 1);
1439  }
1440  } else {
1441  if (! empty($object->fk_project)) {
1442  $proj = new Project($db);
1443  $proj->fetch($object->fk_project);
1444  $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
1445  $morehtmlref.=$proj->ref;
1446  $morehtmlref.='</a>';
1447  } else {
1448  $morehtmlref.='';
1449  }
1450  }
1451  }
1452  $morehtmlref.='</div>';
1453 
1454 
1455  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'none', $morehtmlref);
1456 
1457 
1458  print '<div class="fichecenter">';
1459  print '<div class="underbanner clearboth"></div>';
1460 
1461 
1462  print '<table class="border" width="100%">';
1463 
1464  // Ligne info remises tiers
1465  print '<tr><td class="titlefield">'.$langs->trans('Discount').'</td><td colspan="3">';
1466  if ($object->thirdparty->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$object->thirdparty->remise_percent);
1467  else print $langs->trans("CompanyHasNoRelativeDiscount");
1468  $absolute_discount=$object->thirdparty->getAvailableDiscounts();
1469  print '. ';
1470  if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->trans("Currency".$conf->currency));
1471  else print $langs->trans("CompanyHasNoAbsoluteDiscount");
1472  print '.';
1473  print '</td></tr>';
1474 
1475  // Date
1476  print '<tr>';
1477  print '<td class="titlefield">';
1478  print $form->editfieldkey("Date",'date_contrat',$object->date_contrat,$object,$user->rights->contrat->creer);
1479  print '</td><td>';
1480  print $form->editfieldval("Date",'date_contrat',$object->date_contrat,$object,$user->rights->contrat->creer,'datehourpicker');
1481  print '</td>';
1482  print '</tr>';
1483 
1484  // Other attributes
1485  $cols = 3;
1486  include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
1487 
1488  print "</table>";
1489 
1490  print '</div>';
1491 
1492  if (! empty($object->brouillon) && $user->rights->contrat->creer)
1493  {
1494  print '</form>';
1495  }
1496 
1497  echo '<br>';
1498 
1499  if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB))
1500  {
1501  $blocname = 'contacts';
1502  $title = $langs->trans('ContactsAddresses');
1503  include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
1504  }
1505 
1506  if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB))
1507  {
1508  $blocname = 'notes';
1509  $title = $langs->trans('Notes');
1510  include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
1511  }
1512 
1513 
1514  $colorb = '666666';
1515 
1516  $arrayothercontracts=$object->getListOfContracts('others');
1517 
1518  /*
1519  * Lines of contracts
1520  */
1521 
1522  $productstatic=new Product($db);
1523 
1524  $usemargins=0;
1525  if (! empty($conf->margin->enabled) && ! empty($object->element) && in_array($object->element,array('facture','propal','commande'))) $usemargins=1;
1526 
1527  $var=false;
1528 
1529  // Title line for service
1530  $cursorline=1;
1531  print '<div id="contrat-lines-container" data-contractid="'.$object->id.'" data-element="'.$object->element.'" >';
1532  while ($cursorline <= $nbofservices)
1533  {
1534  print '<div id="contrat-line-container'.$object->lines[$cursorline-1]->id.'" data-contratlineid = "'.$object->lines[$cursorline-1]->id.'" data-element="'.$object->lines[$cursorline-1]->element.'" >';
1535  print '<form name="update" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="post">';
1536  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1537  print '<input type="hidden" name="action" value="updateline">';
1538  print '<input type="hidden" name="elrowid" value="'.$object->lines[$cursorline-1]->id.'">';
1539  print '<input type="hidden" name="idprod" value="'.(!empty($object->lines[$cursorline-1]->fk_product) ? $object->lines[$cursorline-1]->fk_product : 0).'">';
1540  print '<input type="hidden" name="fournprice" value="'.(!empty($object->lines[$cursorline-1]->fk_fournprice) ? $object->lines[$cursorline-1]->fk_fournprice : 0).'">';
1541 
1542  // Area with common detail of line
1543  print '<div class="div-table-responsive-no-min">';
1544  print '<table class="notopnoleftnoright allwidth tableforservicepart1" width="100%">';
1545 
1546  $sql = "SELECT cd.rowid, cd.statut, cd.label as label_det, cd.fk_product, cd.product_type, cd.description, cd.price_ht, cd.qty,";
1547  $sql.= " cd.tva_tx, cd.vat_src_code, cd.remise_percent, cd.info_bits, cd.subprice, cd.multicurrency_subprice,";
1548  $sql.= " cd.date_ouverture_prevue as date_debut, cd.date_ouverture as date_debut_reelle,";
1549  $sql.= " cd.date_fin_validite as date_fin, cd.date_cloture as date_fin_reelle,";
1550  $sql.= " cd.commentaire as comment, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht,";
1551  $sql.= " cd.fk_unit,";
1552  $sql.= " p.rowid as pid, p.ref as pref, p.label as plabel, p.fk_product_type as ptype, p.entity as pentity";
1553  $sql.= " FROM ".MAIN_DB_PREFIX."contratdet as cd";
1554  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid";
1555  $sql.= " WHERE cd.rowid = ".$object->lines[$cursorline-1]->id;
1556 
1557  $result = $db->query($sql);
1558  if ($result)
1559  {
1560  $total = 0;
1561 
1562  print '<tr class="liste_titre'.($cursorline?' liste_titre_add':'').'">';
1563  print '<td>'.$langs->trans("ServiceNb",$cursorline).'</td>';
1564  print '<td width="80" align="center">'.$langs->trans("VAT").'</td>';
1565  print '<td width="80" align="right">'.$langs->trans("PriceUHT").'</td>';
1566  if (!empty($conf->multicurrency->enabled)) {
1567  print '<td width="80" align="right">'.$langs->trans("PriceUHTCurrency").'</td>';
1568  }
1569  print '<td width="30" align="center">'.$langs->trans("Qty").'</td>';
1570  if ($conf->global->PRODUCT_USE_UNITS) print '<td width="30" align="left">'.$langs->trans("Unit").'</td>';
1571  print '<td width="50" align="right">'.$langs->trans("ReductionShort").'</td>';
1572  if (! empty($conf->margin->enabled) && ! empty($conf->global->MARGIN_SHOW_ON_CONTRACT)) print '<td width="50" align="right">'.$langs->trans("BuyingPrice").'</td>';
1573  print '<td width="30">&nbsp;</td>';
1574  print "</tr>\n";
1575 
1576  $objp = $db->fetch_object($result);
1577 
1578  //
1579 
1580  if ($action != 'editline' || GETPOST('rowid') != $objp->rowid)
1581  {
1582  print '<tr class="tdtop oddeven">';
1583  // Label
1584  if ($objp->fk_product > 0)
1585  {
1586  print '<td>';
1587  $productstatic->id=$objp->fk_product;
1588  $productstatic->type=$objp->ptype;
1589  $productstatic->ref=$objp->pref;
1590  $productstatic->entity=$objp->pentity;
1591  $productstatic->label=$objp->plabel;
1592  $text = $productstatic->getNomUrl(1,'',32);
1593  if ($objp->plabel)
1594  {
1595  $text .= ' - ';
1596  $text .= $objp->plabel;
1597  }
1598  $description = $objp->description;
1599 
1600  // Add description in form
1601  if (! empty($conf->global->PRODUIT_DESC_IN_FORM))
1602  {
1603  $text .= (! empty($objp->description) && $objp->description!=$objp->plabel)?'<br>'.dol_htmlentitiesbr($objp->description):'';
1604  $description = ''; // Already added into main visible desc
1605  }
1606 
1607  echo $form->textwithtooltip($text,$description,3,'','',$cursorline,0,(!empty($line->fk_parent_line)?img_picto('', 'rightarrow'):''));
1608 
1609  print '</td>';
1610  }
1611  else
1612  {
1613  print '<td>'.img_object($langs->trans("ShowProductOrService"), ($objp->product_type ? 'service' : 'product')).' '.dol_htmlentitiesbr($objp->description)."</td>\n";
1614  }
1615  // TVA
1616  print '<td align="center">';
1617  print vatrate($objp->tva_tx.($objp->vat_src_code?(' ('.$objp->vat_src_code.')'):''), '%', $objp->info_bits);
1618  print '</td>';
1619  // Price
1620  print '<td align="right">'.($objp->subprice != '' ? price($objp->subprice) : '')."</td>\n";
1621  // Price multicurrency
1622  if (!empty($conf->multicurrency->enabled)) {
1623  print '<td align="right" class="linecoluht_currency nowrap">'.price($objp->multicurrency_subprice).'</td>';
1624  }
1625  // Quantite
1626  print '<td align="center">'.$objp->qty.'</td>';
1627  // Unit
1628  if($conf->global->PRODUCT_USE_UNITS) print '<td align="left">'.$langs->trans($object->lines[$cursorline-1]->getLabelOfUnit()).'</td>';
1629  // Remise
1630  if ($objp->remise_percent > 0)
1631  {
1632  print '<td align="right">'.$objp->remise_percent."%</td>\n";
1633  }
1634  else
1635  {
1636  print '<td>&nbsp;</td>';
1637  }
1638 
1639  // Margin
1640  if (! empty($conf->margin->enabled) && ! empty($conf->global->MARGIN_SHOW_ON_CONTRACT)) print '<td align="right" class="nowrap">'.price($objp->pa_ht).'</td>';
1641 
1642  // Icon move, update et delete (statut contrat 0=brouillon,1=valide,2=ferme)
1643  print '<td align="right" class="nowrap">';
1644  if ($user->rights->contrat->creer && count($arrayothercontracts) && ($object->statut >= 0))
1645  {
1646  print '<!-- link to move service line into another contract -->';
1647  print '<a class="reposition" style="padding-left: 5px;" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=move&amp;rowid='.$objp->rowid.'">';
1648  print img_picto($langs->trans("MoveToAnotherContract"),'uparrow');
1649  print '</a>';
1650  }
1651  if ($user->rights->contrat->creer && ($object->statut >= 0))
1652  {
1653  print '<a class="reposition" style="padding-left: 5px;" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=editline&amp;rowid='.$objp->rowid.'">';
1654  print img_edit();
1655  print '</a>';
1656  }
1657  if ( $user->rights->contrat->creer && ($object->statut >= 0))
1658  {
1659  print '<a style="padding-left: 5px;" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=deleteline&amp;rowid='.$objp->rowid.'">';
1660  print img_delete();
1661  print '</a>';
1662  }
1663  print '</td>';
1664 
1665  print "</tr>\n";
1666 
1667  // Dates of service planed and real
1668  if ($objp->subprice >= 0)
1669  {
1670  $colspan = 6;
1671 
1672  if ($conf->margin->enabled && $conf->global->PRODUCT_USE_UNITS) {
1673  $colspan = 8;
1674  } elseif ($conf->margin->enabled || $conf->global->PRODUCT_USE_UNITS) {
1675  $colspan = 7;
1676  }
1677 
1678  print '<tr class="oddeven">';
1679  print '<td colspan="'.$colspan.'">';
1680 
1681  // Date planned
1682  print $langs->trans("DateStartPlanned").': ';
1683  if ($objp->date_debut)
1684  {
1685  print dol_print_date($db->jdate($objp->date_debut), 'day');
1686  // Warning si date prevu passee et pas en service
1687  if ($objp->statut == 0 && $db->jdate($objp->date_debut) < ($now - $conf->contrat->services->inactifs->warning_delay)) {
1688  $warning_delay=$conf->contrat->services->inactifs->warning_delay / 3600 / 24;
1689  $textlate = $langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($warning_delay) >= 0 ? '+' : '').ceil($warning_delay).' '.$langs->trans("days");
1690  print " ".img_warning($textlate);
1691  }
1692  }
1693  else print $langs->trans("Unknown");
1694  print ' &nbsp;-&nbsp; ';
1695  print $langs->trans("DateEndPlanned").': ';
1696  if ($objp->date_fin)
1697  {
1698  print dol_print_date($db->jdate($objp->date_fin), 'day');
1699  if ($objp->statut == 4 && $db->jdate($objp->date_fin) < ($now - $conf->contrat->services->expires->warning_delay)) {
1700  $warning_delay=$conf->contrat->services->expires->warning_delay / 3600 / 24;
1701  $textlate = $langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($warning_delay) >= 0 ? '+' : '').ceil($warning_delay).' '.$langs->trans("days");
1702  print " ".img_warning($textlate);
1703  }
1704  }
1705  else print $langs->trans("Unknown");
1706 
1707  print '</td>';
1708  print '</tr>';
1709  }
1710 
1711  // Display lines extrafields
1712  if (is_array($extralabelslines) && count($extralabelslines)>0) {
1713  $line = new ContratLigne($db);
1714  $line->fetch_optionals($objp->rowid);
1715  print $line->showOptionals($extrafieldsline, 'view', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1);
1716  }
1717  }
1718  // Ligne en mode update
1719  else
1720  {
1721  // Ligne carac
1722  print '<tr class="oddeven">';
1723  print '<td>';
1724  if ($objp->fk_product)
1725  {
1726  $productstatic->id=$objp->fk_product;
1727  $productstatic->type=$objp->ptype;
1728  $productstatic->ref=$objp->pref;
1729  $productstatic->entity=$objp->pentity;
1730  print $productstatic->getNomUrl(1,'',32);
1731  print $objp->label?' - '.dol_trunc($objp->label,32):'';
1732  print '<br>';
1733  }
1734  else
1735  {
1736  print $objp->label?$objp->label.'<br>':'';
1737  }
1738 
1739  // editeur wysiwyg
1740  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1741  $nbrows=ROWS_2;
1742  if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT;
1743  $enable=(isset($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0);
1744  $doleditor=new DolEditor('product_desc',$objp->description,'',92,'dolibarr_details','',false,true,$enable,$nbrows,'90%');
1745  $doleditor->Create();
1746 
1747  print '</td>';
1748  print '<td align="right">';
1749  print $form->load_tva("eltva_tx", $objp->tva_tx.($objp->vat_src_code?(' ('.$objp->vat_src_code.')'):''), $mysoc, $object->thirdparty, $objp->fk_product, $objp->info_bits, $objp->product_type, 0, 1);
1750  print '</td>';
1751  print '<td align="right"><input size="5" type="text" name="elprice" value="'.price($objp->subprice).'"></td>';
1752  print '<td align="center"><input size="2" type="text" name="elqty" value="'.$objp->qty.'"></td>';
1753  if ($conf->global->PRODUCT_USE_UNITS)
1754  {
1755  print '<td align="left">';
1756  print $form->selectUnits($objp->fk_unit, "unit");
1757  print '</td>';
1758  }
1759  print '<td align="right" class="nowrap"><input size="1" type="text" name="elremise_percent" value="'.$objp->remise_percent.'">%</td>';
1760  if (! empty($usemargins))
1761  {
1762  print '<td align="right">';
1763  if ($objp->fk_product) print '<select id="fournprice" name="fournprice"></select>';
1764  print '<input id="buying_price" type="text" size="5" name="buying_price" value="'.price($objp->pa_ht,0,'',0).'"></td>';
1765  }
1766  print '<td align="center">';
1767  print '<input type="submit" class="button" name="save" value="'.$langs->trans("Modify").'">';
1768  print '<br><input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
1769  print '</td>';
1770  print '</tr>';
1771 
1772  $colspan=6;
1773  if (! empty($conf->margin->enabled) && ! empty($conf->global->MARGIN_SHOW_ON_CONTRACT)) $colspan++;
1774  if($conf->global->PRODUCT_USE_UNITS) $colspan++;
1775 
1776  // Ligne dates prevues
1777  print '<tr class="oddeven">';
1778  print '<td colspan="'.$colspan.'">';
1779  print $langs->trans("DateStartPlanned").' ';
1780  print $form->selectDate($db->jdate($objp->date_debut), "date_start_update", $usehm, $usehm, ($db->jdate($objp->date_debut)>0?0:1), "update");
1781  print ' &nbsp;&nbsp;'.$langs->trans("DateEndPlanned").' ';
1782  print $form->selectDate($db->jdate($objp->date_fin), "date_end_update", $usehm, $usehm, ($db->jdate($objp->date_fin)>0?0:1), "update");
1783  print '</td>';
1784  print '</tr>';
1785 
1786  if (is_array($extralabelslines) && count($extralabelslines)>0) {
1787  $line = new ContratLigne($db);
1788  $line->fetch_optionals($objp->rowid);
1789  print $line->showOptionals($extrafieldsline, 'edit', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1);
1790  }
1791  }
1792 
1793  $db->free($result);
1794  }
1795  else
1796  {
1797  dol_print_error($db);
1798  }
1799 
1800  if ($object->statut > 0)
1801  {
1802  print '<tr class="oddeven">';
1803  print '<td class="tdhrthin" colspan="'.($conf->margin->enabled?7:6).'"><hr class="opacitymedium tdhrthin"></td>';
1804  print "</tr>\n";
1805  }
1806 
1807  print "</table>";
1808  print '</div>';
1809 
1810  print "</form>\n";
1811 
1812 
1813  /*
1814  * Confirmation to delete service line of contract
1815  */
1816  if ($action == 'deleteline' && ! $_REQUEST["cancel"] && $user->rights->contrat->creer && $object->lines[$cursorline-1]->id == GETPOST('rowid'))
1817  {
1818  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid'),$langs->trans("DeleteContractLine"),$langs->trans("ConfirmDeleteContractLine"),"confirm_deleteline",'',0,1);
1819  if ($ret == 'html') print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1820  }
1821 
1822  /*
1823  * Confirmation to move service toward another contract
1824  */
1825  if ($action == 'move' && ! $_REQUEST["cancel"] && $user->rights->contrat->creer && $object->lines[$cursorline-1]->id == GETPOST('rowid'))
1826  {
1827  $arraycontractid=array();
1828  foreach($arrayothercontracts as $contractcursor)
1829  {
1830  $arraycontractid[$contractcursor->id]=$contractcursor->ref;
1831  }
1832  //var_dump($arraycontractid);
1833  // Cree un tableau formulaire
1834  $formquestion=array(
1835  'text' => $langs->trans("ConfirmMoveToAnotherContractQuestion"),
1836  array('type' => 'select', 'name' => 'newcid', 'values' => $arraycontractid));
1837 
1838  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid'),$langs->trans("MoveToAnotherContract"),$langs->trans("ConfirmMoveToAnotherContract"),"confirm_move",$formquestion);
1839  print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1840  }
1841 
1842  /*
1843  * Confirmation de la validation activation
1844  */
1845  if ($action == 'active' && ! $_REQUEST["cancel"] && $user->rights->contrat->activer && $object->lines[$cursorline-1]->id == GETPOST('ligne'))
1846  {
1847  $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
1848  $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
1849  $comment = GETPOST('comment','alpha');
1850  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment),$langs->trans("ActivateService"),$langs->trans("ConfirmActivateService",dol_print_date($dateactstart,"%A %d %B %Y")),"confirm_active", '', 0, 1);
1851  print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1852  }
1853 
1854  /*
1855  * Confirmation de la validation fermeture
1856  */
1857  if ($action == 'closeline' && ! $_REQUEST["cancel"] && $user->rights->contrat->activer && $object->lines[$cursorline-1]->id == GETPOST('ligne'))
1858  {
1859  $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
1860  $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
1861  $comment = GETPOST('comment','alpha');
1862 
1863  if (empty($dateactend))
1864  {
1865  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEndReal")), null, 'errors');
1866  }
1867  else
1868  {
1869  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&ligne=".GETPOST('ligne','int')."&date=".$dateactstart."&dateend=".$dateactend."&comment=".urlencode($comment), $langs->trans("CloseService"), $langs->trans("ConfirmCloseService",dol_print_date($dateactend,"%A %d %B %Y")), "confirm_closeline", '', 0, 1);
1870  }
1871  print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1872  }
1873 
1874 
1875  // Area with status and activation info of line
1876  if ($object->statut > 0)
1877  {
1878  print '<table class="notopnoleftnoright tableforservicepart2'.($cursorline < $nbofservices ?' boxtablenobottom':'').'" width="100%">';
1879 
1880  print '<tr class="oddeven">';
1881  print '<td>'.$langs->trans("ServiceStatus").': '.$object->lines[$cursorline-1]->getLibStatut(4).'</td>';
1882  print '<td width="30" align="right">';
1883  if ($user->societe_id == 0)
1884  {
1885  if ($object->statut > 0 && $action != 'activateline' && $action != 'unactivateline')
1886  {
1887  $tmpaction='activateline';
1888  $tmpactionpicto='play';
1889  $tmpactiontext=$langs->trans("Activate");
1890  if ($objp->statut == 4)
1891  {
1892  $tmpaction='unactivateline';
1893  $tmpactionpicto='playstop';
1894  $tmpactiontext=$langs->trans("Disable");
1895  }
1896  if (($tmpaction=='activateline' && $user->rights->contrat->activer) || ($tmpaction=='unactivateline' && $user->rights->contrat->desactiver))
1897  {
1898  print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;ligne=' . $object->lines[$cursorline - 1]->id . '&amp;action=' . $tmpaction . '">';
1899  print img_picto($tmpactiontext, $tmpactionpicto);
1900  print '</a>';
1901  }
1902  }
1903  }
1904  print '</td>';
1905  print "</tr>\n";
1906 
1907  print '<tr class="oddeven">';
1908 
1909  print '<td>';
1910  // Si pas encore active
1911  if (! $objp->date_debut_reelle) {
1912  print $langs->trans("DateStartReal").': ';
1913  if ($objp->date_debut_reelle) print dol_print_date($objp->date_debut_reelle, 'day');
1914  else print $langs->trans("ContractStatusNotRunning");
1915  }
1916  // Si active et en cours
1917  if ($objp->date_debut_reelle && ! $objp->date_fin_reelle) {
1918  print $langs->trans("DateStartReal").': ';
1919  print dol_print_date($objp->date_debut_reelle, 'day');
1920  }
1921  // Si desactive
1922  if ($objp->date_debut_reelle && $objp->date_fin_reelle) {
1923  print $langs->trans("DateStartReal").': ';
1924  print dol_print_date($objp->date_debut_reelle, 'day');
1925  print ' &nbsp;-&nbsp; ';
1926  print $langs->trans("DateEndReal").': ';
1927  print dol_print_date($objp->date_fin_reelle, 'day');
1928  }
1929  if (! empty($objp->comment)) print " &nbsp;-&nbsp; ".$objp->comment;
1930  print '</td>';
1931 
1932  print '<td align="center">&nbsp;</td>';
1933 
1934  print '</tr>';
1935  print '</table>';
1936  }
1937 
1938  // Form to activate line
1939  if ($user->rights->contrat->activer && $action == 'activateline' && $object->lines[$cursorline-1]->id == GETPOST('ligne'))
1940  {
1941  print '<form name="active" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;ligne='.GETPOST('ligne').'&amp;action=active" method="post">';
1942  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1943 
1944  print '<table class="noborder tableforservicepart2'.($cursorline < $nbofservices ?' boxtablenobottom':'').'" width="100%">';
1945 
1946  // Definie date debut et fin par defaut
1947  $dateactstart = $objp->date_debut;
1948  if (GETPOST('remonth')) $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
1949  elseif (! $dateactstart) $dateactstart = time();
1950 
1951  $dateactend = $objp->date_fin;
1952  if (GETPOST('endmonth')) $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
1953  elseif (! $dateactend)
1954  {
1955  if ($objp->fk_product > 0)
1956  {
1957  $product=new Product($db);
1958  $product->fetch($objp->fk_product);
1959  $dateactend = dol_time_plus_duree(time(), $product->duration_value, $product->duration_unit);
1960  }
1961  }
1962 
1963  print '<tr class="oddeven">';
1964  print '<td class="nohover">'.$langs->trans("DateServiceActivate").'</td><td class="nohover">';
1965  print $form->selectDate($dateactstart, '', $usehm, $usehm, '', "active", 1, 0);
1966  print '</td>';
1967  print '<td class="nohover">'.$langs->trans("DateEndPlanned").'</td><td class="nohover">';
1968  print $form->selectDate($dateactend, "end", $usehm, $usehm, '', "active", 1, 0);
1969  print '</td>';
1970  print '<td class="center nohover">';
1971  print '</td>';
1972 
1973  print '</tr>';
1974 
1975  print '<tr class="oddeven">';
1976  print '<td class="nohover">'.$langs->trans("Comment").'</td><td colspan="3" class="nohover" colspan="'.($conf->margin->enabled?4:3).'"><input size="80" type="text" name="comment" value="'.$_POST["comment"].'"></td>';
1977  print '<td class="nohover right">';
1978  print '<input type="submit" class="button" name="activate" value="'.$langs->trans("Activate").'"> &nbsp; ';
1979  print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
1980  print '</td>';
1981  print '</tr>';
1982 
1983  print '</table>';
1984 
1985  print '</form>';
1986  }
1987 
1988  if ($user->rights->contrat->activer && $action == 'unactivateline' && $object->lines[$cursorline-1]->id == GETPOST('ligne'))
1989  {
1993  print '<!-- Form to disabled a line -->'."\n";
1994  print '<form name="closeline" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;ligne='.$object->lines[$cursorline-1]->id.'" method="post">';
1995 
1996  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1997  print '<input type="hidden" name="action" value="closeline">';
1998 
1999  print '<table class="noborder tableforservicepart2'.($cursorline < $nbofservices ?' boxtablenobottom':'').'" width="100%">';
2000 
2001  // Definie date debut et fin par defaut
2002  $dateactstart = $objp->date_debut_reelle;
2003  if (GETPOST('remonth')) $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
2004  elseif (! $dateactstart) $dateactstart = time();
2005 
2006  $dateactend = $objp->date_fin_reelle;
2007  if (GETPOST('endmonth')) $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
2008  elseif (! $dateactend)
2009  {
2010  if ($objp->fk_product > 0)
2011  {
2012  $product=new Product($db);
2013  $product->fetch($objp->fk_product);
2014  $dateactend = dol_time_plus_duree(time(), $product->duration_value, $product->duration_unit);
2015  }
2016  }
2017  $now=dol_now();
2018  if ($dateactend > $now) $dateactend=$now;
2019 
2020  print '<tr class="oddeven"><td colspan="2" class="nohover">';
2021  if ($objp->statut >= 4)
2022  {
2023  if ($objp->statut == 4)
2024  {
2025  print $langs->trans("DateEndReal").' ';
2026  print $form->selectDate($dateactend, "end", $usehm, $usehm, ($objp->date_fin_reelle>0?0:1), "closeline", 1, 1);
2027  }
2028  }
2029  print '</td>';
2030  print '<td class="center nohover">';
2031  print '</td></tr>';
2032 
2033  print '<tr class="oddeven">';
2034  print '<td class="nohover">'.$langs->trans("Comment").'</td><td class="nohover"><input size="70" type="text" class="flat" name="comment" value="'.dol_escape_htmltag(GETPOST('comment', 'alpha')).'"></td>';
2035  print '<td class="nohover right">';
2036  print '<input type="submit" class="button" name="close" value="'.$langs->trans("Disable").'"> &nbsp; ';
2037  print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
2038  print '</td>';
2039  print '</tr>';
2040 
2041  print '</table>';
2042 
2043  print '</form>';
2044  }
2045  print '</div>';
2046  $cursorline++;
2047  }
2048  print '</div>';
2049 
2050  // Form to add new line
2051  if ($user->rights->contrat->creer && ($object->statut == 0))
2052  {
2053  $dateSelector=1;
2054 
2055  print "\n";
2056  print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline')?'#add':'#line_'.GETPOST('lineid')).'" method="POST">
2057  <input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">
2058  <input type="hidden" name="action" value="'.(($action != 'editline')?'addline':'updateline').'">
2059  <input type="hidden" name="mode" value="">
2060  <input type="hidden" name="id" value="'.$object->id.'">
2061  ';
2062 
2063  print '<div class="div-table-responsive-no-min">';
2064  print '<table id="tablelines" class="noborder noshadow" width="100%">'; // Array with (n*2)+1 lines
2065 
2066  // Trick to not show product entries
2067  $savproductenabled=$conf->product->enabled;
2068  if (empty($conf->global->CONTRACT_SUPPORT_PRODUCTS)) $conf->product->enabled = 0;
2069 
2070  // Form to add new line
2071  if ($action != 'editline')
2072  {
2073  $forcetoshowtitlelines=1;
2074 
2075  // Add free products/services
2076  $object->formAddObjectLine(1, $mysoc, $soc);
2077 
2078  $parameters = array();
2079  $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2080  }
2081 
2082  // Restore correct setup
2083  $conf->product->enabled = $savproductenabled;
2084 
2085  print '</table>';
2086  print '</div>';
2087  print '</form>';
2088  }
2089 
2090  dol_fiche_end();
2091 
2092 
2093  /*
2094  * Buttons
2095  */
2096 
2097  if ($user->societe_id == 0)
2098  {
2099  print '<div class="tabsAction">';
2100 
2101  $parameters=array();
2102  $reshook=$hookmanager->executeHooks('addMoreActionsButtons',$parameters,$object,$action); // Note that $action and $object may have been modified by hook
2103 
2104  if (empty($reshook))
2105  {
2106  // Send
2107  if ($object->statut == 1) {
2108  if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->commande->order_advance->send)) {
2109  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init#formmailbeforetitle">' . $langs->trans('SendMail') . '</a></div>';
2110  } else
2111  print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">' . $langs->trans('SendMail') . '</a></div>';
2112  }
2113 
2114  if ($object->statut == 0 && $nbofservices)
2115  {
2116  if ($user->rights->contrat->creer) print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=valid">'.$langs->trans("Validate").'</a></div>';
2117  else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans("Validate").'</a></div>';
2118  }
2119  if ($object->statut == 1)
2120  {
2121  if ($user->rights->contrat->creer) print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=reopen">'.$langs->trans("Modify").'</a></div>';
2122  else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans("Modify").'</a></div>';
2123  }
2124 
2125  if (! empty($conf->facture->enabled) && $object->statut > 0)
2126  {
2127  $langs->load("bills");
2128  if ($user->rights->facture->creer) print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->thirdparty->id.'">'.$langs->trans("CreateBill").'</a></div>';
2129  else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans("CreateBill").'</a></div>';
2130  }
2131 
2132  if (! empty($conf->commande->enabled) && $object->statut > 0 && $object->nbofservicesclosed < $nbofservices)
2133  {
2134  $langs->load("orders");
2135  if ($user->rights->commande->creer) print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/commande/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->thirdparty->id.'">'.$langs->trans("CreateOrder").'</a></div>';
2136  else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans("CreateOrder").'</a></div>';
2137  }
2138 
2139  // Clone
2140  if ($user->rights->contrat->creer) {
2141  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;socid=' . $object->socid . '&amp;action=clone&amp;object=' . $object->element . '">' . $langs->trans("ToClone") . '</a></div>';
2142  }
2143 
2144  if ($object->nbofservicesclosed > 0 || $object->nbofserviceswait > 0)
2145  {
2146  if ($user->rights->contrat->activer)
2147  {
2148  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=activate">'.$langs->trans("ActivateAllContracts").'</a></div>';
2149  }
2150  else
2151  {
2152  print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">'.$langs->trans("ActivateAllContracts").'</a></div>';
2153  }
2154  }
2155  if ($object->nbofservicesclosed < $nbofservices)
2156  {
2157  if ($user->rights->contrat->desactiver)
2158  {
2159  print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=close">'.$langs->trans("CloseAllContracts").'</a></div>';
2160  }
2161  else
2162  {
2163  print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">'.$langs->trans("CloseAllContracts").'</a></div>';
2164  }
2165 
2166  //if (! $numactive)
2167  //{
2168  //}
2169  //else
2170  //{
2171  // print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.$langs->trans("CloseRefusedBecauseOneServiceActive").'">'.$langs->trans("Close").'</a></div>';
2172  //}
2173  }
2174 
2175  // On peut supprimer entite si
2176  // - Droit de creer + mode brouillon (erreur creation)
2177  // - Droit de supprimer
2178  if (($user->rights->contrat->creer && $object->statut == 0) || $user->rights->contrat->supprimer)
2179  {
2180  print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete">'.$langs->trans("Delete").'</a></div>';
2181  }
2182  else
2183  {
2184  print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("Delete").'</a></div>';
2185  }
2186  }
2187 
2188  print "</div>";
2189  }
2190 
2191  // Select mail models is same action as presend
2192  if (GETPOST('modelselected')) {
2193  $action = 'presend';
2194  }
2195 
2196  if ($action != 'presend')
2197  {
2198  print '<div class="fichecenter"><div class="fichehalfleft">';
2199 
2200  /*
2201  * Documents generes
2202  */
2203  $filename = dol_sanitizeFileName($object->ref);
2204  $filedir = $conf->contrat->dir_output . "/" . dol_sanitizeFileName($object->ref);
2205  $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id;
2206  $genallowed = $user->rights->contrat->lire;
2207  $delallowed = $user->rights->contrat->creer;
2208 
2209 
2210  print $formfile->showdocuments('contract', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang);
2211 
2212 
2213  // Show links to link elements
2214  $linktoelem = $form->showLinkToObjectBlock($object, null, array('contrat'));
2215  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2216 
2217 
2218  print '</div><div class="fichehalfright"><div class="ficheaddleft">';
2219 
2220  // List of actions on element
2221  include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
2222  $formactions = new FormActions($db);
2223  $somethingshown = $formactions->showactions($object, 'contract', $socid, 1);
2224 
2225 
2226  print '</div></div></div>';
2227  }
2228 
2229  // Presend form
2230  $modelmail='contract';
2231  $defaulttopic='SendContractRef';
2232  $diroutput = $conf->contrat->dir_output;
2233  $trackid = 'con'.$object->id;
2234 
2235  include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2236  }
2237 }
2238 
2239 
2240 llxFooter();
2241 
2242 $db->close();
2243 ?>
2244 
2245 <?php
2246 if (! empty($conf->margin->enabled) && $action == 'editline')
2247 {
2248 ?>
2249 
2250 <script type="text/javascript">
2251 $(document).ready(function() {
2252  var idprod = $("input[name='idprod']").val();
2253  var fournprice = $("input[name='fournprice']").val();
2254  if (idprod > 0) {
2255  $.post('<?php echo DOL_URL_ROOT; ?>/fourn/ajax/getSupplierPrices.php', {'idprod': idprod}, function(data) {
2256  if (data.length > 0) {
2257  var options = '';
2258  var trouve=false;
2259  $(data).each(function() {
2260  options += '<option value="'+this.id+'" price="'+this.price+'"';
2261  if (fournprice > 0) {
2262  if (this.id == fournprice) {
2263  options += ' selected';
2264  $("#buying_price").val(this.price);
2265  trouve = true;
2266  }
2267  }
2268  options += '>'+this.label+'</option>';
2269  });
2270  options += '<option value=null'+(trouve?'':' selected')+'><?php echo $langs->trans("InputPrice"); ?></option>';
2271  $("#fournprice").html(options);
2272  if (trouve) {
2273  $("#buying_price").hide();
2274  $("#fournprice").show();
2275  }
2276  else {
2277  $("#buying_price").show();
2278  }
2279  $("#fournprice").change(function() {
2280  var selval = $(this).find('option:selected').attr("price");
2281  if (selval)
2282  $("#buying_price").val(selval).hide();
2283  else
2284  $('#buying_price').show();
2285  });
2286  }
2287  else {
2288  $("#fournprice").hide();
2289  $('#buying_price').show();
2290  }
2291  },
2292  'json');
2293  }
2294  else {
2295  $("#fournprice").hide();
2296  $('#buying_price').show();
2297  }
2298 });
2299 </script>
2300 
2301 <?php
2302 }
print $object label
hash of file content (md5_file(dol_osencode($destfull))
Definition: edit.php:153
File of class to manage predefined price products or services by customer.
llxFooter()
Empty footer.
Definition: wrapper.php:56
load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
GETPOST($paramname, $check='none', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
print
Draft customers invoices.
Definition: index.php:91
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
Class to manage building of HTML components.
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action=='set') else if($action=='specimen') else if($action=='setmodel') else if($action=='del') else if($action=='setdoc') $formactions
View.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm=false, $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
img_edit($titlealt='default', $float=0, $other='class="pictoedit"')
Show logo editer/modifier fiche.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
Class to manage products or services.
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
Class to manage Dolibarr users.
Definition: user.class.php:41
Class to manage contracts.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for properties) With native = 0: P...
contract_prepare_head(Contrat $object)
Prepare array with list of tabs.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
Classe permettant la gestion des lignes de contrats.
dol_concatdesc($text1, $text2, $forxml=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Fonction qui renvoie si tva doit etre tva percue recuperable.
get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller="", $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate, from a $thirdparty_buyer to a $thirdparty_seller Note: This function applies same rules than get_default_tva.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
img_delete($titlealt='default', $other='class="pictodelete"')
Show delete logo.
dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1)
Move a file into another name.
Definition: files.lib.php:814
Class to manage standard extra fields.
Class to manage generation of HTML components Only common components must be here.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
type
Definition: viewcat.php:284
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage projects.
if(! function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
Class to manage building of HTML components.
dol_fiche_end($notab=0)
Show tab footer of a card.
llxHeader()
Empty header.
Definition: wrapper.php:44
Class to manage translations.
if(GETPOST('cancel', 'alpha')) if(! GETPOST( 'confirmmassaction', 'alpha') &&$massaction !='presend' &&$massaction !='confirm_presend')
Draft customers invoices.
Definition: list.php:156
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:59
dol_now($mode='gmt')
Return date for now.
if($_POST["cancel"]==$langs->trans("Cancel") &&! $id) if($action=='add' && $_POST["cancel"]<> $langs->trans("Cancel")) if($action=='delete') if($id) $form
Actions.
Definition: card.php:153
Class to offer components to list and upload files.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages...
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages...
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_mkdir($dir, $dataroot='', $newmask=null)
Creation of a directory (this can create recursive subdir)
restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) Si ...
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
Class to manage a WYSIWYG editor.
dol_time_plus_duree($time, $duration_value, $duration_unit)
Add a delay to a date.
Definition: date.lib.php:116
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it&#39;s its name (generic function)
price2num($amount, $rounding='', $alreadysqlnb=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='')
Show tab header of a card.
$parameters
Actions.
Definition: card.php:114