diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php
index 5bb1f989a92987c57f86542a494b4f629def9f46..8a0318473c9f8727a678a30842de44f97ae97cb7 100644
--- a/htdocs/accountancy/journal/sellsjournal.php
+++ b/htdocs/accountancy/journal/sellsjournal.php
@@ -7,6 +7,7 @@
  * Copyright (C) 2013-2014	Alexandre Spangaro		<alexandre.spangaro@gmail.com>
  * Copyright (C) 2013-2014	Florian Henry			<florian.henry@open-concept.pro>
  * Copyright (C) 2013-2014	Olivier Geffroy			<jeff@jeffinfo.com>
+ * Copyright (C) 2014       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -100,9 +101,9 @@ if (! empty($conf->multicompany->enabled)) {
 }
 $sql .= " AND f.fk_statut > 0";
 if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
-	$sql .= " AND f.type IN (0,1,2)";
+	$sql .= " AND f.type IN (0,1,2,5)";
 else
-	$sql .= " AND f.type IN (0,1,2,3)";
+	$sql .= " AND f.type IN (0,1,2,3,5)";
 $sql .= " AND fd.product_type IN (0,1)";
 if ($date_start && $date_end)
 	$sql .= " AND f.datef >= '" . $db->idate($date_start) . "' AND f.datef <= '" . $db->idate($date_end) . "'";
@@ -136,6 +137,16 @@ if ($result) {
 		$cpttva = (! empty($conf->global->ACCOUNTING_VAT_ACCOUNT)) ? $conf->global->ACCOUNTING_VAT_ACCOUNT : $langs->trans("CodeNotDef");
 		$compta_tva = (! empty($obj->account_tva) ? $obj->account_tva : $cpttva);
 
+		// Situation invoices handling
+		$line = new FactureLigne($db);
+		$line->fetch($obj->id);
+		$prev_progress = $line->get_prev_progress();
+		if ($obj->situation_percent == 0) { // Avoid divide by 0
+			$situation_ratio = 0;
+		} else {
+			$situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
+		}
+
 		// Invoice lines
 		$tabfac[$obj->rowid]["date"] = $obj->df;
 		$tabfac[$obj->rowid]["ref"] = $obj->facnumber;
@@ -148,9 +159,9 @@ if ($result) {
 			$tabht[$obj->rowid][$compta_prod] = 0;
 		if (! isset($tabtva[$obj->rowid][$compta_tva]))
 			$tabtva[$obj->rowid][$compta_tva] = 0;
-		$tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc;
-		$tabht[$obj->rowid][$compta_prod] += $obj->total_ht;
-		$tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
+		$tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc * $situation_ratio;
+		$tabht[$obj->rowid][$compta_prod] += $obj->total_ht * $situation_ratio;
+		$tabtva[$obj->rowid][$compta_tva] += $obj->total_tva * $situation_ratio;
 		$tabcompany[$obj->rowid] = array (
 				'id' => $obj->socid,
 				'name' => $obj->name,
@@ -471,4 +482,4 @@ if ($action == 'export_csv') {
 	// End of page
 	llxFooter();
 }
-$db->close();
\ No newline at end of file
+$db->close();
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index 9f104180defb6310ecb9b8a0a2b4f5e913fe3fce..3feb30cdb27cf8704e76c4ccba2c93b4fe9633ae 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -7,9 +7,10 @@
  * Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
  * Copyright (C) 2010-2013 Juanjo Menent         <jmenent@2byte.es>
  * Copyright (C) 2012-2013 Christophe Battarel   <christophe.battarel@altairis.fr>
+ * Copyright (C) 2012-2013 Cédric Salvador       <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014 Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2013      Jean-Francois FERRY   <jfefe@aternatik.fr>
  * Copyright (C) 2013-2014 Florian Henry         <florian.henry@open-concept.pro>
- * Copyright (C) 2013      Cédric Salvador       <csalvador@gpcsolutions.fr>
  * Copyright (C) 2014	   Ferran Marcet		<fmarcet@2byte.es>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -802,7 +803,7 @@ else if ($action == 'add' && $user->rights->facture->creer)
 	}
 
 	// Standard or deposit or proforma invoice
-	if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT || $_POST['type'] == Facture::TYPE_PROFORMA) && $_POST['fac_rec'] <= 0)
+	if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT || $_POST['type'] == Facture::TYPE_PROFORMA || ($_POST['type'] == Facture::TYPE_SITUATION && empty($_POST['situations']))) && $_POST['fac_rec'] <= 0)
 	{
 		if (GETPOST('socid', 'int') < 1)
 		{
@@ -837,6 +838,12 @@ else if ($action == 'add' && $user->rights->facture->creer)
 			$object->remise_absolue		= $_POST['remise_absolue'];
 			$object->remise_percent		= $_POST['remise_percent'];
 
+			if($_POST['type'] == Facture::TYPE_SITUATION) {
+				$object->situation_counter = 1;
+				$object->situation_final = 0;
+				$object->situation_cycle_ref = $object->newCycle();
+			}
+
 			$object->fetch_thirdparty();
 
 			// If creation from another object of another module (Example: origin=propal, originid=1)
@@ -987,6 +994,7 @@ else if ($action == 'add' && $user->rights->facture->creer)
 
 								$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
 								$desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
+								if ($object->situation_counter == 1) $lines[$i]->situation_percent =  0;
 
 								if ($lines[$i]->subprice < 0)
 								{
@@ -1040,7 +1048,7 @@ else if ($action == 'add' && $user->rights->facture->creer)
 										$array_option = $lines[$i]->array_options;
 									}
 
-									$result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $object->origin, $lines[$i]->rowid, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_option);
+									$result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, $lines[$i]->fk_remise_except, 'HT', 0, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $object->origin, $lines[$i]->rowid, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $array_option, $lines[$i]->situation_percent, $lines[$i]->fk_prev_id);
 
 									if ($result > 0) {
 										$lineid = $result;
@@ -1089,6 +1097,44 @@ else if ($action == 'add' && $user->rights->facture->creer)
 		}
 	}
 
+	if ($_POST['type'] == Facture::TYPE_SITUATION && (!empty($_POST['situations']))) {
+		$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+		if (empty($datefacture)) {
+			$error++;
+			$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
+		}
+
+		if (!($_POST['situations'] > 0)) {
+			$error++;
+			$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")) . '</div>';
+		}
+
+		if (!$error) {
+			$result = $object->fetch($_POST['situations']);
+			$object->fk_facture_source = $_POST['situations'];
+			$object->type = Facture::TYPE_SITUATION;
+
+			$object->fetch_thirdparty();
+			$object->date = $datefacture;
+			$object->note_public = trim($_POST['note_public']);
+			$object->note = trim($_POST['note']);
+			$object->ref_client = $_POST['ref_client'];
+			$object->ref_int = $_POST['ref_int'];
+			$object->modelpdf = $_POST['model'];
+			$object->fk_project = $_POST['projectid'];
+			$object->cond_reglement_id = $_POST['cond_reglement_id'];
+			$object->mode_reglement_id = $_POST['mode_reglement_id'];
+			$object->remise_absolue = $_POST['remise_absolue'];
+			$object->remise_percent = $_POST['remise_percent'];
+
+			// Proprietes particulieres a facture de remplacement
+
+			$object->situation_counter = $object->situation_counter + 1;
+			$id = $object->createFromCurrent($user);
+			if ($id <= 0) $mesg = $object->error;
+		}
+	}
+
 	// End of object creation, we show it
 	if ($id > 0 && ! $error)
 	{
@@ -1312,7 +1358,7 @@ else if ($action == 'addline' && $user->rights->facture->creer)
 			setEventMessage($mesg, 'errors');
 		} else {
 			// Insert line
-			$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_option);
+			$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_option, $_POST['progress']);
 
 			if ($result > 0)
 			{
@@ -1363,6 +1409,9 @@ else if ($action == 'addline' && $user->rights->facture->creer)
 		    	unset($_POST['date_endday']);
 		    	unset($_POST['date_endmonth']);
 		    	unset($_POST['date_endyear']);
+
+				unset($_POST['situations']);
+				unset($_POST['progress']);
 			} else {
 				setEventMessage($object->error, 'errors');
 			}
@@ -1413,6 +1462,17 @@ elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('
 		}
 	}
 
+	$line = new FactureLigne($db);
+	$line->fetch(GETPOST('lineid'));
+	$percent = $line->get_prev_progress();
+
+	if (GETPOST('progress') < $percent) {
+		$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
+		setEventMessages($mesg, null, 'warnings');
+		$error++;
+		$result = -1;
+	}
+
 	// Check minimum price
 	$productid = GETPOST('productid', 'int');
 	if (! empty($productid)) {
@@ -1450,7 +1510,7 @@ elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('
 
 	// Update line
 	if (! $error) {
-		$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $qty, GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option);
+		$result = $object->updateline(GETPOST('lineid'), $description, $pu_ht, $qty, GETPOST('remise_percent'), $date_start, $date_end, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $info_bits, $type, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, 0, $array_option, GETPOST('progress'));
 
 		if ($result >= 0) {
 			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
@@ -1484,12 +1544,28 @@ elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('
 			unset($_POST['buying_price']);
 			unset($_POST['np_marginRate']);
 			unset($_POST['np_markRate']);
+			unset($_POST['situations']);
+			unset($_POST['progress']);
 		} else {
 			setEventMessage($object->error, 'errors');
 		}
 	}
 }
 
+else if ($action == 'updatealllines' && $user->rights->facture->creer && $_POST['all_percent'] == $langs->trans('Modifier')) {
+	if (!$object->fetch($id) > 0) dol_print_error($db);
+	if (!is_null(GETPOST('all_progress')) && GETPOST('all_progress') != "") {
+		foreach ($object->lines as $line) {
+			$percent = $line->get_prev_progress();
+			if (GETPOST('all_progress') < $percent) {
+				$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
+				$result = -1;
+			} else
+				$object->update_percent($line, $_POST['all_progress']);
+		}
+	}
+}
+
 else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) {
 	header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition
 	exit();
@@ -1800,6 +1876,8 @@ if ($action == 'create')
 		require_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
 		print ajax_combobox('fac_replacement');
 		print ajax_combobox('fac_avoir');
+		print ajax_combobox('situations');
+
 	}
 
 	print '<form name="add" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
@@ -1961,6 +2039,29 @@ if ($action == 'create')
 
 	if ($socid > 0)
 	{
+		// First situation invoice
+		print '<tr height="18"><td width="16px" valign="middle">';
+		print '<input type="radio" name="type" value="5"' . (GETPOST('type') == 5 ? ' checked="checked"' : '') . '>';
+		print '</td><td valign="middle">';
+		$desc = $form->textwithpicto($langs->trans("InvoiceFirstSituationAsk"), $langs->transnoentities("InvoiceFirstSituationDesc"), 1);
+		print $desc;
+		print '</td></tr>' . "\n";
+
+		// Next situation invoice
+		$opt = $form->load_situation_invoices(GETPOST('originid'), $socid);
+		print '<tr height="18"><td valign="middle">';
+		print '<input type="radio" name="type" value="5"' . (GETPOST('type') == 5 && GETPOST('originid') ? ' checked="checked"' : '') . ' ';
+		if ($opt == '<option value ="0" selected="selected">' . $langs->trans('NoSituations') . '</option>' || (GETPOST('origin') && GETPOST('origin') != 'facture')) print 'disabled="disabled"';
+		print '>';
+		print '</td><td valign="middle">';
+		$text = $langs->trans("InvoiceSituationAsk") . ' ';
+		$text .= '<select class="flat" id="situations" name="situations">';
+		$text .= $opt;
+		$text .= '</select>';
+		$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceSituationDesc"), 1);
+		print $desc;
+		print '</td></tr>' . "\n";
+
 		// Replacement
 		print '<tr height="18"><td valign="middle">';
 		print '<input type="radio" name="type" id="radio_replacement" value="1"' . (GETPOST('type') == 1 ? ' checked="checked"' : '');
@@ -3093,6 +3194,50 @@ if ($action == 'create')
 	print "</td>";
 	print '</tr>';
 
+	// Situations
+	if ($object->type == 5 && ($object->situation_counter > 1)) {
+		$prevsits = $object->get_prev_sits();
+		print '<tr><td>';
+		print $langs->trans('SituationAmount');
+		print ' ';
+
+		print $prevsits[0]->situation_counter;
+		for ($i = 1; $i < count($prevsits); $i++) {
+			print ' + ';
+			print $prevsits[$i]->situation_counter;
+		}
+		print ' + ';
+		print $object->situation_counter;
+
+		print '</td>';
+		print '<td align="right" colspan="2" nowrap>';
+
+		$prevsits_total_amount = 0;
+		foreach ($prevsits as $situation) {
+			$prevsits_total_amount += $situation->total_ht;
+		}
+		$prevsits_total_amount += $object->total_ht;
+
+		print price($prevsits_total_amount);
+		print '</td>';
+		print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td></tr>';
+
+		// Previous situation(s) deduction(s)
+		for ($i = 0; $i < count($prevsits); $i++) {
+			print '<tr><td>';
+			print '<a href="' . $_SERVER['PHP_SELF'] . '?facid=' . $prevsits[$i]->id . '">';
+			print $langs->trans('SituationDeduction');
+			print ' ';
+			print $prevsits[$i]->situation_counter;
+			print '</a></td>';
+
+			print '<td align="right" colspan="2" nowrap>';
+			print '- ' . price($prevsits[$i]->total_ht);
+			print '</td>';
+			print '<td>' . $langs->trans('Currency' . $conf->currency) . '</td></tr>';
+		}
+	}
+
 	// Amount
 	print '<tr><td>' . $langs->trans('AmountHT') . '</td>';
 	print '<td align="right" colspan="3" nowrap>' . price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency) . '</td></tr>';
