Passed
Push — master ( 0f9140...c4489d )
by Alxarafe
22:27
created

dolibarr/htdocs/compta/facture/card.php (2 issues)

1
<?php
2
/* Copyright (C) 2002-2006  Rodolphe Quiedeville    <[email protected]>
3
 * Copyright (C) 2004       Eric Seigne             <[email protected]>
4
 * Copyright (C) 2004-2016  Laurent Destailleur     <[email protected]>
5
 * Copyright (C) 2005       Marc Barilley / Ocebo   <[email protected]>
6
 * Copyright (C) 2005-2015  Regis Houssin           <[email protected]>
7
 * Copyright (C) 2006       Andre Cianfarani        <[email protected]>
8
 * Copyright (C) 2010-2015  Juanjo Menent           <[email protected]>
9
 * Copyright (C) 2012-2013  Christophe Battarel     <[email protected]>
10
 * Copyright (C) 2012-2013  Cédric Salvador         <[email protected]>
11
 * Copyright (C) 2012-2014  Raphaël Doursenaud      <[email protected]>
12
 * Copyright (C) 2013       Jean-Francois FERRY     <[email protected]>
13
 * Copyright (C) 2013-2014  Florian Henry           <[email protected]>
14
 * Copyright (C) 2013       Cédric Salvador         <[email protected]>
15
 * Copyright (C) 2014-2018  Ferran Marcet           <[email protected]>
16
 * Copyright (C) 2015-2016  Marcos García           <[email protected]>
17
 * Copyright (C) 2018       Frédéric France         <[email protected]>
18
 *
19
 * This program is free software; you can redistribute it and/or modify
20
 * it under the terms of the GNU General Public License as published by
21
 * the Free Software Foundation; either version 3 of the License, or
22
 * (at your option) any later version.
23
 *
24
 * This program is distributed in the hope that it will be useful,
25
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
 * GNU General Public License for more details.
28
 *
29
 * You should have received a copy of the GNU General Public License
30
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31
 */
32
33
/**
34
 * \file 	htdocs/compta/facture/card.php
35
 * \ingroup facture
36
 * \brief 	Page to create/see an invoice
37
 */
38
39
40
// Copyright (C) 2018 Alxarafe/Alixar  <[email protected]>
41
defined('BASE_PATH') or die('Single entry point through the index.php of the main folder');
42
require DOL_BASE_PATH . '/main.inc.php';
43
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
44
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture-rec.class.php';
45
require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php';
46
require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
47
require_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php';
48
require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
49
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
50
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
51
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formmargin.class.php';
52
require_once DOL_DOCUMENT_ROOT . '/core/lib/invoice.lib.php';
53
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
54
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
55
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
56
if (! empty($conf->commande->enabled))
57
	require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
58
if (! empty($conf->projet->enabled)) {
59
	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
60
	require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
61
}
62
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
63
64
if (!empty($conf->variants->enabled)) {
65
	require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
66
}
67
if (! empty($conf->accounting->enabled)) {
68
	require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
69
}
70
71
// Load translation files required by the page
72
$langs->loadLangs(array('bills','companies','compta','products','banks','main','withdrawals'));
73
if (! empty($conf->incoterm->enabled)) $langs->load('incoterm');
74
if (! empty($conf->margin->enabled)) $langs->load('margins');
75
76
$projectid = (GETPOST('projectid','int') ? GETPOST('projectid', 'int') : 0);
77
78
$id = (GETPOST('id', 'int') ? GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility
79
$ref = GETPOST('ref', 'alpha');
80
$socid = GETPOST('socid', 'int');
81
$action = GETPOST('action', 'alpha');
82
$confirm = GETPOST('confirm', 'alpha');
83
$cancel = GETPOST('cancel', 'alpha');
84
$lineid = GETPOST('lineid', 'int');
85
$userid = GETPOST('userid', 'int');
86
$search_ref = GETPOST('sf_ref','alpha') ? GETPOST('sf_ref', 'alpha') : GETPOST('search_ref', 'alpha');
87
$search_societe = GETPOST('search_societe', 'alpha');
88
$search_montant_ht = GETPOST('search_montant_ht', 'alpha');
89
$search_montant_ttc = GETPOST('search_montant_ttc', 'alpha');
90
$origin = GETPOST('origin', 'alpha');
91
$originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility
92
$fac_rec=GETPOST('fac_rec','int');
93
94
// PDF
95
$hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
96
$hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
97
$hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
98
99
// Nombre de ligne pour choix de produit/service predefinis
100
$NBLINES = 4;
101
102
$usehm = (! empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE) ? $conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE : 0);
103
104
$object = new Facture($db);
105
$extrafields = new ExtraFields($db);
106
107
// Load object
108
if ($id > 0 || ! empty($ref)) {
109
	$ret = $object->fetch($id, $ref, '', '', $conf->global->INVOICE_USE_SITUATION);
110
}
111
112
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
113
$hookmanager->initHooks(array('invoicecard','globalcard'));
114
115
$usercanread = $user->rights->facture->lire;
116
$usercancreate = $user->rights->facture->creer;
117
$usercanissuepayment = $user->rights->facture->paiement;
118
$usercandelete = $user->rights->facture->supprimer;
119
$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->validate)));
120
$usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->send);
121
$usercanreopen = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->facture->invoice_advance->reopen);
122
$usercanunvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($usercancreate)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate)));
123
124
$usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS));
125
$usercancreatemargin = $user->rights->margins->creer;
126
$usercanreadallmargin = $user->rights->margins->liretous;
127
$usercancreatewithdrarequest = $user->rights->prelevement->bons->creer;
128
129
$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
130
$permissiondellink = $usercancreate;	// Used by the include of actions_dellink.inc.php
131
$permissiontoedit = $usercancreate; // Used by the include of actions_lineupdonw.inc.php
132
133
// Security check
134
$fieldid = (! empty($ref) ? 'ref' : 'rowid');
135
if ($user->societe_id) $socid = $user->societe_id;
136
$isdraft = (($object->statut == Facture::STATUS_DRAFT) ? 1 : 0);
137
$result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid, $isdraft);
138
139
/*
140
 * Actions
141
 */
142
143
$parameters = array('socid' => $socid);
144
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
145
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
146
147
if (empty($reshook))
148
{
149
	if ($cancel)
150
	{
151
		if (! empty($backtopage))
152
		{
153
			header("Location: ".$backtopage);
154
			exit;
155
		}
156
		$action='';
157
	}
158
159
	include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once
160
161
	include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';		// Must be include, not include_once
162
163
	include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';	// Must be include, not include_once
164
165
	// Action clone object
166
	if ($action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
167
	//	if (1 == 0 && empty($_REQUEST["clone_content"]) && empty($_REQUEST["clone_receivers"])) {
168
	//		$mesgs [] = '<div class="error">' . $langs->trans("NoCloneOptionsSpecified") . '</div>';
169
	//	} else {
170
			if ($object->fetch($id) > 0) {
171
				$result = $object->createFromClone($socid);
172
				if ($result > 0) {
173
					header("Location: " . $_SERVER['PHP_SELF'] . '?facid=' . $result);
174
					exit();
175
				} else {
176
					setEventMessages($object->error, $object->errors, 'errors');
177
					$action = '';
178
				}
179
			}
180
	//	}
181
	}
182
183
	// Change status of invoice
184
	else if ($action == 'reopen' && $usercancreate) {
185
		$result = $object->fetch($id);
186
		if ($object->statut == 2 || ($object->statut == 3 && $object->close_code != 'replaced') || ($object->statut == 1 && $object->paye == 1)) {    // ($object->statut == 1 && $object->paye == 1) should not happened but can be found when data are corrupted
187
			$result = $object->set_unpaid($user);
188
			if ($result > 0) {
189
				header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
190
				exit();
191
			} else {
192
				setEventMessages($object->error, $object->errors, 'errors');
193
			}
194
		}
195
	}
196
197
	// Delete invoice
198
	else if ($action == 'confirm_delete' && $confirm == 'yes') {
199
		$result = $object->fetch($id);
200
		$object->fetch_thirdparty();
201
202
		$idwarehouse = GETPOST('idwarehouse');
203
204
		$qualified_for_stock_change = 0;
205
		if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
206
			$qualified_for_stock_change = $object->hasProductsOrServices(2);
207
		} else {
208
			$qualified_for_stock_change = $object->hasProductsOrServices(1);
209
		}
210
211
		$isErasable=$object->is_erasable();
212
213
		if (($usercandelete && $isErasable > 0)
214
			|| ($usercancreate && $isErasable == 1))
215
		{
216
			$result = $object->delete($user, 0, $idwarehouse);
217
			if ($result > 0) {
218
				header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php?restore_lastsearch_values=1');
219
				exit();
220
			} else {
221
				setEventMessages($object->error, $object->errors, 'errors');
222
				$action='';
223
			}
224
		}
225
	}
226
227
	// Delete line
228
	else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate)
229
	{
230
		$object->fetch($id);
231
		$object->fetch_thirdparty();
232
233
		$result = $object->deleteline(GETPOST('lineid'));
234
		if ($result > 0) {
235
			// Define output language
236
			$outputlangs = $langs;
237
			$newlang = '';
238
			if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id']))
239
				$newlang = $_REQUEST['lang_id'];
240
			if ($conf->global->MAIN_MULTILANGS && empty($newlang))
241
				$newlang = $object->thirdparty->default_lang;
242
			if (! empty($newlang)) {
243
				$outputlangs = new Translate("", $conf);
244
				$outputlangs->setDefaultLang($newlang);
245
				$outputlangs->load('products');
246
			}
247
			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
248
				$ret = $object->fetch($id); // Reload to get new records
249
				$result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
250
			}
251
			if ($result >= 0) {
252
				header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
253
				exit();
254
			}
255
		} else {
256
			setEventMessages($object->error, $object->errors, 'errors');
257
			$action = '';
258
		}
259
	}
260
261
	// Delete link of credit note to invoice
262
	else if ($action == 'unlinkdiscount' && $usercancreate)
263
	{
264
		$discount = new DiscountAbsolute($db);
265
		$result = $discount->fetch(GETPOST("discountid"));
266
		$discount->unlink_invoice();
267
	}
268
269
	// Validation
270
	else if ($action == 'valid' && $usercancreate)
271
	{
272
		$object->fetch($id);
273
274
		// On verifie signe facture
275
		if ($object->type == Facture::TYPE_CREDIT_NOTE) {
276
			// Si avoir, le signe doit etre negatif
277
			if ($object->total_ht >= 0) {
278
				setEventMessages($langs->trans("ErrorInvoiceAvoirMustBeNegative"), null, 'errors');
279
				$action = '';
280
			}
281
		} else {
282
			// Si non avoir, le signe doit etre positif
283
			if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) {
284
				setEventMessages($langs->trans("ErrorInvoiceOfThisTypeMustBePositive"), null, 'errors');
285
				$action = '';
286
			}
287
		}
288
	}
289
290
	else if ($action == 'set_thirdparty' && $usercancreate)
291
	{
292
		$object->fetch($id);
293
		$object->setValueFrom('fk_soc', $socid, '', null, 'int', '', $user, 'BILL_MODIFY');
294
295
		header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
296
		exit();
297
	}
298
299
	else if ($action == 'classin' && $usercancreate)
300
	{
301
		$object->fetch($id);
302
		$object->setProject($_POST['projectid']);
303
	}
304
305
	else if ($action == 'setmode' && $usercancreate)
306
	{
307
		$object->fetch($id);
308
		$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
309
		if ($result < 0)
310
			dol_print_error($db, $object->error);
311
	}
312
313
	// Multicurrency Code
314
	else if ($action == 'setmulticurrencycode' && $usercancreate) {
315
		$result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
316
	}
317
318
	// Multicurrency rate
319
	else if ($action == 'setmulticurrencyrate' && $usercancreate) {
320
		$result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx')), GETPOST('calculation_mode', 'int'));
321
	}
322
323
	else if ($action == 'setinvoicedate' && $usercancreate)
324
	{
325
		$object->fetch($id);
326
		$old_date_lim_reglement = $object->date_lim_reglement;
327
		$date = dol_mktime(12, 0, 0, $_POST['invoicedatemonth'], $_POST['invoicedateday'], $_POST['invoicedateyear']);
328
		if (empty($date))
329
		{
330
			setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
331
			header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate');
332
			exit;
333
		}
334
		$object->date=$date;
335
		$new_date_lim_reglement = $object->calculate_date_lim_reglement();
336
		if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement;
337
		if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date;
338
		$result = $object->update($user);
339
		if ($result < 0) dol_print_error($db, $object->error);
340
	}
341
342
	else if ($action == 'setdate_pointoftax' && $usercancreate)
343
	{
344
		$object->fetch($id);
345
		$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
346
		$object->date_pointoftax=$date_pointoftax;
347
		$result = $object->update($user);
348
		if ($result < 0) dol_print_error($db, $object->error);
349
	}
350
351
	else if ($action == 'setconditions' && $usercancreate)
352
	{
353
		$object->fetch($id);
354
		$object->cond_reglement_code = 0; // To clean property
355
		$object->cond_reglement_id = 0; // To clean property
356
		$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
357
		if ($result < 0) dol_print_error($db, $object->error);
358
359
		$old_date_lim_reglement = $object->date_lim_reglement;
360
		$new_date_lim_reglement = $object->calculate_date_lim_reglement();
361
		if ($new_date_lim_reglement > $old_date_lim_reglement) $object->date_lim_reglement = $new_date_lim_reglement;
362
		if ($object->date_lim_reglement < $object->date) $object->date_lim_reglement = $object->date;
363
		$result = $object->update($user);
364
		if ($result < 0) dol_print_error($db, $object->error);
365
	}
366
367
	else if ($action == 'setpaymentterm' && $usercancreate)
368
	{
369
		$object->fetch($id);
370
		$object->date_lim_reglement = dol_mktime(12, 0, 0, $_POST['paymenttermmonth'], $_POST['paymenttermday'], $_POST['paymenttermyear']);
371
		if ($object->date_lim_reglement < $object->date) {
372
			$object->date_lim_reglement = $object->calculate_date_lim_reglement();
373
			setEventMessages($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), null, 'warnings');
374
		}
375
		$result = $object->update($user);
376
		if ($result < 0)
377
			dol_print_error($db, $object->error);
378
	}
379
380
	else if ($action == 'setrevenuestamp' && $usercancreate)
381
	{
382
		$object->fetch($id);
383
		$object->revenuestamp = GETPOST('revenuestamp');
384
		$result = $object->update($user);
385
		$object->update_price(1);
386
		if ($result < 0)
387
			dol_print_error($db, $object->error);
388
	}
389
390
	// Set incoterm
391
	elseif ($action == 'set_incoterms' && !empty($conf->incoterm->enabled))
392
	{
393
		$result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha'));
394
	}
395
396
	// bank account
397
	else if ($action == 'setbankaccount' && $usercancreate)
398
	{
399
		$result=$object->setBankAccount(GETPOST('fk_account', 'int'));
400
	}
401
402
	else if ($action == 'setremisepercent' && $usercancreate)
403
	{
404
		$object->fetch($id);
405
		$result = $object->set_remise($user, $_POST['remise_percent']);
406
	}
407
408
	else if ($action == "setabsolutediscount" && $usercancreate)
409
	{
410
		// POST[remise_id] or POST[remise_id_for_payment]
411
412
		// We use the credit to reduce amount of invoice
413
		if (! empty($_POST["remise_id"])) {
414
			$ret = $object->fetch($id);
415
			if ($ret > 0) {
416
				$result = $object->insert_discount($_POST["remise_id"]);
417
				if ($result < 0) {
418
					setEventMessages($object->error, $object->errors, 'errors');
419
				}
420
			} else {
421
				dol_print_error($db, $object->error);
422
			}
423
		}
424
		// We use the credit to reduce remain to pay
425
		if (! empty($_POST["remise_id_for_payment"]))
426
		{
427
			require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
428
			$discount = new DiscountAbsolute($db);
429
			$discount->fetch($_POST["remise_id_for_payment"]);
430
431
			//var_dump($object->getRemainToPay(0));
432
			//var_dump($discount->amount_ttc);exit;
433
			if (price2num($discount->amount_ttc) > price2num($object->getRemainToPay(0)))
434
			{
435
				// TODO Split the discount in 2 automatically
436
				$error++;
437
				setEventMessages($langs->trans("ErrorDiscountLargerThanRemainToPaySplitItBefore"), null, 'errors');
438
			}
439
440
			if (! $error)
441
			{
442
				$result = $discount->link_to_invoice(0, $id);
443
				if ($result < 0) {
444
					setEventMessages($discount->error, $discount->errors, 'errors');
445
				}
446
			}
447
		}
448
449
		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
450
		{
451
			$outputlangs = $langs;
452
			$newlang = '';
453
			if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
454
			if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
455
			if (! empty($newlang)) {
456
				$outputlangs = new Translate("", $conf);
457
				$outputlangs->setDefaultLang($newlang);
458
			}
459
			$ret = $object->fetch($id); // Reload to get new records
460
461
			$result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
462
			if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
463
		}
464
	}
465
466
	else if ($action == 'setref_client' && $usercancreate)
467
	{
468
		$object->fetch($id);
469
		$object->set_ref_client(GETPOST('ref_client'));
470
	}
471
472
	// Classify to validated
473
	else if ($action == 'confirm_valid' && $confirm == 'yes' && $usercanvalidate)
474
	{
475
		$idwarehouse = GETPOST('idwarehouse','int');
476
477
		$object->fetch($id);
478
		$object->fetch_thirdparty();
479
480
		// Check parameters
481
482
		// Check for mandatory fields defined into setup
483
		$array_to_check=array('IDPROF1','IDPROF2','IDPROF3','IDPROF4','IDPROF5','IDPROF6','EMAIL');
484
		foreach($array_to_check as $key)
485
		{
486
			$keymin=strtolower($key);
487
			$i=(int) preg_replace('/[^0-9]/','',$key);
488
			$vallabel=$object->thirdparty->$keymin;
489
490
			if ($i > 0)
491
			{
492
				if ($object->thirdparty->isACompany())
493
				{
494
					// Check for mandatory prof id (but only if country is other than ours)
495
					if ($mysoc->country_id > 0 && $object->thirdparty->country_id == $mysoc->country_id)
496
					{
497
						$idprof_mandatory ='SOCIETE_'.$key.'_INVOICE_MANDATORY';
498
						if (! $vallabel && ! empty($conf->global->$idprof_mandatory))
499
						{
500
							$langs->load("errors");
501
							$error++;
502
							setEventMessages($langs->trans('ErrorProdIdIsMandatory', $langs->transcountry('ProfId'.$i, $object->thirdparty->country_code)).' ('.$langs->trans("ForbiddenBySetupRules").')', null, 'errors');
503
						}
504
					}
505
				}
506
			}
507
			else
508
			{
509
				//var_dump($conf->global->SOCIETE_EMAIL_MANDATORY);
510
				if ($key == 'EMAIL')
511
				{
512
					// Check for mandatory
513
					if (! empty($conf->global->SOCIETE_EMAIL_INVOICE_MANDATORY) && ! isValidEMail($object->thirdparty->email))
514
					{
515
						$langs->load("errors");
516
						$error++;
517
						setEventMessages($langs->trans("ErrorBadEMail", $object->thirdparty->email).' ('.$langs->trans("ForbiddenBySetupRules").')', null, 'errors');
518
					}
519
				}
520
			}
521
		}
522
523
		$qualified_for_stock_change = 0;
524
		if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
525
			$qualified_for_stock_change = $object->hasProductsOrServices(2);
526
		} else {
527
			$qualified_for_stock_change = $object->hasProductsOrServices(1);
528
		}
529
530
		// Check for warehouse
531
		if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change)
532
		{
533
			if (! $idwarehouse || $idwarehouse == - 1) {
534
				$error++;
535
				setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
536
				$action = '';
537
			}
538
		}
539
540
		if (! $error)
541
		{
542
			$result = $object->validate($user, '', $idwarehouse);
543
			if ($result >= 0)
544
			{
545
				// Define output language
546
				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
547
				{
548
					$outputlangs = $langs;
549
					$newlang = '';
550
					if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
551
					if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
552
					if (! empty($newlang)) {
553
						$outputlangs = new Translate("", $conf);
554
						$outputlangs->setDefaultLang($newlang);
555
						$outputlangs->load('products');
556
					}
557
					$model=$object->modelpdf;
558
					$ret = $object->fetch($id); // Reload to get new records
559
560
					$result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
561
					if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
562
				}
563
			}
564
			else
565
			{
566
				if (count($object->errors)) setEventMessages(null, $object->errors, 'errors');
567
				else setEventMessages($object->error, $object->errors, 'errors');
568
			}
569
		}
570
	}
571
572
	// Go back to draft status (unvalidate)
573
	else if ($action == 'confirm_modif' && $usercanunvalidate)
574
	{
575
		$idwarehouse = GETPOST('idwarehouse','int');
576
577
		$object->fetch($id);
578
		$object->fetch_thirdparty();
579
580
		$qualified_for_stock_change = 0;
581
		if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
582
			$qualified_for_stock_change = $object->hasProductsOrServices(2);
583
		} else {
584
			$qualified_for_stock_change = $object->hasProductsOrServices(1);
585
		}
586
587
		// Check parameters
588
		if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change)
589
		{
590
			if (! $idwarehouse || $idwarehouse == - 1) {
591
				$error++;
592
				setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
593
				$action = '';
594
			}
595
		}
596
597
		if (! $error) {
598
			// On verifie si la facture a des paiements
599
			$sql = 'SELECT pf.amount';
600
			$sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf';
601
			$sql .= ' WHERE pf.fk_facture = ' . $object->id;
602
603
			$result = $db->query($sql);
604
			if ($result) {
605
				$i = 0;
606
				$num = $db->num_rows($result);
607
608
				while ($i < $num) {
609
					$objp = $db->fetch_object($result);
610
					$totalpaye += $objp->amount;
611
					$i ++;
612
				}
613
			} else {
614
				dol_print_error($db, '');
615
			}
616
617
			$resteapayer = $object->total_ttc - $totalpaye;
618
619
			// On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
620
			$ventilExportCompta = $object->getVentilExportCompta();
621
622
			// On verifie si aucun paiement n'a ete effectue
623
			if ($ventilExportCompta == 0)
624
			{
625
				if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_EDITED) || ($resteapayer == $object->total_ttc && empty($object->paye)))
626
				{
627
					$result=$object->set_draft($user, $idwarehouse);
628
					if ($result<0) setEventMessages($object->error, $object->errors, 'errors');
629
630
					// Define output language
631
					if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
632
					{
633
						$outputlangs = $langs;
634
						$newlang = '';
635
						if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
636
						if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
637
						if (! empty($newlang)) {
638
							$outputlangs = new Translate("", $conf);
639
							$outputlangs->setDefaultLang($newlang);
640
							$outputlangs->load('products');
641
						}
642
						$model=$object->modelpdf;
643
						$ret = $object->fetch($id); // Reload to get new records
644
645
						$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
646
					}
647
				}
648
			}
649
		}
650
	}
651
652
	// Classify "paid"
653
	else if ($action == 'confirm_paid' && $confirm == 'yes' && $usercanissuepayment)
654
	{
655
		$object->fetch($id);
656
		$result = $object->set_paid($user);
657
		if ($result<0) setEventMessages($object->error, $object->errors, 'errors');
658
	} // Classif "paid partialy"
659
	else if ($action == 'confirm_paid_partially' && $confirm == 'yes' && $usercanissuepayment)
660
	{
661
		$object->fetch($id);
662
		$close_code = GETPOST("close_code",'none');
663
		$close_note = GETPOST("close_note",'none');
664
		if ($close_code) {
665
			$result = $object->set_paid($user, $close_code, $close_note);
666
			if ($result<0) setEventMessages($object->error, $object->errors, 'errors');
667
		} else {
668
			setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), null, 'errors');
669
		}
670
	} // Classify "abandoned"
671
	else if ($action == 'confirm_canceled' && $confirm == 'yes') {
672
		$object->fetch($id);
673
		$close_code = GETPOST("close_code",'none');
674
		$close_note = GETPOST("close_note",'none');
675
		if ($close_code) {
676
			$result = $object->set_canceled($user, $close_code, $close_note);
677
			if ($result<0) setEventMessages($object->error, $object->errors, 'errors');
678
		} else {
679
			setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), null, 'errors');
680
		}
681
	}
682
683
	// Convertir en reduc
684
	else if ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $usercancreate)
