';
}
// Form to add a transaction with no invoice
@@ -663,7 +658,8 @@ if ($resql)
print '
';
print '
';
print '';
- if (is_array($options) && count($options)) {
+ if (is_array($options) && count($options))
+ {
print ' '.$langs->trans("Rubrique").': ';
print Form::selectarray('cat1', $options, GETPOST('cat1'), 1);
}
diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php
index 59271f7eec7..0ca4b4d879d 100644
--- a/htdocs/contrat/card.php
+++ b/htdocs/contrat/card.php
@@ -3,7 +3,7 @@
* Copyright (C) 2004-2014 Laurent Destailleur
* Copyright (C) 2005-2014 Regis Houssin
* Copyright (C) 2006 Andre Cianfarani
- * Copyright (C) 2010-2015 Juanjo Menent
+ * Copyright (C) 2010-2017 Juanjo Menent
* Copyright (C) 2013 Christophe Battarel
* Copyright (C) 2013-2014 Florian Henry
* Copyright (C) 2014-2016 Ferran Marcet
@@ -781,6 +781,30 @@ if (empty($reshook))
else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->contrat->creer)
{
$result = $object->validate($user);
+
+ if ($result > 0)
+ {
+ // Define output language
+ if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
+ {
+ $outputlangs = $langs;
+ $newlang = '';
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
+ if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
+ if (! empty($newlang)) {
+ $outputlangs = new Translate("", $conf);
+ $outputlangs->setDefaultLang($newlang);
+ }
+ $model=$object->modelpdf;
+ $ret = $object->fetch($id); // Reload to get new records
+
+ $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
+ }
+ }
+ else
+ {
+ setEventMessages($object->error, $object->errors, 'errors');
+ }
}
else if ($action == 'reopen' && $user->rights->contrat->creer)
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 2df6dfc82b7..18d3f203dac 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -1273,14 +1273,15 @@ abstract class CommonObject
}
/**
- * Load object from specific field
- *
- * @param string $table Table element or element line
- * @param string $field Field selected
- * @param string $key Import key
- * @return int <0 if KO, >0 if OK
- */
- function fetchObjectFrom($table,$field,$key)
+ * Load object from specific field
+ *
+ * @param string $table Table element or element line
+ * @param string $field Field selected
+ * @param string $key Import key
+ * @param string $element Element name
+ * @return int <0 if KO, >0 if OK
+ */
+ function fetchObjectFrom($table, $field, $key, $element = null)
{
global $conf;
@@ -1288,7 +1289,11 @@ abstract class CommonObject
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$table;
$sql.= " WHERE ".$field." = '".$key."'";
- $sql.= " AND entity = ".$conf->entity;
+ if (! empty($element)) {
+ $sql.= " AND entity IN (".getEntity($element).")";
+ } else {
+ $sql.= " AND entity = ".$conf->entity;
+ }
dol_syslog(get_class($this).'::fetchObjectFrom', LOG_DEBUG);
$resql = $this->db->query($sql);
diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php
index d40fcadc17c..7554a82a5fd 100644
--- a/htdocs/core/class/notify.class.php
+++ b/htdocs/core/class/notify.class.php
@@ -404,13 +404,13 @@ class Notify
break;
case 'FICHINTER_ADD_CONTACT':
$link='/fichinter/card.php?id='.$object->id;
- $dir_output = $conf->facture->dir_output;
+ $dir_output = $conf->ficheinter->dir_output;
$object_type = 'ficheinter';
$mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$object->ref);
break;
case 'FICHINTER_VALIDATE':
$link='/fichinter/card.php?id='.$object->id;
- $dir_output = $conf->facture->dir_output;
+ $dir_output = $conf->ficheinter->dir_output;
$object_type = 'ficheinter';
$mesg = $langs->transnoentitiesnoconv("EMailTextInterventionValidated",$object->ref);
break;
@@ -664,8 +664,9 @@ class Notify
}
dol_syslog("Replace the __SUPERVISOREMAIL__ key into recipient email string with ".$newval);
$sendto = preg_replace('/__SUPERVISOREMAIL__/', $newval, $sendto);
- $sendto = preg_replace('/^[\s,]+/','',$sendto); // Clean start of string
- $sendto = preg_replace('/[\s,]+$/','',$sendto); // Clean end of string
+ $sendto = preg_replace('/,\s*,/', ',', $sendto); // in some case you can have $sendto like "email, __SUPERVISOREMAIL__ , otheremail" then you have "email, , othermail" and it's not valid
+ $sendto = preg_replace('/^[\s,]+/', '', $sendto); // Clean start of string
+ $sendto = preg_replace('/[\s,]+$/', '', $sendto); // Clean end of string
}
if ($sendto)
diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php
index 5f5288e7c53..c0dc04ccb38 100644
--- a/htdocs/core/lib/functions2.lib.php
+++ b/htdocs/core/lib/functions2.lib.php
@@ -2258,6 +2258,9 @@ function getModuleDirForApiClass($module)
elseif ($module == 'users') {
$moduledirforclass = 'user';
}
+ elseif ($module == 'ficheinter' || $module == 'interventions') {
+ $moduledirforclass = 'fichinter';
+ }
return $moduledirforclass;
}
diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php
new file mode 100644
index 00000000000..23073737d7e
--- /dev/null
+++ b/htdocs/fichinter/class/api_interventions.class.php
@@ -0,0 +1,424 @@
+
+ * Copyright (C) 2016 Laurent Destailleur
+ *
+ * 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+ use Luracast\Restler\RestException;
+
+ require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
+
+/**
+ * API class for fichinters
+ *
+ * @access protected
+ * @class DolibarrApiAccess {@requires user,external}
+ */
+class Interventions extends DolibarrApi
+{
+
+ /**
+ * @var array $FIELDS Mandatory fields, checked when create and update object
+ */
+ static $FIELDS = array(
+ 'socid',
+ 'fk_project',
+ 'description'
+ );
+
+ /**
+ * @var array $FIELDS Mandatory fields, checked when create and update object
+ */
+ static $FIELDSLINE = array(
+ 'description',
+ 'date',
+ 'duree'
+ );
+
+ /**
+ * @var fichinter $fichinter {@type fichinter}
+ */
+ public $fichinter;
+
+ /**
+ * Constructor
+ */
+ function __construct()
+ {
+ global $db, $conf;
+ $this->db = $db;
+ $this->fichinter = new Fichinter($this->db);
+ }
+
+ /**
+ * Get properties of a Expense Report object
+ *
+ * Return an array with Expense Report informations
+ *
+ * @param int $id ID of Expense Report
+ * @return array|mixed Data without useless information
+ *
+ * @throws RestException
+ */
+ function get($id)
+ {
+ if(! DolibarrApiAccess::$user->rights->ficheinter->lire) {
+ throw new RestException(401);
+ }
+
+ $result = $this->fichinter->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Intervention report not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('fichinter',$this->fichinter->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ $this->fichinter->fetchObjectLinked();
+ return $this->_cleanObjectDatas($this->fichinter);
+ }
+
+ /**
+ * List of interventions
+ *
+ * Return a list of interventions
+ *
+ * @param string $sortfield Sort field
+ * @param string $sortorder Sort order
+ * @param int $limit Limit for list
+ * @param int $page Page number
+ * @param string $thirdparty_ids Thirdparty ids to filter orders of. {@example '1' or '1,2,3'} {@pattern /^[0-9,]*$/i}
+ * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
+ * @return array Array of order objects
+ *
+ * @throws RestException
+ */
+ function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
+ global $db, $conf;
+
+ $obj_ret = array();
+
+ // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
+ $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids;
+
+ // If the internal user must only see his customers, force searching by him
+ $search_sale = 0;
+ if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
+
+ $sql = "SELECT t.rowid";
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
+ $sql.= " FROM ".MAIN_DB_PREFIX."fichinter as t";
+
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
+
+ $sql.= ' WHERE t.entity IN ('.getEntity('fichinter').')';
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.fk_soc = sc.fk_soc";
+ if ($socids) $sql.= " AND t.fk_soc IN (".$socids.")";
+ if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
+ // Insert sale filter
+ if ($search_sale > 0)
+ {
+ $sql .= " AND sc.fk_user = ".$search_sale;
+ }
+ // Add sql filters
+ if ($sqlfilters)
+ {
+ if (! DolibarrApi::_checkFilters($sqlfilters))
+ {
+ throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
+ }
+ $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
+ $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
+ }
+
+ $sql.= $db->order($sortfield, $sortorder);
+ if ($limit) {
+ if ($page < 0)
+ {
+ $page = 0;
+ }
+ $offset = $limit * $page;
+
+ $sql.= $db->plimit($limit + 1, $offset);
+ }
+
+ dol_syslog("API Rest request");
+ $result = $db->query($sql);
+
+ if ($result)
+ {
+ $num = $db->num_rows($result);
+ $min = min($num, ($limit <= 0 ? $num : $limit));
+ while ($i < $min)
+ {
+ $obj = $db->fetch_object($result);
+ $fichinter_static = new Fichinter($db);
+ if($fichinter_static->fetch($obj->rowid)) {
+ $obj_ret[] = $this->_cleanObjectDatas($fichinter_static);
+ }
+ $i++;
+ }
+ }
+ else {
+ throw new RestException(503, 'Error when retrieve fichinter list : '.$db->lasterror());
+ }
+ if( ! count($obj_ret)) {
+ throw new RestException(404, 'No finchinter found');
+ }
+ return $obj_ret;
+ }
+
+ /**
+ * Create intervention object
+ *
+ * @param array $request_data Request data
+ * @return int ID of intervention
+ */
+ function post($request_data = NULL)
+ {
+ if(! DolibarrApiAccess::$user->rights->ficheinter->creer) {
+ throw new RestException(401, "Insuffisant rights");
+ }
+ // Check mandatory fields
+ $result = $this->_validate($request_data);
+ foreach($request_data as $field => $value) {
+ $this->fichinter->$field = $value;
+ }
+
+ if ($this->fichinter->create(DolibarrApiAccess::$user) < 0) {
+ throw new RestException(500, "Error creating fichinter", array_merge(array($this->fichinter->error), $this->fichinter->errors));
+ }
+
+ return $this->fichinter->id;
+ }
+
+
+ /**
+ * Get lines of an intervention
+ *
+ * @param int $id Id of intervention
+ *
+ * @url GET {id}/lines
+ *
+ * @return int
+ */
+ /* TODO
+ function getLines($id) {
+ if(! DolibarrApiAccess::$user->rights->ficheinter->lire) {
+ throw new RestException(401);
+ }
+
+ $result = $this->fichinter->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Intervention not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('fichinter',$this->fichinter->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+ $this->fichinter->getLinesArray();
+ $result = array();
+ foreach ($this->fichinter->lines as $line) {
+ array_push($result,$this->_cleanObjectDatas($line));
+ }
+ return $result;
+ }
+ */
+
+ /**
+ * Add a line to given intervention
+ *
+ * @param int $id Id of intervention to update
+ * @param array $request_data Request data
+ *
+ * @url POST {id}/lines
+ *
+ * @return int
+ */
+ function postLine($id, $request_data = NULL)
+ {
+ if(! DolibarrApiAccess::$user->rights->ficheinter->creer) {
+ throw new RestException(401, "Insuffisant rights");
+ }
+ // Check mandatory fields
+ $result = $this->_validateLine($request_data);
+
+ foreach($request_data as $field => $value) {
+ $this->fichinter->$field = $value;
+ }
+
+ if( ! $result ) {
+ throw new RestException(404, 'Intervention not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('fichinter',$this->fichinter->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ $updateRes = $this->fichinter->addLine(
+ DolibarrApiAccess::$user,
+ $id,
+ $this->fichinter->description,
+ $this->fichinter->date,
+ $this->fichinter->duree
+ );
+
+ if ($updateRes > 0) {
+ return $updateRes;
+ }
+ else {
+ throw new RestException(400, $this->fichinter->error);
+ }
+ }
+
+ /**
+ * Validate an intervention
+ *
+ * If you get a bad value for param notrigger check, provide this in body
+ * {
+ * "notrigger": 0
+ * }
+ *
+ * @param int $id Intervention ID
+ * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
+ *
+ * @url POST {id}/validate
+ *
+ * @return array
+ */
+ function validate($id, $notrigger=0)
+ {
+ if(! DolibarrApiAccess::$user->rights->ficheinter->creer) {
+ throw new RestException(401, "Insuffisant rights");
+ }
+ $result = $this->fichinter->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Intervention not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('fichinter',$this->fichinter->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ $result = $this->fichinter->setValid(DolibarrApiAccess::$user, $notrigger);
+ if ($result == 0) {
+ throw new RestException(304, 'Error nothing done. May be object is already validated');
+ }
+ if ($result < 0) {
+ throw new RestException(500, 'Error when validating Intervention: '.$this->commande->error);
+ }
+
+ $this->fichinter->fetchObjectLinked();
+
+ return $this->_cleanObjectDatas($this->fichinter);
+ }
+
+ /**
+ * Close an intervention
+ *
+ * @param int $id Intervention ID
+ *
+ * @url POST {id}/close
+ *
+ * @return array
+ */
+ function closeFichinter($id)
+ {
+ if(! DolibarrApiAccess::$user->rights->ficheinter->creer)
+ {
+ throw new RestException(401, "Insuffisant rights");
+ }
+ $result = $this->fichinter->fetch($id);
+ if (! $result) {
+ throw new RestException(404, 'Intervention not found');
+ }
+
+ if (! DolibarrApi::_checkAccessToResource('fichinter',$this->fichinter->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ $result = $this->fichinter->setStatut(3);
+
+ if ($result == 0) {
+ throw new RestException(304, 'Error nothing done. May be object is already closed');
+ }
+ if ($result < 0) {
+ throw new RestException(500, 'Error when closing Intervention: '.$this->fichinter->error);
+ }
+
+ $this->fichinter->fetchObjectLinked();
+
+ return $this->_cleanObjectDatas($this->fichinter);
+ }
+
+ /**
+ * Validate fields before create or update object
+ *
+ * @param array $data Data to validate
+ * @return array
+ *
+ * @throws RestException
+ */
+ function _validate($data)
+ {
+ $fichinter = array();
+ foreach (Interventions::$FIELDS as $field) {
+ if (!isset($data[$field]))
+ throw new RestException(400, "$field field missing");
+ $fichinter[$field] = $data[$field];
+ }
+ return $fichinter;
+ }
+
+
+ /**
+ * Clean sensible object datas
+ *
+ * @param object $object Object to clean
+ * @return array Array of cleaned object properties
+ */
+ function _cleanObjectDatas($object) {
+
+ $object = parent::_cleanObjectDatas($object);
+
+ unset($object->statuts_short);
+ unset($object->statuts_logo);
+ unset($object->statuts);
+
+ return $object;
+ }
+
+ /**
+ * Validate fields before create or update object
+ *
+ * @param array $data Data to validate
+ * @return array
+ *
+ * @throws RestException
+ */
+ function _validateLine($data)
+ {
+ $fichinter = array();
+ foreach (Interventions::$FIELDSLINE as $field) {
+ if (!isset($data[$field]))
+ throw new RestException(400, "$field field missing");
+ $fichinter[$field] = $data[$field];
+ }
+ return $fichinter;
+ }
+
+
+}
diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php
index 17b8aca8474..ce122b045b5 100644
--- a/htdocs/fichinter/class/fichinter.class.php
+++ b/htdocs/fichinter/class/fichinter.class.php
@@ -157,7 +157,7 @@ class Fichinter extends CommonObject
*/
function create($user, $notrigger=0)
{
- global $conf, $user, $langs;
+ global $conf, $langs;
dol_syslog(get_class($this)."::create ref=".$this->ref);
diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php
index f2ed3005022..724f90af228 100644
--- a/htdocs/fourn/card.php
+++ b/htdocs/fourn/card.php
@@ -101,6 +101,21 @@ if (empty($reshook))
$result=$object->setPaymentMethods(GETPOST('mode_reglement_supplier_id','int'));
if ($result < 0) dol_print_error($db,$object->error);
}
+ if ($action == 'update_extras') {
+ $object->fetch($id);
+
+ // Fill array 'array_options' with data from update form
+ $extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
+ $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute'));
+
+ if ($ret < 0) $error++;
+ if (! $error)
+ {
+ $result = $object->insertExtraFields();
+ if ($result < 0) $error++;
+ }
+ if ($error) $action = 'edit_extras';
+ }
}
diff --git a/htdocs/install/mysql/tables/llx_commandedet.sql b/htdocs/install/mysql/tables/llx_commandedet.sql
index 81ba14cca2c..0d6468309f5 100644
--- a/htdocs/install/mysql/tables/llx_commandedet.sql
+++ b/htdocs/install/mysql/tables/llx_commandedet.sql
@@ -39,26 +39,26 @@ create table llx_commandedet
remise real DEFAULT 0, -- montant de la remise
fk_remise_except integer NULL, -- Lien vers table des remises fixes
price real, -- prix final
- subprice double(24,8) DEFAULT 0, -- P.U. HT (exemple 100)
- total_ht double(24,8) DEFAULT 0, -- Total HT de la ligne toute quantite et incluant remise ligne et globale
- total_tva double(24,8) DEFAULT 0, -- Total TVA de la ligne toute quantite et incluant remise ligne et globale
- total_localtax1 double(24,8) DEFAULT 0, -- Total LocalTax1
- total_localtax2 double(24,8) DEFAULT 0, -- Total LocalTax2
- total_ttc double(24,8) DEFAULT 0, -- Total TTC de la ligne toute quantite et incluant remise ligne et globale
- product_type integer DEFAULT 0,
+ subprice double(24,8) DEFAULT 0, -- P.U. HT (exemple 100)
+ total_ht double(24,8) DEFAULT 0, -- Total HT de la ligne toute quantite et incluant remise ligne et globale
+ total_tva double(24,8) DEFAULT 0, -- Total TVA de la ligne toute quantite et incluant remise ligne et globale
+ total_localtax1 double(24,8) DEFAULT 0, -- Total LocalTax1
+ total_localtax2 double(24,8) DEFAULT 0, -- Total LocalTax2
+ total_ttc double(24,8) DEFAULT 0, -- Total TTC de la ligne toute quantite et incluant remise ligne et globale
+ product_type integer DEFAULT 0, -- 0 or 1. Value 9 may be used by some modules (amount of line may not be included into generated discount if value is 9).
date_start datetime DEFAULT NULL, -- date debut si service
date_end datetime DEFAULT NULL, -- date fin si service
info_bits integer DEFAULT 0, -- TVA NPR ou non
- buy_price_ht double(24,8) DEFAULT 0, -- buying price
+ buy_price_ht double(24,8) DEFAULT 0, -- buying price
fk_product_fournisseur_price integer DEFAULT NULL, -- reference of supplier price when line was added (may be used to update buy_price_ht current price when future invoice will be created)
- special_code integer DEFAULT 0, -- code pour les lignes speciales
+ special_code integer DEFAULT 0, -- code for special lines (may be 1=transport, 2=ecotax, 3=option, moduleid=...)
rang integer DEFAULT 0,
- fk_unit integer DEFAULT NULL, -- lien vers table des unités
+ fk_unit integer DEFAULT NULL, -- lien vers table des unités
import_key varchar(14),
- fk_commandefourndet integer DEFAULT NULL, -- link to detail line of commande fourn (resplenish)
+ fk_commandefourndet integer DEFAULT NULL, -- link to detail line of commande fourn (resplenish)
fk_multicurrency integer,
multicurrency_code varchar(255),
diff --git a/htdocs/install/mysql/tables/llx_facturedet.sql b/htdocs/install/mysql/tables/llx_facturedet.sql
index 28c07e6d508..05c68e92751 100644
--- a/htdocs/install/mysql/tables/llx_facturedet.sql
+++ b/htdocs/install/mysql/tables/llx_facturedet.sql
@@ -47,7 +47,7 @@ create table llx_facturedet
total_localtax1 double(24,8) DEFAULT 0, -- Total LocalTax1 for total quantity of line
total_localtax2 double(24,8) DEFAULT 0, -- Total LocalTax2 for total quantity of line
total_ttc double(24,8), -- Total TTC de la ligne toute quantite et incluant remise ligne et globale
- product_type integer DEFAULT 0,
+ product_type integer DEFAULT 0, -- 0 or 1. Value 9 may be used by some modules (amount of line may not be included into generated discount if value is 9).
date_start datetime DEFAULT NULL, -- date start if service
date_end datetime DEFAULT NULL, -- date end if service
info_bits integer DEFAULT 0, -- VAT NPR or not (for france only)
@@ -57,7 +57,7 @@ create table llx_facturedet
fk_code_ventilation integer DEFAULT 0 NOT NULL, -- Id in table llx_accounting_bookeeping to know accounting account for product line
- special_code integer DEFAULT 0, -- code pour les lignes speciales
+ special_code integer DEFAULT 0, -- code for special lines (may be 1=transport, 2=ecotax, 3=option, moduleid=...)
rang integer DEFAULT 0, -- position of line
fk_contract_line integer NULL, -- id of contract line when invoice comes from contract lines
import_key varchar(14),
diff --git a/htdocs/install/mysql/tables/llx_propaldet.sql b/htdocs/install/mysql/tables/llx_propaldet.sql
index 70029acdb08..283708fd7ce 100644
--- a/htdocs/install/mysql/tables/llx_propaldet.sql
+++ b/htdocs/install/mysql/tables/llx_propaldet.sql
@@ -44,7 +44,7 @@ create table llx_propaldet
total_localtax1 double(24,8) DEFAULT 0, -- Total localtax1
total_localtax2 double(24,8) DEFAULT 0, -- Total localtax2
total_ttc double(24,8) DEFAULT 0, -- Total TTC de la ligne toute quantite et incluant remise ligne et globale
- product_type integer DEFAULT 0,
+ product_type integer DEFAULT 0, -- 0 or 1. Value 9 may be used by some modules (amount of line may not be included into generated discount if value is 9).
date_start datetime DEFAULT NULL, -- date debut si service
date_end datetime DEFAULT NULL, -- date fin si service
info_bits integer DEFAULT 0, -- TVA NPR ou non
@@ -52,8 +52,8 @@ create table llx_propaldet
buy_price_ht double(24,8) DEFAULT 0, -- buying price
fk_product_fournisseur_price integer DEFAULT NULL, -- reference of supplier price when line was added (may be used to update buy_price_ht current price when future invoice will be created)
- special_code integer DEFAULT 0, -- code pour les lignes speciales
- rang integer DEFAULT 0, -- ordre affichage sur la propal
+ special_code integer DEFAULT 0, -- code for special lines (may be 1=transport, 2=ecotax, 3=option, moduleid=...)
+ rang integer DEFAULT 0, -- ordre affichage sur la propal
fk_unit integer DEFAULT NULL, -- lien vers table des unités
fk_multicurrency integer,
diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php
index 62b35bfdf39..e413c969119 100644
--- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php
+++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php
@@ -211,6 +211,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers
// Contracts
case 'CONTRACT_CREATE':
case 'CONTRACT_ACTIVATE':
+ case 'CONTRACT_MODIFY':
case 'CONTRACT_CANCEL':
case 'CONTRACT_CLOSE':
case 'CONTRACT_DELETE':
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index 9883db3bec6..44e95f4159b 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -1153,6 +1153,7 @@ class Societe extends CommonObject
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid';
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as te ON s.fk_typent = te.id';
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON s.fk_incoterms = i.rowid';
+
$sql .= ' WHERE s.entity IN ('.getEntity($this->element).')';
if ($rowid) $sql .= ' AND s.rowid = '.$rowid;
if ($ref) $sql .= " AND s.nom = '".$this->db->escape($ref)."'";