@@ -3190,6 +3335,58 @@ if ($action == 'create')
 	// Lines
 	$result = $object->getLinesArray();
 
+	if (! empty($conf->use_javascript_ajax) && $object->statut == 0) {
+		include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
+	}
+
+	print '<table id="tablelines" class="noborder noshadow" width="100%">';
+
+	// Show global modifiers
+	if ($object->situation_cycle_ref && $object->statut == 0) {
+		print '<tr class="liste_titre nodrag nodrop">';
+		print '<form name="updatealllines" id="updatealllines" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '"#updatealllines" method="POST">';
+		print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '" />';
+		print '<input type="hidden" name="action" value="updatealllines" />';
+		print '<input type="hidden" name="id" value="' . $object->id . '" />';
+
+		if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) {
+			print '<td align="center" width="5">&nbsp;</td>';
+		}
+		print '<td>' . $langs->trans('ModifyAllLines') . '</td>';
+		print '<td align="right" width="50">&nbsp;</td>';
+		print '<td align="right" width="80">&nbsp;</td>';
+		if ($inputalsopricewithtax) print '<td align="right" width="80">&nbsp;</td>';
+		print '<td align="right" width="50">&nbsp</td>';
+		print '<td align="right" width="50">&nbsp</td>';
+		print '<td align="right" width="50">' . $langs->trans('Progress') . '</td>';
+		if (! empty($conf->margin->enabled) && empty($user->societe_id))
+		{
+			print '<td align="right" class="margininfos" width="80">&nbsp;</td>';
+			if ((! empty($conf->global->DISPLAY_MARGIN_RATES) || ! empty($conf->global->DISPLAY_MARK_RATES)) && $user->rights->margins->liretous) {
+				print '<td align="right" class="margininfos" width="50">&nbsp;</td>';
+			}
+		}
+		print '<td align="right" width="50">&nbsp;</td>';
+		print '<td>&nbsp;</td>';
+		print '<td width="10">&nbsp;</td>';
+		print '<td width="10">&nbsp;</td>';
+		print "</tr>\n";
+
+		if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) {
+			print '<td align="center" width="5">&nbsp;</td>';
+		}
+		print '<tr width="100%" height="18" class="nodrag nodrop">';
+		print '<td>&nbsp;</td>';
+		print '<td width="50">&nbsp;</td>';
+		print '<td width="80">&nbsp;</td>';
+		print '<td width="50">&nbsp;</td>';
+		print '<td width="50">&nbsp;</td>';
+		print '<td align="right" class="nowrap"><input type="text" size="1" value="" name="all_progress">%</td>';
+		print '<td colspan="4" align="right"><input class="button" type="submit" name="all_percent" value="Modifier" /></td>';
+		print '</tr>';
+		print '</form>';
+	}
+
 	print '	<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#add' : '#line_' . GETPOST('lineid')) . '" method="POST">
 	<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
 	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateligne') . '">
@@ -3197,18 +3394,12 @@ if ($action == 'create')
 	<input type="hidden" name="id" value="' . $object->id . '">
 	';
 
-	if (! empty($conf->use_javascript_ajax) && $object->statut == 0) {
-		include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
-	}
-
-	print '<table id="tablelines" class="noborder noshadow" width="100%">';
-
 	// Show object lines
 	if (! empty($object->lines))
 		$ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 1);
 
 	// Form to add new line
-	if ($object->statut == 0 && $user->rights->facture->creer && $action != 'valid' && $action != 'editline')
+	if ($object->statut == 0 && $user->rights->facture->creer && $action != 'valid' && $action != 'editline' && ($object->is_first() || !$object->situation_cycle_ref))
 	{
 		if ($action != 'editline')
 		{
@@ -3245,12 +3436,14 @@ if ($action == 'create')
 				$ventilExportCompta = $object->getVentilExportCompta();
 
 				if ($resteapayer == $object->total_ttc && $object->paye == 0 && $ventilExportCompta == 0) {
-					if (! $objectidnext) {
+					if (! $objectidnext && $object->is_last_in_cycle()) {
 						if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->facture->valider) || $user->rights->facture->invoice_advance->unvalidate) {
 							print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?facid=' . $object->id . '&amp;action=modif">' . $langs->trans('Modify') . '</a></div>';
 						} else {
 							print '<div class="inline-block divButAction"><span class="butActionRefused" title="' . $langs->trans("NotEnoughPermissions") . '">' . $langs->trans('Modify') . '</span></div>';
 						}
+					} else if (!$object->is_last_in_cycle()) {
+						print '<div class="inline-block divButAction"><span class="butActionRefused" title="' . $langs->trans("NotLastInCycle") . '">' . $langs->trans('Modify') . '</span></div>';
 					} else {
 						print '<div class="inline-block divButAction"><span class="butActionRefused" title="' . $langs->trans("DisabledBecauseReplacedInvoice") . '">' . $langs->trans('Modify') . '</span></div>';
 					}
@@ -3273,7 +3466,7 @@ if ($action == 'create')
 			}
 
 			// Validate
-			if ($object->statut == 0 && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA) && (! empty($conf->global->FACTURE_ENABLE_NEGATIVE) || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
+			if ($object->statut == 0 && 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))) {
 				if ($user->rights->facture->valider) {
 					print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?facid=' . $object->id . '&amp;action=valid">' . $langs->trans('Validate') . '</a></div>';
 				}
@@ -3385,6 +3578,17 @@ if ($action == 'create')
 				}
 			}
 
+			//Create next situation invoice
+			if ($user->rights->facture->creer && ($object->type == 5) && ($object->statut == 1 || $object->statut == 2)) {
+				if ($object->is_last_in_cycle() && $object->situation_final != 1) {
+					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>';
+				} else if (!$object->is_last_in_cycle()) {
+					print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="' . $langs->trans("DisabledBecauseNotLastInCycle") . '">' . $langs->trans('CreateNextSituationInvoice') . '</a></div>';
+				} else {
+					print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="' . $langs->trans("DisabledBecauseFinal") . '">' . $langs->trans('CreateNextSituationInvoice') . '</a></div>';
+				}
+			}
+
 			// Delete
 			if ($user->rights->facture->supprimer)
 			{
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index f81fb37849f9221d25c4075c038109363482a8a8..f28f068c2558e6d400a4985373fdf2c4edd63090 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -10,6 +10,8 @@
  * Copyright (C) 2010-2014 Juanjo Menent         <jmenent@2byte.es>
  * Copyright (C) 2012-2014 Christophe Battarel   <christophe.battarel@altairis.fr>
  * Copyright (C) 2012-2014 Marcos García         <marcosgdf@gmail.com>
+ * Copyright (C) 2012      Cédric Salvador       <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014 Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2013      Cedric Gross          <c.gross@kreiz-it.fr>
  * Copyright (C) 2013      Florian Henry		  	<florian.henry@open-concept.pro>
  *
@@ -122,6 +124,21 @@ class Facture extends CommonInvoice
 
 	var $fac_rec;
 
+	/**
+	 * @var int Situation cycle reference number
+	 */
+	public $situation_cycle_ref;
+
+	/**
+	 * @var int Situation counter inside the cycle
+	 */
+	public $situation_counter;
+
+	/**
+	 * @var bool Final situation flag
+	 */
+	public $situation_final;
+
     /**
      * Standard invoice
      */
@@ -147,6 +164,11 @@ class Facture extends CommonInvoice
      */
     const TYPE_PROFORMA = 4;
 
+	/**
+	 * Situation invoice
+	 */
+	const TYPE_SITUATION = 5;
+
 	/**
 	 * 	Constructor
 	 *
@@ -180,6 +202,17 @@ class Facture extends CommonInvoice
 		if (! $this->cond_reglement_id) $this->cond_reglement_id = 0;
 		if (! $this->mode_reglement_id) $this->mode_reglement_id = 0;
 		$this->brouillon = 1;
+		if (empty($this->situation_cycle_ref)) {
+			$this->situation_cycle_ref = 'null';
+		}
+
+		if (empty($this->situation_counter)) {
+			$this->situation_counter = 'null';
+		}
+
+		if (empty($this->situation_final)) {
+			$this->situation_final = '0';
+		}
 
 		dol_syslog(get_class($this)."::create user=".$user->id);
 
@@ -248,6 +281,7 @@ class Facture extends CommonInvoice
         $sql.= ", fk_account";
 		$sql.= ", fk_facture_source, fk_user_author, fk_projet";
 		$sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf";
+		$sql.= ", situation_cycle_ref, situation_counter, situation_final";
 		$sql.= ")";
 		$sql.= " VALUES (";
 		$sql.= "'(PROV)'";
@@ -269,7 +303,11 @@ class Facture extends CommonInvoice
 		$sql.= ",".($this->fk_project?$this->fk_project:"null");
 		$sql.= ','.$this->cond_reglement_id;
 		$sql.= ",".$this->mode_reglement_id;
-		$sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."')";
+		$sql.= ", '".$this->db->idate($datelim)."', '".$this->modelpdf."'";
+		$sql.= ", ".$this->situation_cycle_ref;
+		$sql.= ", ".$this->situation_counter;
+		$sql.= ", ".$this->situation_final;
+		$sql.=")";
 
 		dol_syslog(get_class($this)."::create", LOG_DEBUG);
 		$resql=$this->db->query($sql);
@@ -399,7 +437,9 @@ class Facture extends CommonInvoice
 							$this->lines[$i]->fk_fournprice,
 							$this->lines[$i]->pa_ht,
 							$this->lines[$i]->label,
-							$this->lines[$i]->array_options
+							$this->lines[$i]->array_options,
+							$this->lines[$i]->situation_percent,
+							$this->lines[$i]->fk_prev_id
 						);
 						if ($result < 0)
 						{
@@ -451,7 +491,9 @@ class Facture extends CommonInvoice
 						0,
 						null,
 						0,
-						$_facrec->lines[$i]->label
+						$_facrec->lines[$i]->label,
+						null,
+						$_facrec->lines[$i]->situation_percent
 					);
 
 					if ( $result_insert < 0)
@@ -556,10 +598,14 @@ class Facture extends CommonInvoice
 
 		$facture->lines		    	= $this->lines;	// Tableau des lignes de factures
 		$facture->products		    = $this->lines;	// Tant que products encore utilise
+		$facture->situation_counter = $this->situation_counter;
+		$facture->situation_cycle_ref=$this->situation_cycle_ref;
+		$facture->situation_final  = $this->situation_final;
 
 		// Loop on each line of new invoice
 		foreach($facture->lines as $i => $line)
 		{
+			$facture->lines[$i]->fk_prev_id = $this->lines[$i]->rowid;
 			if ($invertdetail)
 			{
 				$facture->lines[$i]->subprice  = -$facture->lines[$i]->subprice;
@@ -827,6 +873,7 @@ class Facture extends CommonInvoice
 		if ($this->type == self::TYPE_REPLACEMENT) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref;
 		if ($this->type == self::TYPE_CREDIT_NOTE) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref;
 		if ($this->type == self::TYPE_DEPOSIT) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref;
+		if ($this->type == self::TYPE_SITUATION) $label=$langs->transnoentitiesnoconv("ShowInvoiceSituation").': '.$this->ref;
 		if ($moretitle) $label.=' - '.$moretitle;
 
 		$linkstart='<a href="'.$url.'">';
@@ -863,6 +910,7 @@ class Facture extends CommonInvoice
 		$sql.= ', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf';
 		$sql.= ', f.fk_facture_source';
 		$sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams';
+		$sql.= ', f.situation_cycle_ref, f.situation_counter, f.situation_final';
 		$sql.= ', f.fk_account';
 		$sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
 		$sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc';
@@ -923,7 +971,9 @@ class Facture extends CommonInvoice
 				$this->user_author			= $obj->fk_user_author;
 				$this->user_valid			= $obj->fk_user_valid;
 				$this->modelpdf				= $obj->model_pdf;
-
+				$this->situation_cycle_ref  = $obj->situation_cycle_ref;
+				$this->situation_counter    = $obj->situation_counter;
+				$this->situation_final      = $obj->situation_final;
 				$this->extraparams			= (array) json_decode($obj->extraparams, true);
 
 				if ($this->statut == 0)	$this->brouillon = 1;
@@ -974,6 +1024,7 @@ class Facture extends CommonInvoice
 		$this->lines=array();
 
 		$sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.tva_tx, ';
+		$sql .= ' l.situation_percent, l.fk_prev_id,';
 		$sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice,';
 		$sql.= ' l.rang, l.special_code,';
 		$sql.= ' l.date_start as date_start, l.date_end as date_end,';
@@ -1033,6 +1084,8 @@ class Facture extends CommonInvoice
 				$line->rang				= $objp->rang;
 				$line->special_code		= $objp->special_code;
 				$line->fk_parent_line	= $objp->fk_parent_line;
+				$line->situation_percent= $objp->situation_percent;
+				$line->fk_prev_id       = $objp->fk_prev_id;
 
 				$this->lines[$i] = $line;
 
@@ -1073,6 +1126,17 @@ class Facture extends CommonInvoice
 		if (isset($this->note_public)) $this->note_public=trim($this->note_public);
 		if (isset($this->modelpdf)) $this->modelpdf=trim($this->modelpdf);
 		if (isset($this->import_key)) $this->import_key=trim($this->import_key);
+		if (empty($this->situation_cycle_ref)) {
+			$this->situation_cycle_ref = 'null';
+		}
+
+		if (empty($this->situation_counter)) {
+			$this->situation_counter = 'null';
+		}
+
+		if (empty($this->situation_final)) {
+			$this->situation_final = '0';
+		}
 
 		// Check parameters
 		// Put here code to add control on parameters values
@@ -1110,7 +1174,10 @@ class Facture extends CommonInvoice
 		$sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").",";
 		$sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").",";
 		$sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").",";
-		$sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null")."";
+		$sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null");
+		$sql.= ", situation_cycle_ref=".$this->situation_cycle_ref;
+		$sql.= ", situation_counter=".$this->situation_counter;
+		$sql.= ", situation_final=".$this->situation_final;
 
 		$sql.= " WHERE rowid=".$this->id;
 
@@ -1808,6 +1875,15 @@ class Facture extends CommonInvoice
 				$this->statut=1;
 				$this->brouillon=0;
 				$this->date_validation=$now;
+				$i = 0;
+				$final = True;
+				while ($i < count($this->lines) && $final == True) {
+					$final = ($this->lines[$i]->situation_percent == 100);
+					$i++;
+				}
+				if ($final) {
+					$this->setFinal();
+				}
 			}
 		}
 		else
@@ -1947,9 +2023,11 @@ class Facture extends CommonInvoice
 	 * 		@param		int			$pa_ht				Buying price of line (to calculate margin) or ''
 	 * 		@param		string		$label				Label of the line (deprecated, do not use)
 	 *		@param		array		$array_option		extrafields array
+	 *      @param      int         $situation_percent  Situation advance percentage
+	 *      @param      int         $fk_prev_id         Previous situation line id reference
 	 *    	@return    	int             				<0 if KO, Id of line if OK
 	 */
-	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=self::TYPE_STANDARD, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_option=0)
+	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $date_start='', $date_end='', $ventil=0, $info_bits=0, $fk_remise_except='', $price_base_type='HT', $pu_ttc=0, $type=self::TYPE_STANDARD, $rang=-1, $special_code=0, $origin='', $origin_id=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='', $array_option=0, $situation_percent=0, $fk_prev_id='')
 	{
 		global $mysoc, $conf, $langs;
 
@@ -1966,6 +2044,8 @@ class Facture extends CommonInvoice
 		if (empty($txlocaltax1)) $txlocaltax1=0;
 		if (empty($txlocaltax2)) $txlocaltax2=0;
 		if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
+		if (empty($fk_prev_id)) $fk_prev_id = 'null';
+		if (is_null($situation_percent) || $situation_percent > 100) $situation_percent = 100;
 
 		$remise_percent=price2num($remise_percent);
 		$qty=price2num($qty);
@@ -1999,7 +2079,7 @@ class Facture extends CommonInvoice
 
 			$localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty, $mysoc);
 