685
	{
686
		$object->fetch($id);
687
		$object->fetch_thirdparty();
688
		//$object->fetch_lines();	// Already done into fetch
689
690
		// Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
691
		$discountcheck=new DiscountAbsolute($db);
692
		$result=$discountcheck->fetch(0,$object->id);
693
694
		$canconvert=0;
695
		if ($object->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert=1;	// we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc)
696
		if (($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1;	// we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc)
697
		if ($canconvert)
698
		{
699
			$db->begin();
700
701
			$amount_ht = $amount_tva = $amount_ttc = array();
702
703
			// Loop on each vat rate
704
			$i = 0;
705
			foreach ($object->lines as $line)
706
			{
707
				if ($line->product_type < 9 && $line->total_ht != 0) // Remove lines with product_type greater than or equal to 9
708
				{ 	// no need to create discount if amount is null
709
					$amount_ht[$line->tva_tx] += $line->total_ht;
710
					$amount_tva[$line->tva_tx] += $line->total_tva;
711
					$amount_ttc[$line->tva_tx] += $line->total_ttc;
712
					$multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht;
713
					$multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva;
714
					$multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc;
715
					$i ++;
716
				}
717
			}
718
719
			// Insert one discount by VAT rate category
720
			$discount = new DiscountAbsolute($db);
721
			if ($object->type == Facture::TYPE_CREDIT_NOTE)
722
				$discount->description = '(CREDIT_NOTE)';
723
			elseif ($object->type == Facture::TYPE_DEPOSIT)
724
				$discount->description = '(DEPOSIT)';
725
			elseif ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_SITUATION)
726
				$discount->description = '(EXCESS RECEIVED)';
727
			else {
728
				setEventMessages($langs->trans('CantConvertToReducAnInvoiceOfThisType'), null, 'errors');
729
			}
730
			$discount->fk_soc = $object->socid;
731
			$discount->fk_facture_source = $object->id;
732
733
			$error = 0;
734
735
			if ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_SITUATION)
736
			{
737
				// If we're on a standard invoice, we have to get excess received to create a discount in TTC without VAT
738
739
				$sql = 'SELECT SUM(pf.amount) as total_paiements';
740
				$sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'paiement as p';
741
				$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
742
				$sql.= ' WHERE pf.fk_facture = '.$object->id;
743
				$sql.= ' AND pf.fk_paiement = p.rowid';
744
				$sql.= ' AND p.entity IN (' . getEntity('invoice').')';
745
746
				$resql = $db->query($sql);
747
				if (! $resql) dol_print_error($db);
748
749
				$res = $db->fetch_object($resql);
750
				$total_paiements = $res->total_paiements;
751
752
				$discount->amount_ht = $discount->amount_ttc = $total_paiements - $object->total_ttc;
753
				$discount->amount_tva = 0;
754
				$discount->tva_tx = 0;
755
756
				$result = $discount->create($user);
757
				if ($result < 0)
758
				{
759
					$error++;
760
				}
761
			}
762
			if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT)
763
			{
764
				foreach ($amount_ht as $tva_tx => $xxx)
765
				{
766
					$discount->amount_ht = abs($amount_ht[$tva_tx]);
767
					$discount->amount_tva = abs($amount_tva[$tva_tx]);
768
					$discount->amount_ttc = abs($amount_ttc[$tva_tx]);
769
					$discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]);
770
					$discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]);
771
					$discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
772
					$discount->tva_tx = abs($tva_tx);
773
774
					$result = $discount->create($user);
775
					if ($result < 0)
776
					{
777
						$error++;
778
						break;
779
					}
780
				}
781
			}
782
783
			if (empty($error))
784
			{
785
				if($object->type != Facture::TYPE_DEPOSIT) {
786
					// Classe facture
787
					$result = $object->set_paid($user);
788
					if ($result >= 0)
789
					{
790
						$db->commit();
791
					}
792
					else
793
					{
794
						setEventMessages($object->error, $object->errors, 'errors');
795
						$db->rollback();
796
					}
797
				} else {
798
					$db->commit();
799
				}
800
			}
801
			else
802
			{
803
				setEventMessages($discount->error, $discount->errors, 'errors');
804
				$db->rollback();
805
			}
806
		}
807
	}
808
809
	// Delete payment
810
	elseif ($action == 'confirm_delete_paiement' && $confirm == 'yes' && $usercancreate)
811
	{
812
		$object->fetch($id);
813
		if ($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0)
814
		{
815
			$paiement = new Paiement($db);
816
			$result=$paiement->fetch(GETPOST('paiement_id'));
817
			if ($result > 0) {
818
				$result=$paiement->delete(); // If fetch ok and found
819
				header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
820
			}
821
			if ($result < 0) {
822
				setEventMessages($paiement->error, $paiement->errors, 'errors');
823
			}
824
		}
825
	}
826
827
	/*
828
	 * Insert new invoice in database
829
	 */
830
	else if ($action == 'add' && $usercancreate)
831
	{
832
		if ($socid > 0) $object->socid = GETPOST('socid', 'int');
833
834
		$db->begin();
835
836
		$error = 0;
837
838
		// Fill array 'array_options' with data from add form
839
		$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
840
		$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
841
		if ($ret < 0) $error++;
842
843
		// Replacement invoice
844
		if ($_POST['type'] == Facture::TYPE_REPLACEMENT)
845
		{
846
			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
847
			if (empty($dateinvoice))
848
			{
849
				$error++;
850
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
851
			}
852
853
			if (! ($_POST['fac_replacement'] > 0)) {
854
				$error++;
855
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), null, 'errors');
856
			}
857
858
			$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
859
860
			if (! $error) {
861
				// This is a replacement invoice
862
				$result = $object->fetch($_POST['fac_replacement']);
863
				$object->fetch_thirdparty();
864
865
				$object->date				= $dateinvoice;
866
				$object->date_pointoftax	= $date_pointoftax;
867
				$object->note_public		= trim(GETPOST('note_public','none'));
868
				// We do not copy the private note
869
				$object->ref_client			= $_POST['ref_client'];
870
				$object->ref_int			= $_POST['ref_int'];
871
				$object->modelpdf			= $_POST['model'];
872
				$object->fk_project			= $_POST['projectid'];
873
				$object->cond_reglement_id	= $_POST['cond_reglement_id'];
874
				$object->mode_reglement_id	= $_POST['mode_reglement_id'];
875
				$object->fk_account         = GETPOST('fk_account', 'int');
876
				$object->remise_absolue		= $_POST['remise_absolue'];
877
				$object->remise_percent		= $_POST['remise_percent'];
878
				$object->fk_incoterms 		= GETPOST('incoterm_id', 'int');
879
				$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
880
				$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
881
				$object->multicurrency_tx   = GETPOST('originmulticurrency_tx', 'int');
882
				$object->entity				= (GETPOSTISSET('entity')?GETPOST('entity', 'int'):$conf->entity);
883
884
				// Proprietes particulieres a facture de remplacement
885
				$object->fk_facture_source = $_POST['fac_replacement'];
886
				$object->type = Facture::TYPE_REPLACEMENT;
887
888
				$id = $object->createFromCurrent($user);
889
				if ($id <= 0) {
890
					setEventMessages($object->error, $object->errors, 'errors');
891
				}
892
			}
893
		}
894
895
		// Credit note invoice
896
		if ($_POST['type'] == Facture::TYPE_CREDIT_NOTE)
897
		{
898
			$sourceinvoice = GETPOST('fac_avoir');
899
			if (! ($sourceinvoice > 0) && empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE))
900
			{
901
				$error++;
902
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), null, 'errors');
903
			}
904
905
			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
906
			if (empty($dateinvoice))
907
			{
908
				$error++;
909
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->trans("Date")), null, 'errors');
910
			}
911
912
			$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
913
914
			if (! $error)
915
			{
916
				$object->socid				= GETPOST('socid','int');
917
				$object->number				= $_POST['ref'];
918
				$object->date				= $dateinvoice;
919
				$object->date_pointoftax	= $date_pointoftax;
920
				$object->note_public		= trim(GETPOST('note_public','none'));
921
				// We do not copy the private note
922
				$object->ref_client			= $_POST['ref_client'];
923
				$object->ref_int			= $_POST['ref_int'];
924
				$object->modelpdf			= $_POST['model'];
925
				$object->fk_project			= $_POST['projectid'];
926
				$object->cond_reglement_id	= 0;
927
				$object->mode_reglement_id	= $_POST['mode_reglement_id'];
928
				$object->fk_account         = GETPOST('fk_account', 'int');
929
				$object->remise_absolue		= $_POST['remise_absolue'];
930
				$object->remise_percent		= $_POST['remise_percent'];
931
				$object->fk_incoterms 		= GETPOST('incoterm_id', 'int');
932
				$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
933
				$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
934
				$object->multicurrency_tx   = GETPOST('originmulticurrency_tx', 'int');
935
				$object->entity				= (GETPOSTISSET('entity')?GETPOST('entity', 'int'):$conf->entity);
936
937
				// Proprietes particulieres a facture avoir
938
				$object->fk_facture_source = $sourceinvoice > 0 ? $sourceinvoice : '';
939
				$object->type = Facture::TYPE_CREDIT_NOTE;
940
941
				$facture_source = new Facture($db); // fetch origin object
942
				if ($facture_source->fetch($object->fk_facture_source)>0)
943
				{
944
				    if ($facture_source->type == Facture::TYPE_SITUATION)
945
				    {
946
				        $object->situation_counter =  $facture_source->situation_counter;
947
				        $object->situation_cycle_ref = $facture_source->situation_cycle_ref;
948
				        $facture_source->fetchPreviousNextSituationInvoice();
949
				    }
950
				}
951
				$id = $object->create($user);
952
953
				if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0)
954
				{
955
					if (!empty($facture_source->lines))
956
					{
957
						$fk_parent_line = 0;
958
959
						foreach($facture_source->lines as $line)
960
						{
961
							// Extrafields
962
							if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($line, 'fetch_optionals')) {
963
								// load extrafields
964
								$line->fetch_optionals();
965
							}
966
967
							// Reset fk_parent_line for no child products and special product
968
							if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
969
								$fk_parent_line = 0;
970
							}
971
972
973
974
975
							if($facture_source->type == Facture::TYPE_SITUATION)
976
							{
977
							    $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id
978
							    $line->fk_prev_id  = $line->id; // Credit note line need to be linked to the situation invoice it is create from
979
980
							    if(!empty($facture_source->tab_previous_situation_invoice))
981
							    {
982
							        // search the last invoice in cycle
983
							        $lineIndex = count($facture_source->tab_previous_situation_invoice) - 1;
984
							        $searchPreviousInvoice = true;
985
							        while( $searchPreviousInvoice )
986
							        {
987
							            if($facture_source->tab_previous_situation_invoice[$lineIndex]->type  == Facture::TYPE_SITUATION || $lineIndex < 1)
988
							            {
989
							                $searchPreviousInvoice=false; // find, exit;
990
							                break;
991
							            }
992
							            else
993
							            {
994
							                $lineIndex--; // go to previous invoice in cycle
995
							            }
996
							        }
997
998
999
							        $maxPrevSituationPercent = 0;
1000
							        foreach($facture_source->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine)
1001
							        {
1002
							            if($prevLine->id == $source_fk_prev_id)
1003
							            {
1004
							                $maxPrevSituationPercent = max($maxPrevSituationPercent,$prevLine->situation_percent);
1005
1006
							                //$line->subprice  = $line->subprice - $prevLine->subprice;
1007
							                $line->total_ht  = $line->total_ht - $prevLine->total_ht;
1008
							                $line->total_tva = $line->total_tva - $prevLine->total_tva;
1009
							                $line->total_ttc = $line->total_ttc - $prevLine->total_ttc;
1010
							                $line->total_localtax1 = $line->total_localtax1 - $prevLine->total_localtax1;
1011
							                $line->total_localtax2 = $line->total_localtax2 - $prevLine->total_localtax2;
1012
1013
							                $line->multicurrency_subprice  = $line->multicurrency_subprice  - $prevLine->multicurrency_subprice;
1014
							                $line->multicurrency_total_ht  = $line->multicurrency_total_ht  - $prevLine->multicurrency_total_ht;
1015
							                $line->multicurrency_total_tva = $line->multicurrency_total_tva - $prevLine->multicurrency_total_tva;
1016
							                $line->multicurrency_total_ttc = $line->multicurrency_total_ttc - $prevLine->multicurrency_total_ttc;
1017
							            }
1018
							        }
1019
1020
							        // prorata
1021
							        $line->situation_percent = $maxPrevSituationPercent - $line->situation_percent;
1022
							    }
1023
							}
1024
1025
							$line->fk_facture = $object->id;
1026
							$line->fk_parent_line = $fk_parent_line;
1027
1028
							$line->subprice = -$line->subprice; // invert price for object
1029
							$line->pa_ht = $line->pa_ht;       // we choosed to have buy/cost price always positive, so no revert of sign here
1030
							$line->total_ht = -$line->total_ht;
1031
							$line->total_tva = -$line->total_tva;
1032
							$line->total_ttc = -$line->total_ttc;
1033
							$line->total_localtax1 = -$line->total_localtax1;
1034
							$line->total_localtax2 = -$line->total_localtax2;
1035
1036
							$line->multicurrency_subprice = -$line->multicurrency_subprice;
1037
							$line->multicurrency_total_ht = -$line->multicurrency_total_ht;
1038
							$line->multicurrency_total_tva = -$line->multicurrency_total_tva;
1039
							$line->multicurrency_total_ttc = -$line->multicurrency_total_ttc;
1040
1041
							$result = $line->insert(0, 1);     // When creating credit note with same lines than source, we must ignore error if discount alreayd linked
1042
1043
							$object->lines[] = $line; // insert new line in current object
1044
1045
							// Defined the new fk_parent_line
1046
							if ($result > 0 && $line->product_type == 9) {
1047
								$fk_parent_line = $result;
1048
							}
1049
						}
1050
1051
						$object->update_price(1);
1052
					}
1053
				}
1054
1055
				if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0)
1056
				{
1057
					if ($facture_source->fetch($object->fk_facture_source)>0)
1058
					{
1059
						$totalpaye = $facture_source->getSommePaiement();
1060
						$totalcreditnotes = $facture_source->getSumCreditNotesUsed();
1061
						$totaldeposits = $facture_source->getSumDepositsUsed();
1062
						$remain_to_pay = abs($facture_source->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits);
1063
1064
						$object->addline($langs->trans('invoiceAvoirLineWithPaymentRestAmount'),$remain_to_pay,1,0,0,0,0,0,'','','TTC');
1065
					}
1066
				}
1067
1068
				// Add link between credit note and origin
1069
				if(! empty($object->fk_facture_source)) {
1070
					$facture_source->fetch($object->fk_facture_source);
1071
					$facture_source->fetchObjectLinked();
1072
1073
					if(! empty($facture_source->linkedObjectsIds)) {
1074
						foreach($facture_source->linkedObjectsIds as $sourcetype => $TIds) {
1075
							$object->add_object_linked($sourcetype, current($TIds));
1076
						}
1077
					}
1078
				}
1079
			}
1080
		}
1081
1082
		// Standard invoice or Deposit invoice, created from a Predefined template invoice
1083
		if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT) && GETPOST('fac_rec') > 0)
1084
		{
1085
			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
1086
			if (empty($dateinvoice))
1087
			{
1088
				$error++;
1089
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
1090
			}
1091
1092
			$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
1093
1094
			if (! $error)
1095
			{
1096
				$object->socid			 = GETPOST('socid','int');
1097
				$object->type            = $_POST['type'];
1098
				$object->number          = $_POST['ref'];
1099
				$object->date            = $dateinvoice;
1100
				$object->date_pointoftax = $date_pointoftax;
1101
				$object->note_public	 = trim(GETPOST('note_public','none'));
1102
				$object->note_private    = trim(GETPOST('note_private','none'));
1103
				$object->ref_client      = $_POST['ref_client'];
1104
				$object->ref_int     	 = $_POST['ref_int'];
1105
				$object->modelpdf        = $_POST['model'];
1106
				$object->fk_project		 = $_POST['projectid'];
1107
				$object->cond_reglement_id	= ($_POST['type'] == 3?1:$_POST['cond_reglement_id']);
1108
				$object->mode_reglement_id	= $_POST['mode_reglement_id'];
1109
				$object->fk_account         = GETPOST('fk_account', 'int');
1110
				$object->amount				= $_POST['amount'];
1111
				$object->remise_absolue		= $_POST['remise_absolue'];
1112
				$object->remise_percent		= $_POST['remise_percent'];
1113
				$object->fk_incoterms 		= GETPOST('incoterm_id', 'int');
1114
				$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
1115
				$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
1116
				$object->multicurrency_tx   = GETPOST('originmulticurrency_tx', 'int');
1117
				$object->entity				= (GETPOSTISSET('entity')?GETPOST('entity', 'int'):$conf->entity);
1118
1119
				// Source facture
1120
				$object->fac_rec = GETPOST('fac_rec', 'int');
1121
1122
				$id = $object->create($user);       // This include recopy of links from recurring invoice and invoice lines
1123
			}
1124
		}
1125
1126
		// Standard or deposit or proforma invoice, not from a Predefined template invoice
1127
		if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT || $_POST['type'] == Facture::TYPE_PROFORMA || ($_POST['type'] == Facture::TYPE_SITUATION && empty($_POST['situations']))) && GETPOST('fac_rec') <= 0)
0 ignored issues
show
Consider adding parentheses for clarity. Current Interpretation: ($_POST['type'] == Factu...GETPOST('fac_rec') <= 0, Probably Intended Meaning: $_POST['type'] == Factur...ETPOST('fac_rec') <= 0)
Loading history...
1128
		{
1129
			if (GETPOST('socid', 'int') < 1)
1130
			{
1131
				$error++;
1132
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), null, 'errors');
1133
			}
1134
1135
			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
1136
			if (empty($dateinvoice))
1137
			{
1138
				$error++;
1139
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
1140
			}
1141
1142
			$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
1143
1144
			if (! $error)
1145
			{
1146
				// Si facture standard
1147
				$object->socid				= GETPOST('socid','int');
1148
				$object->type				= GETPOST('type');
1149
				$object->number				= $_POST['ref'];
1150
				$object->date				= $dateinvoice;
1151
				$object->date_pointoftax	= $date_pointoftax;
1152
				$object->note_public		= trim(GETPOST('note_public','none'));
1153
				$object->note_private		= trim(GETPOST('note_private','none'));
1154
				$object->ref_client			= $_POST['ref_client'];
1155
				$object->ref_int			= $_POST['ref_int'];
1156
				$object->modelpdf			= $_POST['model'];
1157
				$object->fk_project			= $_POST['projectid'];
1158
				$object->cond_reglement_id	= ($_POST['type'] == 3?1:$_POST['cond_reglement_id']);
1159
				$object->mode_reglement_id	= $_POST['mode_reglement_id'];
1160
				$object->fk_account         = GETPOST('fk_account', 'int');
1161
				$object->amount				= $_POST['amount'];
1162
				$object->remise_absolue		= $_POST['remise_absolue'];
1163
				$object->remise_percent		= $_POST['remise_percent'];
1164
				$object->fk_incoterms 		= GETPOST('incoterm_id', 'int');
1165
				$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
1166
				$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
1167
				$object->multicurrency_tx   = GETPOST('originmulticurrency_tx', 'int');
1168
				$object->entity				= (GETPOSTISSET('entity')?GETPOST('entity', 'int'):$conf->entity);
1169
1170
				if (GETPOST('type') == Facture::TYPE_SITUATION)
1171
				{
1172
					$object->situation_counter = 1;
1173
					$object->situation_final = 0;
1174
					$object->situation_cycle_ref = $object->newCycle();
1175
				}
1176
1177
				$object->fetch_thirdparty();
1178
1179
				// If creation from another object of another module (Example: origin=propal, originid=1)
1180
				if (! empty($origin) && ! empty($originid))
1181
				{
1182
					// Parse element/subelement (ex: project_task)
1183
					$element = $subelement = $origin;
1184
					if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
1185
						$element = $regs [1];
1186
						$subelement = $regs [2];
1187
					}
1188
1189
					// For compatibility
1190
					if ($element == 'order') {
1191
						$element = $subelement = 'commande';
1192
					}
1193
					if ($element == 'propal') {
1194
						$element = 'comm/propal';
1195
						$subelement = 'propal';
1196
					}
1197
					if ($element == 'contract') {
1198
						$element = $subelement = 'contrat';
1199
					}
1200
					if ($element == 'inter') {
1201
						$element = $subelement = 'ficheinter';
1202
					}
1203
					if ($element == 'shipping') {
1204
						$element = $subelement = 'expedition';
1205
					}
1206
1207
					$object->origin = $origin;
1208
					$object->origin_id = $originid;
1209
1210
					// Possibility to add external linked objects with hooks
1211
					$object->linked_objects[$object->origin] = $object->origin_id;
1212
					// link with order if it is a shipping invoice
1213
					if ($object->origin == 'shipping')
1214
					{
1215
						require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
1216
						$exp = new Expedition($db);
1217
						$exp->fetch($object->origin_id);
1218
						$exp->fetchObjectLinked();
1219
						if (is_array($exp->linkedObjectsIds['commande']) && count($exp->linkedObjectsIds['commande']) > 0) {
1220
							foreach ($exp->linkedObjectsIds['commande'] as $key => $value){
1221
								$object->linked_objects['commande'] = $value;
1222
							}
1223
						}
1224
					}
1225
1226
					if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects']))
1227
					{
1228
						$object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
1229
					}
1230
1231
					$id = $object->create($user);      // This include class to add_object_linked() and add add_contact()
1232
1233
					if ($id > 0)
1234
					{
1235
						dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
1236
1237
						$classname = ucfirst($subelement);
1238
						$srcobject = new $classname($db);
1239
1240
						dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines or deposit lines");
1241
						$result = $srcobject->fetch($object->origin_id);
1242
1243
						// If deposit invoice
1244
						if ($_POST['type'] == Facture::TYPE_DEPOSIT)
1245
						{
1246
							$typeamount = GETPOST('typedeposit', 'alpha');
1247
							$valuedeposit = GETPOST('valuedeposit', 'int');
1248
1249
							$amountdeposit = array();
1250
							if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA))
1251
							{
1252
								if ($typeamount == 'amount') $amount = $valuedeposit;
1253
								else $amount = $srcobject->total_ttc * ($valuedeposit / 100);
1254
1255
								$TTotalByTva = array();
1256
								foreach ($srcobject->lines as &$line)
1257
								{
1258
									if(! empty($line->special_code)) continue;
1259
									$TTotalByTva[$line->tva_tx] += $line->total_ttc ;
1260
								}
1261
1262
								$amount_to_diff = 0;
1263
								foreach ($TTotalByTva as $tva => &$total)
1264
								{
1265
									$coef = $total / $srcobject->total_ttc; // Calc coef
1266
									$am = $amount * $coef;
1267
									$amount_ttc_diff += $am;
1268
									$amountdeposit[$tva] += $am / (1 + $tva / 100); // Convert into HT for the addline
1269
								}
1270
							}
1271
							else
1272
							{
1273
								if ($typeamount == 'amount')
1274
								{
1275
									$amountdeposit[0] = $valuedeposit;
1276
								}
1277
								else
1278
								{
1279
									if ($result > 0)
1280
									{
1281
										$totalamount = 0;
1282
										$lines = $srcobject->lines;
1283
										$numlines=count($lines);
1284
										for ($i=0; $i<$numlines; $i++)
1285
										{
1286
											$qualified=1;
1287
											if (empty($lines[$i]->qty)) $qualified=0;	// We discard qty=0, it is an option
1288
											if (! empty($lines[$i]->special_code)) $qualified=0;	// We discard special_code (frais port, ecotaxe, option, ...)
1289
											if ($qualified) $totalamount += $lines[$i]->total_ht; // Fixme : is it not for the customer ? Shouldn't we take total_ttc ?
1290
										}
1291
1292
										if ($totalamount != 0) {
1293
											if ($numlines > 0) $numlines = $numlines-1;
1294
											$tva_tx = $lines[$numlines]->tva_tx;
1295
											if (! empty($lines[$numlines]->vat_src_code) && ! preg_match('/\(/', $tva_tx)) $tva_tx .= ' ('.$lines[$numlines]->vat_src_code.')';
1296
											$amountdeposit[$tva_tx] = ($totalamount * $valuedeposit) / 100;
1297
										} else {
1298
											$amountdeposit[0] = 0;
1299
										}
1300
									} else {
1301
										setEventMessages($srcobject->error, $srcobject->errors, 'errors');
1302
										$error++;
1303
									}
1304
								}
1305
1306
								$amount_ttc_diff = $amountdeposit[0];
1307
							}
1308
1309
							foreach ($amountdeposit as $tva => $amount)
1310
							{
1311
								$arraylist = array('amount' => 'FixAmount','variable' => 'VarAmount');
1312
								$descline = $langs->trans('Deposit');
1313
								//$descline.= ' - '.$langs->trans($arraylist[$typeamount]);
1314
								if ($typeamount=='amount') {
1315
									$descline.= ' ('. price($valuedeposit, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).')';
1316
								} elseif ($typeamount=='variable') {
1317
									$descline.= ' ('. $valuedeposit.'%)';
1318
								}
1319
								$descline.= ' - '.$srcobject->ref;
1320
								$result = $object->addline(
1321
										$descline,
1322
										$amount,		 	// subprice
1323
										1, 						// quantity
1324
										$tva,     // vat rate
1325
										0,                      // localtax1_tx
1326
										0, 						// localtax2_tx
1327
										(empty($conf->global->INVOICE_PRODUCTID_DEPOSIT)?0:$conf->global->INVOICE_PRODUCTID_DEPOSIT), 	// fk_product
1328
										0, 						// remise_percent
1329
										0, 						// date_start
1330
										0, 						// date_end
1331
										0,
1332
										$lines[$i]->info_bits,  // info_bits
1333
										0,
1334
										'HT',
1335
										0,
1336
										0, 						// product_type
1337
										1,
1338
										$lines[$i]->special_code,
1339
										$object->origin,
1340
										0,
1341
										0,
1342
										0,
1343
										0
1344
										//,$langs->trans('Deposit') //Deprecated
1345
									);
1346
							}
1347
1348
							$diff = $object->total_ttc - $amount_ttc_diff;
1349
1350
							if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA) && $diff != 0)
1351
							{
1352
								$object->fetch_lines();
1353
								$subprice_diff = $object->lines[0]->subprice - $diff / (1 + $object->lines[0]->tva_tx / 100);
1354
								$object->updateline($object->lines[0]->id, $object->lines[0]->desc, $subprice_diff, $object->lines[0]->qty, $object->lines[0]->remise_percent, $object->lines[0]->date_start, $object->lines[0]->date_end, $object->lines[0]->tva_tx, 0, 0, 'HT', $object->lines[0]->info_bits, $object->lines[0]->product_type, 0, 0, 0, $object->lines[0]->pa_ht, $object->lines[0]->label, 0, array(), 100);
1355
							}
1356
						}
1357
						else
