'.$langs->trans("Nature").' '.$object->getmorphylib().' ';
@@ -630,7 +630,7 @@ if ($rowid > 0)
print '';
// Birthday
- print ''.$langs->trans("Birthday").' '.dol_print_date($object->birth,'day').' ';
+ print ''.$langs->trans("Birthday").' '.dol_print_date($object->birth,'day').' ';
// Public
print ''.$langs->trans("Public").' '.yn($object->public).' ';
diff --git a/htdocs/adherents/stats/byproperties.php b/htdocs/adherents/stats/byproperties.php
index 35ee0c6f6db..6b7c1c003a9 100644
--- a/htdocs/adherents/stats/byproperties.php
+++ b/htdocs/adherents/stats/byproperties.php
@@ -54,7 +54,7 @@ $langs->load("companies");
$memberstatic=new Adherent($db);
-llxHeader('',$langs->trans("MembersStatisticsByProperties"),'','',0,0,array('http://www.google.com/jsapi'));
+llxHeader('',$langs->trans("MembersStatisticsByProperties"),'','',0,0,array('https://www.google.com/jsapi'));
$title=$langs->trans("MembersStatisticsByProperties");
diff --git a/htdocs/adherents/stats/geo.php b/htdocs/adherents/stats/geo.php
index 85157dc824d..ae128d940e8 100644
--- a/htdocs/adherents/stats/geo.php
+++ b/htdocs/adherents/stats/geo.php
@@ -53,7 +53,7 @@ $langs->load("companies");
* View
*/
-$arrayjs=array('http://www.google.com/jsapi');
+$arrayjs=array('https://www.google.com/jsapi');
if (! empty($conf->dol_use_jmobile)) $arrayjs=array();
$title=$langs->trans("Statistics");
diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php
index b9051f6f33a..76b3b060925 100644
--- a/htdocs/admin/agenda_other.php
+++ b/htdocs/admin/agenda_other.php
@@ -1,8 +1,9 @@
- * Copyright (C) 2011 Regis Houssin
- * Copyright (C) 2011-2013 Juanjo Menent
- * Copyright (C) 2015 Jean-François Ferry
+/* Copyright (C) 2008-2015 Laurent Destailleur
+ * Copyright (C) 2011 Regis Houssin
+ * Copyright (C) 2011-2013 Juanjo Menent
+ * Copyright (C) 2015 Jean-François Ferry
+ * Copyright (C) 2016 Charlie Benke
*
* 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
@@ -36,7 +37,11 @@ $langs->load("admin");
$langs->load("other");
$action = GETPOST('action','alpha');
+$value = GETPOST('value','alpha');
+$param = GETPOST('param','alpha');
$cancel = GETPOST('cancel','alpha');
+$scandir = GETPOST('scandir','alpha');
+$type = 'action';
/*
@@ -71,7 +76,21 @@ if (preg_match('/del_(.*)/',$action,$reg))
dol_print_error($db);
}
}
+// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...)
+if ($action == 'setModuleOptions')
+{
+ if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity);
+ if (! $res > 0) $error++;
+ if (! $error)
+ {
+ setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
+ }
+ else
+ {
+ setEventMessages($langs->trans("Error"), null, 'errors');
+ }
+}
if ($action == 'set')
{
dolibarr_set_const($db, 'AGENDA_USE_EVENT_TYPE_DEFAULT', GETPOST('AGENDA_USE_EVENT_TYPE_DEFAULT'), 'chaine', 0, '', $conf->entity);
@@ -79,6 +98,85 @@ if ($action == 'set')
dolibarr_set_const($db, 'AGENDA_DEFAULT_FILTER_STATUS', GETPOST('AGENDA_DEFAULT_FILTER_STATUS'), 'chaine', 0, '', $conf->entity);
dolibarr_set_const($db, 'AGENDA_DEFAULT_VIEW', GETPOST('AGENDA_DEFAULT_VIEW'), 'chaine', 0, '', $conf->entity);
}
+else if ($action == 'specimen') // For orders
+{
+ $modele=GETPOST('module','alpha');
+
+ $commande = new CommandeFournisseur($db);
+ $commande->initAsSpecimen();
+ $commande->thirdparty=$specimenthirdparty;
+
+ // Search template files
+ $file=''; $classname=''; $filefound=0;
+ $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
+ foreach($dirmodels as $reldir)
+ {
+ $file=dol_buildpath($reldir."core/modules/action/doc/pdf_".$modele.".modules.php",0);
+ if (file_exists($file))
+ {
+ $filefound=1;
+ $classname = "pdf_".$modele;
+ break;
+ }
+ }
+
+ if ($filefound)
+ {
+ require_once $file;
+
+ $module = new $classname($db,$commande);
+
+ if ($module->write_file($commande,$langs) > 0)
+ {
+ header("Location: ".DOL_URL_ROOT."/document.php?modulepart=action&file=SPECIMEN.pdf");
+ return;
+ }
+ else
+ {
+ setEventMessages($module->error, $module->errors, 'errors');
+ dol_syslog($module->error, LOG_ERR);
+ }
+ }
+ else
+ {
+ setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
+ dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
+ }
+}
+
+// Activate a model
+else if ($action == 'setmodel')
+{
+ print "sssd".$value;
+ $ret = addDocumentModel($value, $type, $label, $scandir);
+}
+
+else if ($action == 'del')
+{
+ $ret = delDocumentModel($value, $type);
+ if ($ret > 0)
+ {
+ if ($conf->global->ACTION_EVENT_ADDON_PDF == "$value") dolibarr_del_const($db, 'ACTION_EVENT_ADDON_PDF',$conf->entity);
+ }
+}
+
+// Set default model
+else if ($action == 'setdoc')
+{
+ if (dolibarr_set_const($db, "ACTION_EVENT_ADDON_PDF",$value,'chaine',0,'',$conf->entity))
+ {
+ // La constante qui a ete lue en avant du nouveau set
+ // on passe donc par une variable pour avoir un affichage coherent
+ $conf->global->ACTION_EVENT_ADDON_PDF = $value;
+ }
+
+ // On active le modele
+ $ret = delDocumentModel($value, $type);
+ if ($ret > 0)
+ {
+ $ret = addDocumentModel($value, $type, $label, $scandir);
+ }
+}
/**
@@ -86,7 +184,7 @@ if ($action == 'set')
*/
$formactions=new FormActions($db);
-
+$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
llxHeader();
$linkback=''.$langs->trans("BackToModuleList").' ';
@@ -95,14 +193,151 @@ print " \n";
-print '
';
print ' ';
+// Define $urlwithroot
+$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
+$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
+//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
+
+// Show message
+$message='';
+$url=''.$urlwithroot.'/api/index.php/login?login='.urlencode($user->login).'&password=yourpassword[&reset=1] ';
+$message.=$langs->trans("UrlToGetKeyToUseAPIs").': ';
+$message.=img_picto('','object_globe.png').' '.$url;
+print $message;
+print ' ';
+print ' ';
+
// Explorer
print ''.$langs->trans("ApiExporerIs").': ';
-$url=DOL_MAIN_URL_ROOT.'/api/admin/explorer.php';
+$url=DOL_MAIN_URL_ROOT.'/api/index.php/explorer';
print img_picto('','object_globe.png').' '.$url." \n";
diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php
index b3a2cdaf9d0..00621fdeb59 100644
--- a/htdocs/api/class/api.class.php
+++ b/htdocs/api/class/api.class.php
@@ -88,6 +88,17 @@ class DolibarrApi
// Remove $db object property for object
unset($object->db);
+ // Remove the $oldcopy property because it is not supported by the JSON
+ // encoder. The following error is generated when trying to serialize
+ // it: "Error encoding/decoding JSON: Type is not supported"
+ // Note: Event if this property was correctly handled by the JSON
+ // encoder, it should be ignored because keeping it would let the API
+ // have a very strange behavior: calling PUT and then GET on the same
+ // resource would give different results:
+ // PUT /objects/{id} -> returns object with oldcopy = previous version of the object
+ // GET /objects/{id} -> returns object with oldcopy empty
+ unset($object->oldcopy);
+
// If object has lines, remove $db property
if(isset($object->lines) && count($object->lines) > 0) {
$nboflines = count($object->lines);
diff --git a/htdocs/api/class/api_generic.class.php b/htdocs/api/class/api_login.class.php
similarity index 84%
rename from htdocs/api/class/api_generic.class.php
rename to htdocs/api/class/api_login.class.php
index 9a630a9da47..1fa08b96179 100644
--- a/htdocs/api/class/api_generic.class.php
+++ b/htdocs/api/class/api_login.class.php
@@ -18,14 +18,11 @@
use Luracast\Restler\RestException;
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
-require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php';
-
/**
- * API generic (login, status, ...)
- *
+ * API that allows to log in with an user account.
*/
-class GenericApi extends DolibarrApi
+class Login
{
function __construct() {
@@ -46,7 +43,7 @@ class GenericApi extends DolibarrApi
*
* @throws RestException
*/
- public function login($login, $password, $entity=0, $reset=0) {
+ public function index($login, $password, $entity=0, $reset=0) {
global $conf, $dolibarr_main_authentication, $dolibarr_auto_user;
@@ -103,20 +100,4 @@ class GenericApi extends DolibarrApi
)
);
}
-
- /**
- * Get status (Dolibarr version)
- *
- * @access protected
- * @class DolibarrApiAccess {@requires admin}
- */
- function status() {
- require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
- return array(
- 'success' => array(
- 'code' => 200,
- 'dolibarr_version' => DOL_VERSION
- )
- );
- }
}
diff --git a/htdocs/api/class/api_status.class.php b/htdocs/api/class/api_status.class.php
new file mode 100644
index 00000000000..2ac8da018d6
--- /dev/null
+++ b/htdocs/api/class/api_status.class.php
@@ -0,0 +1,40 @@
+
+ *
+ * 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 .
+ */
+
+require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
+
+
+/**
+ * API that gives the status of the Dolibarr instance.
+ *
+ * @access protected
+ * @class DolibarrApiAccess {@requires user,external}
+ */
+class Status
+{
+ /**
+ * Get status (Dolibarr version)
+ */
+ function index() {
+ return array(
+ 'success' => array(
+ 'code' => 200,
+ 'dolibarr_version' => DOL_VERSION
+ )
+ );
+ }
+}
diff --git a/htdocs/api/index.php b/htdocs/api/index.php
index 660c90d3476..b165a8b1c76 100644
--- a/htdocs/api/index.php
+++ b/htdocs/api/index.php
@@ -58,7 +58,10 @@ if (empty($conf->global->MAIN_MODULE_API))
$api = new DolibarrApi($db);
-$api->r->addAPIClass('Luracast\\Restler\\Resources'); //this creates resources.json at API Root
+// Enable the Restler API Explorer.
+// See https://github.com/Luracast/Restler-API-Explorer for more info.
+$api->r->addAPIClass('Luracast\\Restler\\Explorer');
+
$api->r->setSupportedFormats('JsonFormat', 'XmlFormat');
$api->r->addAuthenticationClass('DolibarrApiAccess','');
@@ -77,25 +80,19 @@ foreach ($modulesdir as $dir)
{
while (($file = readdir($handle))!==false)
{
- if (is_readable($dir.$file) && preg_match("/^(mod.*)\.class\.php$/i",$file,$reg))
+ if (is_readable($dir.$file) && preg_match("/^mod(.*)\.class\.php$/i",$file,$reg))
{
- $modulename=$reg[1];
+ $module = $part = strtolower($reg[1]);
- // Defined if module is enabled
- $enabled=true;
- $module=$part=$obj=strtolower(preg_replace('/^mod/i','',$modulename));
- //if ($part == 'propale') $part='propal';
- if ($module == 'societe') {
- $obj = 'thirdparty';
- }
if ($module == 'categorie') {
$part = 'categories';
- $obj = 'category';
}
if ($module == 'facture') {
$part = 'compta/facture';
- $obj = 'facture';
}
+
+ // Defined if module is enabled
+ $enabled=true;
if (empty($conf->$module->enabled)) $enabled=false;
if ($enabled)
@@ -115,17 +112,25 @@ foreach ($modulesdir as $dir)
{
while (($file_searched = readdir($handle_part))!==false)
{
- if (is_readable($dir_part.$file_searched) && preg_match("/^(api_.*)\.class\.php$/i",$file_searched,$reg))
+ // Support of the deprecated API.
+ if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$reg))
{
- $classname=$reg[1];
- $classname = str_replace('Api_','',ucwords($reg[1])).'Api';
- $classname = ucfirst($classname);
+ $classname = ucwords($reg[1]).'Api';
require_once $dir_part.$file_searched;
- if (class_exists($classname))
+ if (class_exists($classname))
{
- dol_syslog("Found API classname=".$classname);
- $api->r->addAPIClass($classname,'');
- $listofapis[]=array('classname'=>$classname, 'fullpath'=>$file_searched);
+ dol_syslog("Found deprecated API classname=".$classname);
+ $api->r->addAPIClass($classname, '');
+ }
+ }
+ elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$reg))
+ {
+ $classname = ucwords($reg[1]);
+ require_once $dir_part.$file_searched;
+ if (class_exists($classname))
+ {
+ dol_syslog("Found API classname=".$classname);
+ $listofapis[] = $classname;
}
}
}
@@ -136,6 +141,14 @@ foreach ($modulesdir as $dir)
}
}
+// Sort the classes before adding them to Restler. The Restler API Explorer
+// shows the classes in the order they are added and it's a mess if they are
+// not sorted.
+sort($listofapis);
+foreach ($listofapis as $classname)
+{
+ $api->r->addAPIClass($classname);
+}
// TODO If not found, redirect to explorer
diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php
new file mode 100644
index 00000000000..cab36132944
--- /dev/null
+++ b/htdocs/categories/class/api_categories.class.php
@@ -0,0 +1,355 @@
+
+ *
+ * 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.'/categories/class/categorie.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
+
+/**
+ * API class for categories
+ *
+ * @access protected
+ * @class DolibarrApiAccess {@requires user,external}
+ */
+class Categories extends DolibarrApi
+{
+ /**
+ * @var array $FIELDS Mandatory fields, checked when create and update object
+ */
+ static $FIELDS = array(
+ 'label',
+ 'type'
+ );
+
+ static $TYPES = array(
+ 0 => 'product',
+ 1 => 'supplier',
+ 2 => 'customer',
+ 3 => 'member',
+ 4 => 'contact',
+ 5 => 'account',
+ );
+
+ /**
+ * @var Categorie $category {@type Categorie}
+ */
+ public $category;
+
+ /**
+ * Constructor
+ */
+ function __construct()
+ {
+ global $db, $conf;
+ $this->db = $db;
+ $this->category = new Categorie($this->db);
+ }
+
+ /**
+ * Get properties of a category object
+ *
+ * Return an array with category informations
+ *
+ * @param int $id ID of category
+ * @return array|mixed data without useless information
+ *
+ * @throws RestException
+ */
+ function get($id)
+ {
+ if(! DolibarrApiAccess::$user->rights->categorie->lire) {
+ throw new RestException(401);
+ }
+
+ $result = $this->category->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'category not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('category',$this->category->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ return $this->_cleanObjectDatas($this->category);
+ }
+
+ /**
+ * List categories
+ *
+ * Get a list of categories
+ *
+ * @param string $type Type of category ('member', 'customer', 'supplier', 'product', 'contact')
+ * @param string $sortfield Sort field
+ * @param string $sortorder Sort order
+ * @param int $limit Limit for list
+ * @param int $page Page number
+ * @return array Array of category objects
+ *
+ * @throws RestException
+ */
+ function index($type = '', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) {
+ global $db, $conf;
+
+ $obj_ret = array();
+
+ if(! DolibarrApiAccess::$user->rights->categorie->lire) {
+ throw new RestException(401);
+ }
+
+ $sql = "SELECT s.rowid";
+ $sql.= " FROM ".MAIN_DB_PREFIX."categorie as s";
+ $sql.= ' WHERE s.entity IN ('.getEntity('categorie', 1).')';
+ if (!empty($type))
+ {
+ $sql.= ' AND s.type='.array_search($type,Categories::$TYPES);
+ }
+
+ $nbtotalofrecords = 0;
+ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
+ {
+ $result = $db->query($sql);
+ $nbtotalofrecords = $db->num_rows($result);
+ }
+
+ $sql.= $db->order($sortfield, $sortorder);
+ if ($limit) {
+ if ($page < 0)
+ {
+ $page = 0;
+ }
+ $offset = $limit * $page;
+
+ $sql.= $db->plimit($limit + 1, $offset);
+ }
+
+ $result = $db->query($sql);
+ if ($result)
+ {
+ $i=0;
+ $num = $db->num_rows($result);
+ while ($i < $num)
+ {
+ $obj = $db->fetch_object($result);
+ $category_static = new Categorie($db);
+ if($category_static->fetch($obj->rowid)) {
+ $obj_ret[] = parent::_cleanObjectDatas($category_static);
+ }
+ $i++;
+ }
+ }
+ else {
+ throw new RestException(503, 'Error when retrieve category list : '.$category_static->error);
+ }
+ if( ! count($obj_ret)) {
+ throw new RestException(404, 'No category found');
+ }
+ return $obj_ret;
+ }
+
+ /**
+ * List categories of an entity
+ *
+ * Note: This method is not directly exposed in the API, it is used
+ * in the GET /xxx/{id}/categories requests.
+ *
+ * @param string $type Type of category ('member', 'customer', 'supplier', 'product', 'contact')
+ * @param string $sortfield Sort field
+ * @param string $sortorder Sort order
+ * @param int $limit Limit for list
+ * @param int $page Page number
+ * @param int $item Id of the item to get categories for
+ * @return array Array of category objects
+ *
+ * @access private
+ */
+ function getListForItem($type, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $item = 0) {
+ global $db, $conf;
+
+ $obj_ret = array();
+
+ if(! DolibarrApiAccess::$user->rights->categorie->lire) {
+ throw new RestException(401);
+ }
+ //if ($type == "") {
+ //$type="product";
+ //}
+ $sub_type = $type;
+ $subcol_name = "fk_".$type;
+ if ($type=="customer" || $type=="supplier") {
+ $sub_type="societe";
+ $subcol_name="fk_soc";
+ }
+ if ($type=="contact") {
+ $subcol_name="fk_socpeople";
+ }
+ $sql = "SELECT s.rowid";
+ $sql.= " FROM ".MAIN_DB_PREFIX."categorie as s";
+ $sql.= " , ".MAIN_DB_PREFIX."categorie_".$sub_type." as sub ";
+ $sql.= ' WHERE s.entity IN ('.getEntity('categorie', 1).')';
+ $sql.= ' AND s.type='.array_search($type,Categories::$TYPES);
+ $sql.= ' AND s.rowid = sub.fk_categorie';
+ $sql.= ' AND sub.'.$subcol_name.' = '.$item;
+
+ $nbtotalofrecords = 0;
+ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
+ {
+ $result = $db->query($sql);
+ $nbtotalofrecords = $db->num_rows($result);
+ }
+
+ $sql.= $db->order($sortfield, $sortorder);
+ if ($limit) {
+ if ($page < 0)
+ {
+ $page = 0;
+ }
+ $offset = $limit * $page;
+
+ $sql.= $db->plimit($limit + 1, $offset);
+ }
+
+ $result = $db->query($sql);
+ if ($result)
+ {
+ $i=0;
+ $num = $db->num_rows($result);
+ while ($i < $num)
+ {
+ $obj = $db->fetch_object($result);
+ $category_static = new Categorie($db);
+ if($category_static->fetch($obj->rowid)) {
+ $obj_ret[] = parent::_cleanObjectDatas($category_static);
+ }
+ $i++;
+ }
+ }
+ else {
+ throw new RestException(503, 'Error when retrieve category list : '.$category_static->error);
+ }
+ if( ! count($obj_ret)) {
+ throw new RestException(404, 'No category found');
+ }
+ return $obj_ret;
+ }
+
+ /**
+ * Create category object
+ *
+ * @param array $request_data Request data
+ * @return int ID of category
+ */
+ function post($request_data = NULL)
+ {
+ if(! DolibarrApiAccess::$user->rights->categorie->creer) {
+ throw new RestException(401);
+ }
+ // Check mandatory fields
+ $result = $this->_validate($request_data);
+
+ foreach($request_data as $field => $value) {
+ $this->category->$field = $value;
+ }
+ if($this->category->create(DolibarrApiAccess::$user) < 0) {
+ throw new RestException(503, 'Error when create category : '.$this->category->error);
+ }
+ return $this->category->id;
+ }
+
+ /**
+ * Update category
+ *
+ * @param int $id Id of category to update
+ * @param array $request_data Datas
+ * @return int
+ */
+ function put($id, $request_data = NULL)
+ {
+ if(! DolibarrApiAccess::$user->rights->categorie->creer) {
+ throw new RestException(401);
+ }
+
+ $result = $this->category->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'category not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('category',$this->category->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ foreach($request_data as $field => $value) {
+ $this->category->$field = $value;
+ }
+
+ if($this->category->update(DolibarrApiAccess::$user))
+ return $this->get ($id);
+
+ return false;
+ }
+
+ /**
+ * Delete category
+ *
+ * @param int $id Category ID
+ * @return array
+ */
+ function delete($id)
+ {
+ if(! DolibarrApiAccess::$user->rights->categorie->supprimer) {
+ throw new RestException(401);
+ }
+ $result = $this->category->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'category not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('category',$this->category->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ if (! $this->category->delete(DolibarrApiAccess::$user)) {
+ throw new RestException(401,'error when delete category');
+ }
+
+ return array(
+ 'success' => array(
+ 'code' => 200,
+ 'message' => 'Category deleted'
+ )
+ );
+ }
+
+ /**
+ * Validate fields before create or update object
+ *
+ * @param array $data Data to validate
+ * @return array
+ *
+ * @throws RestException
+ */
+ function _validate($data)
+ {
+ $category = array();
+ foreach (Categories::$FIELDS as $field) {
+ if (!isset($data[$field]))
+ throw new RestException(400, "$field field missing");
+ $category[$field] = $data[$field];
+ }
+ return $category;
+ }
+}
diff --git a/htdocs/categories/class/api_category.class.php b/htdocs/categories/class/api_deprecated_category.class.php
similarity index 94%
rename from htdocs/categories/class/api_category.class.php
rename to htdocs/categories/class/api_deprecated_category.class.php
index f5a5b1f037d..656c769bed3 100644
--- a/htdocs/categories/class/api_category.class.php
+++ b/htdocs/categories/class/api_deprecated_category.class.php
@@ -27,7 +27,7 @@
* @access protected
* @class DolibarrApiAccess {@requires user,external}
*
- *
+ * @deprecated Use Categories instead (defined in api_categories.class.php)
*/
class CategoryApi extends DolibarrApi
{
@@ -54,7 +54,7 @@ class CategoryApi extends DolibarrApi
public $category;
/**
- * Constructor
+ * Constructor Warning: Deprecated
*
* @url GET category/
*
@@ -68,7 +68,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Get properties of a category object
+ * Get properties of a category object Warning: Deprecated
*
* Return an array with category informations
*
@@ -97,7 +97,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * List categories
+ * List categories Warning: Deprecated
*
* Get a list of categories
*
@@ -166,7 +166,7 @@ class CategoryApi extends DolibarrApi
return $obj_ret;
}
/**
- * List categories of an entity
+ * List categories of an entity Warning: Deprecated
*
* Get a list of categories
*
@@ -248,7 +248,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Get member categories list
+ * Get member categories list Warning: Deprecated
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
@@ -263,7 +263,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Get customer categories list
+ * Get customer categories list Warning: Deprecated
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
@@ -278,7 +278,7 @@ class CategoryApi extends DolibarrApi
return $this->getList('customer', $sortfield, $sortorder, $limit, $page);
}
/**
- * Get categories for a customer
+ * Get categories for a customer Warning: Deprecated
*
* @param int $cusid Customer id filter
* @param string $sortfield Sort field
@@ -295,7 +295,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Add category to customer
+ * Add category to customer Warning: Deprecated
*
* @param int $cusid Id of customer
* @param int $catid Id of category
@@ -329,7 +329,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Get supplier categories list
+ * Get supplier categories list Warning: Deprecated
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
@@ -345,7 +345,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Get product categories list
+ * Get product categories list Warning: Deprecated
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
@@ -361,7 +361,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Get contact categories list
+ * Get contact categories list Warning: Deprecated
*
* @param string $sortfield Sort field
* @param string $sortorder Sort order
@@ -376,7 +376,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Create category object
+ * Create category object Warning: Deprecated
*
* @param array $request_data Request data
* @return int ID of category
@@ -401,7 +401,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Update category
+ * Update category Warning: Deprecated
*
* @param int $id Id of category to update
* @param array $request_data Datas
@@ -435,7 +435,7 @@ class CategoryApi extends DolibarrApi
}
/**
- * Delete category
+ * Delete category Warning: Deprecated
*
* @param int $id Category ID
* @return array
diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php
index 406d7b5916c..a5016de7ec4 100644
--- a/htdocs/comm/action/class/actioncomm.class.php
+++ b/htdocs/comm/action/class/actioncomm.class.php
@@ -996,7 +996,7 @@ class ActionComm extends CommonObject
}
$this->date_creation = $this->db->jdate($obj->datec);
- $this->date_modification = $this->db->jdate($obj->datem);
+ if (! empty($obj->fk_user_mod)) $this->date_modification = $this->db->jdate($obj->datem);
}
$this->db->free($result);
}
diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
index d91ee35fe3e..81f101359f8 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -1472,7 +1472,7 @@ if ($action == 'create' && $user->rights->commande->creer)
print '';
} else {
print '';
- print $form->select_company('', 'socid', 's.client = 1 OR s.client = 3', 1);
+ print $form->select_company('', 'socid', 's.client = 1 OR s.client = 3', 'SelectThirdParty');
// reload page to retrieve customer informations
if (!empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE))
{
diff --git a/htdocs/commande/class/api_commande.class.php b/htdocs/commande/class/api_deprecated_commande.class.php
similarity index 95%
rename from htdocs/commande/class/api_commande.class.php
rename to htdocs/commande/class/api_deprecated_commande.class.php
index d6a2a3d0f82..2a8caf5321e 100644
--- a/htdocs/commande/class/api_commande.class.php
+++ b/htdocs/commande/class/api_deprecated_commande.class.php
@@ -29,7 +29,7 @@
* @category Api
* @package Api
*
- *
+ * @deprecated Use Orders instead (defined in api_orders.class.php)
*/
class CommandeApi extends DolibarrApi
{
@@ -47,7 +47,7 @@ class CommandeApi extends DolibarrApi
public $commande;
/**
- * Constructor
+ * Constructor Warning: Deprecated
*
* @url GET order/
*
@@ -60,7 +60,7 @@ class CommandeApi extends DolibarrApi
}
/**
- * Get properties of a commande object
+ * Get properties of a commande object Warning: Deprecated
*
* Return an array with commande informations
*
@@ -93,7 +93,7 @@ class CommandeApi extends DolibarrApi
}
/**
- * List orders
+ * List orders Warning: Deprecated
*
* Get a list of orders
*
@@ -181,7 +181,7 @@ class CommandeApi extends DolibarrApi
}
/**
- * List orders for specific thirdparty
+ * List orders for specific thirdparty Warning: Deprecated
*
* Get a list of orders
*
@@ -197,7 +197,7 @@ class CommandeApi extends DolibarrApi
/**
- * Create order object
+ * Create order object Warning: Deprecated
*
* @param array $request_data Request datas
*
@@ -230,7 +230,7 @@ class CommandeApi extends DolibarrApi
return $this->commande->id;
}
/**
- * Get lines of an order
+ * Get lines of an order Warning: Deprecated
*
*
* @param int $id Id of order
@@ -260,7 +260,7 @@ class CommandeApi extends DolibarrApi
return $result;
}
/**
- * Add a line to given order
+ * Add a line to given order Warning: Deprecated
*
*
* @param int $id Id of commande to update
@@ -319,7 +319,7 @@ class CommandeApi extends DolibarrApi
return false;
}
/**
- * Update a line to given order
+ * Update a line to given order Warning: Deprecated
*
*
* @param int $id Id of commande to update
@@ -376,7 +376,7 @@ class CommandeApi extends DolibarrApi
return false;
}
/**
- * Delete a line to given order
+ * Delete a line to given order Warning: Deprecated
*
*
* @param int $id Id of commande to update
@@ -408,7 +408,7 @@ class CommandeApi extends DolibarrApi
}
/**
- * Update order general fields (won't touch lines of order)
+ * Update order general fields (won't touch lines of order) Warning: Deprecated
*
* @param int $id Id of commande to update
* @param array $request_data Datas
@@ -441,7 +441,7 @@ class CommandeApi extends DolibarrApi
}
/**
- * Delete order
+ * Delete order Warning: Deprecated
*
* @param int $id Order ID
*
@@ -477,7 +477,7 @@ class CommandeApi extends DolibarrApi
}
/**
- * Validate an order
+ * Validate an order Warning: Deprecated
*
* @param int $id Order ID
* @param int $idwarehouse Warehouse ID
diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php
new file mode 100644
index 00000000000..1f560775b7b
--- /dev/null
+++ b/htdocs/commande/class/api_orders.class.php
@@ -0,0 +1,498 @@
+
+ *
+ * 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.'/commande/class/commande.class.php';
+
+/**
+ * API class for orders
+ *
+ * @access protected
+ * @class DolibarrApiAccess {@requires user,external}
+ */
+class Orders extends DolibarrApi
+{
+
+ /**
+ * @var array $FIELDS Mandatory fields, checked when create and update object
+ */
+ static $FIELDS = array(
+ 'socid'
+ );
+
+ /**
+ * @var Commande $commande {@type Commande}
+ */
+ public $commande;
+
+ /**
+ * Constructor
+ */
+ function __construct()
+ {
+ global $db, $conf;
+ $this->db = $db;
+ $this->commande = new Commande($this->db);
+ }
+
+ /**
+ * Get properties of a commande object
+ *
+ * Return an array with commande informations
+ *
+ * @param int $id ID of order
+ * @return array|mixed data without useless information
+ *
+ * @throws RestException
+ */
+ function get($id)
+ {
+ if(! DolibarrApiAccess::$user->rights->commande->lire) {
+ throw new RestException(401);
+ }
+
+ $result = $this->commande->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Order not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ $this->commande->fetchObjectLinked();
+ return $this->_cleanObjectDatas($this->commande);
+ }
+
+ /**
+ * List orders
+ *
+ * Get a list of orders
+ *
+ * @param string $sortfield Sort field
+ * @param string $sortorder Sort order
+ * @param int $limit Limit for list
+ * @param int $page Page number
+ * @param string $societe Societe filter field
+ *
+ * @return array Array of order objects
+ */
+ function index($sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $societe = 0) {
+ global $db, $conf;
+
+ $obj_ret = array();
+ // case of external user, $societe param is ignored and replaced by user's socid
+ $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $societe;
+
+ // If the internal user must only see his customers, force searching by him
+ if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id;
+
+ $sql = "SELECT s.rowid";
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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."commande as s";
+
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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 s.entity IN ('.getEntity('commande', 1).')';
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND s.fk_soc = sc.fk_soc";
+ if ($socid) $sql.= " AND s.fk_soc = ".$socid;
+ if ($search_sale > 0) $sql.= " AND s.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;
+ }
+
+ $nbtotalofrecords = 0;
+ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
+ {
+ $result = $db->query($sql);
+ $nbtotalofrecords = $db->num_rows($result);
+ }
+
+ $sql.= $db->order($sortfield, $sortorder);
+ if ($limit) {
+ if ($page < 0)
+ {
+ $page = 0;
+ }
+ $offset = $limit * $page;
+
+ $sql.= $db->plimit($limit + 1, $offset);
+ }
+
+ $result = $db->query($sql);
+
+ if ($result)
+ {
+ $num = $db->num_rows($result);
+ while ($i < $num)
+ {
+ $obj = $db->fetch_object($result);
+ $commande_static = new Commande($db);
+ if($commande_static->fetch($obj->rowid)) {
+ $obj_ret[] = parent::_cleanObjectDatas($commande_static);
+ }
+ $i++;
+ }
+ }
+ else {
+ throw new RestException(503, 'Error when retrieve commande list');
+ }
+ if( ! count($obj_ret)) {
+ throw new RestException(404, 'No commande found');
+ }
+ return $obj_ret;
+ }
+
+ /**
+ * Create order object
+ *
+ * @param array $request_data Request data
+ * @return int ID of commande
+ */
+ function post($request_data = NULL)
+ {
+ if(! DolibarrApiAccess::$user->rights->commande->creer) {
+ throw new RestException(401, "Insuffisant rights");
+ }
+ // Check mandatory fields
+ $result = $this->_validate($request_data);
+
+ foreach($request_data as $field => $value) {
+ $this->commande->$field = $value;
+ }
+ if (isset($request_data["lines"])) {
+ $lines = array();
+ foreach ($request_data["lines"] as $line) {
+ array_push($lines, (object) $line);
+ }
+ $this->commande->lines = $lines;
+ }
+ if(! $this->commande->create(DolibarrApiAccess::$user) ) {
+ throw new RestException(500, "Error while creating order");
+ }
+
+ return $this->commande->id;
+ }
+
+ /**
+ * Get lines of an order
+ *
+ * @param int $id Id of order
+ *
+ * @url GET {id}/lines
+ *
+ * @return int
+ */
+ function getLines($id) {
+ if(! DolibarrApiAccess::$user->rights->commande->lire) {
+ throw new RestException(401);
+ }
+
+ $result = $this->commande->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Commande not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+ $this->commande->getLinesArray();
+ $result = array();
+ foreach ($this->commande->lines as $line) {
+ array_push($result,$this->_cleanObjectDatas($line));
+ }
+ return $result;
+ }
+
+ /**
+ * Add a line to given order
+ *
+ * @param int $id Id of commande to update
+ * @param array $request_data Orderline data
+ *
+ * @url POST {id}/lines
+ *
+ * @return int
+ */
+ function postLine($id, $request_data = NULL) {
+ if(! DolibarrApiAccess::$user->rights->commande->creer) {
+ throw new RestException(401);
+ }
+
+ $result = $this->commande->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Commande not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+ $request_data = (object) $request_data;
+ $updateRes = $this->commande->addline(
+ $request_data->desc,
+ $request_data->subprice,
+ $request_data->qty,
+ $request_data->tva_tx,
+ $request_data->localtax1_tx,
+ $request_data->localtax2_tx,
+ $request_data->fk_product,
+ $request_data->remise_percent,
+ $request_data->info_bits,
+ $request_data->fk_remise_except,
+ 'HT',
+ 0,
+ $request_data->date_start,
+ $request_data->date_end,
+ $request_data->product_type,
+ $request_data->rang,
+ $request_data->special_code,
+ $fk_parent_line,
+ $request_data->fk_fournprice,
+ $request_data->pa_ht,
+ $request_data->label,
+ $request_data->array_options,
+ $request_data->fk_unit,
+ $this->element,
+ $request_data->id
+ );
+
+ if ($updateRes > 0) {
+ return $this->get($id)->line->rowid;
+
+ }
+ return false;
+ }
+
+ /**
+ * Update a line to given order
+ *
+ * @param int $id Id of commande to update
+ * @param int $lineid Id of line to update
+ * @param array $request_data Orderline data
+ *
+ * @url PUT {id}/lines/{lineid}
+ *
+ * @return object
+ */
+ function putLine($id, $lineid, $request_data = NULL) {
+ if(! DolibarrApiAccess::$user->rights->commande->creer) {
+ throw new RestException(401);
+ }
+
+ $result = $this->commande->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Commande not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+ $request_data = (object) $request_data;
+ $updateRes = $this->commande->updateline(
+ $lineid,
+ $request_data->desc,
+ $request_data->subprice,
+ $request_data->qty,
+ $request_data->remise_percent,
+ $request_data->tva_tx,
+ $request_data->localtax1_tx,
+ $request_data->localtax2_tx,
+ 'HT',
+ $request_data->info_bits,
+ $request_data->date_start,
+ $request_data->date_end,
+ $request_data->product_type,
+ $request_data->fk_parent_line,
+ 0,
+ $request_data->fk_fournprice,
+ $request_data->pa_ht,
+ $request_data->label,
+ $request_data->special_code,
+ $request_data->array_options,
+ $request_data->fk_unit
+ );
+
+ if ($updateRes > 0) {
+ $result = $this->get($id);
+ unset($result->line);
+ return $this->_cleanObjectDatas($result);
+ }
+ return false;
+ }
+
+ /**
+ * Delete a line to given order
+ *
+ *
+ * @param int $id Id of commande to update
+ * @param int $lineid Id of line to delete
+ *
+ * @url DELETE {id}/lines/{lineid}
+ *
+ * @return int
+ */
+ function delLine($id, $lineid) {
+ if(! DolibarrApiAccess::$user->rights->commande->creer) {
+ throw new RestException(401);
+ }
+
+ $result = $this->commande->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Commande not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+ $request_data = (object) $request_data;
+ $updateRes = $this->commande->deleteline($lineid);
+ if ($updateRes == 1) {
+ return $this->get($id);
+ }
+ return false;
+ }
+
+ /**
+ * Update order general fields (won't touch lines of order)
+ *
+ * @param int $id Id of commande to update
+ * @param array $request_data Datas
+ *
+ * @return int
+ */
+ function put($id, $request_data = NULL) {
+ if(! DolibarrApiAccess::$user->rights->commande->creer) {
+ throw new RestException(401);
+ }
+
+ $result = $this->commande->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Commande not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+ foreach($request_data as $field => $value) {
+ $this->commande->$field = $value;
+ }
+
+ if($this->commande->update($id, DolibarrApiAccess::$user,1,'','','update'))
+ return $this->get($id);
+
+ return false;
+ }
+
+ /**
+ * Delete order
+ *
+ * @param int $id Order ID
+ *
+ * @return array
+ */
+ function delete($id)
+ {
+ if(! DolibarrApiAccess::$user->rights->commande->supprimer) {
+ throw new RestException(401);
+ }
+ $result = $this->commande->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Order not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ if( ! $this->commande->delete(DolibarrApiAccess::$user)) {
+ throw new RestException(500, 'Error when delete order : '.$this->commande->error);
+ }
+
+ return array(
+ 'success' => array(
+ 'code' => 200,
+ 'message' => 'Order deleted'
+ )
+ );
+
+ }
+
+ /**
+ * Validate an order
+ *
+ * @param int $id Order ID
+ * @param int $idwarehouse Warehouse ID
+ *
+ * @url POST {id}/validate
+ *
+ * @return array
+ * FIXME An error 403 is returned if the request has an empty body.
+ * Error message: "Forbidden: Content type `text/plain` is not supported."
+ * Workaround: send this in the body
+ * {
+ * "idwarehouse": 0
+ * }
+ */
+ function validate($id, $idwarehouse=0)
+ {
+ if(! DolibarrApiAccess::$user->rights->commande->creer) {
+ throw new RestException(401);
+ }
+ $result = $this->commande->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Order not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ if( ! $this->commande->valid(DolibarrApiAccess::$user, $idwarehouse)) {
+ throw new RestException(500, 'Error when validate order');
+ }
+
+ return array(
+ 'success' => array(
+ 'code' => 200,
+ 'message' => 'Order validated'
+ )
+ );
+ }
+
+ /**
+ * Validate fields before create or update object
+ *
+ * @param array $data Array with data to verify
+ * @return array
+ * @throws RestException
+ */
+ function _validate($data)
+ {
+ $commande = array();
+ foreach (Orders::$FIELDS as $field) {
+ if (!isset($data[$field]))
+ throw new RestException(400, "$field field missing");
+ $commande[$field] = $data[$field];
+
+ }
+ return $commande;
+ }
+}
diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
index 3a062788059..6ded9b219ac 100644
--- a/htdocs/commande/list.php
+++ b/htdocs/commande/list.php
@@ -50,6 +50,10 @@ $langs->load('bills');
$action=GETPOST('action','alpha');
$massaction=GETPOST('massaction','alpha');
+$show_files=GETPOST('show_files','int');
+$confirm=GETPOST('confirm','alpha');
+$toselect = GETPOST('toselect', 'array');
+
$orderyear=GETPOST("orderyear","int");
$ordermonth=GETPOST("ordermonth","int");
$orderday=GETPOST("orderday","int");
@@ -72,7 +76,6 @@ $search_sale=GETPOST('search_sale','int');
$search_total_ht=GETPOST('search_total_ht','alpha');
$optioncss = GETPOST('optioncss','alpha');
$billed = GETPOST('billed','int');
-$toselect = GETPOST('toselect', 'array');
// Security check
$id = (GETPOST('orderid')?GETPOST('orderid','int'):GETPOST('id','int'));
@@ -151,7 +154,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab
*/
if (GETPOST('cancel')) { $action='list'; $massaction=''; }
-if (! GETPOST('confirmmassaction')) { $massaction=''; }
+if (! GETPOST('confirmmassaction') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
$parameters=array('socid'=>$socid);
$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
@@ -192,161 +195,11 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETP
if (empty($reshook))
{
- // Mass actions. Controls on number of lines checked
- $maxformassaction=1000;
- if (! empty($massaction) && count($toselect) < 1)
- {
- $error++;
- setEventMessages($langs->trans("NoLineChecked"), null, "warnings");
- }
- if (! $error && count($toselect) > $maxformassaction)
- {
- setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors');
- $error++;
- }
-
- // TODO Use a common inc.php file
- if (! $error && $massaction == 'delete' && $user->rights->commande->supprimer)
- {
- $db->begin();
-
- $objecttmp=new Commande($db);
- $nbok = 0;
- foreach($toselect as $toselectid)
- {
- $result=$objecttmp->fetch($toselectid);
- if ($result > 0)
- {
- $result = $objecttmp->delete($user);
- if ($result <= 0)
- {
- setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
- $error++;
- break;
- }
- else $nbok++;
- }
- else
- {
- setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
- $error++;
- break;
- }
- }
-
- if (! $error)
- {
- if ($nbok > 1) setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs');
- else setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs');
- $db->commit();
- }
- else
- {
- $db->rollback();
- }
- //var_dump($listofobjectthirdparties);exit;
- }
-
- if (! $error && $massaction == "builddoc" && $user->rights->commande->lire && ! GETPOST('button_search'))
- {
- require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
- require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
- require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-
- $objecttmp=new Commande($db);
- $listofobjectid=array();
- $listofobjectthirdparties=array();
- $listofobjectref=array();
- foreach($toselect as $toselectid)
- {
- $objecttmp=new Commande($db); // must create new instance because instance is saved into $listofobjectref array for future use
- $result=$objecttmp->fetch($toselectid);
- if ($result > 0)
- {
- $listoinvoicesid[$toselectid]=$toselectid;
- $thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid;
- $listofobjectthirdparties[$thirdpartyid]=$thirdpartyid;
- $listofobjectref[$toselectid]=$objecttmp->ref;
- }
- }
-
- $arrayofinclusion=array();
- foreach($listofobjectref as $tmppdf) $arrayofinclusion[]=preg_quote($tmppdf.'.pdf','/');
- $listoffiles = dol_dir_list($conf->commande->dir_output,'all',1,implode('|',$arrayofinclusion),'\.meta$|\.png','date',SORT_DESC,0,true);
-
- // build list of files with full path
- $files = array();
- foreach($listofobjectref as $basename)
- {
- foreach($listoffiles as $filefound)
- {
- if (strstr($filefound["name"],$basename))
- {
- $files[] = $conf->commande->dir_output.'/'.$basename.'/'.$filefound["name"];
- break;
- }
- }
- }
-
- // Define output language (Here it is not used because we do only merging existing PDF)
- $outputlangs = $langs;
- $newlang='';
- if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
- if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->thirdparty->default_lang;
- if (! empty($newlang))
- {
- $outputlangs = new Translate("",$conf);
- $outputlangs->setDefaultLang($newlang);
- }
-
- // Create empty PDF
- $pdf=pdf_getInstance();
- if (class_exists('TCPDF'))
- {
- $pdf->setPrintHeader(false);
- $pdf->setPrintFooter(false);
- }
- $pdf->SetFont(pdf_getPDFFont($outputlangs));
-
- if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
-
- // Add all others
- foreach($files as $file)
- {
- // Charge un document PDF depuis un fichier.
- $pagecount = $pdf->setSourceFile($file);
- for ($i = 1; $i <= $pagecount; $i++)
- {
- $tplidx = $pdf->importPage($i);
- $s = $pdf->getTemplatesize($tplidx);
- $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
- $pdf->useTemplate($tplidx);
- }
- }
-
- // Create output dir if not exists
- dol_mkdir($diroutputmassaction);
-
- // Save merged file
- $filename=strtolower(dol_sanitizeFileName($langs->transnoentities("Orders")));
- if ($year) $filename.='_'.$year;
- if ($month) $filename.='_'.$month;
- if ($pagecount)
- {
- $now=dol_now();
- $file=$diroutputmassaction.'/'.$filename.'_'.dol_print_date($now,'dayhourlog').'.pdf';
- $pdf->Output($file,'F');
- if (! empty($conf->global->MAIN_UMASK))
- @chmod($file, octdec($conf->global->MAIN_UMASK));
-
- $langs->load("exports");
- setEventMessages($langs->trans('FileSuccessfullyBuilt',$filename.'_'.dol_print_date($now,'dayhourlog')), null, 'mesgs');
- }
- else
- {
- setEventMessages($langs->trans('NoPDFAvailableForDocGenAmongChecked'), null, 'errors');
- }
- }
+ $objectclass='Commande';
+ $permtoread = $user->rights->commande->lire;
+ $permtodelete = $user->rights->commande->supprimer;
+ $uploaddir = $conf->commande->dir_output;
+ include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
@@ -547,7 +400,8 @@ if ($resql)
if ($search_total_ht != '') $param.='&search_total_ht='.$search_total_ht;
if ($search_total_vat != '') $param.='&search_total_vat='.$search_total_vat;
if ($search_total_ttc != '') $param.='&search_total_ttc='.$search_total_ttc;
- if ($optioncss != '') $param.='&optioncss='.$optioncss;
+ if ($show_files) $param.='&show_files=' .$show_files;
+ if ($optioncss != '') $param.='&optioncss='.$optioncss;
// Add $param from extra fields
foreach ($search_array_options as $key => $val)
{
@@ -557,8 +411,8 @@ if ($resql)
}
$arrayofmassactions = array(
- //'presend'=>$langs->trans("SendByMail"),
- //'builddoc'=>$langs->trans("PDFMerge"),
+ 'presend'=>$langs->trans("SendByMail"),
+ 'builddoc'=>$langs->trans("PDFMerge"),
);
if ($user->rights->commande->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete");
if ($massaction == 'presend') $arrayofmassactions=array();
@@ -576,6 +430,102 @@ if ($resql)
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, '', '', $limit);
+ if ($massaction == 'presend')
+ {
+ $langs->load("mails");
+
+ if (! GETPOST('cancel'))
+ {
+ $objecttmp=new Commande($db);
+ $listofselectedid=array();
+ $listofselectedthirdparties=array();
+ $listofselectedref=array();
+ foreach($arrayofselected as $toselectid)
+ {
+ $result=$objecttmp->fetch($toselectid);
+ if ($result > 0)
+ {
+ $listofselectedid[$toselectid]=$toselectid;
+ $thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid;
+ $listofselectedthirdparties[$thirdpartyid]=$thirdpartyid;
+ $listofselectedref[$thirdpartyid][$toselectid]=$objecttmp->ref;
+ }
+ }
+ }
+
+ print ' ';
+
+ include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+ $formmail = new FormMail($db);
+
+ dol_fiche_head(null, '', '');
+
+ $topicmail="SendOrderRef";
+ $modelmail="order_send";
+
+ // Cree l'objet formulaire mail
+ include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
+ $formmail = new FormMail($db);
+ $formmail->withform=-1;
+ $formmail->fromtype = 'user';
+ $formmail->fromid = $user->id;
+ $formmail->fromname = $user->getFullName($langs);
+ $formmail->frommail = $user->email;
+ if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 1)) // If bit 1 is set
+ {
+ $formmail->trackid='ord'.$object->id;
+ }
+ if (! empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) // If bit 2 is set
+ {
+ include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+ $formmail->frommail=dolAddEmailTrackId($formmail->frommail, 'ord'.$object->id);
+ }
+ $formmail->withfrom=1;
+ $liste=$langs->trans("AllRecipientSelected");
+ if (count($listofselectedthirdparties) == 1)
+ {
+ $liste=array();
+ $thirdpartyid=array_shift($listofselectedthirdparties);
+ $soc=new Societe($db);
+ $soc->fetch($thirdpartyid);
+ foreach ($soc->thirdparty_and_contact_email_array(1) as $key=>$value)
+ {
+ $liste[$key]=$value;
+ }
+ $formmail->withtoreadonly=0;
+ }
+ else
+ {
+ $formmail->withtoreadonly=1;
+ }
+ $formmail->withto=$liste;
+ $formmail->withtofree=0;
+ $formmail->withtocc=1;
+ $formmail->withtoccc=$conf->global->MAIN_EMAIL_USECCC;
+ $formmail->withtopic=$langs->transnoentities($topicmail, '__REF__', '__REFCLIENT__');
+ $formmail->withfile=$langs->trans("OnlyPDFattachmentSupported");
+ $formmail->withbody=1;
+ $formmail->withdeliveryreceipt=1;
+ $formmail->withcancel=1;
+ // Tableau des substitutions
+ $formmail->substit['__REF__']='__REF__'; // We want to keep the tag
+ $formmail->substit['__SIGNATURE__']=$user->signature;
+ $formmail->substit['__REFCLIENT__']='__REFCLIENT__'; // We want to keep the tag
+ $formmail->substit['__PERSONALIZED__']='';
+ $formmail->substit['__CONTACTCIVNAME__']='';
+
+ // Tableau des parametres complementaires du post
+ $formmail->param['action']=$action;
+ $formmail->param['models']=$modelmail;
+ $formmail->param['models_id']=GETPOST('modelmailselected','int');
+ $formmail->param['id']=join(',',$arrayofselected);
+ //$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id;
+
+ print $formmail->get_form();
+
+ dol_fiche_end();
+ }
+
if ($sall)
{
foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
@@ -1156,7 +1106,7 @@ if ($resql)
// Action column
print ' ';
- if ($massactionbutton)
+ if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
{
$selected=0;
if (in_array($obj->rowid, $arrayofselected)) $selected=1;
@@ -1204,6 +1154,30 @@ if ($resql)
print ''."\n";
print ' '.img_help(1,'').' '.$langs->trans("ToBillSeveralOrderSelectCustomer", $langs->transnoentitiesnoconv("CreateInvoiceForThisCustomer")).' ';
+
+ if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files)
+ {
+ /*
+ * Show list of available documents
+ */
+ $urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
+ $urlsource.=str_replace('&','&',$param);
+
+ $filedir=$diroutputmassaction;
+ $genallowed=$user->rights->facture->lire;
+ $delallowed=$user->rights->facture->lire;
+
+ print ' ';
+ $paramwithoutshowfiles=preg_replace('/show_files=1&?/','',$param);
+ $title=$langs->trans("MassFilesArea").' ('.$langs->trans("Hide").') ';
+
+ print $formfile->showdocuments('massfilesarea_orders','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,'');
+ }
+ else
+ {
+ print ''.$langs->trans("ShowTempMassFilesArea").' ';
+ }
+
}
else
{
diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php
index f072a066ec0..68db9aba5e0 100644
--- a/htdocs/compta/bank/class/account.class.php
+++ b/htdocs/compta/bank/class/account.class.php
@@ -258,6 +258,10 @@ class Account extends CommonObject
$string .= $this->code_guichet.' ';
} elseif ($val == 'BankAccountNumberKey') {
$string .= $this->cle_rib.' ';
+ }elseif ($val == 'BIC') {
+ $string .= $this->bic.' ';
+ }elseif ($val == 'IBAN') {
+ $string .= $this->iban.' ';
}
}
@@ -1151,9 +1155,9 @@ class Account extends CommonObject
if ($user->societe_id) {
return 0;
}
-
+
$nb=0;
-
+
$sql = "SELECT COUNT(ba.rowid) as nb";
$sql.= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
$sql.= " WHERE ba.rappro > 0 and ba.clos = 0";
@@ -1169,7 +1173,7 @@ class Account extends CommonObject
return $nb;
}
-
+
/**
* Return clicable name (with picto eventually)
*
@@ -1204,7 +1208,7 @@ class Account extends CommonObject
$link = 'label.$linkend;
return $result;
@@ -1293,6 +1297,55 @@ class Account extends CommonObject
return 0;
}
+ /**
+ * Return 1 is IBAN is need for UE country
+ *
+ * @return int 1 yes / 0 No
+ */
+ function needIBAN()
+ {
+ $country_code=$this->getCountryCode();
+
+ $country_code_in_EEC=array(
+ 'AT', // Austria
+ 'BE', // Belgium
+ 'BG', // Bulgaria
+ 'CY', // Cyprus
+ 'CZ', // Czech republic
+ 'DE', // Germany
+ 'DK', // Danemark
+ 'EE', // Estonia
+ 'ES', // Spain
+ 'FI', // Finland
+ 'FR', // France
+ 'GB', // United Kingdom
+ 'GR', // Greece
+ 'HR', // Croatia
+ 'NL', // Holland
+ 'HU', // Hungary
+ 'IE', // Ireland
+ 'IM', // Isle of Man - Included in UK
+ 'IT', // Italy
+ 'LT', // Lithuania
+ 'LU', // Luxembourg
+ 'LV', // Latvia
+ 'MC', // Monaco - Included in France
+ 'MT', // Malta
+ //'NO', // Norway
+ 'PL', // Poland
+ 'PT', // Portugal
+ 'RO', // Romania
+ 'SE', // Sweden
+ 'SK', // Slovakia
+ 'SI', // Slovenia
+ 'UK', // United Kingdom
+ //'CH', // Switzerland - No. Swizerland in not in EEC
+ );
+
+ if (in_array($country_code,$country_code_in_EEC)) return 1; // France, Spain, Gabon, ...
+ return 0;
+ }
+
/**
* Load miscellaneous information for tab "Info"
*
@@ -1323,18 +1376,26 @@ class Account extends CommonObject
$detailedBBAN = $this->useDetailedBBAN();
if ($detailedBBAN == 0) {
- return array(
- 'BankAccountNumber'
+ $fieldarray= array(
+ 'BankAccountNumber'
);
} elseif ($detailedBBAN == 2) {
- return array(
- 'BankCode',
- 'BankAccountNumber'
+ $fieldarray= array(
+ 'BankCode',
+ 'BankAccountNumber'
);
+ } else {
+ $fieldarray=self::getAccountNumberOrder();
+ }
+
+ if ($this->needIBAN()) {
+ $fieldarray[]='IBAN';
+ $fieldarray[]='BIC';
}
//Get the order the properties are shown
- return self::getAccountNumberOrder();
+ return $fieldarray;
+
}
/**
@@ -1352,10 +1413,10 @@ class Account extends CommonObject
global $conf;
$fieldlists = array(
- 'BankCode',
- 'DeskCode',
- 'BankAccountNumber',
- 'BankAccountNumberKey'
+ 'BankCode',
+ 'DeskCode',
+ 'BankAccountNumber',
+ 'BankAccountNumberKey'
);
if (!empty($conf->global->BANK_SHOW_ORDER_OPTION)) {
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index b2b39e375d7..b6e7fc463e1 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -188,7 +188,7 @@ if (empty($reshook))
$qualified_for_stock_change = $object->hasProductsOrServices(1);
}
- $result = $object->delete(0, 0, $idwarehouse);
+ $result = $object->delete($user, 0, $idwarehouse);
if ($result > 0) {
header('Location: ' . DOL_URL_ROOT . '/compta/facture/list.php');
exit();
diff --git a/htdocs/compta/facture/class/api_invoice.class.php b/htdocs/compta/facture/class/api_deprecated_invoice.class.php
similarity index 95%
rename from htdocs/compta/facture/class/api_invoice.class.php
rename to htdocs/compta/facture/class/api_deprecated_invoice.class.php
index 60098a38b9f..826cc7371a4 100644
--- a/htdocs/compta/facture/class/api_invoice.class.php
+++ b/htdocs/compta/facture/class/api_deprecated_invoice.class.php
@@ -25,7 +25,7 @@
* @smart-auto-routing false
* @access protected
* @class DolibarrApiAccess {@requires user,external}
- *
+ * @deprecated Use Invoices instead (defined in api_invoices.class.php)
*/
class InvoiceApi extends DolibarrApi
{
@@ -43,7 +43,7 @@ class InvoiceApi extends DolibarrApi
public $invoice;
/**
- * Constructor
+ * Constructor Warning: Deprecated
*
* @url GET invoice/
*
@@ -56,7 +56,7 @@ class InvoiceApi extends DolibarrApi
}
/**
- * Get properties of a invoice object
+ * Get properties of a invoice object Warning: Deprecated
*
* Return an array with invoice informations
*
@@ -85,7 +85,7 @@ class InvoiceApi extends DolibarrApi
}
/**
- * List invoices
+ * List invoices Warning: Deprecated
*
* Get a list of invoices
*
@@ -179,7 +179,7 @@ class InvoiceApi extends DolibarrApi
}
/**
- * Create invoice object
+ * Create invoice object Warning: Deprecated
*
* @param array $request_data Request datas
* @return int ID of invoice
@@ -207,7 +207,7 @@ class InvoiceApi extends DolibarrApi
}
/**
- * Update invoice
+ * Update invoice Warning: Deprecated
*
* @param int $id Id of invoice to update
* @param array $request_data Datas
@@ -241,7 +241,7 @@ class InvoiceApi extends DolibarrApi
}
/**
- * Delete invoice
+ * Delete invoice Warning: Deprecated
*
* @param int $id Invoice ID
* @return type
@@ -262,7 +262,7 @@ class InvoiceApi extends DolibarrApi
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
- if( !$this->invoice->delete($id))
+ if( !$this->invoice->delete(DolibarrApiAccess::$user))
{
throw new RestException(500);
}
diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php
new file mode 100644
index 00000000000..8fc6274b1a6
--- /dev/null
+++ b/htdocs/compta/facture/class/api_invoices.class.php
@@ -0,0 +1,281 @@
+
+ *
+ * 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.'/compta/facture/class/facture.class.php';
+
+/**
+ * API class for invoices
+ *
+ * @access protected
+ * @class DolibarrApiAccess {@requires user,external}
+ */
+class Invoices extends DolibarrApi
+{
+ /**
+ *
+ * @var array $FIELDS Mandatory fields, checked when create and update object
+ */
+ static $FIELDS = array(
+ 'socid'
+ );
+
+ /**
+ * @var Facture $invoice {@type Facture}
+ */
+ public $invoice;
+
+ /**
+ * Constructor
+ */
+ function __construct()
+ {
+ global $db, $conf;
+ $this->db = $db;
+ $this->invoice = new Facture($this->db);
+ }
+
+ /**
+ * Get properties of a invoice object
+ *
+ * Return an array with invoice informations
+ *
+ * @param int $id ID of invoice
+ * @return array|mixed data without useless information
+ *
+ * @throws RestException
+ */
+ function get($id)
+ {
+ if(! DolibarrApiAccess::$user->rights->facture->lire) {
+ throw new RestException(401);
+ }
+
+ $result = $this->invoice->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Facture not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ return $this->_cleanObjectDatas($this->invoice);
+ }
+
+ /**
+ * List invoices
+ *
+ * Get a list of invoices
+ *
+ * FIXME this parameter is overwritten in the code and thus ignored
+ * @param int $socid Filter list with thirdparty ID
+ * @param string $status Filter by invoice status : draft | unpaid | paid | cancelled
+ * @param string $sortfield Sort field
+ * @param string $sortorder Sort order
+ * @param int $limit Limit for list
+ * @param int $page Page number
+ * @return array Array of invoice objects
+ *
+ * @throws RestException
+ */
+ function index($socid=0, $status='', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0) {
+ global $db, $conf;
+
+ $obj_ret = array();
+
+ $socid = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : '';
+
+ // If the internal user must only see his customers, force searching by him
+ if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id;
+
+ $sql = "SELECT s.rowid";
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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."facture as s";
+
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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 s.entity IN ('.getEntity('facture', 1).')';
+ if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= " AND s.fk_soc = sc.fk_soc";
+ if ($socid) $sql.= " AND s.fk_soc = ".$socid;
+ if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
+
+
+ // Filter by status
+ if ($status == 'draft') $sql.= " AND s.fk_statut IN (0)";
+ if ($status == 'unpaid') $sql.= " AND s.fk_statut IN (1)";
+ if ($status == 'paid') $sql.= " AND s.fk_statut IN (2)";
+ if ($status == 'cancelled') $sql.= " AND s.fk_statut IN (3)";
+
+ // Insert sale filter
+ if ($search_sale > 0)
+ {
+ $sql .= " AND sc.fk_user = ".$search_sale;
+ }
+
+ $nbtotalofrecords = 0;
+ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
+ {
+ $result = $db->query($sql);
+ $nbtotalofrecords = $db->num_rows($result);
+ }
+
+ $sql.= $db->order($sortfield, $sortorder);
+ if ($limit) {
+ if ($page < 0)
+ {
+ $page = 0;
+ }
+ $offset = $limit * $page;
+
+ $sql.= $db->plimit($limit + 1, $offset);
+ }
+
+ $result = $db->query($sql);
+ if ($result)
+ {
+ $num = $db->num_rows($result);
+ while ($i < $num)
+ {
+ $obj = $db->fetch_object($result);
+ $invoice_static = new Facture($db);
+ if($invoice_static->fetch($obj->rowid)) {
+ $obj_ret[] = parent::_cleanObjectDatas($invoice_static);
+ }
+ $i++;
+ }
+ }
+ else {
+ throw new RestException(503, 'Error when retrieve invoice list');
+ }
+ if( ! count($obj_ret)) {
+ throw new RestException(404, 'No invoice found');
+ }
+ return $obj_ret;
+ }
+
+ /**
+ * Create invoice object
+ *
+ * @param array $request_data Request datas
+ * @return int ID of invoice
+ */
+ function post($request_data = NULL)
+ {
+ if(! DolibarrApiAccess::$user->rights->facture->creer) {
+ throw new RestException(401);
+ }
+ // Check mandatory fields
+ $result = $this->_validate($request_data);
+
+ foreach($request_data as $field => $value) {
+ $this->invoice->$field = $value;
+ }
+ if(! array_keys($request_data,'date')) {
+ $this->invoice->date = dol_now();
+ }
+ if( ! $this->invoice->create(DolibarrApiAccess::$user)) {
+ throw new RestException(500);
+ }
+ return $this->invoice->id;
+ }
+
+ /**
+ * Update invoice
+ *
+ * @param int $id Id of invoice to update
+ * @param array $request_data Datas
+ * @return int
+ */
+ function put($id, $request_data = NULL)
+ {
+ if(! DolibarrApiAccess::$user->rights->facture->creer) {
+ throw new RestException(401);
+ }
+
+ $result = $this->invoice->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Facture not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ foreach($request_data as $field => $value) {
+ $this->invoice->$field = $value;
+ }
+
+ if($this->invoice->update($id, DolibarrApiAccess::$user))
+ return $this->get ($id);
+
+ return false;
+ }
+
+ /**
+ * Delete invoice
+ *
+ * @param int $id Invoice ID
+ * @return type
+ */
+ function delete($id)
+ {
+ if(! DolibarrApiAccess::$user->rights->facture->supprimer) {
+ throw new RestException(401);
+ }
+ $result = $this->invoice->fetch($id);
+ if( ! $result ) {
+ throw new RestException(404, 'Facture not found');
+ }
+
+ if( ! DolibarrApi::_checkAccessToResource('facture',$this->facture->id)) {
+ throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
+ }
+
+ if( $this->invoice->delete($id) < 0)
+ {
+ throw new RestException(500);
+ }
+
+ return array(
+ 'success' => array(
+ 'code' => 200,
+ 'message' => 'Facture deleted'
+ )
+ );
+ }
+
+ /**
+ * Validate fields before create or update object
+ *
+ * @param array $data Datas to validate
+ * @return array
+ *
+ * @throws RestException
+ */
+ function _validate($data)
+ {
+ $invoice = array();
+ foreach (Invoices::$FIELDS as $field) {
+ if (!isset($data[$field]))
+ throw new RestException(400, "$field field missing");
+ $invoice[$field] = $data[$field];
+ }
+ return $invoice;
+ }
+}
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 3b1bb17bfa7..c88648900cc 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -1548,14 +1548,14 @@ class Facture extends CommonInvoice
/**
* Delete invoice
*
- * @param int $rowid Id of invoice to delete. If empty, we delete current instance of invoice
+ * @param User $user User to delete.
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
* @param int $idwarehouse Id warehouse to use for stock change.
* @return int <0 if KO, >0 if OK
*/
- function delete($rowid=0, $notrigger=0, $idwarehouse=-1)
+ function delete($user, $notrigger=0, $idwarehouse=-1)
{
- global $user,$langs,$conf;
+ global $langs,$conf;
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
if (empty($rowid)) $rowid=$this->id;
diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php
index 198b08cb451..8eb77d30767 100644
--- a/htdocs/compta/facture/fiche-rec.php
+++ b/htdocs/compta/facture/fiche-rec.php
@@ -206,7 +206,7 @@ if ($action == 'add')
$result = $object->create($user, $oldinvoice->id);
if ($result > 0)
{
- $result=$oldinvoice->delete(0, 1);
+ $result=$oldinvoice->delete($user, 1);
if ($result < 0)
{
$error++;
@@ -242,7 +242,7 @@ if ($action == 'add')
// Delete
if ($action == 'delete' && $user->rights->facture->supprimer)
{
- $object->delete();
+ $object->delete($user);
header("Location: " . $_SERVER['PHP_SELF'] );
exit;
}
diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
index 99103ee419a..8e87f11b844 100644
--- a/htdocs/compta/facture/list.php
+++ b/htdocs/compta/facture/list.php
@@ -58,10 +58,13 @@ $projectid=(GETPOST('projectid')?GETPOST('projectid','int'):0);
$id=(GETPOST('id','int')?GETPOST('id','int'):GETPOST('facid','int')); // For backward compatibility
$ref=GETPOST('ref','alpha');
$socid=GETPOST('socid','int');
+
$action=GETPOST('action','alpha');
$massaction=GETPOST('massaction','alpha');
$show_files=GETPOST('show_files','int');
$confirm=GETPOST('confirm','alpha');
+$toselect = GETPOST('toselect', 'array');
+
$lineid=GETPOST('lineid','int');
$userid=GETPOST('userid','int');
$search_product_category=GETPOST('search_product_category','int');
@@ -86,7 +89,6 @@ $year = GETPOST('year','int');
$day_lim = GETPOST('day_lim','int');
$month_lim = GETPOST('month_lim','int');
$year_lim = GETPOST('year_lim','int');
-$toselect = GETPOST('toselect', 'array');
$option = GETPOST('option');
if ($option == 'late') $filter = 'paye:0';
@@ -173,7 +175,7 @@ if (is_array($extrafields->attribute_label) && count($extrafields->attribute_lab
*/
if (GETPOST('cancel')) { $action='list'; $massaction=''; }
-if (! GETPOST('confirmmassaction')) { $massaction=''; }
+if (! GETPOST('confirmmassaction') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
$parameters=array('socid'=>$socid);
$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
@@ -216,408 +218,11 @@ if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter") || GETPOS
if (empty($reshook))
{
- // Mass actions. Controls on number of lines checked
- $maxformassaction=1000;
- if (! empty($massaction) && count($toselect) < 1)
- {
- $error++;
- setEventMessages($langs->trans("NoLineChecked"), null, "warnings");
- }
- if (! $error && count($toselect) > $maxformassaction)
- {
- setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors');
- $error++;
- }
-
- // TODO Use a common inc.php file
- if (! $error && $massaction == 'confirm_presend')
- {
- $resaction = '';
- $nbsent = 0;
- $nbignored = 0;
- $langs->load("mails");
- include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
- if (!$error && !isset($user->email))
- {
- $error++;
- setEventMessages($langs->trans("NoSenderEmailDefined"), null, 'warnings');
- }
-
- if (! $error)
- {
- $thirdparty=new Societe($db);
- $objecttmp=new Facture($db);
- $listofobjectid=array();
- $listofobjectthirdparties=array();
- $listofobjectref=array();
- foreach($toselect as $toselectid)
- {
- $objecttmp=new Facture($db); // must create new instance because instance is saved into $listofobjectref array for future use
- $result=$objecttmp->fetch($toselectid);
- if ($result > 0)
- {
- $listoinvoicesid[$toselectid]=$toselectid;
- $thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid;
- $listofobjectthirdparties[$thirdpartyid]=$thirdpartyid;
- $listofobjectref[$thirdpartyid][$toselectid]=$objecttmp;
- }
- }
- //var_dump($listofobjectthirdparties);exit;
-
- foreach ($listofobjectthirdparties as $thirdpartyid)
- {
- $result = $thirdparty->fetch($thirdpartyid);
- if ($result < 0)
- {
- dol_print_error($db);
- exit;
- }
-
- // Define recipient $sendto and $sendtocc
- if (trim($_POST['sendto']))
- {
- // Recipient is provided into free text
- $sendto = trim($_POST['sendto']);
- $sendtoid = 0;
- }
- elseif ($_POST['receiver'] != '-1')
- {
- // Recipient was provided from combo list
- if ($_POST['receiver'] == 'thirdparty') // Id of third party
- {
- $sendto = $thirdparty->email;
- $sendtoid = 0;
- }
- else // Id du contact
- {
- $sendto = $thirdparty->contact_get_property((int) $_POST['receiver'],'email');
- $sendtoid = $_POST['receiver'];
- }
- }
- if (trim($_POST['sendtocc']))
- {
- $sendtocc = trim($_POST['sendtocc']);
- }
- elseif ($_POST['receivercc'] != '-1')
- {
- // Recipient was provided from combo list
- if ($_POST['receivercc'] == 'thirdparty') // Id of third party
- {
- $sendtocc = $thirdparty->email;
- }
- else // Id du contact
- {
- $sendtocc = $thirdparty->contact_get_property((int) $_POST['receivercc'],'email');
- }
- }
-
- //var_dump($listofobjectref[$thirdpartyid]); // Array of invoice for this thirdparty
-
- $attachedfiles=array('paths'=>array(), 'names'=>array(), 'mimes'=>array());
- $listofqualifiedinvoice=array();
- $listofqualifiedref=array();
- foreach($listofobjectref[$thirdpartyid] as $objectid => $object)
- {
- //var_dump($object);
- //var_dump($thirdpartyid.' - '.$objectid.' - '.$object->statut);
-
- if ($object->statut != Facture::STATUS_VALIDATED)
- {
- $nbignored++;
- continue; // Payment done or started or canceled
- }
-
- // Read document
- // TODO Use future field $object->fullpathdoc to know where is stored default file
- // TODO If not defined, use $object->modelpdf (or defaut invoice config) to know what is template to use to regenerate doc.
- $filename=dol_sanitizeFileName($object->ref).'.pdf';
- $filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($object->ref);
- $file = $filedir . '/' . $filename;
- $mime = dol_mimetype($file);
-
- if (dol_is_file($file))
- {
- if (empty($sendto)) // For the case, no recipient were set (multi thirdparties send)
- {
- $object->fetch_thirdparty();
- $sendto = $object->thirdparty->email;
- }
-
- if (empty($sendto))
- {
- //print "No recipient for thirdparty ".$object->thirdparty->name;
- $nbignored++;
- continue;
- }
-
- if (dol_strlen($sendto))
- {
- // Create form object
- $attachedfiles=array(
- 'paths'=>array_merge($attachedfiles['paths'],array($file)),
- 'names'=>array_merge($attachedfiles['names'],array($filename)),
- 'mimes'=>array_merge($attachedfiles['mimes'],array($mime))
- );
- }
-
- $listofqualifiedinvoice[$objectid]=$object;
- $listofqualifiedref[$objectid]=$object->ref;
- }
- else
- {
- $nbignored++;
- $langs->load("other");
- $resaction.=''.$langs->trans('ErrorCantReadFile',$file).'
';
- dol_syslog('Failed to read file: '.$file, LOG_WARNING);
- continue;
- }
-
- //var_dump($listofqualifiedref);
- }
-
- if (count($listofqualifiedinvoice) > 0)
- {
- $langs->load("commercial");
- $from = $user->getFullName($langs) . ' <' . $user->email .'>';
- $replyto = $from;
- $subject = GETPOST('subject');
- $message = GETPOST('message');
- $sendtocc = GETPOST('sentocc');
- $sendtobcc = (empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO)?'':$conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO);
-
- $substitutionarray=array(
- '__ID__' => join(', ',array_keys($listofqualifiedinvoice)),
- '__EMAIL__' => $thirdparty->email,
- '__CHECK_READ__' => ' ',
- //'__LASTNAME__' => $obj2->lastname,
- //'__FIRSTNAME__' => $obj2->firstname,
- '__FACREF__' => join(', ',$listofqualifiedref), // For backward compatibility
- '__REF__' => join(', ',$listofqualifiedref),
- '__REFCLIENT__' => $thirdparty->name
- );
-
- $subject=make_substitutions($subject, $substitutionarray);
- $message=make_substitutions($message, $substitutionarray);
-
- $filepath = $attachedfiles['paths'];
- $filename = $attachedfiles['names'];
- $mimetype = $attachedfiles['mimes'];
-
- //var_dump($filepath);
-
- // Send mail
- require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php');
- $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1);
- if ($mailfile->error)
- {
- $resaction.=''.$mailfile->error.'
';
- }
- else
- {
- $result=$mailfile->sendfile();
- if ($result)
- {
- $resaction.=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)).' '; // Must not contain "
-
- $error=0;
-
- // Insert logs into agenda
- foreach($listofqualifiedinvoice as $invid => $object)
- {
- $actiontypecode='AC_FAC';
- $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto;
- if ($message)
- {
- if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
- $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
- $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
- $actionmsg = dol_concatdesc($actionmsg, $message);
- }
-
- // Initialisation donnees
- $object->sendtoid = 0;
- $object->actiontypecode = $actiontypecode;
- $object->actionmsg = $actionmsg; // Long text
- $object->actionmsg2 = $actionmsg2; // Short text
- $object->fk_element = $invid;
- $object->elementtype = $object->element;
-
- // Appel des triggers
- include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
- $interface=new Interfaces($db);
- $result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf);
- if ($result < 0) { $error++; $errors=$interface->errors; }
- // Fin appel triggers
-
- if ($error)
- {
- setEventMessages($db->lasterror(), $errors, 'errors');
- dol_syslog("Error in trigger BILL_SENTBYMAIL ".$db->lasterror(), LOG_ERR);
- }
- $nbsent++;
- }
- }
- else
- {
- $langs->load("other");
- if ($mailfile->error)
- {
- $resaction.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
- $resaction.=''.$mailfile->error.'
';
- }
- else
- {
- $resaction.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS
';
- }
- }
- }
- }
- }
-
- $resaction.=($resaction?' ':$resaction);
- $resaction.=''.$langs->trans("ResultOfMailSending").': '."\n";
- $resaction.=$langs->trans("NbSelected").': '.count($toselect)."\n ";
- $resaction.=$langs->trans("NbIgnored").': '.($nbignored?$nbignored:0)."\n ";
- $resaction.=$langs->trans("NbSent").': '.($nbsent?$nbsent:0)."\n ";
-
- if ($nbsent)
- {
- $action=''; // Do not show form post if there was at least one successfull sent
- setEventMessages($langs->trans("EMailSentToNRecipients", $nbsent.'/'.count($toselect)), null, 'mesgs');
- setEventMessages($resaction, null, 'mesgs');
- }
- else
- {
- //setEventMessages($langs->trans("EMailSentToNRecipients", 0), null, 'warnings'); // May be object has no generated PDF file
- setEventMessages($resaction, null, 'warnings');
- }
- }
-
- $action='list';
- $massaction='';
- }
-
- if (! $error && $massaction == "builddoc" && $user->rights->facture->lire && ! GETPOST('button_search'))
- {
- require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
- require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
- require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-
- $objecttmp=new Facture($db);
- $listofobjectid=array();
- $listofobjectthirdparties=array();
- $listofobjectref=array();
- foreach($toselect as $toselectid)
- {
- $objecttmp=new Facture($db); // must create new instance because instance is saved into $listofobjectref array for future use
- $result=$objecttmp->fetch($toselectid);
- if ($result > 0)
- {
- $listoinvoicesid[$toselectid]=$toselectid;
- $thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid;
- $listofobjectthirdparties[$thirdpartyid]=$thirdpartyid;
- $listofobjectref[$toselectid]=$objecttmp->ref;
- }
- }
-
- $arrayofinclusion=array();
- foreach($listofobjectref as $tmppdf) $arrayofinclusion[]=preg_quote($tmppdf.'.pdf','/');
- $listoffiles = dol_dir_list($conf->facture->dir_output,'all',1,implode('|',$arrayofinclusion),'\.meta$|\.png','date',SORT_DESC,0,true);
-
- // build list of files with full path
- $files = array();
- foreach($listofobjectref as $basename)
- {
- foreach($listoffiles as $filefound)
- {
- if (strstr($filefound["name"],$basename))
- {
- $files[] = $conf->facture->dir_output.'/'.$basename.'/'.$filefound["name"];
- break;
- }
- }
- }
-
- // Define output language (Here it is not used because we do only merging existing PDF)
- $outputlangs = $langs;
- $newlang='';
- if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id');
- if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->thirdparty->default_lang;
- if (! empty($newlang))
- {
- $outputlangs = new Translate("",$conf);
- $outputlangs->setDefaultLang($newlang);
- }
-
- // Create empty PDF
- $pdf=pdf_getInstance();
- if (class_exists('TCPDF'))
- {
- $pdf->setPrintHeader(false);
- $pdf->setPrintFooter(false);
- }
- $pdf->SetFont(pdf_getPDFFont($outputlangs));
-
- if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
-
- // Add all others
- foreach($files as $file)
- {
- // Charge un document PDF depuis un fichier.
- $pagecount = $pdf->setSourceFile($file);
- for ($i = 1; $i <= $pagecount; $i++)
- {
- $tplidx = $pdf->importPage($i);
- $s = $pdf->getTemplatesize($tplidx);
- $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
- $pdf->useTemplate($tplidx);
- }
- }
-
- // Create output dir if not exists
- dol_mkdir($diroutputmassaction);
-
- // Save merged file
- $filename=strtolower(dol_sanitizeFileName($langs->transnoentities("Invoices")));
- if ($filter=='paye:0')
- {
- if ($option=='late') $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid"))).'_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Late")));
- else $filename.='_'.strtolower(dol_sanitizeFileName($langs->transnoentities("Unpaid")));
- }
- if ($year) $filename.='_'.$year;
- if ($month) $filename.='_'.$month;
- if ($pagecount)
- {
- $now=dol_now();
- $file=$diroutputmassaction.'/'.$filename.'_'.dol_print_date($now,'dayhourlog').'.pdf';
- $pdf->Output($file,'F');
- if (! empty($conf->global->MAIN_UMASK))
- @chmod($file, octdec($conf->global->MAIN_UMASK));
-
- $langs->load("exports");
- setEventMessages($langs->trans('FileSuccessfullyBuilt',$filename.'_'.dol_print_date($now,'dayhourlog')), null, 'mesgs');
- }
- else
- {
- setEventMessages($langs->trans('NoPDFAvailableForDocGenAmongChecked'), null, 'errors');
- }
- }
-
- // Remove file
- if ($action == 'remove_file')
- {
- require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
- $langs->load("other");
- $upload_dir = $diroutputmassaction;
- $file = $upload_dir . '/' . GETPOST('file');
- $ret=dol_delete_file($file);
- if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs');
- else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors');
- $action='';
- }
-
+ $objectclass='Facture';
+ $permtoread = $user->rights->facture->lire;
+ $permtodelete = $user->rights->facture->supprimer;
+ $uploaddir = $conf->facture->dir_output;
+ include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
@@ -836,6 +441,18 @@ if ($resql)
'presend'=>$langs->trans("SendByMail"),
'builddoc'=>$langs->trans("PDFMerge")
);
+ if ($user->rights->facture->supprimer)
+ {
+ //if (! empty($conf->global->STOCK_CALCULATE_ON_BILL) || empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED))
+ if (empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED))
+ {
+ // mass deletion never possible on invoices on such situation
+ }
+ else
+ {
+ $arrayofmassactions['delete']=$langs->trans("Delete");
+ }
+ }
if ($massaction == 'presend') $arrayofmassactions=array();
$massactionbutton=$form->selectMassAction('', $arrayofmassactions);
@@ -940,6 +557,7 @@ if ($resql)
$formmail->param['models']=$modelmail;
$formmail->param['models_id']=GETPOST('modelmailselected','int');
$formmail->param['facid']=join(',',$arrayofselected);
+ // TODO We should use $formmail->param['id']=join(',',$arrayofselected);
//$formmail->param['returnurl']=$_SERVER["PHP_SELF"].'?id='.$object->id;
print $formmail->get_form();
@@ -1429,7 +1047,7 @@ if ($resql)
// Action column
print ' ';
- if ($massactionbutton)
+ if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
{
$selected=0;
if (in_array($obj->facid, $arrayofselected)) $selected=1;
@@ -1494,7 +1112,7 @@ if ($resql)
$paramwithoutshowfiles=preg_replace('/show_files=1&?/','',$param);
$title=$langs->trans("MassFilesArea").' ('.$langs->trans("Hide").') ';
- print $formfile->showdocuments('massfilesarea_facture','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,'');
+ print $formfile->showdocuments('massfilesarea_invoices','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,'');
}
else
{
diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
index a9414fcafeb..c11b2c815bc 100644
--- a/htdocs/compta/paiement.php
+++ b/htdocs/compta/paiement.php
@@ -529,7 +529,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
$sql.= ' WHERE f.entity = '.$conf->entity;
$sql.= ' AND (f.fk_soc = '.$facture->socid;
- if(!empty($conf->global->FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS)) {
+ if(!empty($conf->global->FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS) && !empty($facture->thirdparty->parent)) {
$sql.= ' OR f.fk_soc IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'societe WHERE parent = '.$facture->thirdparty->parent.')';
}
diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php
index 49f8130c5b4..5a9c8a267ea 100644
--- a/htdocs/contrat/card.php
+++ b/htdocs/contrat/card.php
@@ -1117,7 +1117,7 @@ if ($action == 'create')
else
{
print ' ';
- print $form->select_company('','socid','',1,1);
+ print $form->select_company('','socid','','SelectThirdParty',1);
print ' ';
}
print ' '."\n";
diff --git a/htdocs/contrat/index.php b/htdocs/contrat/index.php
index 250f1c98199..86f7c00e566 100644
--- a/htdocs/contrat/index.php
+++ b/htdocs/contrat/index.php
@@ -273,7 +273,7 @@ if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire)
}
else
{
- print '