-			$tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type);
+			$tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, $situation_percent);
 
 			$total_ht  = $tabprice[0];
 			$total_tva = $tabprice[1];
@@ -2060,6 +2140,8 @@ class Facture extends CommonInvoice
 			$this->line->fk_parent_line=$fk_parent_line;
 			$this->line->origin=$origin;
 			$this->line->origin_id=$origin_id;
+			$this->line->situation_percent = $situation_percent;
+			$this->line->fk_prev_id = $fk_prev_id;
 
 			// infos marge
 			$this->line->fk_fournprice = $fk_fournprice;
@@ -2121,9 +2203,10 @@ class Facture extends CommonInvoice
 	 * 	@param		string		$label				Label of the line (deprecated, do not use)
 	 * 	@param		int			$special_code		Special code (also used by externals modules!)
      *  @param		array		$array_option		extrafields array
+	 * @param       int         $situation_percent  Situation advance percentage
 	 *  @return    	int             				< 0 if KO, > 0 if OK
 	 */
-	function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type= self::TYPE_STANDARD, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_option=0)
+	function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type= self::TYPE_STANDARD, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_option=0, $situation_percent=0)
 	{
 		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
 
@@ -2139,6 +2222,8 @@ class Facture extends CommonInvoice
 			if (empty($qty)) $qty=0;
 			if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
 			if (empty($special_code) || $special_code == 3) $special_code=0;
+			if ($situation_percent > 100 || is_null($situation_percent) || $situation_percent == "") $situation_percent = 100;
+
 
 			$remise_percent	= price2num($remise_percent);
 			$qty			= price2num($qty);
@@ -2157,7 +2242,7 @@ class Facture extends CommonInvoice
 
 			$localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty, $mysoc);
 
-			$tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type,'',$localtaxes_type);
+			$tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type,'',$localtaxes_type, $situation_percent);
 			$total_ht  = $tabprice[0];
 			$total_tva = $tabprice[1];
 			$total_ttc = $tabprice[2];
@@ -2205,6 +2290,8 @@ class Facture extends CommonInvoice
 			$this->line->product_type		= $type;
 			$this->line->fk_parent_line		= $fk_parent_line;
 			$this->line->skip_update_total	= $skip_update_total;
+			$this->line->situation_percent  = $situation_percent;
+
 
 			// infos marge
 			if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) {
@@ -2247,6 +2334,28 @@ class Facture extends CommonInvoice
 		}
 	}
 
+	/**
+	 * @param FactureLigne $line Invoice line
+	 * @param int $percent
+	 */
+	function update_percent($line, $percent)
+	{
+		include_once(DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php');
+
+		// Cap percentages to 100
+		if ($percent > 100) $percent = 100;
+		$line->situation_percent = $percent;
+		$tabprice = calcul_price_total($line->qty, $line->subprice, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->product_type, 'HT', 0, 0, '', '', $percent);
+		$line->total_ht = $tabprice[0];
+		$line->total_tva = $tabprice[1];
+		$line->total_ttc = $tabprice[2];
+		$line->total_localtax1 = $tabprice[9];
+		$line->total_localtax2 = $tabprice[10];
+		$line->update();
+		$this->update_price(1);
+		$this->db->commit();
+	}
+
 	/**
 	 *	Delete line in database
 	 *
@@ -2647,6 +2756,10 @@ class Facture extends CommonInvoice
 			if ($maxfacnumber == '' && $ventilExportCompta == 0) return 1;
 			// If invoice to delete is last one and not already dispatched, we can delete
 			if ($maxfacnumber == $this->ref && $ventilExportCompta == 0) return 1;
+			if ($this->situation_cycle_ref) {
+				$last = $this->is_last_in_cycle();
+				return $last;
+			}
 		}
 		else if ($this->statut == 0 && $facref == 'PROV') // Si facture brouillon et provisoire
 		{
@@ -3206,6 +3319,7 @@ class Facture extends CommonInvoice
 	{
 		$sql = 'SELECT l.rowid, l.label as custom_label, l.description, l.fk_product, l.product_type, l.qty, l.tva_tx,';
 		$sql.= ' l.fk_remise_except, l.localtax1_tx, l.localtax2_tx,';
+		$sql .= ' l.situation_percent, l.fk_prev_id,';
 		$sql.= ' l.remise_percent, l.subprice, l.info_bits, l.rang, l.special_code, l.fk_parent_line,';
 		$sql.= ' l.total_ht, l.total_tva, l.total_ttc, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht,';
 		$sql.= ' l.date_start, l.date_end,';
@@ -3247,6 +3361,8 @@ class Facture extends CommonInvoice
 				$this->lines[$i]->total_tva			= $obj->total_tva;
 				$this->lines[$i]->total_ttc			= $obj->total_ttc;
 				$this->lines[$i]->fk_parent_line	= $obj->fk_parent_line;
+				$this->lines[$i]->situation_percent = $obj->situation_percent;
+				$this->lines[$i]->fk_prev_id        = $obj->fk_prev_id;
 				$this->lines[$i]->special_code		= $obj->special_code;
 				$this->lines[$i]->rang				= $obj->rang;
 				$this->lines[$i]->date_start		= $this->db->jdate($obj->date_start);
@@ -3304,11 +3420,118 @@ class Facture extends CommonInvoice
 		return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
 	}
 
+	/**
+	 * Gets the smallest reference available for a new cycle
+	 *
+	 * @return int >= 1 if OK, -1 if error
+	 *
+	 *
+	 */
+	function newCycle()
+	{
+		$sql = 'SELECT max(situation_cycle_ref) FROM ' . MAIN_DB_PREFIX . 'facture';
+		$resql = $this->db->query($sql);
+		if ($resql) {
+			if ($resql->num_rows > 0) {
+				$res = $this->db->fetch_array($resql);
+				$ref = $res['max(situation_cycle_ref)'];
+				$ref++;
+			} else {
+				$ref = 1;
+			}
+			$this->db->free($resql);
+			return $ref;
+		} else {
+			$this->error = $this->db->error();
+			dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR);
+			return -1;
+		}
+	}
 
+	/**
+	 * Checks if the invoice is the first of a cycle
+	 *
+	 */
+	function is_first()
+	{
+		return ($this->situation_counter == 1);
+	}
 
-}
+	/**
+	 * Returns an array containing the previous situations as Facture objects
+	 *
+	 */
+	function get_prev_sits()
+	{
+
+		$sql = 'SELECT rowid FROM ' . MAIN_DB_PREFIX . 'facture';
+		$sql .= ' where situation_cycle_ref = ' . $this->situation_cycle_ref;
+		$sql .= ' and situation_counter < ' . $this->situation_counter;
+		$resql = $this->db->query($sql);
+		$res = array();
+		if ($resql && $resql->num_rows > 0) {
+			while ($row = $this->db->fetch_object($resql)) {
+				$id = $row->rowid;
+				$situation = new Facture($this->db);
+				$situation->fetch($id);
+				$res[] = $situation;
+			}
+		} else {
+			$this->error = $this->db->error();
+			dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR);
+			return -1;
+		}
+
+		return $res;
+	}
+
+	/**
+	 * Sets the invoice as a final situation
+	 *
+	 * @return int 1 if ok, -1 if error
+	 */
+	function setFinal()
+	{
+		global $conf, $langs, $user;
+		$this->situation_final = 1;
+		$sql = 'update ' . MAIN_DB_PREFIX . 'facture set situation_final = ' . $this->situation_final . ' where rowid = ' . $this->id;
+		$resql = $this->db->query($sql);
+		if ($resql) {
+			// FIXME: call triggers?
+			$this->db->commit();
+			return 1;
+		} else {
+			$this->error = $this->db->error();
+			dol_syslog(get_class($this) . "::update Error setFinal " . $sql, LOG_ERR);
+			$this->db->rollback();
+			return -1;
+		}
+	}
 