1358
						{
1359
							if ($result > 0)
1360
							{
1361
								$lines = $srcobject->lines;
1362
								if (empty($lines) && method_exists($srcobject, 'fetch_lines'))
1363
								{
1364
									$srcobject->fetch_lines();
1365
									$lines = $srcobject->lines;
1366
								}
1367
1368
								$fk_parent_line=0;
1369
								$num=count($lines);
1370
								for ($i=0;$i<$num;$i++)
1371
								{
1372
									// Don't add lines with qty 0 when coming from a shipment including all order lines
1373
									if($srcobject->element == 'shipping' && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS && $lines[$i]->qty == 0) continue;
1374
									// Don't add closed lines when coming from a contract
1375
									if($srcobject->element == 'contrat' && $lines[$i]->statut == 5) continue;
1376
1377
									$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
1378
									$desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
1379
									if ($object->situation_counter == 1) $lines[$i]->situation_percent =  0;
1380
1381
									if ($lines[$i]->subprice < 0)
1382
									{
1383
										// Negative line, we create a discount line
1384
										$discount = new DiscountAbsolute($db);
1385
										$discount->fk_soc = $object->socid;
1386
										$discount->amount_ht = abs($lines[$i]->total_ht);
1387
										$discount->amount_tva = abs($lines[$i]->total_tva);
1388
										$discount->amount_ttc = abs($lines[$i]->total_ttc);
1389
										$discount->tva_tx = $lines[$i]->tva_tx;
1390
										$discount->fk_user = $user->id;
1391
										$discount->description = $desc;
1392
										$discountid = $discount->create($user);
1393
										if ($discountid > 0) {
1394
											$result = $object->insert_discount($discountid); // This include link_to_invoice
1395
										} else {
1396
											setEventMessages($discount->error, $discount->errors, 'errors');
1397
											$error++;
1398
											break;
1399
										}
1400
									} else {
1401
										// Positive line
1402
										$product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
1403
1404
										// Date start
1405
										$date_start = false;
1406
										if ($lines[$i]->date_debut_prevue)
1407
											$date_start = $lines[$i]->date_debut_prevue;
1408
										if ($lines[$i]->date_debut_reel)
1409
											$date_start = $lines[$i]->date_debut_reel;
1410
										if ($lines[$i]->date_start)
1411
											$date_start = $lines[$i]->date_start;
1412
1413
											// Date end
1414
										$date_end = false;
1415
										if ($lines[$i]->date_fin_prevue)
1416
											$date_end = $lines[$i]->date_fin_prevue;
1417
										if ($lines[$i]->date_fin_reel)
1418
											$date_end = $lines[$i]->date_fin_reel;
1419
										if ($lines[$i]->date_end)
1420
											$date_end = $lines[$i]->date_end;
1421
1422
											// Reset fk_parent_line for no child products and special product
1423
										if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
1424
											$fk_parent_line = 0;
1425
										}
1426
1427
										// Extrafields
1428
										if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) {
1429
											$lines[$i]->fetch_optionals($lines[$i]->rowid);
1430
											$array_options = $lines[$i]->array_options;
1431
										}
1432
1433
										$tva_tx = $lines[$i]->tva_tx;
1434
										if (! empty($lines[$i]->vat_src_code) && ! preg_match('/\(/', $tva_tx)) $tva_tx .= ' ('.$lines[$i]->vat_src_code.')';
1435
1436
										// View third's localtaxes for NOW and do not use value from origin.
1437
										// TODO Is this really what we want ? Yes if source if template invoice but what if proposal or order ?
1438
										$localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty);
1439
										$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
1440
1441
										$result = $object->addline(
1442
											$desc, $lines[$i]->subprice, $lines[$i]->qty, $tva_tx, $localtax1_tx, $localtax2_tx, $lines[$i]->fk_product,
1443
											$lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except,
1444
											'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $object->origin, $lines[$i]->rowid,
1445
											$fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_options,
1446
											$lines[$i]->situation_percent, $lines[$i]->fk_prev_id, $lines[$i]->fk_unit
1447
										);
1448
1449
										if ($result > 0) {
1450
											$lineid = $result;
1451
										} else {
1452
											$lineid = 0;
1453
											$error++;
1454
											break;
1455
										}
1456
1457
										// Defined the new fk_parent_line
1458
										if ($result > 0 && $lines[$i]->product_type == 9) {
1459
											$fk_parent_line = $result;
1460
										}
1461
									}
1462
								}
1463
							} else {
1464
								setEventMessages($srcobject->error, $srcobject->errors, 'errors');
1465
								$error++;
1466
							}
1467
						}
1468
1469
						// Now we create same links to contact than the ones found on origin object
1470
						/* Useless, already into the create
1471
						if (! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN))
1472
						{
1473
    						$originforcontact = $object->origin;
1474
    						$originidforcontact = $object->origin_id;
1475
    						if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
1476
    						{
1477
    						    $originforcontact=$srcobject->origin;
1478
    						    $originidforcontact=$srcobject->origin_id;
1479
    						}
1480
    						$sqlcontact = "SELECT code, fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
1481
    						$sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
1482
1483
    						$resqlcontact = $db->query($sqlcontact);
1484
    						if ($resqlcontact)
1485
    						{
1486
                                while($objcontact = $db->fetch_object($resqlcontact))
1487
                                {
1488
                                    //print $objcontact->code.'-'.$objcontact->fk_socpeople."\n";
1489
                                    $object->add_contact($objcontact->fk_socpeople, $objcontact->code);
1490
                                }
1491
    						}
1492
    						else dol_print_error($resqlcontact);
1493
						}*/
1494
1495
						// Hooks
1496
						$parameters = array('objFrom' => $srcobject);
1497
						$reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
1498
						// modified by hook
1499
						if ($reshook < 0)
1500
						{
1501
							setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1502
							$error++;
1503
						}
1504
					} else {
1505
						setEventMessages($object->error, $object->errors, 'errors');
1506
						$error++;
1507
					}
1508
				}
1509
				else
1510
				{   // If some invoice's lines coming from page
1511
					$id = $object->create($user);
1512
1513
					for ($i = 1; $i <= $NBLINES; $i ++) {
1514
						if ($_POST['idprod' . $i]) {
1515
							$product = new Product($db);
1516
							$product->fetch($_POST['idprod' . $i]);
1517
							$startday = dol_mktime(12, 0, 0, $_POST['date_start' . $i . 'month'], $_POST['date_start' . $i . 'day'], $_POST['date_start' . $i . 'year']);
1518
							$endday = dol_mktime(12, 0, 0, $_POST['date_end' . $i . 'month'], $_POST['date_end' . $i . 'day'], $_POST['date_end' . $i . 'year']);
1519
							$result = $object->addline($product->description, $product->price, $_POST['qty' . $i], $product->tva_tx, $product->localtax1_tx, $product->localtax2_tx, $_POST['idprod' . $i], $_POST['remise_percent' . $i], $startday, $endday, 0, 0, '', $product->price_base_type, $product->price_ttc, $product->type, -1, 0, '', 0, 0, null, 0, '', 0, 100, '', $product->fk_unit);
1520
						}
1521
					}
1522
				}
1523
			}
1524
		}
1525
1526
		// Situation invoices
1527
		if (GETPOST('type') == Facture::TYPE_SITUATION && (!empty($_POST['situations'])))
1528
		{
1529
			$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
1530
			if (empty($datefacture)) {
1531
				$error++;
1532
				$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
1533
			}
1534
1535
			$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
1536
1537
			if (!($_POST['situations'] > 0)) {
1538
				$error++;
1539
				$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")) . '</div>';
1540
			}
1541
1542
			if (!$error) {
1543
				$result = $object->fetch($_POST['situations']);
1544
				$object->fk_facture_source = $_POST['situations'];
1545
				$object->type = Facture::TYPE_SITUATION;
1546
1547
				if (!empty($origin) && !empty($originid))
1548
				{
1549
					$object->origin = $origin;
1550
					$object->origin_id = $originid;
1551
1552
					foreach ($object->lines as $i => &$line)
1553
					{
1554
						$line->origin = $object->origin;
1555
						$line->origin_id = $line->id;
1556
						$line->fk_prev_id = $line->id;
1557
						$line->fetch_optionals($line->id);
1558
						$line->situation_percent =  $line->get_prev_progress($object->id); // get good progress including credit note
1559
1560
						// Si fk_remise_except defini on vérifie si la réduction à déjà été appliquée
1561
						if ($line->fk_remise_except)
1562
						{
1563
						    $discount=new DiscountAbsolute($line->db);
1564
						    $result=$discount->fetch($line->fk_remise_except);
1565
						    if ($result > 0)
1566
						    {
1567
						        // Check if discount not already affected to another invoice
1568
						        if ($discount->fk_facture_line > 0)
1569
						        {
1570
						            $line->fk_remise_except = 0;
1571
						        }
1572
						    }
1573
						}
1574
					}
1575
				}
1576
1577
				$object->fetch_thirdparty();
1578
				$object->date = $datefacture;
1579
				$object->date_pointoftax = $date_pointoftax;
1580
				$object->note_public = trim(GETPOST('note_public','none'));
1581
				$object->note = trim(GETPOST('note','none'));
1582
				$object->ref_client = GETPOST('ref_client','alpha');
1583
				$object->ref_int = GETPOST('ref_int','alpha');
1584
				$object->modelpdf = GETPOST('model','alpha');
1585
				$object->fk_project = GETPOST('projectid','int');
1586
				$object->cond_reglement_id = GETPOST('cond_reglement_id','int');
1587
				$object->mode_reglement_id = GETPOST('mode_reglement_id','int');
1588
				$object->remise_absolue = GETPOST('remise_absolue','int');
1589
				$object->remise_percent = GETPOST('remise_percent','int');
1590
1591
				// Proprietes particulieres a facture de remplacement
1592
1593
				$object->situation_counter = $object->situation_counter + 1;
1594
				$id = $object->createFromCurrent($user);
1595
				if ($id <= 0)
1596
				{
1597
					$mesg = $object->error;
1598
				}
1599
				else
1600
				{
1601
					$nextSituationInvoice = new Facture($db);
1602
					$nextSituationInvoice->fetch($id);
1603
					// create extrafields with data from create form
1604
					$extralabels = $extrafields->fetch_name_optionals_label($nextSituationInvoice->table_element);
1605
					$ret = $extrafields->setOptionalsFromPost($extralabels, $nextSituationInvoice);
1606
					if ($ret > 0) {
1607
						$nextSituationInvoice->insertExtraFields();
1608
					}
1609
				}
1610
			}
1611
		}
1612
1613
		// End of object creation, we show it
1614
		if ($id > 0 && ! $error)
1615
		{
1616
			$db->commit();
1617
1618
			// Define output language
1619
			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE) && count($object->lines))
1620
			{
1621
				$outputlangs = $langs;
1622
				$newlang = '';
1623
				if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
1624
				if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
1625
				if (! empty($newlang)) {
1626
					$outputlangs = new Translate("", $conf);
1627
					$outputlangs->setDefaultLang($newlang);
1628
					$outputlangs->load('products');
1629
				}
1630
				$model=$object->modelpdf;
1631
				$ret = $object->fetch($id); // Reload to get new records
1632
1633
				$result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1634
				if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
1635
			}
1636
1637
			header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id);
1638
			exit();
1639
		}
1640
		else
1641
		{
1642
			$db->rollback();
1643
			$action = 'create';
1644
			$_GET["origin"] = $_POST["origin"];
1645
			$_GET["originid"] = $_POST["originid"];
1646
			setEventMessages($object->error, $object->errors, 'errors');
1647
		}
1648
	}
1649
1650
	// Add a new line
1651
	else if ($action == 'addline' && $usercancreate)
1652
	{
1653
		$langs->load('errors');
1654
		$error = 0;
1655
1656
		// Set if we used free entry or predefined product
1657
		$predef='';
1658
		$product_desc=(GETPOST('dp_desc','none')?GETPOST('dp_desc','none'):'');
1659
		$price_ht = GETPOST('price_ht');
1660
		$price_ht_devise = GETPOST('multicurrency_price_ht');
1661
		$prod_entry_mode = GETPOST('prod_entry_mode','alpha');
1662
		if ($prod_entry_mode == 'free')
1663
		{
1664
			$idprod=0;
1665
			$tva_tx = (GETPOST('tva_tx','alpha') ? GETPOST('tva_tx','alpha') : 0);
1666
		}
1667
		else
1668
		{
1669
			$idprod=GETPOST('idprod', 'int');
1670
			$tva_tx = '';
1671
		}
1672
1673
		$qty = GETPOST('qty' . $predef);
1674
		$remise_percent = GETPOST('remise_percent' . $predef);
1675
1676
		// Extrafields
1677
		$extrafieldsline = new ExtraFields($db);
1678
		$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
1679
		$array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
1680
		// Unset extrafield
1681
		if (is_array($extralabelsline)) {
1682
			// Get extra fields
1683
			foreach ($extralabelsline as $key => $value) {
1684
				unset($_POST["options_" . $key . $predef]);
1685
			}
1686
		}
1687
1688
		if (empty($idprod) && ($price_ht < 0) && ($qty < 0)) {
1689
			setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1690
			$error++;
1691
		}
1692
		if (!$prod_entry_mode)
1693
		{
1694
			if (GETPOST('type') < 0 && ! GETPOST('search_idprod'))
1695
			{
1696
				setEventMessages($langs->trans('ErrorChooseBetweenFreeEntryOrPredefinedProduct'), null, 'errors');
1697
				$error++;
1698
			}
1699
		}
1700
		if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) {
1701
			setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
1702
			$error++;
1703
		}
1704
		if ($prod_entry_mode == 'free' && empty($idprod) && (($price_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $price_ht == '') && $price_ht_devise == '') 	// Unit price can be 0 but not ''
1705
		{
1706
			if ($price_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES))
1707
			{
1708
				$langs->load("errors");
1709
				setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
1710
				$error++;
1711
			}
1712
			else
1713
			{
1714
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
1715
				$error++;
1716
			}
1717
		}
1718
		if ($qty == '') {
1719
			setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1720
			$error++;
1721
		}
1722
		if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) {
1723
			setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
1724
			$error++;
1725
		}
1726
		if ($qty < 0) {
1727
			$langs->load("errors");
1728
			setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors');
1729
			$error++;
1730
		}
1731
1732
		if (!$error && !empty($conf->variants->enabled) && $prod_entry_mode != 'free') {
1733
			if ($combinations = GETPOST('combinations', 'array')) {
1734
				//Check if there is a product with the given combination
1735
				$prodcomb = new ProductCombination($db);
1736
1737
				if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
1738
					$idprod = $res->fk_product_child;
1739
				}
1740
				else
1741
				{
1742
					setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
1743
					$error++;
1744
				}
1745
			}
1746
		}
1747
1748
		if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) {
1749
1750
			$ret = $object->fetch($id);
1751
			if ($ret < 0) {
1752
				dol_print_error($db, $object->error);
1753
				exit();
1754
			}
1755
			$ret = $object->fetch_thirdparty();
1756
1757
			// Clean parameters
1758
			$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'));
1759
			$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'));
1760
			$price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
1761
1762
			// Define special_code for special lines
1763
			$special_code = 0;
1764
			// if (empty($_POST['qty'])) $special_code=3; // Options should not exists on invoices
1765
1766
			// Ecrase $pu par celui du produit
1767
			// Ecrase $desc par celui du produit
1768
			// Ecrase $tva_tx par celui du produit
1769
			// Ecrase $base_price_type par celui du produit
1770
			// Replaces $fk_unit with the product's
1771
			if (! empty($idprod))
1772
			{
1773
				$prod = new Product($db);
1774
				$prod->fetch($idprod);
1775
1776
				$label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
1777
1778
				// Update if prices fields are defined
1779
				$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
1780
				$tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
1781
				if (empty($tva_tx)) $tva_npr=0;
1782
1783
				$pu_ht = $prod->price;
1784
				$pu_ttc = $prod->price_ttc;
1785
				$price_min = $prod->price_min;
1786
				$price_base_type = $prod->price_base_type;
1787
1788
				// If price per segment
1789
				if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
1790
				{
1791
					$pu_ht = $prod->multiprices[$object->thirdparty->price_level];
1792
					$pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
1793
					$price_min = $prod->multiprices_min[$object->thirdparty->price_level];
1794
					$price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
1795
					if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL))  // using this option is a bug. kept for backward compatibility
1796
					{
1797
						if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
1798
						if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level];
1799
						if (empty($tva_tx)) $tva_npr=0;
1800
					}
1801
				}
1802
				// If price per customer
1803
				elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
1804
				{
1805
					require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
1806
1807
					$prodcustprice = new Productcustomerprice($db);
1808
1809
					$filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id);
1810
1811
					$result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
1812
					if ($result) {
1813
						if (count($prodcustprice->lines) > 0) {
1814
							$pu_ht = price($prodcustprice->lines[0]->price);
1815
							$pu_ttc = price($prodcustprice->lines[0]->price_ttc);
1816
							$price_base_type = $prodcustprice->lines[0]->price_base_type;
1817
							$tva_tx = $prodcustprice->lines[0]->tva_tx;
1818
							if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')';
1819
							$tva_npr = $prodcustprice->lines[0]->recuperableonly;
1820
							if (empty($tva_tx)) $tva_npr=0;
1821
						}
1822
					}
1823
				}
1824
				// If price per quantity
1825
				elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
1826
				{
1827
					if ($prod->prices_by_qty[0])	// yes, this product has some prices per quantity
1828
					{
1829
						// Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
1830
						$pqp = GETPOST('pbq','int');
1831
1832
						// Search price into product_price_by_qty from $prod->id
1833
						foreach($prod->prices_by_qty_list[0] as $priceforthequantityarray)
1834
						{
1835
							if ($priceforthequantityarray['rowid'] != $pqp) continue;
1836
							// We found the price
1837
							if ($priceforthequantityarray['price_base_type'] == 'HT')
1838
							{
1839
								$pu_ht = $priceforthequantityarray['unitprice'];
1840
							}
1841
							else
1842
							{
1843
								$pu_ttc = $priceforthequantityarray['unitprice'];
1844
							}
1845
							// Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
1846
							break;
1847
						}
1848
					}
1849
				}
1850
				// If price per quantity and customer
1851
				elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
1852
				{
1853
					if ($prod->prices_by_qty[$object->thirdparty->price_level]) // yes, this product has some prices per quantity
1854
					{
1855
						// Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
1856
						$pqp = GETPOST('pbq','int');
1857
1858
						// Search price into product_price_by_qty from $prod->id
1859
						foreach($prod->prices_by_qty_list[$object->thirdparty->price_level] as $priceforthequantityarray)
1860
						{
1861
							if ($priceforthequantityarray['rowid'] != $pqp) continue;
1862
							// We found the price
1863
							if ($priceforthequantityarray['price_base_type'] == 'HT')
1864
							{
1865
								$pu_ht = $priceforthequantityarray['unitprice'];
1866
							}
1867
							else
1868
							{
1869
								$pu_ttc = $priceforthequantityarray['unitprice'];
1870
							}
1871
							// Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
1872
							break;
1873
						}
1874
					}
1875
				}
1876
1877
				$tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx));
1878
				$tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx));
1879
1880
				// if price ht was forced (ie: from gui when calculated by margin rate and cost price). TODO Why this ?
1881
				if (! empty($price_ht))
1882
				{
1883
					$pu_ht = price2num($price_ht, 'MU');
1884
					$pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
1885
				}
1886
				// On reevalue prix selon taux tva car taux tva transaction peut etre different
1887
				// de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
1888
				elseif ($tmpvat != $tmpprodvat)
1889
				{
1890
					if ($price_base_type != 'HT')
1891
					{
1892
						$pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
1893
					}
1894
					else
1895
					{
1896
						$pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
1897
					}
1898
				}
1899
1900
				$desc = '';
1901
1902
				// Define output language
1903
				if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
1904
					$outputlangs = $langs;
1905
					$newlang = '';
1906
					if (empty($newlang) && GETPOST('lang_id','aZ09'))
1907
						$newlang = GETPOST('lang_id','aZ09');
1908
					if (empty($newlang))
1909
						$newlang = $object->thirdparty->default_lang;
1910
					if (! empty($newlang)) {
1911
						$outputlangs = new Translate("", $conf);
1912
						$outputlangs->setDefaultLang($newlang);
1913
						$outputlangs->load('products');
1914
					}
1915
1916
					$desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
1917
				} else {
1918
					$desc = $prod->description;
1919
				}
1920
1921
				$desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->CHANGE_ORDER_CONCAT_DESCRIPTION));
1922
1923
				// Add custom code and origin country into description
1924
				if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code))) {
1925
					$tmptxt = '(';
1926
					// Define output language
1927
					if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
1928
						$outputlangs = $langs;
1929
						$newlang = '';
1930
						if (empty($newlang) && GETPOST('lang_id','alpha'))
1931
							$newlang = GETPOST('lang_id','alpha');
1932
						if (empty($newlang))
1933
							$newlang = $object->thirdparty->default_lang;
1934
						if (! empty($newlang)) {
1935
							$outputlangs = new Translate("", $conf);
1936
							$outputlangs->setDefaultLang($newlang);
1937
							$outputlangs->load('products');
1938
						}
1939
						if (! empty($prod->customcode))
1940
							$tmptxt .= $outputlangs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode;
1941
						if (! empty($prod->customcode) && ! empty($prod->country_code))
1942
							$tmptxt .= ' - ';
1943
						if (! empty($prod->country_code))
1944
							$tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $outputlangs, 0);
1945
					} else {
1946
						if (! empty($prod->customcode))
1947
							$tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode;
1948
						if (! empty($prod->customcode) && ! empty($prod->country_code))
1949
							$tmptxt .= ' - ';
1950
						if (! empty($prod->country_code))
1951
							$tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0);
1952
					}
1953
					$tmptxt .= ')';
1954
					$desc = dol_concatdesc($desc, $tmptxt);
1955
				}
1956
1957
				$type = $prod->type;
1958
				$fk_unit = $prod->fk_unit;
1959
			} else {
1960
				$pu_ht = price2num($price_ht, 'MU');
1961
				$pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
1962
				$tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
1963
				$tva_tx = str_replace('*', '', $tva_tx);
1964
				if (empty($tva_tx)) $tva_npr=0;
1965
				$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1966
				$desc = $product_desc;
1967
				$type = GETPOST('type');
1968
				$fk_unit= GETPOST('units', 'alpha');
1969
				$pu_ht_devise = price2num($price_ht_devise, 'MU');
1970
			}
1971
1972
			// Margin
1973
			$fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
1974
			$buyingprice = price2num(GETPOST('buying_price' . $predef) != '' ? GETPOST('buying_price' . $predef) : '');    // If buying_price is '0', we must keep this value
1975
1976
			// Local Taxes
1977
			$localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr);
1978
			$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr);
1979
1980
			$info_bits = 0;
1981
			if ($tva_npr)
1982
				$info_bits |= 0x01;
1983
1984
			if ($usercanproductignorepricemin && (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) {
1985
				$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
1986
				setEventMessages($mesg, null, 'errors');
1987
			} else {
1988
				// Insert line
1989
				$result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $date_start, $date_end, 0, $info_bits, '', $price_base_type, $pu_ttc, $type, - 1, $special_code, '', 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $_POST['progress'], '', $fk_unit, $pu_ht_devise);
1990
1991
				if ($result > 0)
1992
				{
1993
					// Define output language
1994
					if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
1995
					{
1996
						$outputlangs = $langs;
1997
						$newlang = '';
1998
						if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
1999
						if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
2000
						if (! empty($newlang)) {
2001
							$outputlangs = new Translate("", $conf);
2002
							$outputlangs->setDefaultLang($newlang);
2003
							$outputlangs->load('products');
2004
						}
2005
						$model=$object->modelpdf;
2006
						$ret = $object->fetch($id); // Reload to get new records
2007
2008
						$result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
2009
						if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
2010
					}
2011
2012
					unset($_POST['prod_entry_mode']);
2013
2014
					unset($_POST['qty']);
2015
					unset($_POST['type']);
2016
					unset($_POST['remise_percent']);
2017
					unset($_POST['price_ht']);
2018
					unset($_POST['multicurrency_price_ht']);
2019
					unset($_POST['price_ttc']);
2020
					unset($_POST['tva_tx']);
2021
					unset($_POST['product_ref']);
2022
					unset($_POST['product_label']);
2023
					unset($_POST['product_desc']);
2024
					unset($_POST['fournprice']);
2025
					unset($_POST['buying_price']);
2026
					unset($_POST['np_marginRate']);
2027
					unset($_POST['np_markRate']);
2028
					unset($_POST['dp_desc']);
2029
					unset($_POST['idprod']);
2030
					unset($_POST['units']);
2031
2032
					unset($_POST['date_starthour']);
2033
					unset($_POST['date_startmin']);
2034
					unset($_POST['date_startsec']);
2035
					unset($_POST['date_startday']);
2036
					unset($_POST['date_startmonth']);
2037
					unset($_POST['date_startyear']);
2038
					unset($_POST['date_endhour']);
2039
					unset($_POST['date_endmin']);
2040
					unset($_POST['date_endsec']);
2041
					unset($_POST['date_endday']);
2042
					unset($_POST['date_endmonth']);
2043
					unset($_POST['date_endyear']);
2044
2045
					unset($_POST['situations']);
2046
					unset($_POST['progress']);
2047
				} else {
2048
					setEventMessages($object->error, $object->errors, 'errors');
2049
				}
2050
2051
				$action = '';
2052
			}
2053
		}
2054
	}
2055
2056
	elseif ($action == 'updateline' && $usercancreate && ! GETPOST('cancel','alpha'))
2057
	{
2058
		if (! $object->fetch($id) > 0)	dol_print_error($db);
2059
		$object->fetch_thirdparty();
2060
2061
		// Clean parameters
2062
		$date_start = '';
2063
		$date_end = '';
2064
		$date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
2065
		$date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
2066
		$description = dol_htmlcleanlastbr(GETPOST('product_desc','none') ? GETPOST('product_desc','none') : GETPOST('desc','none'));
2067
		$pu_ht = GETPOST('price_ht');
2068
		$vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
2069
		$qty = GETPOST('qty');
2070
		$pu_ht_devise = GETPOST('multicurrency_subprice');
2071
2072
		// Define info_bits
2073
		$info_bits = 0;
2074
		if (preg_match('/\*/', $vat_rate)) $info_bits |= 0x01;
2075
2076
		// Define vat_rate
2077
		$vat_rate = str_replace('*', '', $vat_rate);
2078
		$localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty);
2079
		$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
2080
2081
		// Add buying price
2082
		$fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
2083
		$buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : '');       // If buying_price is '0', we muste keep this value
2084
2085
		// Extrafields
2086
		$extrafieldsline = new ExtraFields($db);
2087
		$extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
2088
		$array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline);
2089
		// Unset extrafield
2090
		if (is_array($extralabelsline)) {
2091
			// Get extra fields
2092
			foreach ($extralabelsline as $key => $value) {
2093
				unset($_POST["options_" . $key]);
2094
			}
2095
		}
2096
2097
		// Define special_code for special lines
2098
		$special_code=GETPOST('special_code');
2099
		if (! GETPOST('qty')) $special_code=3;
2100
2101
		$line = new FactureLigne($db);
2102
		$line->fetch(GETPOST('lineid'));
2103
		$percent = $line->get_prev_progress($object->id);
2104
2105
		if($object->type == Facture::TYPE_CREDIT_NOTE && $object->situation_cycle_ref>0)
2106
		{
2107
		    // in case of situation credit note
2108
		    if(GETPOST('progress') >= 0 )
2109
		    {
2110
		        $mesg = $langs->trans("CantBeNullOrPositive");
2111
		        setEventMessages($mesg, null, 'warnings');
2112
		        $error++;
2113
		        $result = -1;
2114
		    }
2115
		    elseif (GETPOST('progress') < $line->situation_percent) // TODO : use a modified $line->get_prev_progress($object->id) result
2116
		    {
2117
		        $mesg = $langs->trans("CantBeLessThanMinPercent");
2118
		        setEventMessages($mesg, null, 'warnings');
2119
		        $error++;
2120
		        $result = -1;
2121
		    }
2122
		}
2123
		elseif (GETPOST('progress') < $percent)
2124
		{
2125
			$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
2126
			setEventMessages($mesg, null, 'warnings');
2127
			$error++;
2128
			$result = -1;
2129
		}
2130
2131
		// Check minimum price
2132
		$productid = GETPOST('productid', 'int');
2133
		if (! empty($productid))
2134
		{
2135
			$product = new Product($db);
2136
			$product->fetch($productid);
2137
2138
			$type = $product->type;
2139
2140
			$price_min = $product->price_min;
2141
			if ((! empty($conf->global->PRODUIT_MULTIPRICES)  || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) && ! empty($object->thirdparty->price_level))
2142
				$price_min = $product->multiprices_min [$object->thirdparty->price_level];
2143
2144
			$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
2145
2146
			// Check price is not lower than minimum (check is done only for standard or replacement invoices)
2147
			if ($usercanproductignorepricemin && (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))) {
2148
				setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
2149
				$error++;
2150
			}
2151
		} else {
2152
			$type = GETPOST('type');
2153
			$label = (GETPOST('product_label') ? GETPOST('product_label') : '');
2154
2155
			// Check parameters
2156
			if (GETPOST('type') < 0) {
2157
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
2158
				$error++;
2159
			}
2160
		}
2161
		if ($qty < 0) {
2162
			$langs->load("errors");
2163
			setEventMessages($langs->trans('ErrorQtyForCustomerInvoiceCantBeNegative'), null, 'errors');
2164
			$error++;
2165
		}
2166
		if (empty($productid) && (($pu_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) || $pu_ht == '') && $pu_ht_devise == '') 	// Unit price can be 0 but not ''
2167
		{
2168
			if ($pu_ht < 0 && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES))
2169
			{
2170
				$langs->load("errors");
2171
				setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
2172
				$error++;
2173
			}
2174
			else
2175
			{
2176
				setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
2177
				$error++;
2178
			}
2179
		}
2180
2181
2182
		// Update line
2183
		if (! $error) {
2184
			if (empty($usercancreatemargin))
2185
			{
2186
				foreach ($object->lines as &$line)
2187
				{
2188
					if ($line->id == GETPOST('lineid'))
2189
					{
2190
						$fournprice = $line->fk_fournprice;
2191
						$buyingprice = $line->pa_ht;
2192
						break;
2193
					}
2194
				}
2195
			}
2196
2197
			$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $qty, GETPOST('remise_percent'),
2198
				$date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type,
2199
				GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOST('progress'),
2200
				$_POST['units'],$pu_ht_devise);
2201
2202
			if ($result >= 0) {
2203
				if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
2204
					// Define output language
2205
					$outputlangs = $langs;
2206
					$newlang = '';
2207
					if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09'))
2208
						$newlang = GETPOST('lang_id','aZ09');
2209
					if ($conf->global->MAIN_MULTILANGS && empty($newlang))
2210
						$newlang = $object->thirdparty->default_lang;
2211
					if (! empty($newlang)) {
2212
						$outputlangs = new Translate("", $conf);
2213
						$outputlangs->setDefaultLang($newlang);
2214
						$outputlangs->load('products');
2215
					}
2216
2217
					$ret = $object->fetch($id); // Reload to get new records
2218
					$object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2219
				}
2220
2221
				unset($_POST['qty']);
2222
				unset($_POST['type']);
2223
				unset($_POST['productid']);
2224
				unset($_POST['remise_percent']);
2225
				unset($_POST['price_ht']);
2226
				unset($_POST['multicurrency_price_ht']);
2227
				unset($_POST['price_ttc']);
2228
				unset($_POST['tva_tx']);
2229
				unset($_POST['product_ref']);
2230
				unset($_POST['product_label']);
2231
				unset($_POST['product_desc']);
2232
				unset($_POST['fournprice']);
2233
				unset($_POST['buying_price']);
2234
				unset($_POST['np_marginRate']);
2235
				unset($_POST['np_markRate']);
2236
2237
				unset($_POST['dp_desc']);
2238
				unset($_POST['idprod']);
2239
				unset($_POST['units']);
2240
2241
				unset($_POST['date_starthour']);
2242
				unset($_POST['date_startmin']);
2243
				unset($_POST['date_startsec']);
2244
				unset($_POST['date_startday']);
2245
				unset($_POST['date_startmonth']);
2246
				unset($_POST['date_startyear']);
2247
				unset($_POST['date_endhour']);
2248
				unset($_POST['date_endmin']);
2249
				unset($_POST['date_endsec']);
2250
				unset($_POST['date_endday']);
2251
				unset($_POST['date_endmonth']);
2252
				unset($_POST['date_endyear']);
2253
2254
				unset($_POST['situations']);
2255
				unset($_POST['progress']);
2256
			} else {
2257
				setEventMessages($object->error, $object->errors, 'errors');
2258
			}
2259
		}
2260
	}
2261
2262
	else if ($action == 'updatealllines' && $usercancreate && $_POST['all_percent'] == $langs->trans('Modifier'))
2263
	{
2264
		if (!$object->fetch($id) > 0) dol_print_error($db);
2265
		if (!is_null(GETPOST('all_progress')) && GETPOST('all_progress') != "")
2266
		{
2267
			foreach ($object->lines as $line)
2268
			{
2269
				$percent = $line->get_prev_progress($object->id);
2270
				if (GETPOST('all_progress') < $percent) {
2271
					$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
2272
					$result = -1;
2273
				} else
2274
					$object->update_percent($line, $_POST['all_progress']);
2275
			}
2276
		}
2277
	}
2278
2279
	else if ($action == 'updateline' && $usercancreate && $_POST['cancel'] == $langs->trans('Cancel')) {
2280
		header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition
2281
		exit();
2282
	}
2283
2284
	// Outing situation invoice from cycle
2285
	elseif ($action == 'confirm_situationout' && $confirm == 'yes' && $usercancreate)
2286
	{
2287
	    $object->fetch($id,'', '','', true);
2288
2289
	    if ($object->statut == Facture::STATUS_VALIDATED
2290
	        && $object->type == Facture::TYPE_SITUATION
2291
	        && $usercancreate
2292
	        && !$objectidnext
2293
	        && $object->is_last_in_cycle()
2294
	    	&& $usercanunvalidate
2295
	        )
2296
	    {
2297
	        $outingError = 0;
2298
	        $newCycle = $object->newCycle(); // we need to keep the "situation behavior" so we place it on a new situation cycle
2299
	        if($newCycle > 1)
2300
	        {
2301
	            // Search credit notes
2302
	            $lastCycle = $object->situation_cycle_ref;
2303
	            $lastSituationCounter = $object->situation_counter;
2304
	            $linkedCreditNotesList = array();
2305
2306
                if (count($object->tab_next_situation_invoice) > 0) {
2307
                    foreach ($object->tab_next_situation_invoice as $next_invoice) {
2308
                        if($next_invoice->type == Facture::TYPE_CREDIT_NOTE
2309
                            && $next_invoice->situation_counter == $object->situation_counter
2310
                            && $next_invoice->fk_facture_source == $object->id
2311
                          )
2312
                        {
2313
                            $linkedCreditNotesList[] = $next_invoice->id ;
2314
                        }
2315
                    }
2316
                }
2317
2318
	            $object->situation_cycle_ref = $newCycle;
2319
	            $object->situation_counter = 1;
2320
	            $object->situation_final = 0;
2321
	            if($object->update($user) > 0)
2322
	            {
2323
	                $errors = 0;
2324
	                if(count($linkedCreditNotesList) > 0)
2325
	                {
2326
	                    // now, credit note must follow
2327
	                    $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture ';
2328
	                    $sql.= ' SET situation_cycle_ref='.$newCycle;
2329
	                    $sql.= ' , situation_final=0';
2330
	                    $sql.= ' , situation_counter='.$object->situation_counter;
2331
	                    $sql.= ' WHERE rowid IN ('.implode(',',$linkedCreditNotesList).')';
2332
2333
	                    $resql=$db->query($sql);
2334
	                    if (!$resql) $errors++;
2335
2336
	                    // Change each progression persent on each lines
2337
	                    foreach($object->lines as $line)
2338
	                    {
2339
2340
	                        // no traitement for special product
2341
	                        if ($line->product_type == 9 )  continue;
2342
2343
2344
	                        if(!empty($object->tab_previous_situation_invoice))
2345
	                        {
2346
                                // search the last invoice in cycle
2347
	                            $lineIndex = count($object->tab_previous_situation_invoice) - 1;
2348
                                $searchPreviousInvoice = true;
2349
                                while( $searchPreviousInvoice )
2350
                                {
2351
                                    if($object->tab_previous_situation_invoice[$lineIndex]->type  == Facture::TYPE_SITUATION || $lineIndex < 1)
2352
                                    {
2353
                                        $searchPreviousInvoice=false; // find, exit;
2354
                                        break;
2355
                                    }
2356
                                    else
2357
                                    {
2358
                                        $lineIndex--; // go to previous invoice in cycle
2359
                                    }
2360
                                }
2361
2362
2363
                                $maxPrevSituationPercent = 0;
2364
                                foreach($object->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine)
2365
                                {
2366
                                    if($prevLine->id == $line->fk_prev_id)
2367
                                    {
2368
                                        $maxPrevSituationPercent = max($maxPrevSituationPercent,$prevLine->situation_percent);
2369
                                    }
2370
                                }
2371
2372
2373
                                $line->situation_percent = $line->situation_percent - $maxPrevSituationPercent;
2374
2375
                                if($line->update()<0) $errors++;
2376
	                        }
2377
	                    }
2378
	                }
2379
2380
                    if (!$errors)
2381
                    {
2382
                        setEventMessages($langs->trans('Updated'), '', 'mesgs');
2383
                        header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
2384
                    }
2385
                    else
2386
                    {
2387
                        setEventMessages($langs->trans('ErrorOutingSituationInvoiceCreditNote'), array(), 'errors');
2388
                    }
2389
	            }
2390
	            else
2391
	            {
2392
	                setEventMessages($langs->trans('ErrorOutingSituationInvoiceOnUpdate'), array(), 'errors');
2393
	            }
2394
	        }
2395
	        else
2396
	        {
2397
	            setEventMessages($langs->trans('ErrorFindNextSituationInvoice'), array(), 'errors');
2398
	        }
2399
	    }
2400
	}
2401
2402
	// add lines from objectlinked
2403
	elseif($action == 'import_lines_from_object'
2404
	    && $usercancreate
2405
	    && $object->statut == Facture::STATUS_DRAFT
2406
	    && ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION))
2407
	{
2408
	    $fromElement = GETPOST('fromelement');
2409
	    $fromElementid = GETPOST('fromelementid');
2410
	    $importLines = GETPOST('line_checkbox');
2411
2412
	    if(!empty($importLines) && is_array($importLines) && !empty($fromElement) && ctype_alpha($fromElement) && !empty($fromElementid))
2413
	    {
2414
	        if($fromElement == 'commande')
2415
	        {
2416
	            dol_include_once('/'.$fromElement.'/class/'.$fromElement.'.class.php');
2417
	            $lineClassName = 'OrderLine';
2418
	        }
2419
	        elseif($fromElement == 'propal')
2420
	        {
2421
	            dol_include_once('/comm/'.$fromElement.'/class/'.$fromElement.'.class.php');
2422
	            $lineClassName = 'PropaleLigne';
2423
	        }
2424
	        $nextRang = count($object->lines) + 1;
2425
	        $importCount = 0;
2426
	        $error = 0;
2427
	        foreach($importLines as $lineId)
2428
	        {
2429
	            $lineId = intval($lineId);
2430
                $originLine = new $lineClassName($db);
2431
                if(intval($fromElementid) > 0 && $originLine->fetch( $lineId ) > 0)
2432
                {
2433
                    $originLine->fetch_optionals($lineId);
2434
                    $desc = $originLine->desc;
2435
                    $pu_ht = $originLine->subprice;
2436
                    $qty = $originLine->qty;
2437
                    $txtva = $originLine->tva_tx;
2438
                    $txlocaltax1 = $originLine->localtax1_tx;
2439
                    $txlocaltax2 = $originLine->localtax2_tx;
2440
                    $fk_product = $originLine->fk_product;
2441
                    $remise_percent = $originLine->remise_percent;
2442
                    $date_start = $originLine->date_start;
2443
                    $date_end = $originLine->date_end;
2444
                    $ventil = 0;
2445
                    $info_bits = $originLine->info_bits;
2446
                    $fk_remise_except = $originLine->fk_remise_except;
2447
                    $price_base_type='HT';
2448
                    $pu_ttc=0;
2449
                    $type = $originLine->product_type;
2450
                    $rang=$nextRang++;
2451
                    $special_code = $originLine->special_code;
2452
                    $origin = $originLine->element;
2453
                    $origin_id = $originLine->id;
2454
                    $fk_parent_line=0;
2455
                    $fk_fournprice=$originLine->fk_fournprice;
2456
                    $pa_ht = $originLine->pa_ht;
2457
                    $label = $originLine->label;
2458
                    $array_options = $originLine->array_options;
2459
                    $situation_percent = 100;
2460
                    $fk_prev_id = '';
2461
                    $fk_unit = $originLine->fk_unit;
2462
                    $pu_ht_devise = $originLine->multicurrency_subprice;
2463
2464
                    $res = $object->addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $ventil, $info_bits, $fk_remise_except, $price_base_type, $pu_ttc, $type, $rang, $special_code, $origin, $origin_id, $fk_parent_line, $fk_fournprice, $pa_ht, $label, $array_options, $situation_percent, $fk_prev_id, $fk_unit,$pu_ht_devise);
2465
2466
                    if($res > 0){
2467
                        $importCount++;
2468
                    }else{
2469
                        $error++;
2470
                    }
2471
                }
2472
                else{
2473
                    $error++;
2474
                }
2475
	        }
2476
2477
	        if($error)
2478
	        {
2479
	            setEventMessages($langs->trans('ErrorsOnXLines',$error), null, 'errors');
2480
	        }
2481
	    }
2482
	}
2483
2484
	// Actions when printing a doc from card
2485
	include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
2486
2487
	// Actions to send emails
2488
	if (empty($id)) $id=$facid;
2489
	$trigger_name='BILL_SENTBYMAIL';
2490
	$paramname='id';
2491
	$autocopy='MAIN_MAIL_AUTOCOPY_INVOICE_TO';
2492
	$trackid='inv'.$object->id;
2493
	include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
2494
2495
	// Actions to build doc
2496
	$upload_dir = $conf->facture->dir_output;
2497
	$permissioncreate=$usercancreate;
2498
	include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
2499
2500
2501
	if ($action == 'update_extras') {
2502
		$object->oldcopy = dol_clone($object);
2503
2504
		// Fill array 'array_options' with data from add form
2505
		$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
2506
		$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute','none'));
2507
		if ($ret < 0) $error++;
2508
2509
		if (! $error)
2510
		{
2511
			// Actions on extra fields
2512
			$result = $object->insertExtraFields('BILL_MODIFY');
2513
			if ($result < 0)
2514
			{
2515
				setEventMessages($object->error, $object->errors, 'errors');
2516
				$error++;
2517
			}
2518
		}
2519
2520
		if ($error)
2521
			$action = 'edit_extras';
2522
	}
2523
2524
	if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $usercancreate) {
2525
		if ($action == 'addcontact') {
2526
			$result = $object->fetch($id);
2527
2528
			if ($result > 0 && $id > 0) {
2529
				$contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
2530
				$result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]);
2531
			}
2532
2533
			if ($result >= 0) {
2534
				header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
2535
				exit();
2536
			} else {
2537
				if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2538
					$langs->load("errors");
2539
					setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
2540
				} else {
2541
					setEventMessages($object->error, $object->errors, 'errors');
2542
				}
2543
			}
2544
		} // bascule du statut d'un contact
2545
		elseif ($action == 'swapstatut') {
2546
			if ($object->fetch($id)) {
2547
				$result = $object->swapContactStatus(GETPOST('ligne'));
2548
			} else {
2549
				dol_print_error($db);
2550
			}
2551
		} // Efface un contact
2552
		elseif ($action == 'deletecontact') {
2553
			$object->fetch($id);
2554
			$result = $object->delete_contact($lineid);
2555
2556
			if ($result >= 0) {
2557
				header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
2558
				exit();
2559
			} else {
2560
				dol_print_error($db);
2561
			}
2562
		}
2563
2564
		if ($error)
2565
			$action = 'edit_extras';
2566
	}
2567
}
2568
2569
2570
/*
2571
 * View
2572
 */
2573
2574
$form = new Form($db);
2575
$formother = new FormOther($db);
2576
$formfile = new FormFile($db);
2577
$formmargin = new FormMargin($db);
2578
$paymentstatic=new Paiement($db);
2579
$bankaccountstatic = new Account($db);
2580
if (! empty($conf->projet->enabled)) { $formproject = new FormProjets($db); }
2581
2582
$now = dol_now();
2583
2584
$title = $langs->trans('InvoiceCustomer') . " - " . $langs->trans('Card');
2585
$helpurl = "EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes";
2586
llxHeader('', $title, $helpurl);
2587
2588
2589
// Mode creation
2590
2591
if ($action == 'create')
2592
{
2593
	$facturestatic = new Facture($db);
2594
	$extralabels = $extrafields->fetch_name_optionals_label($facturestatic->table_element);
2595
2596
	print load_fiche_titre($langs->trans('NewBill'));
2597
2598
	$soc = new Societe($db);
2599
	if ($socid > 0)
2600
		$res = $soc->fetch($socid);
2601
2602
	$currency_code = $conf->currency;
2603
2604
	// Load objectsrc
2605
	$remise_absolue = 0;
2606
2607
	if (! empty($origin) && ! empty($originid))
2608
	{
2609
		// Parse element/subelement (ex: project_task)
2610
		$element = $subelement = $origin;
2611
		if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
2612
			$element = $regs [1];
2613
			$subelement = $regs [2];
2614
		}
2615
2616
		if ($element == 'project') {
2617
			$projectid = $originid;
2618
2619
			if (!$cond_reglement_id) {
2620
				$cond_reglement_id = $soc->cond_reglement_id;
2621
			}
2622
			if (!$mode_reglement_id) {
2623
				$mode_reglement_id = $soc->mode_reglement_id;
2624
			}
2625
			if (!$remise_percent) {
2626
				$remise_percent = $soc->remise_percent;
2627
			}
2628
			if (!$dateinvoice) {
2629
				// Do not set 0 here (0 for a date is 1970)
2630
				$dateinvoice = (empty($dateinvoice)?(empty($conf->global->MAIN_AUTOFILL_DATE)?-1:''):$dateinvoice);
2631
			}
2632
		} else {
2633
			// For compatibility
2634
			if ($element == 'order' || $element == 'commande') {
2635
				$element = $subelement = 'commande';
2636
			}
2637
			if ($element == 'propal') {
2638
				$element = 'comm/propal';
2639
				$subelement = 'propal';
2640
			}
2641
			if ($element == 'contract') {
2642
				$element = $subelement = 'contrat';
2643
			}
2644
			if ($element == 'shipping') {
2645
				$element = $subelement = 'expedition';
2646
			}
2647
2648
			dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
2649
2650
			$classname = ucfirst($subelement);
2651
			$objectsrc = new $classname($db);
2652
			$objectsrc->fetch($originid);
2653
			if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines'))
2654
				$objectsrc->fetch_lines();
2655
			$objectsrc->fetch_thirdparty();
2656
2657
			$projectid = (! empty($projectid) ? $projectid : $objectsrc->fk_project);
2658
			$ref_client = (! empty($objectsrc->ref_client) ? $objectsrc->ref_client : (! empty($objectsrc->ref_customer) ? $objectsrc->ref_customer:''));
2659
			$ref_int = (! empty($objectsrc->ref_int) ? $objectsrc->ref_int : '');
2660
2661
			// only if socid not filled else it's allready done upper
2662
			if (empty($socid))
2663
				$soc = $objectsrc->thirdparty;
2664
2665
			$cond_reglement_id 	= (! empty($objectsrc->cond_reglement_id)?$objectsrc->cond_reglement_id:(! empty($soc->cond_reglement_id)?$soc->cond_reglement_id:0));
2666
			$mode_reglement_id 	= (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0));
2667
			$fk_account         = (! empty($objectsrc->fk_account)?$objectsrc->fk_account:(! empty($soc->fk_account)?$soc->fk_account:0));
2668
			$remise_percent 	= (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0));
2669
			$remise_absolue 	= (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0));
2670
			$dateinvoice		= (empty($dateinvoice)?(empty($conf->global->MAIN_AUTOFILL_DATE)?-1:''):$dateinvoice);
2671
2672
			if (!empty($conf->multicurrency->enabled))
2673
			{
2674
				if (!empty($objectsrc->multicurrency_code)) $currency_code = $objectsrc->multicurrency_code;
2675
				if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx))	$currency_tx = $objectsrc->multicurrency_tx;
2676
			}
2677
2678
			// Replicate extrafields
2679
			$objectsrc->fetch_optionals($originid);
2680
			$object->array_options = $objectsrc->array_options;
2681
		}
2682
	}
2683
	else
2684
	{
2685
		$cond_reglement_id 	= $soc->cond_reglement_id;
2686
		$mode_reglement_id 	= $soc->mode_reglement_id;
2687
		$fk_account        	= $soc->fk_account;
2688
		$remise_percent 	= $soc->remise_percent;
2689
		$remise_absolue 	= 0;
2690
		$dateinvoice		= (empty($dateinvoice)?(empty($conf->global->MAIN_AUTOFILL_DATE)?-1:''):$dateinvoice);		// Do not set 0 here (0 for a date is 1970)
2691
2692
		if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code;
2693
	}
2694
2695
	if (!empty($soc->id)) $absolute_discount = $soc->getAvailableDiscounts();
2696
	$note_public = $object->getDefaultCreateValueFor('note_public', (is_object($objectsrc)?$objectsrc->note_public:null));
2697
	$note_private = $object->getDefaultCreateValueFor('note_private', ((! empty($origin) && ! empty($originid) && is_object($objectsrc))?$objectsrc->note_private:null));
2698
2699
	if (! empty($conf->use_javascript_ajax))
2700
	{
2701
		require_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
2702
		print ajax_combobox('fac_replacement');
2703
		print ajax_combobox('fac_avoir');
2704
		print ajax_combobox('situations');
2705
	}
2706
2707
	if ($origin == 'contrat')
2708
	{
2709
		$langs->load("admin");
2710
		$text=$langs->trans("ToCreateARecurringInvoice");
2711
		$text.=' '.$langs->trans("ToCreateARecurringInvoiceGene", $langs->transnoentitiesnoconv("MenuFinancial"), $langs->transnoentitiesnoconv("BillsCustomers"), $langs->transnoentitiesnoconv("ListOfTemplates"));
2712
		if (empty($conf->global->INVOICE_DISABLE_AUTOMATIC_RECURRING_INVOICE))
2713
		{
2714
		   $text.=' '.$langs->trans("ToCreateARecurringInvoiceGeneAuto", $langs->transnoentitiesnoconv('Module2300Name'));
2715
		}
2716
		print info_admin($text, 0, 0, 0).'<br>';
2717
	}
2718
2719
	print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
2720
	print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
2721
	print '<input type="hidden" name="action" value="add">';
2722
	if ($soc->id > 0) print '<input type="hidden" name="socid" value="' . $soc->id . '">' . "\n";