+	/**
+	 * Checks if the invoice is the last in its cycle
+	 *
+	 * @return int 0 or 1 if OK, -1 if error
+	 *
+	 */
+
+	function is_last_in_cycle()
+	{
+		$sql = 'SELECT max(situation_counter) FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_cycle_ref = ' . $this->situation_cycle_ref;
+		$resql = $this->db->query($sql);
 
+		if ($resql && $resql->num_rows > 0) {
+			$res = $this->db->fetch_array($resql);
+			$last = $res['max(situation_counter)'];
+			return ($last == $this->situation_counter);
+		} else {
+			$this->error = $this->db->error();
+			dol_syslog(get_class($this) . "::select Error " . $this->error, LOG_ERR);
+			$this->db->rollback();
+			return -1;
+		}
+	}
+}
 
 /**
  *	Class to manage invoice lines.
@@ -3391,6 +3614,16 @@ class FactureLigne extends CommonInvoiceLine
 
 	var $skip_update_total; // Skip update price total for special lines
 
+	/**
+	 * @var int Situation advance percentage
+	 */
+	public $situation_percent;
+
+	/**
+	 * @var int Previous situation line id reference
+	 */
+	public $fk_prev_id;
+
 	/**
 	 *  Constructor
 	 *
@@ -3414,6 +3647,7 @@ class FactureLigne extends CommonInvoiceLine
 		$sql.= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,';
 		$sql.= ' fd.info_bits, fd.special_code, fd.total_ht, fd.total_tva, fd.total_ttc, fd.total_localtax1, fd.total_localtax2, fd.rang,';
 		$sql.= ' fd.fk_code_ventilation,';
+		$sql.= ' fd.situation_percent, fd.fk_prev_id,';
 		$sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc';
 		$sql.= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd';
 		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid';
@@ -3461,6 +3695,9 @@ class FactureLigne extends CommonInvoiceLine
 			$this->product_label		= $objp->product_libelle;
 			$this->product_desc			= $objp->product_desc;
 
+			$this->situation_percent    = $objp->situation_percent;
+			$this->fk_prev_id           = $objp->fk_prev_id;
+
 			$this->db->free($result);
 		}
 		else
@@ -3498,6 +3735,8 @@ class FactureLigne extends CommonInvoiceLine
 		if (empty($this->subprice)) $this->subprice=0;
 		if (empty($this->special_code)) $this->special_code=0;
 		if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
+		if (empty($this->fk_prev_id)) $this->fk_prev_id = 'null';
+		if (empty($this->situation_percent)) $this->situation_percent = 0;
 
 		if (empty($this->pa_ht)) $this->pa_ht=0;
 
@@ -3541,7 +3780,8 @@ class FactureLigne extends CommonInvoiceLine
 		$sql.= ' fk_product, product_type, remise_percent, subprice, fk_remise_except,';
 		$sql.= ' date_start, date_end, fk_code_ventilation, ';
 		$sql.= ' rang, special_code, fk_product_fournisseur_price, buy_price_ht,';
-		$sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2)';
+		$sql.= ' info_bits, total_ht, total_tva, total_ttc, total_localtax1, total_localtax2,';
+		$sql.= ' situation_percent, fk_prev_id)';
 		$sql.= " VALUES (".$this->fk_facture.",";
 		$sql.= " ".($this->fk_parent_line>0?"'".$this->fk_parent_line."'":"null").",";
 		$sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").",";
@@ -3570,6 +3810,8 @@ class FactureLigne extends CommonInvoiceLine
 		$sql.= " ".price2num($this->total_ttc).",";
 		$sql.= " ".price2num($this->total_localtax1).",";
 		$sql.= " ".price2num($this->total_localtax2);
+		$sql .= ", " . $this->situation_percent;
+		$sql .= ", " . $this->fk_prev_id;
 		$sql.= ')';
 
 		dol_syslog(get_class($this)."::insert", LOG_DEBUG);
@@ -3687,6 +3929,7 @@ class FactureLigne extends CommonInvoiceLine
 		if (empty($this->special_code)) $this->special_code=0;
 		if (empty($this->product_type)) $this->product_type=0;
 		if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
+		if (is_null($this->situation_percent)) $this->situation_percent=100;
 
 		// Check parameters
 		if ($this->product_type < 0) return -1;
@@ -3732,6 +3975,7 @@ class FactureLigne extends CommonInvoiceLine
 		$sql.= " , buy_price_ht='".price2num($this->pa_ht)."'";
 		$sql.= ",fk_parent_line=".($this->fk_parent_line>0?$this->fk_parent_line:"null");
 		if (! empty($this->rang)) $sql.= ", rang=".$this->rang;
+		$sql .= ", situation_percent=" . $this->situation_percent;
 		$sql.= " WHERE rowid = ".$this->rowid;
 
 		dol_syslog(get_class($this)."::update", LOG_DEBUG);
@@ -3846,5 +4090,29 @@ class FactureLigne extends CommonInvoiceLine
 			return -2;
 		}
 	}
-}
 
+	/**
+	 * Returns situation_percent of the previous line
+	 *
+	 * @return int >= 0
+	 */
+
+	function get_prev_progress()
+	{
+		if (is_null($this->fk_prev_id) || empty($this->fk_prev_id) || $this->fk_prev_id == "") {
+			return 0;
+		} else {
+			$sql = 'SELECT situation_percent FROM ' . MAIN_DB_PREFIX . 'facturedet WHERE rowid=' . $this->fk_prev_id;
+			$resql = $this->db->query($sql);
+			if ($resql && $resql->num_rows > 0) {
+				$res = $this->db->fetch_array($resql);
+				return $res['situation_percent'];
+			} else {
+				$this->error = $this->db->error();
+				dol_syslog(get_class($this) . "::select Error " . $this->error, LOG_ERR);
+				$this->db->rollback();
+				return -1;
+			}
+		}
+	}
+}
diff --git a/htdocs/compta/facture/impayees.php b/htdocs/compta/facture/impayees.php
index a010e7d74011ad39929659a115881cc95cceedef..0c6b2af84f0f0836847f1ed1f1112fb2054b6b5f 100644
--- a/htdocs/compta/facture/impayees.php
+++ b/htdocs/compta/facture/impayees.php
@@ -3,6 +3,8 @@
  * Copyright (C) 2004      Eric Seigne          <eric.seigne@ryxeo.com>
  * Copyright (C) 2004-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
+ * Copyright (C) 2012      Cédric Salvador      <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2014      Raphaël Doursenaud   <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -408,7 +410,7 @@ $sql.= ",".MAIN_DB_PREFIX."facture as f";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid=pf.fk_facture ";
 $sql.= " WHERE f.fk_soc = s.rowid";
 $sql.= " AND f.entity = ".$conf->entity;
-$sql.= " AND f.type IN (0,1,3) AND f.fk_statut = 1";
+$sql.= " AND f.type IN (0,1,3,5) AND f.fk_statut = 1";
 $sql.= " AND f.paye = 0";
 if ($option == 'late') $sql.=" AND f.date_lim_reglement < '".$db->idate(dol_now() - $conf->facture->client->warning_delay)."'";
 if (! $user->rights->societe->client->voir && ! $socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php
index e249d3fe55479afd8a282a75a0eb70329efeb8fb..9fd0d411d8ee06afae1004a2cb4871bd5de9b433 100644
--- a/htdocs/compta/journal/sellsjournal.php
+++ b/htdocs/compta/journal/sellsjournal.php
@@ -4,7 +4,9 @@
  * Copyright (C) 2011-2014	Juanjo Menent		<jmenent@2byte.es>
  * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
  * Copyright (C) 2011-2012  Alexandre Spangaro	<alexandre.spangaro@gmail.com>
+ * Copyright (C) 2012       Cédric Salvador     <csalvador@gpcsolutions.fr>
  * Copyright (C) 2013		Marcos García		<marcosgdf@gmail.com>
+ * Copyright (C) 2014       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -101,7 +103,7 @@ $p = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY);
 $idpays = $p[0];
 
 $sql = "SELECT f.rowid, f.facnumber, f.type, f.datef, f.ref_client,";
-$sql.= " fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2,";
+$sql.= " fd.product_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.total_ttc, fd.localtax1_tx, fd.localtax2_tx, fd.total_localtax1, fd.total_localtax2, fd.rowid as id, fd.situation_percent,";
 $sql.= " s.rowid as socid, s.nom as name, s.code_compta, s.client,";
 $sql.= " p.rowid as pid, p.ref as pref, p.accountancy_code_sell,";
 $sql.= " ct.accountancy_code_sell as account_tva, ct.recuperableonly";
@@ -112,8 +114,8 @@ $sql.= " JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_tva ct ON fd.tva_tx = ct.taux AND fd.info_bits = ct.recuperableonly AND ct.fk_pays = '".$idpays."'";
 $sql.= " WHERE f.entity = ".$conf->entity;
 $sql.= " AND f.fk_statut > 0";
-if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-else $sql.= " AND f.type IN (0,1,2,3)";
+if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+else $sql.= " AND f.type IN (0,1,2,3,5)";
 $sql.= " AND fd.product_type IN (0,1)";
 if ($date_start && $date_end) $sql .= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
 $sql.= " ORDER BY f.rowid";
@@ -157,6 +159,16 @@ if ($result)
 		$account_localtax2=getLocalTaxesFromRate($obj->tva_tx, 2, $obj->thirdparty, $mysoc);
 		$compta_localtax2= (! empty($account_localtax2[3])?$account_localtax2[3]:$langs->trans("CodeNotDef"));
 
+		// Situation invoices handling
+		$line = new FactureLigne($db);
+		$line->fetch($obj->id);
+		$prev_progress = $line->get_prev_progress();
+		if ($obj->situation_percent == 0) { // Avoid divide by 0
+			$situation_ratio = 0;
+		} else {
+			$situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
+		}
+
     	//la ligne facture
    		$tabfac[$obj->rowid]["date"] = $obj->datef;
    		$tabfac[$obj->rowid]["ref"] = $obj->facnumber;
@@ -166,9 +178,9 @@ if ($result)
    		if (! isset($tabtva[$obj->rowid][$compta_tva])) $tabtva[$obj->rowid][$compta_tva]=0;
    		if (! isset($tablocaltax1[$obj->rowid][$compta_localtax1])) $tablocaltax1[$obj->rowid][$compta_localtax1]=0;
    		if (! isset($tablocaltax2[$obj->rowid][$compta_localtax2])) $tablocaltax2[$obj->rowid][$compta_localtax2]=0;
-   		$tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc;
-   		$tabht[$obj->rowid][$compta_prod] += $obj->total_ht;
-   		if($obj->recuperableonly != 1) $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
+		$tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc * $situation_ratio;
+		$tabht[$obj->rowid][$compta_prod] += $obj->total_ht * $situation_ratio;
+		if($obj->recuperableonly != 1) $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva * $situation_ratio;
    		$tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1;
    		$tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2;
    		$tabcompany[$obj->rowid]=array('id'=>$obj->socid, 'name'=>$obj->name, 'client'=>$obj->client);
diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
index 0ccf0dee6bfc06174afc620d060cda6c096330b0..fabf656c89543bef36bce13292fb799de24e5fb1 100644
--- a/htdocs/compta/paiement.php
+++ b/htdocs/compta/paiement.php
@@ -4,6 +4,8 @@
  * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
  * Copyright (C) 2005-2012 Regis Houssin         <regis.houssin@capnetworks.com>
  * Copyright (C) 2007      Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