2723
	print '<input name="ref" type="hidden" value="provisoire">';
2724
	print '<input name="ref_client" type="hidden" value="' . $ref_client . '">';
2725
	print '<input name="ref_int" type="hidden" value="' . $ref_int . '">';
2726
	print '<input type="hidden" name="origin" value="' . $origin . '">';
2727
	print '<input type="hidden" name="originid" value="' . $originid . '">';
2728
	if (!empty($currency_tx)) print '<input type="hidden" name="originmulticurrency_tx" value="' . $currency_tx . '">';
2729
2730
	dol_fiche_head('');
2731
2732
	print '<table class="border" width="100%">';
2733
2734
	// Ref
2735
	print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans('Ref') . '</td><td colspan="2">' . $langs->trans('Draft') . '</td></tr>';
2736
2737
	// Thirdparty
2738
	print '<td class="fieldrequired">' . $langs->trans('Customer') . '</td>';
2739
	if ($soc->id > 0 && ! GETPOST('fac_rec','alpha'))
2740
	{
2741
		print '<td colspan="2">';
2742
		print $soc->getNomUrl(1);
2743
		print '<input type="hidden" name="socid" value="' . $soc->id . '">';
2744
		// Outstanding Bill
2745
		$outstandingBills = $soc->get_OutstandingBill();
2746
		print ' (' . $langs->trans('CurrentOutstandingBill') . ': ';
2747
		print price($outstandingBills, '', $langs, 0, 0, -1, $conf->currency);
2748
		if ($soc->outstanding_limit != '')
2749
		{
2750
			if ($outstandingBills > $soc->outstanding_limit) print img_warning($langs->trans("OutstandingBillReached"));
2751
			print ' / ' . price($soc->outstanding_limit, '', $langs, 0, 0, -1, $conf->currency);
2752
		}
2753
		print ')';
2754
		print '</td>';
2755
	}
2756
	else
2757
	{
2758
		print '<td colspan="2">';
2759
		print $form->select_company($soc->id, 'socid', '(s.client = 1 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
2760
		// Option to reload page to retrieve customer informations. Note, this clear other input
2761
		if (!empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE))
2762
		{
2763
			print '<script type="text/javascript">
2764
			$(document).ready(function() {
2765
				$("#socid").change(function() {
2766
					var socid = $(this).val();
2767
			        var fac_rec = $(\'#fac_rec\').val();
2768
					// reload page
2769
        			window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec;
2770
				});
2771
			});
2772
			</script>';
2773
		}
2774
		print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&client=3&fournisseur=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">'.$langs->trans("AddThirdParty").'</a>';
2775
		print '</td>';
2776
	}
2777
	print '</tr>' . "\n";
2778
2779
	$exampletemplateinvoice=new FactureRec($db);
2780
2781
	// Overwrite value if creation of invoice is from a predefined invoice
2782
	if (empty($origin) && empty($originid) && GETPOST('fac_rec','int') > 0)
2783
	{
2784
		$invoice_predefined = new FactureRec($db);
2785
		$invoice_predefined->fetch(GETPOST('fac_rec','int'));
2786
2787
		$dateinvoice = $invoice_predefined->date_when;     // To use next gen date by default later
2788
		if (empty($projectid)) $projectid = $invoice_predefined->fk_project;
2789
		$cond_reglement_id = $invoice_predefined->cond_reglement_id;
2790
		$mode_reglement_id = $invoice_predefined->mode_reglement_id;
2791
		$fk_account = $invoice_predefined->fk_account;
2792
		$note_public = $invoice_predefined->note_public;
2793
		$note_private = $invoice_predefined->note_private;
2794
2795
		$sql = 'SELECT r.rowid, r.titre, r.total_ttc';
2796
		$sql .= ' FROM ' . MAIN_DB_PREFIX . 'facture_rec as r';
2797
		$sql .= ' WHERE r.fk_soc = ' . $invoice_predefined->socid;
2798
2799
		$resql = $db->query($sql);
2800
		if ($resql)
2801
		{
2802
			$num = $db->num_rows($resql);
2803
			$i = 0;
2804
2805
			if ($num > 0)
2806
			{
2807
				print '<tr><td>' . $langs->trans('CreateFromRepeatableInvoice') . '</td><td>';
2808
				print '<select class="flat" id="fac_rec" name="fac_rec">';
2809
				print '<option value="0" selected></option>';
2810
				while ($i < $num)
2811
				{
2812
					$objp = $db->fetch_object($resql);
2813
					print '<option value="' . $objp->rowid . '"';
2814
					if (GETPOST('fac_rec') == $objp->rowid)
2815
					{
2816
						print ' selected';
2817
						$exampletemplateinvoice->fetch(GETPOST('fac_rec'));
2818
					}
2819
					print '>' . $objp->titre . ' (' . price($objp->total_ttc) . ' ' . $langs->trans("TTC") . ')</option>';
2820
					$i ++;
2821
				}
2822
				print '</select>';
2823
				// Option to reload page to retrieve customer informations. Note, this clear other input
2824
				if (!empty($conf->global->RELOAD_PAGE_ON_TEMPLATE_CHANGE))
2825
				{
2826
					print '<script type="text/javascript">
2827
        			$(document).ready(function() {
2828
        				$("#fac_rec").change(function() {
2829
        					var fac_rec = $(this).val();
2830
        			        var socid = $(\'#socid\').val();
2831
        					// reload page
2832
        					window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec;
2833
        				});
2834
        			});
2835
        			</script>';
2836
				}
2837
				print '</td></tr>';
2838
			}
2839
			$db->free($resql);
2840
		} else {
2841
			dol_print_error($db);
2842
		}
2843
	}
2844
2845
	// Type de facture
2846
	$facids = $facturestatic->list_replacable_invoices($soc->id);
2847
	if ($facids < 0) {
2848
		dol_print_error($db, $facturestatic);
2849
		exit();
2850
	}
2851
	$options = "";
2852
	foreach ($facids as $facparam)
2853
	{
2854
		$options .= '<option value="' . $facparam ['id'] . '"';
2855
		if ($facparam ['id'] == $_POST['fac_replacement'])
2856
			$options .= ' selected';
2857
		$options .= '>' . $facparam ['ref'];
2858
		$options .= ' (' . $facturestatic->LibStatut(0, $facparam ['status']) . ')';
2859
		$options .= '</option>';
2860
	}
2861
2862
	// Show link for credit note
2863
	$facids=$facturestatic->list_qualified_avoir_invoices($soc->id);
2864
	if ($facids < 0)
2865
	{
2866
		dol_print_error($db,$facturestatic);
2867
		exit;
2868
	}
2869
	$optionsav = "";
2870
	$newinvoice_static = new Facture($db);
2871
	foreach ($facids as $key => $valarray)
2872
	{
2873
		$newinvoice_static->id = $key;
2874
		$newinvoice_static->ref = $valarray ['ref'];
2875
		$newinvoice_static->statut = $valarray ['status'];
2876
		$newinvoice_static->type = $valarray ['type'];
2877
		$newinvoice_static->paye = $valarray ['paye'];
2878
2879
		$optionsav .= '<option value="' . $key . '"';
2880
		if ($key == GETPOST('fac_avoir'))
2881
			$optionsav .= ' selected';
2882
		$optionsav .= '>';
2883
		$optionsav .= $newinvoice_static->ref;
2884
		$optionsav .= ' (' . $newinvoice_static->getLibStatut(1, $valarray ['paymentornot']) . ')';
2885
		$optionsav .= '</option>';
2886
	}
2887
2888
	print '<tr><td class="tdtop fieldrequired">' . $langs->trans('Type') . '</td><td colspan="2">';
2889
2890
	print '<div class="tagtable">' . "\n";
2891
2892
	// Standard invoice
2893
	print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2894
	$tmp='<input type="radio" id="radio_standard" name="type" value="0"' . (GETPOST('type') == 0 ? ' checked' : '') . '> ';
2895
	$tmp  = $tmp.'<label for="radio_standard" >'.$langs->trans("InvoiceStandardAsk").'</label>';
2896
	$desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3);
2897
	print $desc;
2898
	print '</div></div>';
2899
2900
	if ((empty($origin)) || ((($origin == 'propal') || ($origin == 'commande')) && (! empty($originid))))
2901
	{
2902
		// Deposit
2903
		if (empty($conf->global->INVOICE_DISABLE_DEPOSIT))
2904
   		{
2905
			print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2906
			$tmp='<input type="radio" id="radio_deposit" name="type" value="3"' . (GETPOST('type') == 3 ? ' checked' : '') . '> ';
2907
			print '<script type="text/javascript" language="javascript">
2908
    		jQuery(document).ready(function() {
2909
    			jQuery("#typedeposit, #valuedeposit").click(function() {
2910
    				jQuery("#radio_deposit").prop("checked", true);
2911
    			});
2912
    		});
2913
    		</script>';
2914
2915
			$tmp  = $tmp.'<label for="radio_deposit" >'.$langs->trans("InvoiceDeposit").'</label>';
2916
			$desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
2917
			print '<table class="nobordernopadding"><tr><td>';
2918
			print $desc;
2919
			print '</td>';
2920
			if (($origin == 'propal') || ($origin == 'commande'))
2921
			{
2922
				print '<td class="nowrap" style="padding-left: 5px">';
2923
				$arraylist = array('amount' => $langs->transnoentitiesnoconv('FixAmount'), 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')));
2924
				print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit'), 0, 0, 0, '', 1);
2925
				print '</td>';
2926
				print '<td class="nowrap" style="padding-left: 5px">' . $langs->trans('Value') . ':<input type="text" id="valuedeposit" name="valuedeposit" size="3" value="' . GETPOST('valuedeposit', 'int') . '"/>';
2927
			}
2928
			print '</td></tr></table>';
2929
2930
			print '</div></div>';
2931
   		}
2932
	}
2933
2934
	if ($socid > 0)
2935
	{
2936
		if (! empty($conf->global->INVOICE_USE_SITUATION))
2937
		{
2938
			// First situation invoice
2939
			print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2940
			$tmp='<input id="radio_situation invoice" type="radio" name="type" value="5"' . (GETPOST('type') == 5 ? ' checked' : '') . '> ';
2941
			$tmp  = $tmp.'<label for="radio_situation invoice" >'.$langs->trans("InvoiceFirstSituationAsk").'</label>';
2942
			$desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3);
2943
			print $desc;
2944
			print '</div></div>';
2945
2946
			// Next situation invoice
2947
			$opt = $form->selectSituationInvoices(GETPOST('originid'), $socid);
2948
			print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2949
			$tmp='<input type="radio" name="type" value="5"' . (GETPOST('type') == 5 && GETPOST('originid') ? ' checked' : '');
2950
			if ($opt == ('<option value ="0" selected>' . $langs->trans('NoSituations') . '</option>') || (GETPOST('origin') && GETPOST('origin') != 'facture' && GETPOST('origin') != 'commande')) $tmp.=' disabled';
2951
			$tmp.= '> ';
2952
			$text = '<label>'.$tmp.$langs->trans("InvoiceSituationAsk") . '</label> ';
2953
			$text .= '<select class="flat" id="situations" name="situations">';
2954
			$text .= $opt;
2955
			$text .= '</select>';
2956
			$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceSituationDesc"), 1, 'help', '', 0, 3);
2957
			print $desc;
2958
			print '</div></div>';
2959
		}
2960
2961
		// Replacement
2962
		if (empty($conf->global->INVOICE_DISABLE_REPLACEMENT))
2963
		{
2964
			print '<!-- replacement line -->';
2965
			print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2966
			$tmp='<input type="radio" name="type" id="radio_replacement" value="1"' . (GETPOST('type') == 1 ? ' checked' : '');
2967
			if (! $options) $tmp.=' disabled';
2968
			$tmp.='> ';
2969
			print '<script type="text/javascript" language="javascript">
2970
    		jQuery(document).ready(function() {
2971
    			jQuery("#fac_replacement").change(function() {
2972
    				jQuery("#radio_replacement").prop("checked", true);
2973
    			});
2974
    		});
2975
    		</script>';
2976
			$text = '<label>'.$tmp.$langs->trans("InvoiceReplacementAsk") . '</label>';
2977
			$text .= '<select class="flat" name="fac_replacement" id="fac_replacement"';
2978
			if (! $options)
2979
				$text .= ' disabled';
2980
			$text .= '>';
2981
			if ($options) {
2982
				$text .= '<option value="-1">&nbsp;</option>';
2983
				$text .= $options;
2984
			} else {
2985
				$text .= '<option value="-1">' . $langs->trans("NoReplacableInvoice") . '</option>';
2986
			}
2987
			$text .= '</select>';
2988
			$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
2989
			print $desc;
2990
			print '</div></div>';
2991
		}
2992
	}
2993
	else
2994
	{
2995
		print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
2996
		$tmp='<input type="radio" name="type" id="radio_replacement" value="0" disabled> ';
2997
		$text = '<label>'.$tmp.$langs->trans("InvoiceReplacement") . '</label> ';
2998
		$text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') ';
2999
		$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
3000
		print $desc;
3001
		print '</div></div>';
3002
	}
3003
3004
3005
	if (empty($origin))
3006
	{
3007
		if ($socid > 0)
3008
		{
3009
			// Credit note
3010
			if (empty($conf->global->INVOICE_DISABLE_CREDIT_NOTE))
3011
			{
3012
				print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
3013
				$tmp='<input type="radio" id="radio_creditnote" name="type" value="2"' . (GETPOST('type') == 2 ? ' checked' : '');
3014
				if (! $optionsav) $tmp.=' disabled';
3015
				$tmp.= '> ';
3016
				// Show credit note options only if we checked credit note
3017
				print '<script type="text/javascript" language="javascript">
3018
    			jQuery(document).ready(function() {
3019
    				if (! jQuery("#radio_creditnote").is(":checked"))
3020
    				{
3021
    					jQuery("#credit_note_options").hide();
3022
    				}
3023
    				jQuery("#radio_creditnote").click(function() {
3024
    					jQuery("#credit_note_options").show();
3025
    				});
3026
    				jQuery("#radio_standard, #radio_replacement, #radio_deposit").click(function() {
3027
    					jQuery("#credit_note_options").hide();
3028
    				});
3029
    			});
3030
    			</script>';
3031
				$text = '<label>'.$tmp.$langs->transnoentities("InvoiceAvoirAsk") . '</label> ';
3032
				// $text.='<input type="text" value="">';
3033
				$text .= '<select class="flat valignmiddle" name="fac_avoir" id="fac_avoir"';
3034
				if (! $optionsav)
3035
					$text .= ' disabled';
3036
				$text .= '>';
3037
				if ($optionsav) {
3038
					$text .= '<option value="-1"></option>';
3039
					$text .= $optionsav;
3040
				} else {
3041
					$text .= '<option value="-1">' . $langs->trans("NoInvoiceToCorrect") . '</option>';
3042
				}
3043
				$text .= '</select>';
3044
				$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
3045
				print $desc;
3046
3047
				print '<div id="credit_note_options" class="clearboth">';
3048
				print '&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="$(\'#credit_note_options input[type=checkbox]\').not(this).prop(\'checked\', false);" '.(GETPOST('invoiceAvoirWithLines','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
3049
				print '<br>&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="$(\'#credit_note_options input[type=checkbox]\').not(this).prop(\'checked\', false);" '.(GETPOST('invoiceAvoirWithPaymentRestAmount','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
3050
				print '</div>';
3051
3052
    			print '</div></div>';
3053
    		}
3054
		}
3055
		else
3056
		{
3057
			print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
3058
			if (empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE)) $tmp='<input type="radio" name="type" id="radio_creditnote" value="0" disabled> ';
3059
			else $tmp='<input type="radio" name="type" id="radio_creditnote" value="2" > ';
3060
			$text = '<label>'.$tmp.$langs->trans("InvoiceAvoir") . '</label> ';
3061
			$text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') ';
3062
			$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
3063
			print $desc;
3064
			print '</div></div>' . "\n";
3065
		}
3066
	}
3067
3068
	// Template invoice
3069
	print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
3070
	$tmp='<input type="radio" name="type" id="radio_template" value="0" disabled> ';
3071
	$text = '<label>'.$tmp.$langs->trans("RepeatableInvoice") . '</label> ';
3072
	//$text.= '('.$langs->trans("YouMustCreateStandardInvoiceFirst").') ';
3073
	$desc = $form->textwithpicto($text, $langs->transnoentities("YouMustCreateStandardInvoiceFirstDesc"), 1, 'help', '', 0, 3);
3074
	print $desc;
3075
	print '</div></div>';
3076
3077
	print '</div>';
3078
3079
3080
	if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)) // Hidden conf
3081
	{
3082
    	// Add auto select default document model
3083
    	$listtType=array(Facture::TYPE_STANDARD,Facture::TYPE_REPLACEMENT,Facture::TYPE_CREDIT_NOTE,Facture::TYPE_DEPOSIT,Facture::TYPE_SITUATION);
3084
    	$jsListType='';
3085
    	foreach ($listtType as $type)
3086
    	{
3087
    	    $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type;
3088
    	    $curent = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF;
3089
    	    $jsListType.=(!empty($jsListType)?',':'').'"'.$type.'":"'.$curent.'"';
3090
    	}
3091
3092
    	print '<script type="text/javascript" language="javascript">
3093
        		$(document).ready(function() {
3094
                    var listType = {'.$jsListType.'};
3095
        			$("[name=\'type\'").change(function() {
3096
        				if($( this ).prop("checked"))
3097
                        {
3098
                            if(($( this ).val() in listType))
3099
                            {
3100
                                $("#model").val(listType[$( this ).val()]);
3101
                            }
3102
                            else
3103
                            {
3104
                                $("#model").val("'.$conf->global->FACTURE_ADDON_PDF.'");
3105
                            }
3106
                        }
3107
        			});
3108
        		});
3109
        		</script>';
3110
	}
3111
3112
3113
3114
	print '</td></tr>';
3115
3116
	if ($socid > 0)
3117
	{
3118
		// Discounts for third party
3119
		print '<tr><td>' . $langs->trans('Discounts') . '</td><td colspan="2">';
3120
3121
		$thirdparty = $soc;
3122
		$discount_type = 0;
3123
		$backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
3124
		include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
3125
3126
		print '</td></tr>';
3127
	}
3128
3129
	$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
3130
3131
	// Date invoice
3132
	print '<tr><td class="fieldrequired">' . $langs->trans('DateInvoice') . '</td><td colspan="2">';
3133
	print $form->selectDate($datefacture?$datefacture:$dateinvoice, '', '', '', '', "add", 1, 1);
3134
	print '</td></tr>';
3135
3136
	// Date point of tax
3137
	if (! empty($conf->global->INVOICE_POINTOFTAX_DATE))
3138
	{
3139
		print '<tr><td class="fieldrequired">' . $langs->trans('DatePointOfTax') . '</td><td colspan="2">';
3140
		$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
3141
		print $form->selectDate($date_pointoftax?$date_pointoftax:-1, 'date_pointoftax', '', '', '', "add", 1, 1);
3142
		print '</td></tr>';
3143
	}
3144
3145
	// Payment term
3146
	print '<tr><td class="nowrap fieldrequired">' . $langs->trans('PaymentConditionsShort') . '</td><td colspan="2">';
3147
	$form->select_conditions_paiements(isset($_POST['cond_reglement_id']) ? $_POST['cond_reglement_id'] : $cond_reglement_id, 'cond_reglement_id');
3148
	print '</td></tr>';
3149
3150
	// Payment mode
3151
	print '<tr><td>' . $langs->trans('PaymentMode') . '</td><td colspan="2">';
3152
	$form->select_types_paiements(isset($_POST['mode_reglement_id']) ? $_POST['mode_reglement_id'] : $mode_reglement_id, 'mode_reglement_id', 'CRDT');
3153
	print '</td></tr>';
3154
3155
	// Bank Account
3156
	if (isset($_POST['fk_account'])) {
3157
		$fk_account = $_POST['fk_account'];
3158
	}
3159
3160
	print '<tr><td>' . $langs->trans('BankAccount') . '</td><td colspan="2">';
3161
	$form->select_comptes($fk_account, 'fk_account', 0, '', 1);
3162
	print '</td></tr>';
3163
3164
	// Project
3165
	if (! empty($conf->projet->enabled))
3166
	{
3167
		$langs->load('projects');
3168
		print '<tr><td>' . $langs->trans('Project') . '</td><td colspan="2">';
3169
		$numprojet = $formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1);
3170
		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.($fac_rec?'&fac_rec='.$fac_rec:'')).'">' . $langs->trans("AddProject") . '</a>';
3171
		print '</td></tr>';
3172
	}
3173
3174
	// Incoterms
3175
	if (!empty($conf->incoterm->enabled))
3176
	{
3177
		print '<tr>';
3178
		print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $objectsrc->libelle_incoterms, 1).'</label></td>';
3179
		print '<td colspan="2" class="maxwidthonsmartphone">';
3180
		$incoterm_id = GETPOST('incoterm_id');
3181
		$incoterm_location = GETPOST('location_incoterms');
3182
		if (empty($incoterm_id))
3183
		{
3184
			$incoterm_id = (!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : $soc->fk_incoterms);
3185
			$incoterm_location = (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : $soc->location_incoterms);
3186
		}
3187
		print $form->select_incoterms($incoterm_id, $incoterm_location);
3188
		print '</td></tr>';
3189
	}
3190
3191
	// Other attributes
3192
	$parameters = array('objectsrc' => $objectsrc,'colspan' => ' colspan="2"', 'cols'=>2);
3193
	$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3194
	print $hookmanager->resPrint;
3195
	if (empty($reshook)) {
3196
		print $object->showOptionals($extrafields, 'edit');
3197
	}
3198
3199
	// Template to use by default
3200
	print '<tr><td>' . $langs->trans('Model') . '</td>';
3201
	print '<td colspan="2">';
3202
	include_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php';
3203
	$liste = ModelePDFFactures::liste_modeles($db);
3204
	if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)){ // Hidden conf
3205
	   $paramkey='FACTURE_ADDON_PDF_'.$object->type;
3206
	   $curent = !empty($conf->global->$paramkey)?$conf->global->$paramkey:$conf->global->FACTURE_ADDON_PDF;
3207
	}
3208
	else{
3209
	   $curent = $conf->global->FACTURE_ADDON_PDF;
3210
	}
3211
	print $form->selectarray('model', $liste, $curent);
3212
	print "</td></tr>";
3213
3214
	// Multicurrency
3215
	if (! empty($conf->multicurrency->enabled))
3216
	{
3217
		print '<tr>';
3218
		print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
3219
		print '<td colspan="2" class="maxwidthonsmartphone">';
3220
		print $form->selectMultiCurrency($currency_code, 'multicurrency_code');
3221
		print '</td></tr>';
3222
	}
3223
3224
	// Help of substitution key
3225
	$htmltext='';
3226
	if (GETPOST('fac_rec','int') > 0)
3227
	{
3228
		$dateexample=($datefacture ? $datefacture : $dateinvoice);
3229
		if (empty($dateexample)) $dateexample=dol_now();
3230
		$substitutionarray=array(
3231
			'__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ht).')',
3232
			'__TOTAL_TTC__' =>  $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ttc).')',
3233
			'__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'),'%m').')',
3234
			'__INVOICE_MONTH__' =>  $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample,'%m').')',
3235
			'__INVOICE_NEXT_MONTH__' => $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'),'%m').')',
3236
			'__INVOICE_PREVIOUS_MONTH_TEXT__' => $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'),'%B').')',
3237
			'__INVOICE_MONTH_TEXT__' =>  $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample,'%B').')',
3238
			'__INVOICE_NEXT_MONTH_TEXT__' => $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B').')',
3239
			'__INVOICE_PREVIOUS_YEAR__' => $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'),'%Y').')',
3240
			'__INVOICE_YEAR__' =>  $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample,'%Y').')',
3241
			'__INVOICE_NEXT_YEAR__' => $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'),'%Y').')'
3242
		);
3243
3244
		$htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br>';
3245
		foreach($substitutionarray as $key => $val)
3246
		{
3247
			$htmltext.=$key.' = '.$langs->trans($val).'<br>';
3248
		}
3249
		$htmltext.='</i>';
3250
	}
3251
3252
	// Public note
3253
	print '<tr>';
3254
	print '<td class="tdtop">';
3255
	print $form->textwithpicto($langs->trans('NotePublic'), $htmltext);
3256
	print '</td>';
3257
	print '<td valign="top" colspan="2">';
3258
	$doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%');
3259
	print $doleditor->Create(1);
3260
3261
	// Private note
3262
	if (empty($user->societe_id))
3263
	{
3264
		print '<tr>';
3265
		print '<td class="tdtop">';
3266
		print $form->textwithpicto($langs->trans('NotePrivate'), $htmltext);
3267
		print '</td>';
3268
		print '<td valign="top" colspan="2">';
3269
		$doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%');
3270
		print $doleditor->Create(1);
3271
		// print '<textarea name="note_private" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'.</textarea>
3272
		print '</td></tr>';
3273
	}
3274
3275
	// Lines from source
3276
	if (! empty($origin) && ! empty($originid) && is_object($objectsrc))
3277
	{
3278
		// TODO for compatibility
3279
		if ($origin == 'contrat') {
3280
			// Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
3281
			$objectsrc->remise_absolue = $remise_absolue;
3282
			$objectsrc->remise_percent = $remise_percent;
3283
			$objectsrc->update_price(1, - 1, 1);
3284
		}
3285
3286
		print "\n<!-- " . $classname . " info -->";
3287
		print "\n";
3288
		print '<input type="hidden" name="amount"         value="' . $objectsrc->total_ht . '">' . "\n";
3289
		print '<input type="hidden" name="total"          value="' . $objectsrc->total_ttc . '">' . "\n";
3290
		print '<input type="hidden" name="tva"            value="' . $objectsrc->total_tva . '">' . "\n";
3291
		print '<input type="hidden" name="origin"         value="' . $objectsrc->element . '">';
3292
		print '<input type="hidden" name="originid"       value="' . $objectsrc->id . '">';
3293
3294
		switch (get_class($objectsrc)) {
3295
			case 'Propal':
3296
				$newclassname = 'CommercialProposal';
3297
				break;
3298
			case 'Commande':
3299
				$newclassname = 'Order';
3300
				break;
3301
			case 'Expedition':
3302
				$newclassname = 'Sending';
3303
				break;
3304
			case 'Contrat':
3305
				$newclassname = 'Contract';
3306
				break;
3307
			case 'Fichinter':
3308
				$newclassname = 'Intervention';
3309
				break;
3310
			default:
3311
				$newclassname = get_class($objectsrc);
3312
		}
3313
3314
		print '<tr><td>' . $langs->trans($newclassname) . '</td><td colspan="2">' . $objectsrc->getNomUrl(1);
3315
		// We check if Origin document (id and type is known) has already at least one invoice attached to it
3316
		$objectsrc->fetchObjectLinked($originid,$origin,'','facture');
3317
		if (is_array($objectsrc->linkedObjects['facture']) && count($objectsrc->linkedObjects['facture']) >= 1)
3318
		{
3319
			setEventMessages('WarningBillExist', null, 'warnings');
3320
			echo ' ('.$langs->trans('LatestRelatedBill').end($objectsrc->linkedObjects['facture'])->getNomUrl(1).')';
3321
		}
3322
		echo '</td></tr>';
3323
		print '<tr><td>' . $langs->trans('TotalHT') . '</td><td colspan="2">' . price($objectsrc->total_ht) . '</td></tr>';
3324
		print '<tr><td>' . $langs->trans('TotalVAT') . '</td><td colspan="2">' . price($objectsrc->total_tva) . "</td></tr>";
3325
		if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) 		// Localtax1
3326
		{
3327
			print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td><td colspan="2">' . price($objectsrc->total_localtax1) . "</td></tr>";
3328
		}
3329
3330
		if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) 		// Localtax2
3331
		{
3332
			print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td><td colspan="2">' . price($objectsrc->total_localtax2) . "</td></tr>";
3333
		}
3334
		print '<tr><td>' . $langs->trans('TotalTTC') . '</td><td colspan="2">' . price($objectsrc->total_ttc) . "</td></tr>";
3335
3336
		if (!empty($conf->multicurrency->enabled))
3337
		{
3338
			print '<tr><td>' . $langs->trans('MulticurrencyAmountHT') . '</td><td colspan="2">' . price($objectsrc->multicurrency_total_ht) . '</td></tr>';
3339
			print '<tr><td>' . $langs->trans('MulticurrencyAmountVAT') . '</td><td colspan="2">' . price($objectsrc->multicurrency_total_tva) . "</td></tr>";
3340
			print '<tr><td>' . $langs->trans('MulticurrencyAmountTTC') . '</td><td colspan="2">' . price($objectsrc->multicurrency_total_ttc) . "</td></tr>";
3341
		}
3342
	}
3343
3344
	print "</table>\n";
3345
3346
	dol_fiche_end();
3347
3348
	// Button "Create Draft"
3349
	print '<div class="center">';
3350
	print '<input type="submit" class="button" name="bouton" value="' . $langs->trans('CreateDraft') . '">';
3351
	print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
3352
	print '<input type="button" class="button" value="' . $langs->trans("Cancel") . '" onClick="javascript:history.go(-1)">';
3353
	print '</div>';
3354
3355
	print "</form>\n";
3356
3357
	// Show origin lines
3358
	if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) {
3359
		print '<br>';
3360
3361
		$title = $langs->trans('ProductsAndServices');
3362
		print load_fiche_titre($title);
3363
3364
		print '<table class="noborder" width="100%">';
3365
3366
		$objectsrc->printOriginLinesList();
3367
3368
		print '</table>';
3369
	}
3370
3371
	print '<br>';
3372
}
3373
else if ($id > 0 || ! empty($ref))
3374
{
3375
	/*
3376
	 * Show object in view mode
3377
	 */
3378
3379
	$result = $object->fetch($id, $ref);
3380
	if ($result <= 0) {
3381
		dol_print_error($db, $object->error);
3382
		exit();
3383
	}
3384
3385
	// fetch optionals attributes and labels
3386
	$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
3387
3388
	if ($user->societe_id > 0 && $user->societe_id != $object->socid)
3389
		accessforbidden('', 0);
3390
3391
	$result = $object->fetch_thirdparty();
3392
3393
	$soc = new Societe($db);
3394
	$result=$soc->fetch($object->socid);
3395
	if ($result < 0) dol_print_error($db);
3396
	$selleruserevenustamp = $mysoc->useRevenueStamp();
3397
3398
	$totalpaye = $object->getSommePaiement();
3399
	$totalcreditnotes = $object->getSumCreditNotesUsed();
3400
	$totaldeposits = $object->getSumDepositsUsed();
3401
	// print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits."
3402
	// selleruserrevenuestamp=".$selleruserevenustamp;
3403
3404
	// We can also use bcadd to avoid pb with floating points
3405
	// For example print 239.2 - 229.3 - 9.9; does not return 0.
3406
	// $resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
3407
	// $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
3408
	$resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
3409
3410
	if ($object->paye)
3411
	{
3412
		$resteapayer = 0;
3413
	}
3414
	$resteapayeraffiche = $resteapayer;
3415
3416
	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {	// Never use this
3417
		$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
3418
		$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
3419
	} else {
3420
		$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
3421
		$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
3422
	}
3423
3424
	$absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount);
3425
	$absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote);
3426
	$absolute_discount = price2num($absolute_discount, 'MT');
3427
	$absolute_creditnote = price2num($absolute_creditnote, 'MT');
3428
3429
	$author = new User($db);
3430
	if ($object->user_author) {
3431
		$author->fetch($object->user_author);
3432
	}
3433
3434
	$objectidnext = $object->getIdReplacingInvoice();
3435
3436
	$head = facture_prepare_head($object);
3437
3438
	dol_fiche_head($head, 'compta', $langs->trans('InvoiceCustomer'), -1, 'bill');
3439
3440
	$formconfirm = '';
3441
3442
	// Confirmation de la conversion de l'avoir en reduc
3443
	if ($action == 'converttoreduc') {
3444
		if($object->type == Facture::TYPE_STANDARD) $type_fac = 'ExcessReceived';
3445
		elseif($object->type == Facture::TYPE_CREDIT_NOTE) $type_fac = 'CreditNote';
3446
		elseif($object->type == Facture::TYPE_DEPOSIT) $type_fac = 'Deposit';
3447
		$text = $langs->trans('ConfirmConvertToReduc', strtolower($langs->transnoentities($type_fac)));
3448
		$formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
3449
	}
3450
3451
	// Confirmation to delete invoice
3452
	if ($action == 'delete') {
3453
		$text = $langs->trans('ConfirmDeleteBill', $object->ref);
3454
		$formquestion = array();
3455
3456
		$qualified_for_stock_change = 0;
3457
		if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
3458
			$qualified_for_stock_change = $object->hasProductsOrServices(2);
3459
		} else {
3460
			$qualified_for_stock_change = $object->hasProductsOrServices(1);
3461
		}
3462
3463
		if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change && $object->statut >= 1)
3464
		{
3465
			$langs->load("stocks");
3466
			require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
3467
			$formproduct = new FormProduct($db);
3468
			$label = $object->type == Facture::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockDecrease") : $langs->trans("SelectWarehouseForStockIncrease");
3469
			$forcecombo=0;
3470
			if ($conf->browser->name == 'ie') $forcecombo = 1;	// There is a bug in IE10 that make combo inside popup crazy
3471
			$formquestion = array(
3472
				// 'text' => $langs->trans("ConfirmClone"),
3473
				// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
3474
				// array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
3475
				array('type' => 'other','name' => 'idwarehouse','label' => $label,'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, $langs->trans("NoStockAction"), 0, $forcecombo))
3476
			);
3477
			$formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('DeleteBill'), $text, 'confirm_delete', $formquestion, "yes", 1);
3478
		} else {
3479
			$formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('DeleteBill'), $text, 'confirm_delete', '', 'no', 1);
3480
		}
3481
	}
3482
3483
	// Confirmation to remove invoice from cycle
3484
	if ($action == 'situationout') {
3485
	    $text = $langs->trans('ConfirmRemoveSituationFromCycle', $object->ref);
3486
	    $label = $langs->trans("ConfirmOuting");
3487
	    $formquestion = array();
3488
	    // remove situation from cycle
3489
	    if ($object->statut == Facture::STATUS_VALIDATED
3490
	        && $usercancreate
3491
	        && !$objectidnext
3492
	        && $object->is_last_in_cycle()
3493
	    	&& $usercanunvalidate
3494
	        )
3495
	    {
3496
	        $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $label, $text, 'confirm_situationout', $formquestion, "yes", 1);
3497
		}
3498
	}
3499
3500
	// Confirmation of validation
3501
	if ($action == 'valid')
3502
	{
3503
		// we check object has a draft number
3504
		$objectref = substr($object->ref, 1, 4);
3505
		if ($objectref == 'PROV') {
3506
			$savdate = $object->date;
3507
			if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) {
3508
				$object->date = dol_now();
3509
				$object->date_lim_reglement = $object->calculate_date_lim_reglement();
3510
			}
3511
			$numref = $object->getNextNumRef($soc);
3512
			// $object->date=$savdate;
3513
		} else {
3514
			$numref = $object->ref;
3515
		}
3516
3517
		$text = $langs->trans('ConfirmValidateBill', $numref);
3518
		if (! empty($conf->notification->enabled)) {
3519
			require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
3520
			$notify = new Notify($db);
3521
			$text .= '<br>';
3522
			$text .= $notify->confirmMessage('BILL_VALIDATE', $object->socid, $object);
3523
		}
3524
		$formquestion = array();
3525
3526
		$qualified_for_stock_change = 0;
3527
		if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
3528
			$qualified_for_stock_change = $object->hasProductsOrServices(2);
3529
		} else {
3530
			$qualified_for_stock_change = $object->hasProductsOrServices(1);
3531
		}
3532
3533
		if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change)
3534
		{
3535
			$langs->load("stocks");
3536
			require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
3537
			require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
3538
			$formproduct = new FormProduct($db);
3539
			$warehouse = new Entrepot($db);
3540
			$warehouse_array = $warehouse->list_array();
3541
			if (count($warehouse_array) == 1) {
3542
				$label = $object->type == Facture::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockIncrease", current($warehouse_array)) : $langs->trans("WarehouseForStockDecrease", current($warehouse_array));
3543
				$value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="' . key($warehouse_array) . '">';
3544
			} else {
3545
				$label = $object->type == Facture::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
3546
				$value = $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1);
3547
			}
3548
			$formquestion = array(
3549
								// 'text' => $langs->trans("ConfirmClone"),
3550
								// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' =>
3551
								// 1),
3552
								// array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value'
3553
								// => 1),
3554
								array('type' => 'other','name' => 'idwarehouse','label' => $label,'value' => $value));
3555
		}
3556
		if ($object->type != Facture::TYPE_CREDIT_NOTE && $object->total_ttc < 0) 		// Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on
3557
		{
3558
			$text .= '<br>' . img_warning() . ' ' . $langs->trans("ErrorInvoiceOfThisTypeMustBePositive");
3559
		}
3560
		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, (($object->type != Facture::TYPE_CREDIT_NOTE && $object->total_ttc < 0) ? "no" : "yes"), 2);
3561
	}
3562
3563
	// Confirm back to draft status
3564
	if ($action == 'modif') {
3565
		$text = $langs->trans('ConfirmUnvalidateBill', $object->ref);
3566
		$formquestion = array();
3567
3568
		$qualified_for_stock_change = 0;
3569
		if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
3570
			$qualified_for_stock_change = $object->hasProductsOrServices(2);
3571
		} else {
3572
			$qualified_for_stock_change = $object->hasProductsOrServices(1);
3573
		}
3574
		if ($object->type != Facture::TYPE_DEPOSIT && ! empty($conf->global->STOCK_CALCULATE_ON_BILL) && $qualified_for_stock_change) {
3575
			$langs->load("stocks");
3576
			require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
3577
			require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
3578
			$formproduct = new FormProduct($db);
3579
			$warehouse = new Entrepot($db);
3580
			$warehouse_array = $warehouse->list_array();
3581
			if (count($warehouse_array) == 1) {
3582
				$label = $object->type == Facture::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockDecrease", current($warehouse_array)) : $langs->trans("WarehouseForStockIncrease", current($warehouse_array));
3583
				$value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="' . key($warehouse_array) . '">';
3584
			} else {
3585
				$label = $object->type == Facture::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockDecrease") : $langs->trans("SelectWarehouseForStockIncrease");
3586
				$value = $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1);
3587
			}
3588
			$formquestion = array(
3589
								// 'text' => $langs->trans("ConfirmClone"),
3590
								// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' =>
3591
								// 1),
3592
								// array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value'
3593
								// => 1),
3594
								array('type' => 'other','name' => 'idwarehouse','label' => $label,'value' => $value));
3595
		}
3596
3597
		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('UnvalidateBill'), $text, 'confirm_modif', $formquestion, "yes", 1);
3598
	}
3599
3600
	// Confirmation du classement paye
3601
	if ($action == 'paid' && $resteapayer <= 0) {
3602
		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', "yes", 1);
3603
	}
3604
	if ($action == 'paid' && $resteapayer > 0) {
3605
		// Code
3606
		$i = 0;
3607
		$close [$i]['code'] = 'discount_vat';	// escompte
3608
		$i ++;
3609
		$close [$i]['code'] = 'badcustomer';
3610
		$i ++;
3611
		// Help
3612
		$i = 0;
3613
		$close [$i]['label'] = $langs->trans("HelpEscompte") . '<br><br>' . $langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");
3614
		$i ++;
3615
		$close [$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
3616
		$i ++;
3617
		// Texte
3618
		$i = 0;
3619
		$close [$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscount", $resteapayer, $langs->trans("Currency" . $conf->currency)), $close[$i]['label'], 1);
3620
		$i ++;
3621
		$close [$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency" . $conf->currency)), $close[$i]['label'], 1);
3622
		$i ++;
3623
		// arrayreasons[code]=reason
3624
		foreach ($close as $key => $val) {
3625
			$arrayreasons[$close [$key]['code']] = $close[$key]['reason'];
3626
		}
3627
3628
		// Cree un tableau formulaire
3629
		$formquestion = array('text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"),array('type' => 'radio','name' => 'close_code','label' => $langs->trans("Reason"),'values' => $arrayreasons),array('type' => 'text','name' => 'close_note','label' => $langs->trans("Comment"),'value' => '','morecss' => 'minwidth300'));
3630
		// Paiement incomplet. On demande si motif = escompte ou autre
3631
		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes", 1, 310);
3632
	}
3633
3634
	// Confirmation du classement abandonne
3635
	if ($action == 'canceled') {
3636
		// S'il y a une facture de remplacement pas encore validee (etat brouillon),
3637
		// on ne permet pas de classer abandonner la facture.
3638
		if ($objectidnext) {
3639
			$facturereplacement = new Facture($db);
3640
			$facturereplacement->fetch($objectidnext);
3641
			$statusreplacement = $facturereplacement->statut;
3642
		}
3643
		if ($objectidnext && $statusreplacement == 0) {
3644
			print '<div class="error">' . $langs->trans("ErrorCantCancelIfReplacementInvoiceNotValidated") . '</div>';
3645
		} else {
3646
			// Code
3647
			$close [1] ['code'] = 'badcustomer';
3648
			$close [2] ['code'] = 'abandon';
3649
			// Help
3650
			$close [1] ['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc");
3651
			$close [2] ['label'] = $langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
3652
			// Texte
3653
			$close [1] ['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $object->ref), $close [1] ['label'], 1);
3654
			$close [2] ['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"), $close [2] ['label'], 1);
3655
			// arrayreasons
3656
			$arrayreasons [$close [1] ['code']] = $close [1] ['reason'];
3657
			$arrayreasons [$close [2] ['code']] = $close [2] ['reason'];
3658
3659
			// Cree un tableau formulaire
3660
			$formquestion = array('text' => $langs->trans("ConfirmCancelBillQuestion"),array('type' => 'radio','name' => 'close_code','label' => $langs->trans("Reason"),'values' => $arrayreasons),array('type' => 'text','name' => 'close_note','label' => $langs->trans("Comment"),'value' => '','morecss' => 'minwidth300'));
3661
3662
			$formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('CancelBill'), $langs->trans('ConfirmCancelBill', $object->ref), 'confirm_canceled', $formquestion, "yes", 1, 250);
3663
		}
3664
	}
3665
3666
	if ($action == 'deletepaiement')
3667
	{
3668
		$payment_id = GETPOST('paiement_id');
3669
		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&paiement_id='.$payment_id, $langs->trans('DeletePayment'), $langs->trans('ConfirmDeletePayment'), 'confirm_delete_paiement', '', 'no', 1);
3670
	}
3671
3672
	// Confirmation de la suppression d'une ligne produit
3673
	if ($action == 'ask_deleteline') {
3674
		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
3675
	}
3676
3677
	// Clone confirmation
3678
	if ($action == 'clone')
3679
	{
3680
		// Create an array for form
3681
		$formquestion = array(
3682
							// 'text' => $langs->trans("ConfirmClone"),
3683
							// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1)
3684
							array('type' => 'other','name' => 'socid','label' => $langs->trans("SelectThirdParty"),'value' => $form->select_company($object->socid, 'socid', '(s.client=1 OR s.client=2 OR s.client=3)', 1)));
3685
		// Paiement incomplet. On demande si motif = escompte ou autre
3686
		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('CloneInvoice'), $langs->trans('ConfirmCloneInvoice', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
3687
	}
3688
3689
	// Call Hook formConfirm
3690
	$parameters = array('lineid' => $lineid);
3691
	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3692
	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
3693
	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
3694
3695
	// Print form confirm
3696
	print $formconfirm;
3697
3698
	// Invoice content
3699
3700
	$linkback = '<a href="' . DOL_URL_ROOT . '/compta/facture/list.php?restore_lastsearch_values=1' . (! empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
3701
3702
	$morehtmlref='<div class="refidno">';
3703
	// Ref customer
3704
	$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', 0, 1);
3705
	$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', null, null, '', 1);
3706
	// Thirdparty
3707
	$morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1,'customer');
3708
	if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) $morehtmlref.=' (<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)';
3709
	// Project
3710
	if (! empty($conf->projet->enabled))
3711
	{
3712
		$langs->load("projects");
3713
		$morehtmlref.='<br>'.$langs->trans('Project') . ' ';
3714
		if ($usercancreate)
3715
		{
3716
			if ($action != 'classify')
3717
				$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
3718
				if ($action == 'classify') {
3719
					//$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
3720
					$morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
3721
					$morehtmlref.='<input type="hidden" name="action" value="classin">';
3722
					$morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
3723
					$morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
3724
					$morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
3725
					$morehtmlref.='</form>';
3726
				} else {
3727
					$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
3728
				}
3729
		} else {
3730
			if (! empty($object->fk_project)) {
3731
				$proj = new Project($db);
3732
				$proj->fetch($object->fk_project);
3733
				$morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
3734
				$morehtmlref.=$proj->ref;
3735
				$morehtmlref.='</a>';
3736
			} else {
3737
				$morehtmlref.='';
3738
			}
3739
		}
3740
	}
3741
	$morehtmlref.='</div>';
3742
3743
	$object->totalpaye = $totalpaye;   // To give a chance to dol_banner_tab to use already paid amount to show correct status
3744
3745
	dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '');
3746
3747
	print '<div class="fichecenter">';
3748
	print '<div class="fichehalfleft">';
3749
	print '<div class="underbanner clearboth"></div>';
3750
3751
	print '<table class="border" width="100%">';
3752
3753
	// Type
3754
	print '<tr><td class="titlefield">' . $langs->trans('Type') . '</td><td>';
3755
	print $object->getLibType();
3756
	if ($object->type == Facture::TYPE_REPLACEMENT) {
3757
		$facreplaced = new Facture($db);
3758
		$facreplaced->fetch($object->fk_facture_source);
3759
		print ' (' . $langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)) . ')';
3760
	}
3761
	if ($object->type == Facture::TYPE_CREDIT_NOTE && !empty($object->fk_facture_source)) {
3762
		$facusing = new Facture($db);
3763
		$facusing->fetch($object->fk_facture_source);
3764
		print ' (' . $langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)) . ')';
3765
	}
3766
3767
	$facidavoir = $object->getListIdAvoirFromInvoice();
3768
	if (count($facidavoir) > 0) {
3769
		print ' (' . $langs->transnoentities("InvoiceHasAvoir");
3770
		$i = 0;
3771
		foreach ($facidavoir as $id) {
3772
			if ($i == 0)
3773
				print ' ';
3774
			else
3775
				print ',';
3776
			$facavoir = new Facture($db);
3777
			$facavoir->fetch($id);
3778
			print $facavoir->getNomUrl(1);
3779
		}
3780
		print ')';
3781
	}
3782
	if ($objectidnext > 0) {
3783
		$facthatreplace = new Facture($db);
3784
		$facthatreplace->fetch($objectidnext);
3785
		print ' (' . $langs->transnoentities("ReplacedByInvoice", $facthatreplace->getNomUrl(1)) . ')';
3786
	}
3787
3788
	if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) {
3789
		$discount = new DiscountAbsolute($db);
3790
		$result = $discount->fetch(0, $object->id);
3791
		if ($result > 0){
3792
			print '. '.$langs->trans("CreditNoteConvertedIntoDiscount", $object->getLibType(1), $discount->getNomUrl(1, 'discount')).'<br>';
3793
		}
3794
	}
3795
	print '</td></tr>';
3796
3797
	// Relative and absolute discounts
3798
	print '<!-- Discounts --><tr><td>' . $langs->trans('Discounts');
3799
3800
	print '</td><td>';
3801
	$thirdparty = $soc;
3802
	$discount_type = 0;
3803
	$backtopage = urlencode($_SERVER["PHP_SELF"] . '?facid=' . $object->id);
3804
	include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
3805
3806
	print '</td></tr>';
3807
3808
	// Date invoice
3809
	print '<tr><td>';
3810
	print '<table class="nobordernopadding" width="100%"><tr><td>';
3811
	print $langs->trans('DateInvoice');
3812
	print '</td>';
3813
	if ($object->type != Facture::TYPE_CREDIT_NOTE && $action != 'editinvoicedate' && ! empty($object->brouillon) && $usercancreate && empty($conf->global->FAC_FORCE_DATE_VALIDATION))
3814
		print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editinvoicedate&amp;facid=' . $object->id . '">' . img_edit($langs->trans('SetDate'), 1) . '</a></td>';
3815
	print '</tr></table>';
3816
	print '</td><td>';
3817
3818
	if ($object->type != Facture::TYPE_CREDIT_NOTE) {
3819
		if ($action == 'editinvoicedate') {
3820
			$form->form_date($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->date, 'invoicedate');
3821
		} else {
3822
			print dol_print_date($object->date, 'day');
3823
		}
3824
	} else {
3825
		print dol_print_date($object->date, 'day');
3826
	}
3827
	print '</td>';
3828
3829
	print '</tr>';
3830
3831
	if (! empty($conf->global->INVOICE_POINTOFTAX_DATE))
3832
	{
3833
		// Date invoice
3834
		print '<tr><td>';
3835
		print '<table class="nobordernopadding" width="100%"><tr><td>';
3836
		print $langs->trans('DatePointOfTax');
3837
		print '</td>';
3838
		print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editdate_pointoftax&amp;facid=' . $object->id . '">' . img_edit($langs->trans('SetDate'), 1) . '</a></td>';
3839
		print '</tr></table>';
3840
		print '</td><td>';
3841
		if ($action == 'editdate_pointoftax') {
3842
			$form->form_date($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->date_pointoftax, 'date_pointoftax');
3843
		} else {
3844
			print dol_print_date($object->date_pointoftax, 'day');
3845
		}
3846
		print '</td></tr>';
3847
	}
3848
3849
	// Payment term
3850
	print '<tr><td>';
3851
	print '<table class="nobordernopadding" width="100%"><tr><td>';
3852
	print $langs->trans('PaymentConditionsShort');
3853
	print '</td>';
3854
	if ($object->type != Facture::TYPE_CREDIT_NOTE && $action != 'editconditions' && $usercancreate)
3855
		print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editconditions&amp;facid=' . $object->id . '">' . img_edit($langs->trans('SetConditions'), 1) . '</a></td>';
3856
	print '</tr></table>';
3857
	print '</td><td>';
3858
	if ($object->type != Facture::TYPE_CREDIT_NOTE)
3859
	{
3860
		if ($action == 'editconditions') {
3861
			$form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->cond_reglement_id, 'cond_reglement_id');
3862
		} else {
3863
			$form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->cond_reglement_id, 'none');
3864
		}
3865
	} else {
3866
		print '&nbsp;';
3867
	}
3868
	print '</td></tr>';
3869
3870
	// Date payment term
3871
	print '<tr><td>';
3872
	print '<table class="nobordernopadding" width="100%"><tr><td>';
3873
	print $langs->trans('DateMaxPayment');
3874
	print '</td>';
3875
	if ($object->type != Facture::TYPE_CREDIT_NOTE && $action != 'editpaymentterm' && $usercancreate)
3876
		print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editpaymentterm&amp;facid=' . $object->id . '">' . img_edit($langs->trans('SetDate'), 1) . '</a></td>';
3877
	print '</tr></table>';
3878
	print '</td><td>';
3879
	if ($object->type != Facture::TYPE_CREDIT_NOTE)