+ * Copyright (C) 2012      Cédric Salvador       <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2014      Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2014		Teddy Andreotti			<125155@supinfo.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -469,7 +471,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
         $sql.= ' AND f.fk_statut = 1'; // Statut=0 => not validated, Statut=2 => canceled
         if ($facture->type != 2)
         {
-            $sql .= ' AND type IN (0,1,3)';	// Standard invoice, replacement, deposit
+            $sql .= ' AND type IN (0,1,3,5)';	// Standard invoice, replacement, deposit, situation
         }
         else
         {
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index 95503db6ff97aeea6d5f3497b33ae83e8cc4524b..6c3743f70a60f09a0538d4b79ffa5667dab6d526 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -2,6 +2,8 @@
 /* Copyright (C) 2002-2004 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
  * Copyright (C) 2004-2010 Laurent Destailleur   <eldy@users.sourceforge.net>
  * Copyright (C)      2005 Marc Barilley / Ocebo <marc@ocebo.com>
+ * Copyright (C) 2012      Cédric Salvador       <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2014      Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2014      Marcos García <marcosgdf@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -212,13 +214,14 @@ class Paiement extends CommonObject
 
                             //Invoice types that are eligible for changing status to paid
 							$affected_types = array(
-								0,
-								1,
-								2,
-								3
+								Facture::TYPE_STANDARD,
+								Facture::TYPE_REPLACEMENT,
+								Facture::TYPE_CREDIT_NOTE,
+								Facture::TYPE_DEPOSIT,
+								Facture::TYPE_SITUATION
 							);
 
-                            if (!in_array($invoice->type, $affected_types)) dol_syslog("Invoice ".$facid." is not a standard, nor replacement invoice, nor credit note, nor deposit invoice. We do nothing more.");
+                            if (!in_array($invoice->type, $affected_types)) dol_syslog("Invoice ".$facid." is not a standard, nor replacement invoice, nor credit note, nor deposit invoice, nor situation invoice. We do nothing more.");
                             else if ($remaintopay) dol_syslog("Remain to pay for invoice ".$facid." not null. We do nothing more.");
                             else if ($mustwait) dol_syslog("There is ".$mustwait." differed payment to process, we do nothing more.");
                             else
diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php
index 9122ece2ed9216cf205732f3c8dd303985b41296..8c522df75d4dd10008bf99b9785c1646432bdc63 100644
--- a/htdocs/compta/resultat/clientfourn.php
+++ b/htdocs/compta/resultat/clientfourn.php
@@ -2,6 +2,8 @@
 /* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  * Copyright (C) 2004-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
+ * Copyright (C) 2012      Cédric Salvador      <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014 Raphaël Dourseanud   <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2014	   Ferran Marcet        <fmarcet@2byte.es>
  * Copyright (C) 2014	   Juanjo Menent        <jmenent@2byte.es>
  * Copyright (C) 2014	   Florian Henry        <florian.henry@open-concept.pro>
@@ -166,9 +168,9 @@ if ($modecompta == 'CREANCES-DETTES')
     $sql.= " WHERE f.fk_soc = s.rowid";
     $sql.= " AND f.fk_statut IN (1,2)";
     if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
-    	$sql.= " AND f.type IN (0,1,2)";
+    	$sql.= " AND f.type IN (0,1,2,5)";
 	else
-		$sql.= " AND f.type IN (0,1,2,3)";
+		$sql.= " AND f.type IN (0,1,2,3,5)";
     if (! empty($date_start) && ! empty($date_end))
     	$sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
 }
@@ -693,9 +695,9 @@ if ($modecompta == 'CREANCES-DETTES')
     $sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
     $sql.= " WHERE f.fk_statut IN (1,2)";
     if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS))
-    	$sql.= " AND f.type IN (0,1,2)";
+    	$sql.= " AND f.type IN (0,1,2,5)";
 	else
-		$sql.= " AND f.type IN (0,1,2,3)";
+		$sql.= " AND f.type IN (0,1,2,3,5)";
     if (! empty($date_start) && ! empty($date_end))
     	$sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
     $sql.= " AND f.entity = ".$conf->entity;
diff --git a/htdocs/compta/resultat/index.php b/htdocs/compta/resultat/index.php
index b586241c11ece86fd053ffc7eb8a35e3252d6d41..ec29d25a76ecaca214a0f8aa4cb0171bc6d8e09a 100644
--- a/htdocs/compta/resultat/index.php
+++ b/htdocs/compta/resultat/index.php
@@ -103,8 +103,8 @@ if ($modecompta == 'CREANCES-DETTES')
 	$sql.= ", ".MAIN_DB_PREFIX."facture as f";
 	$sql.= " WHERE f.fk_soc = s.rowid";
 	$sql.= " AND f.fk_statut IN (1,2)";
-	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-	else $sql.= " AND f.type IN (0,1,2,3)";
+	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+	else $sql.= " AND f.type IN (0,1,2,3,5)";
 }
 else
 {
@@ -246,8 +246,8 @@ if ($modecompta == 'CREANCES-DETTES')
 	$sql = "SELECT sum(f.tva) as amount, date_format(f.datef,'%Y-%m') as dm";
 	$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
 	$sql.= " WHERE f.fk_statut IN (1,2)";
-	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-	else $sql.= " AND f.type IN (0,1,2,3)";
+	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+	else $sql.= " AND f.type IN (0,1,2,3,5)";
 	$sql.= " AND f.entity = ".$conf->entity;
 	$sql.= " GROUP BY dm";
 
diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php
index 8263dc76cb8b4ed021ac8214e2e8cc6b697e392c..61f0bbb590d44411aa3897e1f06f46eec3fff428 100644
--- a/htdocs/compta/stats/cabyprodserv.php
+++ b/htdocs/compta/stats/cabyprodserv.php
@@ -193,9 +193,9 @@ if ($modecompta == 'CREANCES-DETTES')
 	$sql.= " AND l.fk_facture = f.rowid";
     $sql.= " AND f.fk_statut in (1,2)";
     if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
-	$sql.= " AND f.type IN (0,1,2)";
+	$sql.= " AND f.type IN (0,1,2,5)";
     } else {
-	$sql.= " AND f.type IN (0,1,2,3)";
+	$sql.= " AND f.type IN (0,1,2,3,5)";
     }
     if ($date_start && $date_end) {
 	$sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
diff --git a/htdocs/compta/stats/cabyuser.php b/htdocs/compta/stats/cabyuser.php
index e88d370a0c6b93d1ed2f8e02defd52bed871c08d..066967cc2c3f97da102b707d3b3d379cb9b2200d 100644
--- a/htdocs/compta/stats/cabyuser.php
+++ b/htdocs/compta/stats/cabyuser.php
@@ -178,9 +178,9 @@ if ($modecompta == 'CREANCES-DETTES') {
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.fk_user_author = u.rowid";
     $sql.= " WHERE f.fk_statut in (1,2)";
 	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
-	    $sql.= " AND f.type IN (0,1,2)";
+	    $sql.= " AND f.type IN (0,1,2,5)";
 	    } else {
-	    $sql.= " AND f.type IN (0,1,2,3)";
+	    $sql.= " AND f.type IN (0,1,2,3,5)";
 	}
 	if ($date_start && $date_end) {
 	    $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
diff --git a/htdocs/compta/stats/casoc.php b/htdocs/compta/stats/casoc.php
index 1d34f78a181ca76071585092cc3137fd8e54df7c..a4c4663dc40052c0ffc652d262c0e99854721a65 100644
--- a/htdocs/compta/stats/casoc.php
+++ b/htdocs/compta/stats/casoc.php
@@ -191,9 +191,9 @@ if ($modecompta == 'CREANCES-DETTES') {
 	}
 	$sql.= " WHERE f.fk_statut in (1,2)";
 	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
-	    $sql.= " AND f.type IN (0,1,2)";
+	    $sql.= " AND f.type IN (0,1,2,5)";
 	} else {
-	    $sql.= " AND f.type IN (0,1,2,3)";
+	    $sql.= " AND f.type IN (0,1,2,3,5)";
 	}
 	$sql.= " AND f.fk_soc = s.rowid";
 	if ($date_start && $date_end) {
diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php
index cfd816c29b6b1ddd0dba75d8ddeda9e338471cf4..f704ca90f73ed400c1c9c9ded356219554e0caba 100644
--- a/htdocs/compta/stats/index.php
+++ b/htdocs/compta/stats/index.php
@@ -91,8 +91,8 @@ if ($modecompta == 'CREANCES-DETTES')
 	$sql  = "SELECT date_format(f.datef,'%Y-%m') as dm, sum(f.total) as amount, sum(f.total_ttc) as amount_ttc";
 	$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
 	$sql.= " WHERE f.fk_statut in (1,2)";
-	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-	else $sql.= " AND f.type IN (0,1,2,3)";
+	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+	else $sql.= " AND f.type IN (0,1,2,3,5)";
 }
 else
 {
diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php
index 90ad3e196e3a627cf39c49b1eb9863b9291778c2..991601a4fbd3ba5c82a9d50a84a9bcaf0f026115 100644
--- a/htdocs/core/class/commoninvoice.class.php
+++ b/htdocs/core/class/commoninvoice.class.php
@@ -1,5 +1,7 @@
 <?php
-/* Copyright (C) 2012 Regis Houssin  <regis.houssin@capnetworks.com>
+/* Copyright (C) 2012       Regis Houssin       <regis.houssin@capnetworks.com>
+ * Copyright (C) 2012       Cédric Salvador     <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014  Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -143,11 +145,12 @@ abstract class CommonInvoice extends CommonObject
 	function getLibType()
 	{
 		global $langs;
-		if ($this->type == 0) return $langs->trans("InvoiceStandard");
-		if ($this->type == 1) return $langs->trans("InvoiceReplacement");
-		if ($this->type == 2) return $langs->trans("InvoiceAvoir");
-		if ($this->type == 3) return $langs->trans("InvoiceDeposit");
-		if ($this->type == 4) return $langs->trans("InvoiceProForma");
+		if ($this->type == Facture::TYPE_STANDARD) return $langs->trans("InvoiceStandard");
+		if ($this->type == Facture::TYPE_REPLACEMENT) return $langs->trans("InvoiceReplacement");
+		if ($this->type == Facture::TYPE_CREDIT_NOTE) return $langs->trans("InvoiceAvoir");
+		if ($this->type == Facture::TYPE_DEPOSIT) return $langs->trans("InvoiceDeposit");
+		if ($this->type == Facture::TYPE_PROFORMA) return $langs->trans("InvoiceProForma");
+		if ($this->type == Facture::TYPE_SITUATION) return $langs->trans("InvoiceSituation");
 		return $langs->trans("Unknown");
 	}
 
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 0dedb135298610778354952281ca7cdbed65d674..81a4946208a40a87bbed00c550c88c95905bbbcc 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -7,6 +7,7 @@
  * Copyright (C) 2012-2013 Christophe Battarel  <christophe.battarel@altairis.fr>
  * Copyright (C) 2011-2014 Philippe Grand	    <philippe.grand@atoo-net.com>
  * Copyright (C) 2012-2014 Marcos García        <marcosgdf@gmail.com>
+ * Copyright (C) 2012-2014 Raphaël Doursenaud   <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -1740,6 +1741,19 @@ abstract class CommonObject
             // Add revenue stamp to total
             $this->total_ttc       += isset($this->revenuestamp)?$this->revenuestamp:0;
 
+			// Situations totals
+			if ($this->situation_cycle_ref && $this->situation_counter > 1) {
+				$prev_sits = $this->get_prev_sits();
+
+				foreach ($prev_sits as $sit) {
+					$this->total_ht -= $sit->total_ht;
+					$this->total_tva -= $sit->total_tva;
+					$this->total_localtax1 -= $sit->total_localtax1;
+					$this->total_localtax2 -= $sit->total_localtax2;
+					$this->total_ttc -= $sit->total_ttc;
+				}
+			}
+
             $this->db->free($resql);
 
             // Now update global field total_ht, total_ttc and tva
@@ -2568,6 +2582,10 @@ abstract class CommonObject
 		// Reduction short
 		print '<td align="right" width="50"><label for="remise_percent">'.$langs->trans('ReductionShort').'</label></td>';
 
+		if ($this->situation_cycle_ref) {
+			print '<td align="right" width="50"><label for="progress">' . $langs->trans('Progress') . '</label></td>';
+		}
+
 		if (! empty($conf->margin->enabled) && empty($user->societe_id))
 		{
 			if ($conf->global->MARGIN_TYPE == "1")
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 491e590403cb993b254bcbc736b61a22f4d7539a..9ce830ac513969804aa505ec5d1dc2f06b4b3792 100755
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -13,7 +13,8 @@
  * Copyright (C) 2010-2014 Philippe Grand        <philippe.grand@atoo-net.com>
  * Copyright (C) 2011      Herve Prot            <herve.prot@symeos.com>
  * Copyright (C) 2012-2014 Marcos García         <marcosgdf@gmail.com>
- * Copyright (C) 2013      Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
+ * Copyright (C) 2012      Cedric Salvador       <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014 Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2014      Alexandre Spangaro    <alexandre.spangaro@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -2657,6 +2658,57 @@ class Form
         }
     }
 
+	/**
+	 * Creates HTML last in cycle situation invoices selector
+	 *
+	 * @param       string  $selected   Preselected ID
+	 * @param       int     $socid      Company ID
+	 *
+	 * @return    string                     HTML select
+	 */
+	function load_situation_invoices($selected = '', $socid)
+	{
+		global $langs;
+
+		$langs->load('bills');
+
+		$opt = '<option value ="" selected="selected"></option>';
+		$sql = 'SELECT rowid, facnumber, situation_cycle_ref, situation_counter, situation_final, fk_soc FROM ' . MAIN_DB_PREFIX . 'facture WHERE situation_counter>=1';
+		$sql .= ' order by situation_cycle_ref, situation_counter desc';
+		$resql = $this->db->query($sql);
+		if ($resql && $this->db->num_rows($resql) > 0) {
+			// Last seen cycle
+			$ref = 0;
+			while ($res = $this->db->fetch_array($resql, MYSQL_NUM)) {
+				//Same company ?
+				if ($socid == $res[5]) {
+					//Same cycle ?
+					if ($res[2] != $ref) {
+						// Just seen this cycle
+						$ref = $res[2];
+						//not final ?
+						if ($res[4] != 1) {
+							//Not prov?
+							if (substr($res[1], 1, 4) != 'PROV') {
+								if ($selected == $res[0]) {
+									$opt .= '<option value="' . $res[0] . '" selected="selected">' . $res[1] . '</option>';
+								} else {
+									$opt .= '<option value="' . $res[0] . '">' . $res[1] . '</option>';
+								}
+							}
+						}
+					}
+				}
+			}
+		} else {
+				dol_syslog("Error sql=" . $sql . ", error=" . $this->error, LOG_ERR);
+		}
+		if ($opt == '<option value ="" selected="selected"></option>') {
+			$opt = '<option value ="0" selected="selected">' . $langs->trans('NoSituations') . '</option>';
+		}
+		return $opt;
+	}
+
     /**
      *  Return a HTML select list of bank accounts
      *
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index 129d32fc7d9a691eebec697cb57910e252926692..4f1c8f71c5ae40fc1f2d1e8a98d6698f52a113a5 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -5,6 +5,8 @@
  * Copyright (C) 2010-2012	Regis Houssin       	<regis.houssin@capnetworks.com>
  * Copyright (C) 2010		Juanjo Menent       	<jmenent@2byte.es>
  * Copyright (C) 2012		Christophe Battarel		<christophe.battarel@altairis.fr>
+ * Copyright (C) 2012       Cédric Salvador         <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014  Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2014		Cedric GROSS			<c.gross@kreiz-it.fr>
  * Copyright (C) 2014		Teddy Andreotti			<125155@supinfo.com>
  *
@@ -1448,6 +1450,31 @@ function pdf_getlineremisepercent($object,$i,$outputlangs,$hidedetails=0)
 	}
 }
 
+/**
+ * Return line percent
+ *
+ * @param Object $object Object
+ * @param int $i Current line number
+ * @param Translate $outputlangs Object langs for output
+ * @param int $hidedetails Hide details (0=no, 1=yes, 2=just special lines)
+ * @param HookManager $hookmanager Hook manager instance
+ * @return void
+ */
+function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookmanager = null)
+{
+	if ($object->lines[$i]->special_code != 3) {
+		if (is_object($hookmanager) && (($object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line))) {
+			$special_code = $object->lines[$i]->special_code;
+			if (!empty($object->lines[$i]->fk_parent_line)) $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line);
+			$parameters = array('i' => $i, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'special_code' => $special_code);
+			$action = '';
+			return $hookmanager->executeHooks('pdf_getlineprogress', $parameters, $object, $action);    // Note that $action and $object may have been modified by some hooks
+		} else {
+			if (empty($hidedetails) || $hidedetails > 1) return $object->lines[$i]->situation_percent . '%';
+		}
+	}
+}
+
 /**
  *	Return line total excluding tax
  *
diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php
index 00144db74e5adf0357281835ac5cfbae010207cf..aa3a1e11a46141757d91216e8496d2924402ade4 100644
--- a/htdocs/core/lib/price.lib.php
+++ b/htdocs/core/lib/price.lib.php
@@ -3,6 +3,8 @@
  * Copyright (C) 2006-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
  * Copyright (C) 2010-2013 Juanjo Menent        <jmenent@2byte.es>
  * Copyright (C) 2012      Christophe Battarel  <christophe.battarel@altairis.fr>
+ * Copyright (C) 2012      Cédric Salvador      <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014 Raphaël Doursenaud   <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,6 +49,7 @@
  *		@param	int		$type						0/1=Product/service
  *		@param  Societe	$seller						Thirdparty seller (we need $seller->country_id property). Provided only if seller is the supplier, otherwise $seller will be $mysoc.
  *		@param  array	$localtaxes_array			Array with localtaxes info (loaded by getLocalTaxesFromRate function).
+ *		@param  float   $progress                   Situation invoices progress
  *		@return result[ 0=total_ht,
  *						 1=total_vat,
  *						 2=total_ttc,
@@ -64,7 +67,7 @@
  *						14=amount tax1 for total_ht_without_discount,
  *						15=amount tax2 for total_ht_without_discount]
  */