3880
	{
3881
		if ($action == 'editpaymentterm') {
3882
			$form->form_date($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $object->date_lim_reglement, 'paymentterm');
3883
		} else {
3884
			print dol_print_date($object->date_lim_reglement, 'day');
3885
			if ($object->hasDelay()) {
3886
				print img_warning($langs->trans('Late'));
3887
			}
3888
		}
3889
	} else {
3890
		print '&nbsp;';
3891
	}
3892
	print '</td></tr>';
3893
3894
	// Payment mode
3895
	print '<tr><td>';
3896
	print '<table class="nobordernopadding" width="100%"><tr><td>';
3897
	print $langs->trans('PaymentMode');
3898
	print '</td>';
3899
	if ($action != 'editmode' && $usercancreate)
3900
		print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmode&amp;facid=' . $object->id . '">' . img_edit($langs->trans('SetMode'), 1) . '</a></td>';
3901
	print '</tr></table>';
3902
	print '</td><td>';
3903
	if ($action == 'editmode')
3904
	{
3905
		$form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT');
3906
	}
3907
	else
3908
	{
3909
		$form->form_modes_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->mode_reglement_id, 'none', 'CRDT');
3910
	}
3911
	print '</td></tr>';
3912
3913
	// Multicurrency
3914
	if (! empty($conf->multicurrency->enabled))
3915
	{
3916
		// Multicurrency code
3917
		print '<tr>';
3918
		print '<td>';
3919
		print '<table class="nobordernopadding" width="100%"><tr><td>';
3920
		print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0);
3921
		print '</td>';
3922
		if ($usercancreate && $action != 'editmulticurrencycode' && ! empty($object->brouillon))
3923
			print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmulticurrencycode&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '</a></td>';
3924
		print '</tr></table>';
3925
		print '</td><td>';
3926
		$htmlname = (($usercancreate && $action == 'editmulticurrencycode')?'multicurrency_code':'none');
3927
		$form->form_multicurrency_code($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_code, $htmlname);
3928
		print '</td></tr>';
3929
3930
		print '<tr>';
3931
		print '<td>';
3932
		print '<table class="nobordernopadding" width="100%"><tr><td>';
3933
		print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0);
3934
		print '</td>';
3935
		if ($usercancreate && $action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency)
3936
			print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmulticurrencyrate&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '</a></td>';
3937
		print '</tr></table>';
3938
		print '</td><td>';
3939
		if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
3940
			if($action == 'actualizemulticurrencyrate') {
3941
				list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
3942
			}
3943
			$form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, ($usercancreate?'multicurrency_tx':'none'), $object->multicurrency_code);
3944
		} else {
3945
			$form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
3946
			if($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
3947
				print '<div class="inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; ';
3948
				print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=actualizemulticurrencyrate">'.$langs->trans("ActualizeCurrency").'</a>';
3949
				print '</div>';
3950
			}
3951
		}
3952
		print '</td></tr>';
3953
	}
3954
3955
	// Bank Account
3956
	print '<tr><td class="nowrap">';
3957
	print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
3958
	print $langs->trans('BankAccount');
3959
	print '<td>';
3960
	if (($action != 'editbankaccount') && $usercancreate)
3961
		print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&amp;id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'),1).'</a></td>';
3962
	print '</tr></table>';
3963
	print '</td><td>';
3964
	if ($action == 'editbankaccount')
3965
	{
3966
		$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
3967
	}
3968
	else
3969
	{
3970
		$form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
3971
	}
3972
	print "</td>";
3973
	print '</tr>';
3974
3975
3976
3977
3978
3979
3980
	// Incoterms
3981
	if (!empty($conf->incoterm->enabled))
3982
	{
3983
		print '<tr><td>';
3984
		print '<table width="100%" class="nobordernopadding"><tr><td>';
3985
		print $langs->trans('IncotermLabel');
3986
		print '<td><td align="right">';
3987
		if ($usercancreate) print '<a href="'.DOL_URL_ROOT.'/compta/facture/card.php?facid='.$object->id.'&action=editincoterm">'.img_edit().'</a>';
3988
		else print '&nbsp;';
3989
		print '</td></tr></table>';
3990
		print '</td>';
3991
		print '<td>';
3992
		if ($action != 'editincoterm')
3993
		{
3994
			print $form->textwithpicto($object->display_incoterms(), $object->libelle_incoterms, 1);
3995
		}
3996
		else
3997
		{
3998
			print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:''), $_SERVER['PHP_SELF'].'?id='.$object->id);
3999
		}
4000
		print '</td></tr>';
4001
	}
4002
4003
	// Other attributes
4004
	$cols = 2;
4005
	include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
4006
4007
	print '</table>';
4008
4009
	print '</div>';
4010
	print '<div class="fichehalfright">';
4011
	print '<div class="ficheaddleft">';
4012
	print '<div class="underbanner clearboth"></div>';
4013
4014
	print '<table class="border centpercent">';
4015
4016
	if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency))
4017
	{
4018
		// Multicurrency Amount HT
4019
		print '<tr><td class="titlefieldmiddle">' . $form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0) . '</td>';
4020
		print '<td class="nowrap amountcard">' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
4021
		print '</tr>';
4022
4023
		// Multicurrency Amount VAT
4024
		print '<tr><td>' . $form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0) . '</td>';
4025
		print '<td class="nowrap amountcard">' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
4026
		print '</tr>';
4027
4028
		// Multicurrency Amount TTC
4029
		print '<tr><td>' . $form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0) . '</td>';
4030
		print '<td class="nowrap amountcard">' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
4031
		print '</tr>';
4032
	}
4033
4034
	// Amount
4035
	print '<tr><td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
4036
	print '<td class="nowrap amountcard">' . price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency) . '</td></tr>';
4037
4038
	// Vat
4039
	print '<tr><td>' . $langs->trans('AmountVAT') . '</td><td colspan="3" class="nowrap amountcard">' . price($object->total_tva, 1, '', 1, - 1, - 1, $conf->currency) . '</td></tr>';
4040
	print '</tr>';
4041
4042
	// Amount Local Taxes
4043
	if (($mysoc->localtax1_assuj == "1" && $mysoc->useLocalTax(1)) || $object->total_localtax1 != 0) 	// Localtax1
4044
	{
4045
		print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
4046
		print '<td class="nowrap amountcard">' . price($object->total_localtax1, 1, '', 1, - 1, - 1, $conf->currency) . '</td></tr>';
4047
	}
4048
	if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) 	// Localtax2
4049
	{
4050
		print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
4051
		print '<td class=nowrap amountcard">' . price($object->total_localtax2, 1, '', 1, - 1, - 1, $conf->currency) . '</td></tr>';
4052
	}
4053
4054
	// Revenue stamp
4055
	if ($selleruserevenustamp) 	// Test company use revenue stamp
4056
	{
4057
		print '<tr><td>';
4058
		print '<table class="nobordernopadding" width="100%"><tr><td>';
4059
		print $langs->trans('RevenueStamp');
4060
		print '</td>';
4061
		if ($action != 'editrevenuestamp' && ! empty($object->brouillon) && $usercancreate)
4062
		{
4063
			print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editrevenuestamp&amp;facid=' . $object->id . '">' . img_edit($langs->trans('SetRevenuStamp'), 1) . '</a></td>';
4064
		}
4065
		print '</tr></table>';
4066
		print '</td><td>';
4067
		if ($action == 'editrevenuestamp') {
4068
			print '<form action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
4069
			print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
4070
			print '<input type="hidden" name="action" value="setrevenuestamp">';
4071
			print '<input type="hidden" name="revenuestamp" id="revenuestamp_val" value="'.price2num($object->revenuestamp).'">';
4072
			print $formother->select_revenue_stamp('', 'revenuestamp_type', $mysoc->country_code);
4073
			print ' &rarr; <span id="revenuestamp_span"></span>';
4074
			print ' <input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
4075
			print '</form>';
4076
			print " <script>
4077
                $(document).ready(function(){
4078
                    js_recalculate_revenuestamp();
4079
                    $('select[name=revenuestamp_type]').on('change',function(){
4080
                        js_recalculate_revenuestamp();
4081
                    });
4082
                });
4083
                function js_recalculate_revenuestamp(){
4084
					var valselected = $('select[name=revenuestamp_type]').val();
4085
					console.log('Calculate revenue stamp from '+valselected);
4086
					var revenue = 0;
4087
					if (valselected.indexOf('%') == -1)
4088
					{
4089
						revenue = valselected;
4090
					}
4091
					else
4092
					{
4093
	                    var revenue_type = parseFloat(valselected);
4094
	                    var amount_net = ".round($object->total_ht, 2).";
4095
	                    revenue = revenue_type * amount_net / 100;
4096
	                    revenue = revenue.toFixed(2);
4097
					}
4098
                    $('#revenuestamp_val').val(revenue);
4099
                    $('#revenuestamp_span').html(revenue);
4100
                }
4101
            </script>";
4102
		} else {
4103
			print price($object->revenuestamp, 1, '', 1, - 1, - 1, $conf->currency);
4104
		}
4105
		print '</td></tr>';
4106
	}
4107
4108
	// Total with tax
4109
	print '<tr><td>' . $langs->trans('AmountTTC') . '</td><td class="nowrap amountcard">' . price($object->total_ttc, 1, '', 1, - 1, - 1, $conf->currency) . '</td></tr>';
4110
4111
	print '</table>';
4112
4113
4114
	$sign = 1;
4115
	if ($object->type == Facture::TYPE_CREDIT_NOTE) $sign = - 1;
4116
	$nbrows = 8;
4117
	$nbcols = 3;
4118
	if (! empty($conf->projet->enabled))
4119
		$nbrows ++;
4120
	if (! empty($conf->banque->enabled)) {
4121
		$nbrows ++;
4122
		$nbcols ++;
4123
	}
4124
	if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0)
4125
		$nbrows ++;
4126
	if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0)
4127
		$nbrows ++;
4128
	if ($selleruserevenustamp)
4129
		$nbrows ++;
4130
	if (! empty($conf->multicurrency->enabled))
4131
		$nbrows += 5;
4132
	if (! empty($conf->incoterm->enabled))
4133
		$nbrows += 1;
4134
4135
	// List of previous situation invoices
4136
	if (($object->situation_cycle_ref > 0) && ! empty($conf->global->INVOICE_USE_SITUATION))
4137
	{
4138
4139
	    print '<table class="noborder situationstable" width="100%">';
4140
4141
4142
	    print '<tr class="liste_titre">';
4143
	    print '<td>' . $langs->trans('ListOfSituationInvoices') . '</td>';
4144
	    print '<td></td>';
4145
	    print '<td align="center">' . $langs->trans('Situation') . '</td>';
4146
	    if (! empty($conf->banque->enabled)) print '<td align="right"></td>';
4147
	    print '<td align="right">' . $langs->trans('AmountHT') . '</td>';
4148
	    print '<td align="right">' . $langs->trans('AmountTTC') . '</td>';
4149
	    print '<td width="18">&nbsp;</td>';
4150
	    print '</tr>';
4151
4152
4153
	    $total_prev_ht = $total_prev_ttc = 0;
4154
	    $total_global_ht = $total_global_ttc = 0;
4155
4156
	    if (count($object->tab_previous_situation_invoice) > 0) {
4157
	        // List of previous invoices
4158
4159
	        $current_situation_counter = array();
4160
	        foreach ($object->tab_previous_situation_invoice as $prev_invoice) {
4161
	            $totalpaye = $prev_invoice->getSommePaiement();
4162
	            $total_prev_ht += $prev_invoice->total_ht;
4163
	            $total_prev_ttc += $prev_invoice->total_ttc;
4164
	            $current_situation_counter[] = (($prev_invoice->type == Facture::TYPE_CREDIT_NOTE)?-1:1) * $prev_invoice->situation_counter;
4165
	            print '<tr class="oddeven">';
4166
	            print '<td>' . $prev_invoice->getNomUrl(1) . '</td>';
4167
	            print '<td></td>';
4168
	            print '<td align="center" >'.(($prev_invoice->type == Facture::TYPE_CREDIT_NOTE)?$langs->trans('situationInvoiceShortcode_AS'):$langs->trans('situationInvoiceShortcode_S')) . $prev_invoice->situation_counter.'</td>';
4169
	            if (! empty($conf->banque->enabled)) print '<td align="right"></td>';
4170
	            print '<td align="right">' . price($prev_invoice->total_ht) . '</td>';
4171
	            print '<td align="right">' . price($prev_invoice->total_ttc) . '</td>';
4172
	            print '<td align="right">' . $prev_invoice->getLibStatut(3, $totalpaye) . '</td>';
4173
	            print '</tr>';
4174
	        }
4175
	    }
4176
4177
4178
	    $total_global_ht += $total_prev_ht ;
4179
	    $total_global_ttc += $total_prev_ttc ;
4180
	    $total_global_ht += $object->total_ht;
4181
	    $total_global_ttc += $object->total_ttc;
4182
	    $current_situation_counter[] = (($object->type == Facture::TYPE_CREDIT_NOTE)?-1:1) * $object->situation_counter;
4183
	    print '<tr class="oddeven">';
4184
	    print '<td>' . $object->getNomUrl(1) . '</td>';
4185
	    print '<td></td>';
4186
	    print '<td align="center">'.(($object->type == Facture::TYPE_CREDIT_NOTE)?$langs->trans('situationInvoiceShortcode_AS'):$langs->trans('situationInvoiceShortcode_S')) . $object->situation_counter.'</td>';
4187
	    if (! empty($conf->banque->enabled)) print '<td align="right"></td>';
4188
	    print '<td align="right">' . price($object->total_ht) . '</td>';
4189
	    print '<td align="right">' . price($object->total_ttc) . '</td>';
4190
	    print '<td align="right">' . $object->getLibStatut(3, $object->getSommePaiement()) . '</td>';
4191
	    print '</tr>';
4192
4193
4194
	    print '<tr class="oddeven">';
4195
	    print '<td colspan="2" align="left"><b>' . $langs->trans('CurrentSituationTotal') . '</b></td>';
4196
	    print '<td>';
4197
	    $i =0;
4198
	    foreach ($current_situation_counter as $sit)
4199
	    {
4200
	        $curSign = $sit>0?'+':'-';
4201
	        $curType = $sit>0?$langs->trans('situationInvoiceShortcode_S'):$langs->trans('situationInvoiceShortcode_AS');
4202
	        if($i>0) print ' '.$curSign.' ';
4203
	        print $curType . abs($sit);
4204
	        $i++;
4205
	    }
4206
	    print '</td>';
4207
	    if (! empty($conf->banque->enabled)) print '<td></td>';
4208
	    print '<td align="right"><b>' . price($total_global_ht) . '</b></td>';
4209
	    print '<td align="right"><b>' . price($total_global_ttc) . '</b></td>';
4210
	    print '<td width="18">&nbsp;</td>';
4211
	    print '</tr>';
4212
4213
4214
	    if (count($object->tab_next_situation_invoice) > 0) {
4215
	        // List of next invoices
4216
	        /*print '<tr class="liste_titre">';
4217
	         print '<td>' . $langs->trans('ListOfNextSituationInvoices') . '</td>';
4218
	         print '<td></td>';
4219
	         print '<td></td>';
4220
	         if (! empty($conf->banque->enabled)) print '<td align="right"></td>';
4221
	         print '<td align="right">' . $langs->trans('AmountHT') . '</td>';
4222
	         print '<td align="right">' . $langs->trans('AmountTTC') . '</td>';
4223
	         print '<td width="18">&nbsp;</td>';
4224
	         print '</tr>';*/
4225
4226
	        $total_next_ht = $total_next_ttc = 0;
4227
4228
	        foreach ($object->tab_next_situation_invoice as $next_invoice) {
4229
	            $totalpaye = $next_invoice->getSommePaiement();
4230
	            $total_next_ht += $next_invoice->total_ht;
4231
	            $total_next_ttc += $next_invoice->total_ttc;
4232
4233
	            print '<tr class="oddeven">';
4234
	            print '<td>' . $next_invoice->getNomUrl(1) . '</td>';
4235
	            print '<td></td>';
4236
	            print '<td align="center">'.(($next_invoice->type == Facture::TYPE_CREDIT_NOTE)?$langs->trans('situationInvoiceShortcode_AS'):$langs->trans('situationInvoiceShortcode_S')) . $next_invoice->situation_counter.'</td>';
4237
	            if (! empty($conf->banque->enabled)) print '<td align="right"></td>';
4238
	            print '<td align="right">' . price($next_invoice->total_ht) . '</td>';
4239
	            print '<td align="right">' . price($next_invoice->total_ttc) . '</td>';
4240
	            print '<td align="right">' . $next_invoice->getLibStatut(3, $totalpaye) . '</td>';
4241
	            print '</tr>';
4242
	        }
4243
4244
	        $total_global_ht += $total_next_ht;
4245
	        $total_global_ttc += $total_next_ttc;
4246
4247
	        print '<tr class="oddeven">';
4248
	        print '<td colspan="3" align="right"></td>';
4249
	        if (! empty($conf->banque->enabled)) print '<td align="right"></td>';
4250
	        print '<td align="right"><b>' . price($total_global_ht) . '</b></td>';
4251
	        print '<td align="right"><b>' . price($total_global_ttc) . '</b></td>';
4252
	        print '<td width="18">&nbsp;</td>';
4253
	        print '</tr>';
4254
	    }
4255
4256
	    print '</table>';
4257
	}
4258
4259
4260
	// List of payments already done
4261
4262
	print '<div class="div-table-responsive-no-min">';
4263
	print '<table class="noborder paymenttable" width="100%">';
4264
4265
	print '<tr class="liste_titre">';
4266
	print '<td class="liste_titre">' . ($object->type == Facture::TYPE_CREDIT_NOTE ? $langs->trans("PaymentsBack") : $langs->trans('Payments')) . '</td>';
4267
	print '<td class="liste_titre">' . $langs->trans('Date') . '</td>';
4268
	print '<td class="liste_titre">' . $langs->trans('Type') . '</td>';
4269
	if (! empty($conf->banque->enabled)) {
4270
		print '<td class="liste_titre" align="right">' . $langs->trans('BankAccount') . '</td>';
4271
	}
4272
	print '<td class="liste_titre" align="right">' . $langs->trans('Amount') . '</td>';
4273
	print '<td class="liste_titre" width="18">&nbsp;</td>';
4274
	print '</tr>';
4275
4276
	// Payments already done (from payment on this invoice)
4277
	$sql = 'SELECT p.datep as dp, p.ref, p.num_paiement, p.rowid, p.fk_bank,';
4278
	$sql .= ' c.code as payment_code, c.libelle as payment_label,';
4279
	$sql .= ' pf.amount,';
4280
	$sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal';
4281
	$sql .= ' FROM ' . MAIN_DB_PREFIX . 'paiement_facture as pf, ' . MAIN_DB_PREFIX . 'paiement as p';
4282
	$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_paiement as c ON p.fk_paiement = c.id' ;
4283
	$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank as b ON p.fk_bank = b.rowid';
4284
	$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank_account as ba ON b.fk_account = ba.rowid';
4285
	$sql .= ' WHERE pf.fk_facture = ' . $object->id . ' AND pf.fk_paiement = p.rowid';
4286
	$sql .= ' AND p.entity IN (' . getEntity('invoice').')';
4287
	$sql .= ' ORDER BY p.datep, p.tms';
4288
4289
	$result = $db->query($sql);
4290
	if ($result) {
4291
		$num = $db->num_rows($result);
4292
		$i = 0;
4293
4294
		// if ($object->type != 2)
4295
		// {
4296
		if ($num > 0) {
4297
			while ($i < $num) {
4298
				$objp = $db->fetch_object($result);
4299
4300
				$paymentstatic->id = $objp->rowid;
4301
				$paymentstatic->datepaye = $db->jdate($objp->dp);
4302
				$paymentstatic->ref = $objp->ref;
4303
				$paymentstatic->num_paiement = $objp->num_paiement;
4304
				$paymentstatic->payment_code = $objp->payment_code;
4305
4306
				print '<tr class="oddeven"><td>';
4307
				print $paymentstatic->getNomUrl(1);
4308
				print '</td>';
4309
				print '<td>' . dol_print_date($db->jdate($objp->dp), 'day') . '</td>';
4310
				$label = ($langs->trans("PaymentType" . $objp->payment_code) != ("PaymentType" . $objp->payment_code)) ? $langs->trans("PaymentType" . $objp->payment_code) : $objp->payment_label;
4311
				print '<td>' . $label . ' ' . $objp->num_paiement . '</td>';
4312
				if (! empty($conf->banque->enabled))
4313
				{
4314
					$bankaccountstatic->id = $objp->baid;
4315
					$bankaccountstatic->ref = $objp->baref;
4316
					$bankaccountstatic->label = $objp->baref;
4317
					$bankaccountstatic->number = $objp->banumber;
4318
4319
					if (! empty($conf->accounting->enabled)) {
4320
						$bankaccountstatic->account_number = $objp->account_number;
4321
4322
						$accountingjournal = new AccountingJournal($db);
4323
						$accountingjournal->fetch($objp->fk_accountancy_journal);
4324
						$bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0,1,1,'',1);
4325
					}
4326
4327
					print '<td align="right">';
4328
					if ($bankaccountstatic->id)
4329
						print $bankaccountstatic->getNomUrl(1, 'transactions');
4330
					print '</td>';
4331
				}
4332
				print '<td align="right">' . price($sign * $objp->amount) . '</td>';
4333
				print '<td align="center">';
4334
				if ($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $user->societe_id == 0)
4335
				{
4336
					print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deletepaiement&paiement_id='.$objp->rowid.'">';
4337
					print img_delete();
4338
					print '</a>';
4339
				}
4340
				print '</td>';
4341
				print '</tr>';
4342
				$i ++;
4343
			}
4344
		}
4345
		/*else {
4346
            print '<tr class="oddeven"><td colspan="' . $nbcols . '" class="opacitymedium">' . $langs->trans("None") . '</td><td></td><td></td></tr>';
4347
        }*/
4348
		// }
4349
		$db->free($result);
4350
	} else {
4351
		dol_print_error($db);
4352
	}
4353
4354
	if ($object->type != Facture::TYPE_CREDIT_NOTE) {
4355
		// Total already paid
4356
		print '<tr><td colspan="' . $nbcols . '" align="right">';
4357
		if ($object->type != Facture::TYPE_DEPOSIT)
4358
			print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
4359
		else
4360
			print $langs->trans('AlreadyPaid');
4361
		print ' :</td><td align="right"'.(($totalpaye > 0)?' class="amountalreadypaid"':'').'>' . price($totalpaye) . '</td><td>&nbsp;</td></tr>';
4362
4363
		$resteapayeraffiche = $resteapayer;
4364
		$cssforamountpaymentcomplete = 'amountpaymentcomplete';
4365
4366
		// Loop on each credit note or deposit amount applied
4367
		$creditnoteamount = 0;
4368
		$depositamount = 0;
4369
		$sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
4370
		$sql .= " re.description, re.fk_facture_source";
4371
		$sql .= " FROM " . MAIN_DB_PREFIX . "societe_remise_except as re";
4372
		$sql .= " WHERE fk_facture = " . $object->id;
4373
		$resql = $db->query($sql);
4374
		if ($resql) {
4375
			$num = $db->num_rows($resql);
4376
			$i = 0;
4377
			$invoice = new Facture($db);
4378
			while ($i < $num) {
4379
				$obj = $db->fetch_object($resql);
4380
				$invoice->fetch($obj->fk_facture_source);
4381
				print '<tr><td colspan="' . $nbcols . '" align="right">';
4382
				if ($invoice->type == Facture::TYPE_CREDIT_NOTE)
4383
					print $langs->trans("CreditNote") . ' ';
4384
				if ($invoice->type == Facture::TYPE_DEPOSIT)
4385
					print $langs->trans("Deposit") . ' ';
4386
				print $invoice->getNomUrl(0);
4387
				print ' :</td>';
4388
				print '<td align="right">' . price($obj->amount_ttc) . '</td>';
4389
				print '<td align="right">';
4390
				print '<a href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&action=unlinkdiscount&discountid=' . $obj->rowid . '">' . img_delete() . '</a>';
4391
				print '</td></tr>';
4392
				$i ++;
4393
				if ($invoice->type == Facture::TYPE_CREDIT_NOTE)
4394
					$creditnoteamount += $obj->amount_ttc;
4395
				if ($invoice->type == Facture::TYPE_DEPOSIT)
4396
					$depositamount += $obj->amount_ttc;
4397
			}
4398
		} else {
4399
			dol_print_error($db);
4400
		}
4401
4402
		// Paye partiellement 'escompte'
4403
		if (($object->statut == Facture::STATUS_CLOSED || $object->statut == Facture::STATUS_ABANDONED) && $object->close_code == 'discount_vat') {
4404
			print '<tr><td colspan="' . $nbcols . '" align="right" class="nowrap">';
4405
			print $form->textwithpicto($langs->trans("Discount") . ':', $langs->trans("HelpEscompte"), - 1);
4406
			print '</td><td align="right">' . price(price2num($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye, 'MT')) . '</td><td>&nbsp;</td></tr>';
4407
			$resteapayeraffiche = 0;
4408
			$cssforamountpaymentcomplete = 'amountpaymentneutral';
4409
		}
4410
		// Paye partiellement ou Abandon 'badcustomer'
4411
		if (($object->statut == Facture::STATUS_CLOSED || $object->statut == Facture::STATUS_ABANDONED) && $object->close_code == 'badcustomer') {
4412
			print '<tr><td colspan="' . $nbcols . '" align="right" class="nowrap">';
4413
			print $form->textwithpicto($langs->trans("Abandoned") . ':', $langs->trans("HelpAbandonBadCustomer"), - 1);
4414
			print '</td><td align="right">' . price(price2num($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye, 'MT')) . '</td><td>&nbsp;</td></tr>';
4415
			// $resteapayeraffiche=0;
4416
			$cssforamountpaymentcomplete = 'amountpaymentneutral';
4417
		}
4418
		// Paye partiellement ou Abandon 'product_returned'
4419
		if (($object->statut == Facture::STATUS_CLOSED || $object->statut == Facture::STATUS_ABANDONED) && $object->close_code == 'product_returned') {
4420
			print '<tr><td colspan="' . $nbcols . '" align="right" class="nowrap">';
4421
			print $form->textwithpicto($langs->trans("ProductReturned") . ':', $langs->trans("HelpAbandonProductReturned"), - 1);
4422
			print '</td><td align="right">' . price(price2num($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye, 'MT')) . '</td><td>&nbsp;</td></tr>';
4423
			$resteapayeraffiche = 0;
4424
			$cssforamountpaymentcomplete = 'amountpaymentneutral';
4425
		}
4426
		// Paye partiellement ou Abandon 'abandon'
4427
		if (($object->statut == Facture::STATUS_CLOSED || $object->statut == Facture::STATUS_ABANDONED) && $object->close_code == 'abandon') {
4428
			print '<tr><td colspan="' . $nbcols . '" align="right" class="nowrap">';
4429
			$text = $langs->trans("HelpAbandonOther");
4430
			if ($object->close_note)
4431
				$text .= '<br><br><b>' . $langs->trans("Reason") . '</b>:' . $object->close_note;
4432
			print $form->textwithpicto($langs->trans("Abandoned") . ':', $text, - 1);
4433
			print '</td><td align="right">' . price(price2num($object->total_ttc - $creditnoteamount - $depositamount - $totalpaye, 'MT')) . '</td><td>&nbsp;</td></tr>';
4434
			$resteapayeraffiche = 0;
4435
			$cssforamountpaymentcomplete = 'amountpaymentneutral';
4436
		}
4437
4438
		// Billed
4439
		print '<tr><td colspan="' . $nbcols . '" align="right">' . $langs->trans("Billed") . ' :</td><td align="right">' . price($object->total_ttc) . '</td><td>&nbsp;</td></tr>';
4440
4441
		// Remainder to pay
4442
		print '<tr><td colspan="' . $nbcols . '" align="right">';
4443
		if ($resteapayeraffiche >= 0)
4444
			print $langs->trans('RemainderToPay');
4445
		else
4446
			print $langs->trans('ExcessReceived');
4447
		print ' :</td>';
4448
		print '<td align="right"'.($resteapayeraffiche?' class="amountremaintopay"':(' class="'.$cssforamountpaymentcomplete.'"')).'>' . price($resteapayeraffiche) . '</td>';
4449
		print '<td class="nowrap">&nbsp;</td></tr>';
4450
	}
4451
	else // Credit note
4452
	{
4453
		$cssforamountpaymentcomplete='amountpaymentneutral';
4454
4455
		// Total already paid back
4456
		print '<tr><td colspan="' . $nbcols . '" align="right">';
4457
		print $langs->trans('AlreadyPaidBack');
4458
		print ' :</td><td align="right">' . price($sign * $totalpaye) . '</td><td>&nbsp;</td></tr>';
4459
4460
		// Billed
4461
		print '<tr><td colspan="' . $nbcols . '" align="right">' . $langs->trans("Billed") . ' :</td><td align="right">' . price($sign * $object->total_ttc) . '</td><td>&nbsp;</td></tr>';
4462
4463
		// Remainder to pay back
4464
		print '<tr><td colspan="' . $nbcols . '" align="right">';
4465
		if ($resteapayeraffiche <= 0)
4466
			print $langs->trans('RemainderToPayBack');
4467
		else
4468
			print $langs->trans('ExcessPaid');
4469
		print ' :</td>';
4470
		print '<td align="right"'.($resteapayeraffiche?' class="amountremaintopayback"':(' class="'.$cssforamountpaymentcomplete.'"')).'>' . price($sign * $resteapayeraffiche) . '</td>';
4471
		print '<td class="nowrap">&nbsp;</td></tr>';
4472
4473
		// Sold credit note
4474
		// print '<tr><td colspan="'.$nbcols.'" align="right">'.$langs->trans('TotalTTC').' :</td>';
4475
		// print '<td align="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign *
4476
		// $object->total_ttc).'</b></td><td>&nbsp;</td></tr>';
4477
	}
4478
4479
	print '</table>';
4480
	print '</div>';
4481
4482
	// Margin Infos
4483
	if (! empty($conf->margin->enabled)) {
4484
		$formmargin->displayMarginInfos($object);
4485
	}
4486
4487
	print '</div>';
4488
	print '</div>';
4489
	print '</div>';
4490
4491
	print '<div class="clearboth"></div><br>';
4492
4493
	if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) {
4494
		$blocname = 'contacts';
4495
		$title = $langs->trans('ContactsAddresses');
4496
		include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php';
4497
	}
4498
4499
	if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
4500
		$blocname = 'notes';
4501
		$title = $langs->trans('Notes');
4502
		include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php';
4503
	}
4504
4505
	// Lines
4506
	$result = $object->getLinesArray();
4507
4508
	// Show global modifiers
4509
	if (! empty($conf->global->INVOICE_USE_SITUATION))
4510
	{
4511
		if ($object->situation_cycle_ref && $object->statut == 0) {
4512
			print '<div class="div-table-responsive">';
4513
4514
			print '<form name="updatealllines" id="updatealllines" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '#updatealllines" method="POST">';
4515
			print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '" />';
4516
			print '<input type="hidden" name="action" value="updatealllines" />';
4517
			print '<input type="hidden" name="id" value="' . $object->id . '" />';
4518
4519
			print '<table id="tablelines_all_progress" class="noborder noshadow" width="100%">';
4520
4521
			print '<tr class="liste_titre nodrag nodrop">';
4522
4523
			// Adds a line numbering column
4524
			if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) {
4525
				print '<td align="center" width="5">&nbsp;</td>';
4526
			}
4527
			print '<td>' . $langs->trans('ModifyAllLines') . '</td>';
4528
			print '<td align="right" width="50">&nbsp;</td>';
4529
			print '<td align="right" width="80">&nbsp;</td>';
4530
			if ($inputalsopricewithtax) print '<td align="right" width="80">&nbsp;</td>';
4531
			print '<td align="right" width="50">&nbsp</td>';
4532
			print '<td align="right" width="50">&nbsp</td>';
4533
			print '<td align="right" width="50">' . $langs->trans('Progress') . '</td>';
4534
			if (! empty($conf->margin->enabled) && empty($user->societe_id))
4535
			{
4536
				print '<td align="right" class="margininfos" width="80">&nbsp;</td>';
4537
				if ((! empty($conf->global->DISPLAY_MARGIN_RATES) || ! empty($conf->global->DISPLAY_MARK_RATES)) && $usercanreadallmargin) {
4538
					print '<td align="right" class="margininfos" width="50">&nbsp;</td>';
4539
				}
4540
			}
4541
			print '<td align="right" width="50">&nbsp;</td>';
4542
			print '<td>&nbsp;</td>';
4543
			print '<td width="10">&nbsp;</td>';
4544
			print '<td width="10">&nbsp;</td>';
4545
			print "</tr>\n";
4546
4547
			// Adds a line numbering column
4548
			if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) {
4549
				print '<td align="center" width="5">&nbsp;</td>';
4550
			}
4551
			print '<tr width="100%" class="nodrag nodrop">';
4552
			print '<td>&nbsp;</td>';
4553
			print '<td width="50">&nbsp;</td>';
4554
			print '<td width="80">&nbsp;</td>';
4555
			print '<td width="50">&nbsp;</td>';
4556
			print '<td width="50">&nbsp;</td>';
4557
			print '<td align="right" class="nowrap"><input type="text" size="1" value="" name="all_progress">%</td>';
4558
			print '<td colspan="4" align="right"><input class="button" type="submit" name="all_percent" value="Modifier" /></td>';
4559
			print '</tr>';
4560
4561
			print '</table>';
4562
4563
			print '</form>';
4564
4565
			print '</div>';
4566
		}
4567
	}
4568
4569
	print '	<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#addline' : '#line_' . GETPOST('lineid')) . '" method="POST">
4570
	<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
4571
	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline') . '">
4572
	<input type="hidden" name="mode" value="">
4573
	<input type="hidden" name="id" value="' . $object->id . '">
4574
	';
4575
4576
	if (! empty($conf->use_javascript_ajax) && $object->statut == 0) {
4577
		include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
4578
	}
4579
4580
	print '<div class="div-table-responsive-no-min">';
4581
	print '<table id="tablelines" class="noborder noshadow" width="100%">';
4582
4583
	// Show object lines
4584
	if (! empty($object->lines))
4585
		$ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 1);
4586
4587
	// Form to add new line
4588
	if ($object->statut == 0 && $usercancreate && $action != 'valid' && $action != 'editline' && ($object->is_first() || !$object->situation_cycle_ref))
4589
	{
4590
	    if ($action != 'editline' && $action != 'selectlines')
4591
		{
4592
			// Add free products/services
4593
			$object->formAddObjectLine(1, $mysoc, $soc);
4594
4595
			$parameters = array();
4596
			$reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
4597
		}
4598
	}
4599
4600
	print "</table>\n";
4601
	print "</div>";
4602
4603
	print "</form>\n";
4604
4605
	dol_fiche_end();
4606
4607
4608
	// Actions buttons
4609
4610
	if ($action != 'prerelance' && $action != 'presend' && $action != 'valid' && $action != 'editline')
4611
	{
4612
		print '<div class="tabsAction">';
4613
4614
		$parameters = array();
4615
		$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
4616
		if (empty($reshook)) {
4617
			// Editer une facture deja validee, sans paiement effectue et pas exporte en compta
4618
			if ($object->statut == Facture::STATUS_VALIDATED)
4619
			{
4620
				// On verifie si les lignes de factures ont ete exportees en compta et/ou ventilees
4621
				$ventilExportCompta = $object->getVentilExportCompta();
4622
4623
				if ($ventilExportCompta == 0)
4624
				{
4625
					if (! empty($conf->global->INVOICE_CAN_ALWAYS_BE_EDITED) || ($resteapayer == $object->total_ttc && empty($object->paye)))
4626
					{
4627
						if (! $objectidnext && $object->is_last_in_cycle())
4628
						{
4629
							if ($usercanunvalidate)
4630
							{
4631
								print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&amp;action=modif">' . $langs->trans('Modify') . '</a></div>';
4632
							} else {
4633
								print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("NotEnoughPermissions") . '">' . $langs->trans('Modify') . '</span></div>';
4634
							}
4635
						} else if (!$object->is_last_in_cycle()) {
4636
							print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("NotLastInCycle") . '">' . $langs->trans('Modify') . '</span></div>';
4637
						} else {
4638
							print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('Modify') . '</span></div>';
4639
						}
4640
					}
4641
				}
4642
				else
4643
				{
4644
					print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("DisabledBecauseDispatchedInAccounting") . '">' . $langs->trans('Modify') . '</span></div>';
4645
				}
4646
			}
4647
4648
			$discount = new DiscountAbsolute($db);
4649
			$result = $discount->fetch(0, $object->id);
4650
4651
			// Reopen a standard paid invoice
4652
			if ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT)
4653
				|| ($object->type == Facture::TYPE_CREDIT_NOTE && empty($discount->id))
4654
				|| ($object->type == Facture::TYPE_DEPOSIT && empty($discount->id)))
4655
				&& ($object->statut == 2 || $object->statut == 3 || ($object->statut == 1 && $object->paye == 1))   // Condition ($object->statut == 1 && $object->paye == 1) should not happened but can be found due to corrupted data
4656
				&& ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || $usercanreopen))				// A paid invoice (partially or completely)
4657
			{
4658
				if (! $objectidnext && $object->close_code != 'replaced') 				// Not replaced by another invoice
4659
				{
4660
					print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&amp;action=reopen">' . $langs->trans('ReOpen') . '</a></div>';
4661
				} else {
4662
					print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('ReOpen') . '</span></div>';
4663
				}
4664
			}
4665
4666
			// Validate
4667
			if ($object->statut == Facture::STATUS_DRAFT && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
4668
				if ($usercanvalidate)
4669
				{
4670
					print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&amp;action=valid">' . $langs->trans('Validate') . '</a></div>';
4671
				}
4672
			}
4673
4674
			// Send by mail
4675
			if (($object->statut == Facture::STATUS_VALIDATED || $object->statut == Facture::STATUS_CLOSED) || ! empty($conf->global->FACTURE_SENDBYEMAIL_FOR_ALL_STATUS)) {
4676
				if ($objectidnext) {
4677
					print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('SendMail') . '</span></div>';
4678
				} else {
4679
					if ($usercansend) {
4680
						print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&action=presend&mode=init#formmailbeforetitle">' . $langs->trans('SendMail') . '</a></div>';
4681
					} else
4682
						print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans('SendMail') . '</a></div>';
4683
				}
4684
			}
4685
4686
			// Request a direct debit order
4687
			if ($object->statut > Facture::STATUS_DRAFT && $object->paye == 0 && $num == 0)
4688
			{
4689
				if ($resteapayer > 0)
4690
				{
4691
					if ($usercancreatewithdrarequest)
4692
					{
4693
						if (! $objectidnext && $object->close_code != 'replaced') 				// Not replaced by another invoice
4694
						{
4695
							print '<a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$object->id.'" title="'.dol_escape_htmltag($langs->trans("MakeWithdrawRequest")).'">'.$langs->trans("MakeWithdrawRequest").'</a>';
4696
						} else {
4697
							print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('MakeWithdrawRequest') . '</span></div>';
4698
						}
4699
					}
4700
					else
4701
					{
4702
						//print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans("MakeWithdrawRequest").'</a>';
4703
					}
4704
				}
4705
				else
4706
				{
4707
					//print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("AmountMustBePositive")).'">'.$langs->trans("MakeWithdrawRequest").'</a>';
4708
				}
4709
			}
4710
4711
			// Create payment
4712
			if ($object->type != Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercanissuepayment) {
4713
				if ($objectidnext) {
4714
					print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('DoPayment') . '</span></div>';
4715
				} else {
4716
					//if ($resteapayer == 0) {		// Sometimes we can receive more, so we accept to enter more and will offer a button to convert into discount (but it is not a credit note, just a prepayment done)
4717
					//	print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("DisabledBecauseRemainderToPayIsZero") . '">' . $langs->trans('DoPayment') . '</span></div>';
4718
					//} else {
4719
						print '<div class="inline-block divButAction"><a class="butAction" href="'. DOL_URL_ROOT .'/compta/paiement.php?facid=' . $object->id . '&amp;action=create&amp;accountid='.$object->fk_account.'">' . $langs->trans('DoPayment') . '</a></div>';
4720
					//}
4721
				}
4722
			}
4723
4724
			// Reverse back money or convert to reduction
4725
			if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_STANDARD) {
4726
				// For credit note only
4727
				if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercanissuepayment)
4728
				{
4729
					if ($resteapayer == 0)
4730
					{
4731
						print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPaymentBack').'</span></div>';
4732
					}
4733
					else
4734
					{
4735
						print '<div class="inline-block divButAction"><a class="butAction" href="'. DOL_URL_ROOT .'/compta/paiement.php?facid='.$object->id.'&amp;action=create&amp;accountid='.$object->fk_account.'">'.$langs->trans('DoPaymentBack').'</a></div>';
4736
					}
4737
				}
4738
4739
				// For standard invoice with excess received
4740
				if ($object->type == Facture::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) < 0 && $usercancreate && empty($discount->id))
4741
				{
4742
					print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertExcessReceivedToReduc').'</a></div>';
4743
				}
4744
				// For credit note
4745
				if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate && $object->getSommePaiement() == 0) {
4746
					print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&amp;action=converttoreduc">' . $langs->trans('ConvertToReduc') . '</a></div>';
4747
				}
4748
				// For deposit invoice
4749
				if ($object->type == Facture::TYPE_DEPOSIT && $usercancreate && $object->statut > 0 && empty($discount->id))
4750
				{
4751
					print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a></div>';
4752
				}
4753
			}
4754
4755
			// Classify paid
4756
			if ($object->statut == 1 && $object->paye == 0 && $usercanissuepayment && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0))
0 ignored issues
show
Consider adding parentheses for clarity. Current Interpretation: ($object->statut == 1 &&...&& empty($discount->id), Probably Intended Meaning: $object->statut == 1 && ...& empty($discount->id))
Loading history...
4757
				|| ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 0 && $object->total_ttc > 0 && $resteapayer == 0 && $usercanissuepayment && empty($discount->id))
4758
			)
4759
			{
4760
				print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaid').'</a></div>';
4761
			}
4762
4763
			// Classify 'closed not completely paid' (possible si validee et pas encore classee payee)
4764
4765
			if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 && $usercanissuepayment)
4766
			{
4767
				if ($totalpaye > 0 || $totalcreditnotes > 0)
4768
				{
4769
					// If one payment or one credit note was linked to this invoice
4770
					print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&amp;action=paid">' . $langs->trans('ClassifyPaidPartially') . '</a></div>';
4771
				}
4772
				else
4773
				{
4774
					if ( empty($conf->global->INVOICE_CAN_NEVER_BE_CANCELED))
4775
					{
4776
						if ($objectidnext)
4777
						{
4778
							print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('ClassifyCanceled') . '</span></div>';
4779
						}
4780
						else
4781
						{
4782
							print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&amp;action=canceled">' . $langs->trans('ClassifyCanceled') . '</a></div>';
4783
						}
4784
					}
4785
				}
4786
			}
4787
4788
			// Clone
4789
			if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA) && $usercancreate)
4790
			{
4791
				print '<div class="inline-block divButAction"><a class="butAction'.($conf->use_javascript_ajax?' reposition':'').'" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&amp;action=clone&amp;object=invoice">' . $langs->trans("ToClone") . '</a></div>';
4792
			}
4793
4794
			// Clone as predefined / Create template
4795
			if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA) && $object->statut == 0 && $usercancreate)
4796
			{
4797
				if (! $objectidnext && count($object->lines) > 0)
4798
				{
4799
					print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/fiche-rec.php?facid=' . $object->id . '&amp;action=create">' . $langs->trans("ChangeIntoRepeatableInvoice") . '</a></div>';
4800
				}
4801
			}
4802
4803
			// Create a credit note
4804
			if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA) && $object->statut > 0 && $usercancreate)
4805
			{
4806
				if (! $objectidnext)
4807
				{
4808
					print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?socid=' . $object->socid .'&amp;fac_avoir=' . $object->id . '&amp;action=create&amp;type=2'.($object->fk_project > 0 ? '&amp;projectid='.$object->fk_project : '').'">' . $langs->trans("CreateCreditNote") . '</a></div>';
4809
				}
4810
			}
4811
4812
			// For situation invoice with excess received
4813
			if ($object->statut > Facture::STATUS_DRAFT
4814
			    && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) > 0
4815
			    && $usercancreate
4816
			    && !$objectidnext
4817
			    && $object->is_last_in_cycle()
4818
			    && $conf->global->INVOICE_USE_SITUATION_CREDIT_NOTE
4819
			    )
4820
			{
4821
				if ($usercanunvalidate)
4822
			    {
4823
			        print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?socid=' . $object->socid .'&amp;fac_avoir=' . $object->id . '&amp;invoiceAvoirWithLines=1&amp;action=create&amp;type=2'.($object->fk_project > 0 ? '&amp;projectid='.$object->fk_project : '').'">' . $langs->trans("CreateCreditNote") . '</a></div>';
4824
			    } else {
4825
			        print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="' . $langs->trans("NotEnoughPermissions") . '">' . $langs->trans("CreateCreditNote") . '</span></div>';
4826
			    }
4827
			}
4828
4829
			// remove situation from cycle
4830
			if ($object->statut > Facture::STATUS_DRAFT
4831
			    && $object->type == Facture::TYPE_SITUATION
4832
			    && $usercancreate
4833
			    && !$objectidnext
4834
			    && $object->situation_counter > 1
4835
			    && $object->is_last_in_cycle()
4836
				&& $usercanunvalidate
4837
			    )
4838
			{
4839
			    if(($object->total_ttc - $totalcreditnotes  ) == 0 )
4840
			    {
4841
			        print '<div class="inline-block divButAction"><a id="butSituationOut" class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&amp;action=situationout">' . $langs->trans("RemoveSituationFromCycle") . '</a></div>';
4842
			    }
4843
			    else
4844
			    {
4845
			        print '<div class="inline-block divButAction"><a id="butSituationOutRefused" class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecauseNotEnouthCreditNote") . '" >' . $langs->trans("RemoveSituationFromCycle") . '</a></div>';
4846
			    }
4847
			}
4848
4849
			// Create next situation invoice
4850
			if ($usercancreate && ($object->type == 5) && ($object->statut == 1 || $object->statut == 2)) {
4851
				if ($object->is_last_in_cycle() && $object->situation_final != 1) {
4852
					print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=create&amp;type=5&amp;origin=facture&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '" >' . $langs->trans('CreateNextSituationInvoice') . '</a></div>';
4853
				} else if (!$object->is_last_in_cycle()) {
4854
					print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecauseNotLastInCycle") . '">' . $langs->trans('CreateNextSituationInvoice') . '</a></div>';
4855
				} else {
4856
					print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecauseFinal") . '">' . $langs->trans('CreateNextSituationInvoice') . '</a></div>';
4857
				}
4858
			}
4859
4860
			// Delete
4861
			$isErasable = $object->is_erasable();
4862
			if ($usercandelete || ($usercancreate && $isErasable == 1))	// isErasable = 1 means draft with temporary ref (draft can always be deleted with no need of permissions)
4863
			{
4864
				//var_dump($isErasable);
4865
				if ($isErasable == -4) {
4866
					print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecausePayments") . '">' . $langs->trans('Delete') . '</a></div>';
4867
				}
4868
				elseif ($isErasable == -3) {
4869
					print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecauseNotLastSituationInvoice") . '">' . $langs->trans('Delete') . '</a></div>';
4870
				}
4871
				elseif ($isErasable == -2) {
4872
					print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecauseNotLastInvoice") . '">' . $langs->trans('Delete') . '</a></div>';
4873
				}
4874
				elseif ($isErasable == -1) {
4875
					print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecauseDispatchedInBookkeeping") . '">' . $langs->trans('Delete') . '</a></div>';
4876
				}
4877
				elseif ($isErasable <= 0)	// Any other cases
4878
				{
4879
					print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecauseNotErasable") . '">' . $langs->trans('Delete') . '</a></div>';
4880
				}
4881
				elseif ($objectidnext)
4882
				{
4883
					print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('Delete') . '</a></div>';
4884
				}
4885
				else
4886
				{
4887
					print '<div class="inline-block divButAction"><a class="butActionDelete'.($conf->use_javascript_ajax?' reposition':'').'" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&amp;action=delete">' . $langs->trans('Delete') . '</a></div>';
4888
				}
4889
			} else {
4890
				print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("NotAllowed") . '">' . $langs->trans('Delete') . '</a></div>';
4891
			}
4892
		}
4893
		print '</div>';
4894
	}
4895
4896
	// Select mail models is same action as presend
4897
	if (GETPOST('modelselected','alpha')) {
4898
		$action = 'presend';
4899
	}
4900
	if ($action != 'prerelance' && $action != 'presend')
4901
	{
4902
		print '<div class="fichecenter"><div class="fichehalfleft">';
4903
		print '<a name="builddoc"></a>'; // ancre
4904
4905
		// Documents generes
4906
		$filename = dol_sanitizeFileName($object->ref);
4907
		$filedir = $conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref);
4908
		$urlsource = $_SERVER['PHP_SELF'] . '?facid=' . $object->id;
4909
		$genallowed = $usercanread;
4910
		$delallowed = $usercancreate;
4911
4912
		print $formfile->showdocuments('facture', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang);
4913
		$somethingshown = $formfile->numoffiles;
4914
4915
		// Show links to link elements
4916
		$linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice'));
4917
4918
		$compatibleImportElementsList = false;
4919
		if($usercancreate
4920
		    && $object->statut == Facture::STATUS_DRAFT
4921
		    && ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) )
4922
		{
4923
		    $compatibleImportElementsList = array('commande','propal'); // import from linked elements
4924
		}
4925
		$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem,$compatibleImportElementsList);
4926
4927
4928
		// Show online payment link
4929
		$useonlinepayment = (! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled));
4930
4931
		if ($object->statut != Facture::STATUS_DRAFT && $useonlinepayment)
4932
		{
4933
			print '<br><!-- Link to pay -->'."\n";
4934
			require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
4935
			print showOnlinePaymentUrl('invoice', $object->ref).'<br>';
4936
		}
4937
4938
		// Show direct download link
4939
		if ($object->statut != Facture::STATUS_DRAFT && ! empty($conf->global->INVOICE_ALLOW_EXTERNAL_DOWNLOAD))
4940
		{
4941
			print '<br><!-- Link to download main doc -->'."\n";
4942
			print showDirectDownloadLink($object).'<br>';
4943
		}
4944
4945
		print '</div><div class="fichehalfright"><div class="ficheaddleft">';
4946
4947
		// List of actions on element
4948
		include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
4949
		$formactions = new FormActions($db);
4950
		$somethingshown = $formactions->showactions($object, 'invoice', $socid, 1);
4951
4952
		print '</div></div></div>';
4953
	}
4954
4955
4956
	// Presend form
4957
	$modelmail='facture_send';
4958
	$defaulttopic='SendBillRef';
4959
	$diroutput = $conf->facture->dir_output;
4960
	$trackid = 'inv'.$object->id;
4961
4962
	include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
4963
}
4964
4965
// End of page
4966
llxFooter();
4967
$db->close();
4968