-function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '',$localtaxes_array='')
+function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller = '', $localtaxes_array='', $progress=100)
 {
 	global $conf,$mysoc,$db;
 
@@ -128,7 +131,7 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt
 		else dol_print_error($db);
 	}
 	// initialize total (may be HT or TTC depending on price_base_type)
-	$tot_sans_remise = $pu * $qty;
+	$tot_sans_remise = $pu * $qty * $progress / 100;
 	$tot_avec_remise_ligne = $tot_sans_remise       * (1 - ($remise_percent_ligne / 100));
 	$tot_avec_remise       = $tot_avec_remise_ligne * (1 - ($remise_percent_global / 100));
 
diff --git a/htdocs/core/lib/tax.lib.php b/htdocs/core/lib/tax.lib.php
index cc9478f5d6157fff7b8cecec4bba88503517f7de..1c048c7d6f592ec0e60e725fe65c591f7e2f7a53 100644
--- a/htdocs/core/lib/tax.lib.php
+++ b/htdocs/core/lib/tax.lib.php
@@ -3,6 +3,8 @@
  * Copyright (C) 2006-2007	Yannick Warnier		<ywarnier@beeznest.org>
  * Copyright (C) 2011		Regis Houssin		<regis.houssin@capnetworks.com>
  * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
+ * Copyright (C) 2012      Cédric Salvador      <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014 Raphaël Doursenaud   <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -133,8 +135,8 @@ function vat_by_thirdparty($db, $y, $date_start, $date_end, $modetax, $direction
             $sql.= " ".MAIN_DB_PREFIX."societe as s";
             $sql.= " WHERE f.entity = " . $conf->entity;
             $sql.= " AND f.fk_statut in (1,2)"; // Validated or paid (partially or completely)
-        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-        	else $sql.= " AND f.type IN (0,1,2,3)";
+        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+			else $sql.= " AND f.type IN (0,1,2,3,5)";
             if ($y && $m)
             {
                 $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
@@ -170,8 +172,8 @@ function vat_by_thirdparty($db, $y, $date_start, $date_end, $modetax, $direction
             $sql.= " FROM ".MAIN_DB_PREFIX.$invoicetable." as f, ".MAIN_DB_PREFIX.$invoicetable." as fd, ".MAIN_DB_PREFIX."societe as s";
             $sql.= " WHERE ";
             $sql.= " f.fk_statut in (2)";   // Paid (partially or completely)
-        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-        	else $sql.= " AND f.type IN (0,1,2,3)";
+        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+			else $sql.= " AND f.type IN (0,1,2,3,5)";
             if ($y && $m)
             {
                 $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
@@ -294,8 +296,8 @@ function vat_by_date($db, $y, $q, $date_start, $date_end, $modetax, $direction,
             $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid";
             $sql.= " WHERE f.entity = " . $conf->entity;
             $sql.= " AND f.fk_statut in (1,2)"; // Validated or paid (partially or completely)
-            if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-            else $sql.= " AND f.type IN (0,1,2,3)";
+            if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+			else $sql.= " AND f.type IN (0,1,2,3,5)";
             $sql.= " AND f.rowid = d.".$fk_facture;
             if ($y && $m)
             {
@@ -339,8 +341,8 @@ function vat_by_date($db, $y, $q, $date_start, $date_end, $modetax, $direction,
             $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid";
             $sql.= " WHERE f.entity = " . $conf->entity;
             $sql.= " AND f.fk_statut in (1,2)"; // Validated or paid (partially or completely)
-        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-        	else $sql.= " AND f.type IN (0,1,2,3)";
+        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+			else $sql.= " AND f.type IN (0,1,2,3,5)";
             $sql.= " AND f.rowid = d.".$fk_facture;
             if ($y && $m)
             {
@@ -452,8 +454,8 @@ function vat_by_date($db, $y, $q, $date_start, $date_end, $modetax, $direction,
             $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid";
             $sql.= " WHERE f.entity = " . $conf->entity;
             $sql.= " AND f.fk_statut in (1,2)"; // Validated or paid (partially or completely)
-        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-        	else $sql.= " AND f.type IN (0,1,2,3)";
+        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+			else $sql.= " AND f.type IN (0,1,2,3,5)";
             $sql.= " AND f.rowid = d.".$fk_facture;
             if ($y && $m)
             {
@@ -500,8 +502,8 @@ function vat_by_date($db, $y, $q, $date_start, $date_end, $modetax, $direction,
             $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid";
             $sql.= " WHERE f.entity = " . $conf->entity;
             $sql.= " AND f.fk_statut in (1,2)"; // Paid (partially or completely)
-        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
-        	else $sql.= " AND f.type IN (0,1,2,3)";
+        	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)";
+			else $sql.= " AND f.type IN (0,1,2,3,5)";
             $sql.= " AND f.rowid = d.".$fk_facture;;
             $sql.= " AND pf.".$fk_facture2." = f.rowid";
             $sql.= " AND pa.rowid = pf.".$fk_payment;
diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
index 6d1f5636b851ac0c6a9d9c88b6b3c463be3774df..06c3df85f4d04818cadaeaebc3b53014a2e11c12 100644
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -4,6 +4,8 @@
  * Copyright (C) 2008		Raphael Bertrand	<raphael.bertrand@resultic.fr>
  * Copyright (C) 2010-2014	Juanjo Menent		<jmenent@2byte.es>
  * Copyright (C) 2012      	Christophe Battarel <christophe.battarel@altairis.fr>
+ * Copyright (C) 2012       Cédric Salvador     <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014  Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,6 +58,16 @@ class pdf_crabe extends ModelePDFFactures
 
 	var $emetteur;	// Objet societe qui emet
 
+	/**
+	 * @var bool Situation invoice type
+	 */
+	public $situationinvoice;
+
+	/**
+	 * @var float X position for the situation progress column
+	 */
+	public $posxprogress;
+
 
 	/**
 	 *	Constructor
@@ -107,6 +119,7 @@ class pdf_crabe extends ModelePDFFactures
 		$this->posxup=126;
 		$this->posxqty=145;
 		$this->posxdiscount=162;
+		$this->posxprogress=174; // Only displayed for situation invoices
 		$this->postotalht=174;
 		if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) $this->posxtva=$this->posxup;
 		$this->posxpicture=$this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH);	// width of images
@@ -125,6 +138,7 @@ class pdf_crabe extends ModelePDFFactures
 		$this->localtax2=array();
 		$this->atleastoneratenotnull=0;
 		$this->atleastonediscount=0;
+		$this->situationinvoice=False;
 	}
 
 
@@ -278,6 +292,17 @@ class pdf_crabe extends ModelePDFFactures
 					//$this->postotalht;
 				}
 
+				// Situation invoice handling
+				if ($object->situation_cycle_ref) {
+					$this->situationinvoice = True;
+					$progress_width = 14;
+					$this->posxtva -= $progress_width;
+					$this->posxup -= $progress_width;
+					$this->posxqty -= $progress_width;
+					$this->posxdiscount -= $progress_width;
+					$this->posxprogress -= $progress_width;
+				}
+
 				// New page
 				$pdf->AddPage();
 				if (! empty($tplidx)) $pdf->useTemplate($tplidx);
@@ -444,16 +469,27 @@ class pdf_crabe extends ModelePDFFactures
 					{
                         $pdf->SetXY($this->posxdiscount-2, $curY);
 					    $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
-						$pdf->MultiCell($this->postotalht-$this->posxdiscount+2, 3, $remise_percent, 0, 'R');
+						$pdf->MultiCell($this->posxprogress-$this->posxdiscount+2, 3, $remise_percent, 0, 'R');
 					}
 
+					// Situation progress
+					$progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails);
+					$pdf->SetXY($this->posxprogress, $curY);
+					$pdf->MultiCell($this->postotalht-$this->posxprogress, 3, $progress, 0, 'R');	// Enough for 6 chars
+
 					// Total HT line
 					$total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
 					$pdf->SetXY($this->postotalht, $curY);
 					$pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->postotalht, 3, $total_excl_tax, 0, 'R', 0);
 
 					// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
-					$tvaligne=$object->lines[$i]->total_tva;
+					$prev_progress = $object->lines[$i]->get_prev_progress();
+					if ($prev_progress > 0) // Compute progress from previous situation
+					{
+						$tvaligne = $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
+					} else {
+						$tvaligne = $object->lines[$i]->total_tva;
+					}
 					$localtax1ligne=$object->lines[$i]->total_localtax1;
 					$localtax2ligne=$object->lines[$i]->total_localtax2;
 					$localtax1_rate=$object->lines[$i]->localtax1_tx;
@@ -912,7 +948,7 @@ class pdf_crabe extends ModelePDFFactures
 		$pdf->SetFont('','', $default_font_size - 1);
 
 		// Tableau total
-		$col1x = 120; $col2x = 170;
+		$col1x = 120; $col2x = $this->postotalht;
 		if ($this->page_largeur < 210) // To work with US executive format
 		{
 			$col2x-=20;
@@ -922,11 +958,44 @@ class pdf_crabe extends ModelePDFFactures
 		$useborder=0;
 		$index = 0;
 
+		// Previous situations summary
+		if ($object->situation_cycle_ref && $object->situation_counter > 1) {
+			// Situations total w/out VAT
+			$counter = ' 1';
+			for ($i = 2; $i <= $object->situation_counter; $i++) {
+				$counter .= ' + ' . $i;
+			}
+
+			$prevsits = $object->get_prev_sits();
+			$prevsits_total_amount = 0;
+			foreach ($prevsits as $situation) {
+				$prevsits_total_amount += $situation->total_ht;
+			}
+			$prevsits_total_amount += $object->total_ht;
+
+			$pdf->SetFillColor(255, 255, 255);
+			$pdf->SetXY($col1x, $tab2_top + 0);
+			$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("SituationAmount") . $counter, 0, 'L', 1);
+			$pdf->SetXY($col2x, $tab2_top + 0);
+			$pdf->MultiCell($largcol2, $tab2_hl, price($prevsits_total_amount), 0, 'R', 1);
+
+			// Previous situations deduction
+			$pdf->Line($col2x, 0, $col2x, 100000);
+			for ($i = 0; $i < count($prevsits); $i++) {
+				$index++;
+				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+				$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("SituationDeduction") . ' ' . ($i + 1) . ' (' . $prevsits[$i]->ref . ')', 0, 'L', 1);
+				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+				$pdf->MultiCell($largcol2, $tab2_hl, ' - ' . price($prevsits[$i]->total_ht), 0, 'R', 1);
+			}
+			$index++;
+		}
+
 		// Total HT
 		$pdf->SetFillColor(255,255,255);
-		$pdf->SetXY($col1x, $tab2_top + 0);
+		$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
 		$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
-		$pdf->SetXY($col2x, $tab2_top + 0);
+		$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
 		$pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($object->total_ht + (! empty($object->remise)?$object->remise:0)), 0, $outputlangs), 0, 'R', 1);
 
 		// Show VAT by rates and total
@@ -1265,19 +1334,21 @@ class pdf_crabe extends ModelePDFFactures
 			$pdf->SetXY($this->posxqty-1, $tab_top+1);
 			$pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C');
 		}
-
 		$pdf->line($this->posxdiscount-1, $tab_top, $this->posxdiscount-1, $tab_top + $tab_height);
-		if (empty($hidetop))
-		{
-			if ($this->atleastonediscount)
-			{
-				$pdf->SetXY($this->posxdiscount-1, $tab_top+1);
-				$pdf->MultiCell($this->postotalht-$this->posxdiscount+1,2, $outputlangs->transnoentities("ReductionShort"),'','C');
+		if ($this->atleastonediscount) {
+			$pdf->line($this->posxprogress, $tab_top, $this->posxprogress, $tab_top + $tab_height);
+			if (empty($hidetop)) {
+				$pdf->SetXY($this->posxdiscount - 1, $tab_top + 1);
+				$pdf->MultiCell($this->posxprogress - $this->posxdiscount + 1, 2, $outputlangs->transnoentities("ReductionShort"), '', 'C');
 			}
 		}
-		if ($this->atleastonediscount)
-		{
+
+		if ($this->situationinvoice) {
 			$pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
+			if (empty($hidetop)) {
+				$pdf->SetXY($this->posxprogress - 1, $tab_top + 1);
+				$pdf->MultiCell($this->postotalht - $this->posxprogress - 1, 2, $outputlangs->transnoentities("Progress"), '', 'C');
+			}
 		}
 		if (empty($hidetop))
 		{
@@ -1353,6 +1424,8 @@ class pdf_crabe extends ModelePDFFactures
 		if ($object->type == 2) $title=$outputlangs->transnoentities("InvoiceAvoir");
 		if ($object->type == 3) $title=$outputlangs->transnoentities("InvoiceDeposit");
 		if ($object->type == 4) $title=$outputlangs->transnoentities("InvoiceProFormat");
+		if ($object->type == 5 && $object->situation_final == 0) $title = $outputlangs->transnoentities("InvoiceSituation").' n°'.$object->situation_counter;
+		if ($object->type == 5 && $object->situation_final == 1) $title = 'Situation n°'.$object->situation_counter.' : '.$outputlangs->transnoentities("InvoiceSituationLast");
 		$pdf->MultiCell(100, 3, $title, '', 'R');
 
 		$pdf->SetFont('','B',$default_font_size);
diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php
index 6037f6c77c92610467ac39f3d19505ffed94d798..d90526aba067e8e47f4ce690503cd5f3b25ff158 100644
--- a/htdocs/core/tpl/objectline_create.tpl.php
+++ b/htdocs/core/tpl/objectline_create.tpl.php
@@ -2,7 +2,9 @@
 /* Copyright (C) 2010-2012	Regis Houssin		<regis.houssin@capnetworks.com>
  * Copyright (C) 2010-2014	Laurent Destailleur	<eldy@users.sourceforge.net>
  * Copyright (C) 2012-2013	Christophe Battarel	<christophe.battarel@altairis.fr>
+ * Copyright (C) 2012       Cédric Salvador     <csalvador@gpcsolutions.fr>
  * Copyright (C) 2013		Florian Henry		<florian.henry@open-concept.pro>
+ * Copyright (C) 2014       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -58,6 +60,9 @@ if (in_array($object->element,array('propal','facture','invoice','commande','ord
 	<td align="right"><?php echo $langs->trans('Qty'); ?></td>
 	<td align="right"><?php echo $langs->trans('ReductionShort'); ?></td>
 	<?php
+	if ($this->situation_cycle_ref) {
+		print '<td align="right">' . $langs->trans('Progress') . '</td>';
+	}
 	if (! empty($usemargins))
 	{
 		?>
@@ -214,8 +219,11 @@ else {
 	<td align="right"><input type="text" size="2" name="qty" id="qty" class="flat" value="<?php echo (isset($_POST["qty"])?$_POST["qty"]:1); ?>">
 	</td>
 	<td align="right" class="nowrap"><input type="text" size="1" name="remise_percent" id="remise_percent" class="flat" value="<?php echo (isset($_POST["remise_percent"])?$_POST["remise_percent"]:$buyer->remise_percent); ?>"><span class="hideonsmartphone">%</span></td>
-
 	<?php
+	if ($this->situation_cycle_ref) {
+		$coldisplay++;
+		print '<td align="right" class="nowrap"><input type="text" size="1" value="0" name="progress">%</td>';
+	}
 	if (! empty($usemargins))
 	{
 		?>
@@ -277,6 +285,7 @@ if (! empty($conf->service->enabled) && $dateSelector && GETPOST('type') != '0')
 {
 	if(! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) $colspan = 10;
 	else $colspan = 9;
+	if($this->situation_cycle_ref) $colspan++;
 	if (! empty($inputalsopricewithtax)) $colspan++;	// We add 1 if col total ttc
 	if (in_array($object->element,array('propal','facture','invoice','commande','order'))) $colspan++;	// With this, there is a column move button
 
diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php
index fbe2870a6a4adbfc90f7bd55abb488a0d79e8d6e..fd2e3e0d469059dd627ac6f596045f8e1dc2a9a5 100644
--- a/htdocs/core/tpl/objectline_edit.tpl.php
+++ b/htdocs/core/tpl/objectline_edit.tpl.php
@@ -2,6 +2,8 @@
 /* Copyright (C) 2010-2012	Regis Houssin		<regis.houssin@capnetworks.com>
  * Copyright (C) 2010-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
  * Copyright (C) 2012		Christophe Battarel	<christophe.battarel@altairis.fr>
+ * Copyright (C) 2012       Cédric Salvador     <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014  Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2013		Florian Henry		<florian.henry@open-concept.pro>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -83,22 +85,44 @@ $coldisplay=-1; // We remove first td
 	    $reshook=$hookmanager->executeHooks('formEditProductOptions',$parameters,$this,$action);
 	}
 
-	// editeur wysiwyg
-	require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
-    $nbrows=ROWS_2;
-    if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT;
-    $enable=(isset($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0);
-	$doleditor=new DolEditor('product_desc',$line->description,'',164,'dolibarr_details','',false,true,$enable,$nbrows,'98%');
-	$doleditor->Create();
+	// Do not allow editing during a situation cycle
+	if ($this->situation_counter == 1 || !$this->situation_cycle_ref) {
+		// editeur wysiwyg
+		require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+		$nbrows=ROWS_2;
+		if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT;
+		$enable=(isset($conf->global->FCKEDITOR_ENABLE_DETAILS)?$conf->global->FCKEDITOR_ENABLE_DETAILS:0);
+		$doleditor=new DolEditor('product_desc',$line->description,'',164,'dolibarr_details','',false,true,$enable,$nbrows,'98%');
+		$doleditor->Create();
+	} else {
+		print '<textarea id="desc" class="flat" name="desc" readonly="readonly" style="width: 200px; height:80px;">' . $line->description . '</textarea>';
+	}
 	?>
 	</td>
 
-	<td align="right"><?php $coldisplay++; ?><?php echo $form->load_tva('tva_tx',$line->tva_tx,$seller,$buyer,0,$line->info_bits,$line->product_type); ?></td>
+	<?php
+	$coldisplay++;
+	if ($this->situation_counter == 1 || !$this->situation_cycle_ref) {
+		print '<td align="right">' . $form->load_tva('tva_tx',$line->tva_tx,$seller,$buyer,0,$line->info_bits,$line->product_type) . '</td>';
+	} else {
+		print '<td align="right"><input size="1" type="text" class="flat" name="tva_tx" value="' . price($line->tva_tx) . '" readonly="readonly" />%</td>';
+	}
 
-	<td align="right"><?php $coldisplay++; ?><input type="text" class="flat" size="8" id="price_ht" name="price_ht" value="<?php echo price($line->subprice,0,'',0); ?>"></td>
-	<?php if ($inputalsopricewithtax) { ?>
-	<td align="right"><?php $coldisplay++; ?><input type="text" class="flat" size="8" id="price_ttc" name="price_ttc" value="<?php echo price($pu_ttc,0,'',0); ?>"></td>
-	<?php } ?>
+	$coldisplay++;
+	print '<td align="right"><input type="text" class="flat" size="8" id="price_ht" name="price_ht" value="' . price($line->subprice,0,'',0) . '" ';
+	if ($this->situation_counter > 1) {
+		print 'readonly="readonly" ';
+	}
+	print '></td>';
+
+	if ($inputalsopricewithtax) {
+		$coldisplay++;
+		print '<td align="right"><input type="text" class="flat" size="8" id="price_ttc" name="price_ttc" value="' . price($pu_ttc,0,'',0) . '"';
+		if ($this->situation_counter > 1) {
+			print 'readonly="readonly" ';
+		}
+		print '></td>';
+	} ?>
 
 	<td align="right"><?php $coldisplay++; ?>
 	<?php if (($line->info_bits & 2) != 2) {
@@ -106,22 +130,32 @@ $coldisplay=-1; // We remove first td
 		// for example always visible on invoice but must be visible only if stock module on and stock decrease option is on invoice validation and status is not validated
 		// must also not be output for most entities (proposal, intervention, ...)
 		//if($line->qty > $line->stock) print img_picto($langs->trans("StockTooLow"),"warning", 'style="vertical-align: bottom;"')." ";
-	?>
-		<input size="3" type="text" class="flat" name="qty" id="qty" value="<?php echo $line->qty; ?>">
-	<?php } else { ?>
+		print '<input size="3" type="text" class="flat" name="qty" id="qty" value="' . $line->qty . '" ';
+		if ($this->situation_counter > 1) {
+			print 'readonly="readonly" ';
+		}
+		print '/>';
+	} else { ?>
 		&nbsp;
 	<?php } ?>
 	</td>
 
 	<td align="right" nowrap><?php $coldisplay++; ?>
-	<?php if (($line->info_bits & 2) != 2) { ?>
-		<input size="1" type="text" class="flat" name="remise_percent" id="remise_percent" value="<?php echo $line->remise_percent; ?>">%
-	<?php } else { ?>
+	<?php if (($line->info_bits & 2) != 2) {
+		print '<input size="1" type="text" class="flat" name="remise_percent" id="remise_percent" value="' . $line->remise_percent . '" ';
+		if ($this->situation_counter > 1) {
+			print 'readonly="readonly" ';
+		}
+		print '/>%';
+	} else { ?>
 		&nbsp;
 	<?php } ?>
 	</td>
-
 	<?php
+	if ($this->situation_cycle_ref) {
+		$coldisplay++;
+		print '<td align="right" nowrap><input type="text" size="1" value="' . $line->situation_percent . '" name="progress">%</td>';
+	}
 	if (! empty($usemargins))
 	{
 	?>
diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php
index 3d2ea127b8506947c2c17f31e53b8a88b2bcbc12..2e1cc0f3678e95a33f7558cf0db4832201ce748a 100644
--- a/htdocs/core/tpl/objectline_view.tpl.php
+++ b/htdocs/core/tpl/objectline_view.tpl.php
@@ -2,6 +2,8 @@
 /* Copyright (C) 2010-2013	Regis Houssin		<regis.houssin@capnetworks.com>
  * Copyright (C) 2010-2011	Laurent Destailleur	<eldy@users.sourceforge.net>
  * Copyright (C) 2012-2013	Christophe Battarel	<christophe.battarel@altairis.fr>
+ * Copyright (C) 2012       Cédric Salvador     <csalvador@gpcsolutions.fr>
+ * Copyright (C) 2012-2014  Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
  * Copyright (C) 2013		Florian Henry		<florian.henry@open-concept.pro>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -138,6 +140,11 @@ if (empty($inputalsopricewithtax)) $inputalsopricewithtax=0;
 	<td><?php $coldisplay++; ?>&nbsp;</td>
 	<?php }
 
+	if ($this->situation_cycle_ref) {
+		$coldisplay++;
+		print '<td align="right" nowrap="nowrap">' . $line->situation_percent . '%</td>';
+	}
+
   if (! empty($conf->margin->enabled) && empty($user->societe_id)) {
 	$rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT,$conf->global->MAIN_MAX_DECIMALS_TOT);
   ?>
@@ -167,12 +174,16 @@ if (empty($inputalsopricewithtax)) $inputalsopricewithtax=0;
 	</td>
 
 	<td align="center"><?php $coldisplay++; ?>
-		<a href="<?php echo $_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=ask_deleteline&amp;lineid='.$line->id; ?>">
-		<?php echo img_delete(); ?>
-		</a>
+		<?php
+		if ($this->situation_counter == 1 || !$this->situation_cycle_ref) {
+			print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $this->id . '&amp;action=ask_deleteline&amp;lineid=' . $line->id . '">';
+			print img_delete();
+			print '</a>';
+		}
+		?>
 	</td>
 
-	<?php if ($num > 1 && empty($conf->browser->phone)) { ?>
+	<?php if ($num > 1 && empty($conf->browser->phone) && ($this->situation_counter == 1 || !$this->situation_cycle_ref)) { ?>
 	<td align="center" class="tdlineupdown"><?php $coldisplay++; ?>
 		<?php if ($i > 0) { ?>
 		<a class="lineupdown" href="<?php echo $_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=up&amp;rowid='.$line->id; ?>">
diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql
index 755195c2a61a5bd8112539abc57d934c12903a2b..02265ff86c87a341a34b4e49f5a315647177d9f0 100755
--- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql
+++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql
@@ -30,3 +30,10 @@ ALTER TABLE llx_product_fournisseur_price ADD fk_price_expression integer DEFAUL
 
 -- Taiwan VAT Rates
 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 2131, 213, '5', '0', 'VAT 5%', 1);
+
+-- Add situation invoices
+ALTER TABLE llx_facture ADD situation_cycle_ref smallint UNSIGNED;
+ALTER TABLE llx_facture ADD situation_counter tinyint UNSIGNED;
+ALTER TABLE llx_facture ADD situation_final boolean;
+ALTER TABLE llx_facturedet ADD situation_percent real;
+ALTER TABLE llx_facturedet ADD fk_prev_id integer;
diff --git a/htdocs/install/mysql/tables/llx_facture.sql b/htdocs/install/mysql/tables/llx_facture.sql
index 9757f749cd0a51764601d7f03352bf04bf18b519..144cd349dd6c8548169631f1d36c100e8df272b3 100644
--- a/htdocs/install/mysql/tables/llx_facture.sql
+++ b/htdocs/install/mysql/tables/llx_facture.sql
@@ -3,6 +3,8 @@
 -- Copyright (C) 2004-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
 -- Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
 -- Copyright (C) 2010      Juanjo Menent        <jmenent@2byte.es>
+-- Copyright (C) 2012      Cédric Salvador      <csalvador@gpcsolutions.fr>
+-- Copyright (C) 2014      Raphaël Doursenaud   <rdoursenaud@gpcsolutions.fr>
 -- 
 -- This program is free software; you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -74,6 +76,10 @@ create table llx_facture
   note_public			text,
   model_pdf				varchar(255),
   import_key			varchar(14),
-  extraparams			varchar(255)							-- for stock other parameters with json format
+  extraparams			varchar(255),							-- for stock other parameters with json format
+
+  situation_cycle_ref smallint UNSIGNED,  -- situation cycle reference
+  situation_counter   tinyint UNSIGNED,   -- situation counter
+  situation_final     boolean             -- is the situation final ?
 
 )ENGINE=innodb;
diff --git a/htdocs/install/mysql/tables/llx_facturedet.sql b/htdocs/install/mysql/tables/llx_facturedet.sql
index 6a328d4688edeb67d31cf55fc52b4422f4e2e082..2c01234f4b943eb394f22d47a882552a4b53e99b 100644
--- a/htdocs/install/mysql/tables/llx_facturedet.sql
+++ b/htdocs/install/mysql/tables/llx_facturedet.sql
@@ -3,6 +3,8 @@
 -- Copyright (C) 2004-2005	Laurent Destailleur		<eldy@users.sourceforge.net>
 -- Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@capnetworks.com>
 -- Copyright (C) 2010		Juanjo Menent			<jmenent@2byte.es>
+-- Copyright (C) 2012       Cédric Salvador       <csalvador@gpcsolutions.fr>
+-- Copyright (C) 2014       Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
 --
 -- This program is free software; you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -55,8 +57,11 @@ create table llx_facturedet
   fk_code_ventilation			integer    DEFAULT 0 NOT NULL,
   special_code					integer UNSIGNED DEFAULT 0,			-- code pour les lignes speciales
   rang							integer    DEFAULT 0,				-- ordre d'affichage
-  import_key					varchar(14)
-  
+  import_key					varchar(14),
+
+  situation_percent real,   -- % progression of lines invoicing
+  fk_prev_id        integer -- id of the line in the previous situation
+
 )ENGINE=innodb;
 
 -- 
diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang
index 12778d6b9ead0d185e4ce96fb9564459b5253f25..ccf994aff95c946fa2033cb020ea8f97139e1492 100644
--- a/htdocs/langs/en_US/bills.lang
+++ b/htdocs/langs/en_US/bills.lang
@@ -389,7 +389,7 @@ DisabledBecausePayments=Not possible since there are some payments
 CantRemovePaymentWithOneInvoicePaid=Can't remove payment since there is at least one invoice classified paid
 ExpectedToPay=Expected payment
 PayedByThisPayment=Paid by this payment
-ClosePaidInvoicesAutomatically=Classify "Paid" all standard or replacement invoices entirely paid. 
+ClosePaidInvoicesAutomatically=Classify "Paid" all standard, situation or replacement invoices entirely paid.
 ClosePaidCreditNotesAutomatically=Classify "Paid" all credit notes entirely paid back. 
 AllCompletelyPayedInvoiceWillBeClosed=All invoice with no remain to pay will be automatically closed to status "Paid".
 ToMakePayment=Pay
@@ -411,3 +411,20 @@ TypeContact_invoice_supplier_internal_SALESREPFOLL=Representative following-up s
 TypeContact_invoice_supplier_external_BILLING=Supplier invoice contact
 TypeContact_invoice_supplier_external_SHIPPING=Supplier shipping contact
 TypeContact_invoice_supplier_external_SERVICE=Supplier service contact
+# Situation invoices
+InvoiceFirstSituationAsk=First situation invoice
+InvoiceFirstSituationDesc=The <b>situation invoices</b> are tied to situations related to a progression, for example the progression of a construction. Each situation is tied to an invoice.
+InvoiceSituation=Situation invoice
+InvoiceSituationAsk=Invoice following the situation
+InvoiceSituationDesc=Create a new situation following an already existing one
+SituationAmount=Situation invoice amount(net)
+SituationDeduction=Situation subtraction
+Progress=Progress
+ModifyAllLines=Modify all lines
+CreateNextSituationInvoice=Create next situation
+NotLastInCycle=This invoice in not the last in cycle and must not be modified.
+DisabledBecauseNotLastInCycle=The next situation already exists.
+DisabledBecauseFinal=This situation is final.
+CantBeLessThanMinPercent=The progress can't be smaller than its value in the previous situation.
+NoSituations=No opened situations
+InvoiceSituationLast=Final and general invoice
diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang
index 24ebe5ff923f79cef4d13cc59d80f0087b5a39a1..22c80d41300dcb9143fb1e1b2997ed1032f4e2c5 100644
--- a/htdocs/langs/fr_FR/bills.lang
+++ b/htdocs/langs/fr_FR/bills.lang
@@ -410,3 +410,21 @@ TypeContact_invoice_supplier_internal_SALESREPFOLL=Responsable suivi facture fou
 TypeContact_invoice_supplier_external_BILLING=Contact fournisseur facturation
 TypeContact_invoice_supplier_external_SHIPPING=Contact fournisseur livraison
 TypeContact_invoice_supplier_external_SERVICE=Contact fournisseur prestation
+# Factures de situation
+InvoiceFirstSituationAsk=Facture de première situation
+InvoiceFirstSituationDesc=Les <b>factures de situation</b> correspondent aux situations liées à un avancement, par exemple l'avancement des travaux dans le cadre d’un chantier (BTP). Chaque situation correspond à une facture.
+InvoiceFirstSituation=Facture de première situation
+InvoiceSituationAsk=Facture suivant la situation
+InvoiceSituationDesc=Création d'une nouvelle situation qui fera suite à une situation déjà ouverte.
+InvoiceSituation=Facture de situation
+SituationAmount=Montant HT situation
+SituationDeduction=Déduction situation
+Progress=Avanct.
+ModifyAllLines=Modifier toutes les lignes
+CreateNextSituationInvoice=Créer situation suivante
+NotLastInCycle=Cette facture n'est pas la dernière du cycle, il ne faut pas la modifier.
+DisabledBecauseNotLastInCycle=La situation suivante existe déjà.
+DisabledBecauseFinal=Cette situation est finale.
+CantBeLessThanMinPercent=L'avancement d'une ligne ne peut pas être inférieur à sa valeur à la situation précédente.
+NoSituations=Pas de situations en cours
+InvoiceSituationLast=Décompte général et définitif