2015-05-01 14:12:30 +00:00
< ? php
2024-03-14 22:39:16 +00:00
/* Copyright ( C ) 2015 Jean - François Ferry < jfefe @ aternatik . fr >
* Copyright ( C ) 2018 Pierre Chéné < pierre . chene44 @ gmail . com >
2024-10-05 16:55:36 +00:00
* Copyright ( C ) 2019 Cedric Ancelin < icedo . anc @ gmail . com >
2025-11-20 00:47:46 +00:00
* Copyright ( C ) 2020 - 2025 Frédéric France < frederic . france @ free . fr >
2024-03-14 22:39:16 +00:00
* Copyright ( C ) 2023 Alexandre Janniaux < alexandre . janniaux @ gmail . com >
2026-07-23 17:06:39 +00:00
* Copyright ( C ) 2024 - 2026 MDW < mdeweerd @ users . noreply . github . com >
2024-03-16 09:08:19 +00:00
* Copyright ( C ) 2024 Jon Bendtsen < jon . bendtsen . github @ jonb . dk >
2025-05-07 09:20:14 +00:00
* Copyright ( C ) 2025 William Mead < william @ m34d . com >
2025-05-14 10:50:45 +00:00
* Copyright ( C ) 2025 Charlene Benke < charlene @ patas - monkey . com >
2026-02-04 20:23:46 +00:00
* Copyright ( C ) 2026 Benjamin Falière < benjamin @ faliere . com >
2015-05-01 14:12:30 +00:00
*
* 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
2019-09-23 19:55:30 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2015-05-01 14:12:30 +00:00
*/
2018-02-12 03:07:45 +00:00
use Luracast\Restler\RestException ;
2015-05-01 14:12:30 +00:00
/**
2016-06-15 15:08:17 +00:00
* API class for thirdparties
2015-05-01 14:12:30 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 3.8 . 0 Initial implementation
*
2017-10-03 11:07:07 +00:00
* @ access protected
2015-05-02 23:54:04 +00:00
* @ class DolibarrApiAccess { @ requires user , external }
2015-05-01 14:12:30 +00:00
*/
2016-06-15 15:08:17 +00:00
class Thirdparties extends DolibarrApi
2015-05-05 22:55:42 +00:00
{
2018-02-12 03:07:45 +00:00
/**
2025-03-03 00:49:20 +00:00
* @ var string [] Mandatory fields , checked when we create and update the object
2018-02-12 03:07:45 +00:00
*/
2021-02-26 20:17:52 +00:00
public static $FIELDS = array (
2018-08-26 15:29:04 +00:00
'name'
2018-02-12 03:07:45 +00:00
);
/**
2025-03-02 11:13:32 +00:00
* @ var Societe { @ type Societe }
2018-02-12 03:07:45 +00:00
*/
public $company ;
/**
* Constructor
*/
2020-10-31 13:32:18 +00:00
public function __construct ()
2018-02-12 03:07:45 +00:00
{
2024-03-14 22:39:16 +00:00
global $db ;
2015-05-01 14:12:30 +00:00
$this -> db = $db ;
2017-10-22 12:48:42 +00:00
2020-12-21 14:25:15 +00:00
require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php' ;
2018-08-26 15:29:04 +00:00
require_once DOL_DOCUMENT_ROOT . '/societe/class/societeaccount.class.php' ;
2017-10-22 12:48:42 +00:00
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php' ;
2018-10-16 19:43:40 +00:00
require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php' ;
2024-03-13 22:14:49 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php' ;
2017-10-22 12:48:42 +00:00
2018-02-12 03:07:45 +00:00
$this -> company = new Societe ( $this -> db );
2023-11-27 11:08:48 +00:00
if ( getDolGlobalString ( 'SOCIETE_EMAIL_MANDATORY' )) {
2018-02-12 03:07:45 +00:00
static :: $FIELDS [] = 'email' ;
}
}
/**
2025-05-07 09:20:14 +00:00
* Get a third party
*
* Return the third party object
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 3.8 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party to load
* @ return Object Object with cleaned properties
2018-02-12 03:07:45 +00:00
*
2023-09-26 16:43:25 +00:00
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function get ( $id )
2018-02-12 03:07:45 +00:00
{
2020-10-31 13:32:18 +00:00
return $this -> _fetch ( $id );
}
2018-02-12 03:07:45 +00:00
2019-10-19 14:43:10 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get properties of a third party by email .
*
* Return an array with third party information
2019-10-19 14:43:10 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 11.0 . 0 Initial implementation
2019-10-19 14:43:10 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param string $email Email of the third party to load
* @ return array | mixed Cleaned Societe object
2025-03-03 13:23:57 +00:00
* @ phan - return Societe
* @ phpstan - return Societe
2019-10-19 14:43:10 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET email / { email }
2019-10-19 14:43:10 +00:00
*
* @ throws RestException
*/
public function getByEmail ( $email )
{
2024-09-29 19:51:51 +00:00
return $this -> _fetch ( null , '' , '' , '' , '' , '' , '' , '' , '' , '' , $email );
2018-02-12 03:07:45 +00:00
}
2020-08-29 09:39:10 +00:00
2020-08-29 09:37:16 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get a third party by barcode .
2020-08-29 09:37:16 +00:00
*
2025-05-07 09:20:14 +00:00
* Return an array with third party information
2020-08-29 09:37:16 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 13.0 . 0 Initial implementation
2020-08-29 09:37:16 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param string $barcode Barcode of the third party
* @ return array | mixed Cleaned Societe object
*
* @ url GET barcode / { barcode }
2020-08-29 09:37:16 +00:00
*
* @ throws RestException
*/
public function getByBarcode ( $barcode )
{
2024-09-29 19:51:51 +00:00
return $this -> _fetch ( null , '' , '' , $barcode );
2020-08-29 09:37:16 +00:00
}
2018-02-12 03:07:45 +00:00
/**
2025-05-07 09:20:14 +00:00
* List third parties
*
* Get a list of third parties
*
* @ since 3.8 . 0 Initial implementation
2026-03-20 15:24:47 +00:00
* @ since 21.0 . 0 Data pagination
2025-05-07 09:20:14 +00:00
*
2026-03-20 15:24:47 +00:00
* @ param string $sortfield Sort field
2025-05-07 09:20:14 +00:00
* @ param string $sortorder Sort order
* @ param int $limit List limit
* @ param int $page Page number
2026-03-20 15:24:47 +00:00
* @ param int $mode Set to 0 to show all third parties , Set to 1 to show only customers , 2 for prospects , 3 for neither customer nor prospect , 4 for suppliers
2025-05-07 09:20:14 +00:00
* @ param int $category Use this param to filter the list by category
* @ param string $sqlfilters Other criteria to filter answers separated by a comma . Syntax example " ((t.nom:like:'TheCompany%') or (t.name_alias:like:'TheCompany%')) and (t.datec:<:'20160101') "
* @ param string $properties Restrict the data returned to these properties . Ignored if empty . Comma separated list of properties names
2026-03-20 15:24:47 +00:00
* @ param bool $pagination_data If this parameter is set to true , the response will include pagination data . The default value is false . Page starts from 0 *
* @ return array Array of third party objects
2025-03-03 00:49:20 +00:00
* @ phan - return Societe [] | array { data : Societe [], pagination : array { total : int , page : int , page_count : int , limit : int }}
* @ phpstan - return Societe [] | array { data : Societe [], pagination : array { total : int , page : int , page_count : int , limit : int }}
2025-05-07 09:20:14 +00:00
*
2026-03-20 15:24:47 +00:00
* @ throws RestException 400
* @ throws RestException 403
* @ throws RestException 404
* @ throws RestException 503
2018-02-12 03:07:45 +00:00
*/
2024-07-06 13:04:11 +00:00
public function index ( $sortfield = " t.rowid " , $sortorder = 'ASC' , $limit = 100 , $page = 0 , $mode = 0 , $category = 0 , $sqlfilters = '' , $properties = '' , $pagination_data = false )
2020-10-31 13:32:18 +00:00
{
2018-02-12 03:07:45 +00:00
$obj_ret = array ();
2022-09-10 09:10:33 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2021-04-08 17:05:28 +00:00
}
2018-02-12 03:07:45 +00:00
// case of external user, we force socids
2024-01-09 09:44:50 +00:00
$socids = DolibarrApiAccess :: $user -> socid ? ( string ) DolibarrApiAccess :: $user -> socid : '' ;
2018-02-12 03:07:45 +00:00
// If the internal user must only see his customers, force searching by him
$search_sale = 0 ;
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'client' , 'voir' ) && ! $socids ) {
2021-02-26 20:17:52 +00:00
$search_sale = DolibarrApiAccess :: $user -> id ;
}
2018-02-12 03:07:45 +00:00
$sql = " SELECT t.rowid " ;
2019-11-14 11:09:15 +00:00
$sql .= " FROM " . MAIN_DB_PREFIX . " societe as t " ;
2022-12-15 19:34:23 +00:00
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " societe_extrafields AS ef ON ef.fk_object = t.rowid " ; // So we will be able to filter on extrafields
2020-10-31 13:32:18 +00:00
if ( $category > 0 ) {
2021-02-26 20:17:52 +00:00
if ( $mode != 4 ) {
$sql .= " , " . MAIN_DB_PREFIX . " categorie_societe as c " ;
}
if ( ! in_array ( $mode , array ( 1 , 2 , 3 ))) {
$sql .= " , " . MAIN_DB_PREFIX . " categorie_fournisseur as cc " ;
}
}
2020-05-28 17:50:27 +00:00
$sql .= " WHERE t.entity IN ( " . getEntity ( 'societe' ) . " ) " ;
2021-02-26 20:17:52 +00:00
if ( $mode == 1 ) {
$sql .= " AND t.client IN (1, 3) " ;
} elseif ( $mode == 2 ) {
$sql .= " AND t.client IN (2, 3) " ;
} elseif ( $mode == 3 ) {
$sql .= " AND t.client IN (0) " ;
} elseif ( $mode == 4 ) {
$sql .= " AND t.fournisseur IN (1) " ;
}
2026-03-20 15:24:47 +00:00
// Select third parties of a given category
2020-10-31 13:32:18 +00:00
if ( $category > 0 ) {
2021-02-26 20:17:52 +00:00
if ( ! empty ( $mode ) && $mode != 4 ) {
2021-06-09 13:36:47 +00:00
$sql .= " AND c.fk_categorie = " . (( int ) $category ) . " AND c.fk_soc = t.rowid " ;
2021-02-26 20:17:52 +00:00
} elseif ( ! empty ( $mode ) && $mode == 4 ) {
2021-06-09 13:36:47 +00:00
$sql .= " AND cc.fk_categorie = " . (( int ) $category ) . " AND cc.fk_soc = t.rowid " ;
2021-02-26 20:17:52 +00:00
} else {
2021-06-09 13:36:47 +00:00
$sql .= " AND ((c.fk_categorie = " . (( int ) $category ) . " AND c.fk_soc = t.rowid) OR (cc.fk_categorie = " . (( int ) $category ) . " AND cc.fk_soc = t.rowid)) " ;
2021-02-26 20:17:52 +00:00
}
2020-10-31 13:32:18 +00:00
}
2021-02-26 20:17:52 +00:00
if ( $socids ) {
2021-03-22 10:30:18 +00:00
$sql .= " AND t.rowid IN ( " . $this -> db -> sanitize ( $socids ) . " ) " ;
2021-02-26 20:17:52 +00:00
}
2024-01-09 09:44:50 +00:00
// Search on sale representative
if ( $search_sale && $search_sale != '-1' ) {
if ( $search_sale == - 2 ) {
$sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM " . MAIN_DB_PREFIX . " societe_commerciaux as sc WHERE sc.fk_soc = t.rowid) " ;
} elseif ( $search_sale > 0 ) {
$sql .= " AND EXISTS (SELECT sc.fk_soc FROM " . MAIN_DB_PREFIX . " societe_commerciaux as sc WHERE sc.fk_soc = t.rowid AND sc.fk_user = " . (( int ) $search_sale ) . " ) " ;
}
2018-02-12 03:07:45 +00:00
}
// Add sql filters
2021-02-26 20:17:52 +00:00
if ( $sqlfilters ) {
2021-12-20 19:49:32 +00:00
$errormessage = '' ;
2023-02-25 18:48:33 +00:00
$sql .= forgeSQLFromUniversalSearchCriteria ( $sqlfilters , $errormessage );
if ( $errormessage ) {
throw new RestException ( 400 , 'Error when validating parameter sqlfilters -> ' . $errormessage );
2018-02-12 03:07:45 +00:00
}
}
2024-07-06 13:04:11 +00:00
//this query will return total thirdparties with the filters given
$sqlTotals = str_replace ( 'SELECT t.rowid' , 'SELECT count(t.rowid) as total' , $sql );
2018-02-12 03:07:45 +00:00
2024-07-06 13:04:11 +00:00
$sql .= $this -> db -> order ( $sortfield , $sortorder );
2018-02-12 03:07:45 +00:00
if ( $limit ) {
2020-11-05 22:03:44 +00:00
if ( $page < 0 ) {
2018-02-12 03:07:45 +00:00
$page = 0 ;
}
$offset = $limit * $page ;
2020-09-19 21:30:29 +00:00
$sql .= $this -> db -> plimit ( $limit + 1 , $offset );
2018-02-12 03:07:45 +00:00
}
2015-05-03 22:33:44 +00:00
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2021-02-26 20:17:52 +00:00
if ( $result ) {
2020-09-19 21:30:29 +00:00
$num = $this -> db -> num_rows ( $result );
2018-02-12 03:07:45 +00:00
$min = min ( $num , ( $limit <= 0 ? $num : $limit ));
2020-10-31 13:32:18 +00:00
$i = 0 ;
2021-02-26 20:17:52 +00:00
while ( $i < $min ) {
2020-09-19 21:30:29 +00:00
$obj = $this -> db -> fetch_object ( $result );
$soc_static = new Societe ( $this -> db );
2019-11-14 11:09:15 +00:00
if ( $soc_static -> fetch ( $obj -> rowid )) {
2022-08-29 12:46:26 +00:00
if ( isModEnabled ( 'mailing' )) {
$soc_static -> getNoEmail ();
}
2023-09-26 16:04:48 +00:00
$obj_ret [] = $this -> _filterObjectProperties ( $this -> _cleanObjectDatas ( $soc_static ), $properties );
2018-02-12 03:07:45 +00:00
}
$i ++ ;
}
2020-05-21 13:05:19 +00:00
} else {
2026-03-20 15:24:47 +00:00
throw new RestException ( 503 , 'Error when retrieve third parties : ' . $this -> db -> lasterror ());
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( ! count ( $obj_ret )) {
2025-05-14 14:57:44 +00:00
$message = '' ;
switch ( $mode ) {
case 0 :
$message = 'No third parties found' ;
break ;
case 1 :
$message = 'No customers found' ;
break ;
case 2 :
$message = 'No prospects found' ;
break ;
case 3 :
$message = 'No other third parties found' ;
break ;
case 4 :
$message = 'No suppliers found' ;
}
throw new RestException ( 404 , $message );
2018-02-12 03:07:45 +00:00
}
2024-07-06 13:04:11 +00:00
2026-03-20 15:24:47 +00:00
//if $pagination_data is true, the response will contain element data with all values and element pagination with pagination data(total,page,limit)
2024-07-06 13:04:11 +00:00
if ( $pagination_data ) {
$totalsResult = $this -> db -> query ( $sqlTotals );
$total = $this -> db -> fetch_object ( $totalsResult ) -> total ;
$tmp = $obj_ret ;
$obj_ret = [];
$obj_ret [ 'data' ] = $tmp ;
$obj_ret [ 'pagination' ] = [
'total' => ( int ) $total ,
'page' => $page , //count starts from 0
'page_count' => ceil (( int ) $total / $limit ),
'limit' => $limit
];
}
2015-05-03 14:59:47 +00:00
return $obj_ret ;
2018-02-12 03:07:45 +00:00
}
/**
2025-05-07 09:20:14 +00:00
* Create a third party
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 3.8 . 0 Initial implementation
*
* @ param array $request_data Request data
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2025-05-07 09:20:14 +00:00
* @ return int ID of third party
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function post ( $request_data = null )
2018-02-12 03:07:45 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
2025-11-20 22:56:03 +00:00
// External api user does not know internal country ID
if ( ! isset ( $request_data [ 'country_id' ]) && isset ( $request_data [ 'country_code' ])) {
$field = strlen ( $request_data [ 'country_code' ]) > 2 ? 'code_iso' : 'code' ;
$id = dol_getIdFromCode ( $this -> db , $request_data [ 'country_code' ], " c_country " , $field , " rowid " );
if ( $id < 0 ) {
throw new RestException ( 404 , 'Country code not found in database: ' . $this -> db -> error );
}
$request_data [ 'country_id' ] = $id ;
}
2018-02-12 03:07:45 +00:00
// Check mandatory fields
$result = $this -> _validate ( $request_data );
2019-11-14 11:09:15 +00:00
foreach ( $request_data as $field => $value ) {
2023-11-29 15:18:34 +00:00
if ( $field === 'caller' ) {
2024-01-12 16:18:52 +00:00
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2024-04-02 10:28:55 +00:00
$this -> company -> context [ 'caller' ] = sanitizeVal ( $request_data [ 'caller' ], 'aZ09' );
2023-11-29 15:18:34 +00:00
continue ;
}
2025-11-20 22:56:03 +00:00
if ( $field == 'array_options' && is_array ( $value )) {
2026-05-08 23:16:35 +00:00
$this -> company -> fetch_optionals (); // To force the load of the extrafields definition by fetch_name_optionals_label()
2025-11-20 22:56:03 +00:00
foreach ( $value as $index => $val ) {
2026-05-08 23:16:35 +00:00
$this -> company -> array_options [ $index ] = $this -> _checkValExtrafieldsForAPI ( $index , $val , $this -> company );
2025-11-20 22:56:03 +00:00
}
continue ;
}
2023-12-15 11:15:33 +00:00
2024-03-14 22:39:16 +00:00
$this -> company -> $field = $this -> _checkValForAPI ( $field , $value , $this -> company );
2018-02-12 03:07:45 +00:00
}
2023-11-29 15:18:34 +00:00
2021-02-26 20:17:52 +00:00
if ( $this -> company -> create ( DolibarrApiAccess :: $user ) < 0 ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 500 , 'Error creating thirdparty' , array_merge ( array ( $this -> company -> error ), $this -> company -> errors ));
2021-02-26 20:17:52 +00:00
}
2022-08-29 12:46:26 +00:00
if ( isModEnabled ( 'mailing' ) && ! empty ( $this -> company -> email ) && isset ( $this -> company -> no_email )) {
$this -> company -> setNoEmail ( $this -> company -> no_email );
}
2018-02-12 03:07:45 +00:00
2018-08-26 15:29:04 +00:00
return $this -> company -> id ;
2018-02-12 03:07:45 +00:00
}
/**
2025-05-07 09:20:14 +00:00
* Update third party
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 3.8 . 0 Initial implementation
*
* @ param int $id ID of thirdparty to update
* @ param array $request_data Data
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2025-05-07 09:20:14 +00:00
* @ return Object Updated object
2025-03-03 13:23:57 +00:00
* @ phan - return Societe
* @ phpstan - return Societe
2024-05-03 16:24:03 +00:00
*
2024-05-03 16:03:14 +00:00
* @ throws RestException 401
* @ throws RestException 404
* @ throws RestException 500
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function put ( $id , $request_data = null )
2018-02-12 03:07:45 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
foreach ( $request_data as $field => $value ) {
2021-02-26 20:17:52 +00:00
if ( $field == 'id' ) {
continue ;
}
2023-12-15 11:15:33 +00:00
if ( $field === 'caller' ) {
2024-01-12 16:18:52 +00:00
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2024-04-02 10:28:55 +00:00
$this -> company -> context [ 'caller' ] = sanitizeVal ( $request_data [ 'caller' ], 'aZ09' );
2023-12-15 11:15:33 +00:00
continue ;
}
2024-04-01 21:05:49 +00:00
if ( $field == 'array_options' && is_array ( $value )) {
foreach ( $value as $index => $val ) {
2026-05-08 23:16:35 +00:00
$this -> company -> array_options [ $index ] = $this -> _checkValExtrafieldsForAPI ( $index , $val , $this -> company );
2024-04-01 21:05:49 +00:00
}
continue ;
}
2024-03-14 22:39:16 +00:00
$this -> company -> $field = $this -> _checkValForAPI ( $field , $value , $this -> company );
2018-02-12 03:07:45 +00:00
}
2022-08-29 12:46:26 +00:00
if ( isModEnabled ( 'mailing' ) && ! empty ( $this -> company -> email ) && isset ( $this -> company -> no_email )) {
$this -> company -> setNoEmail ( $this -> company -> no_email );
}
2024-11-04 11:34:21 +00:00
if ( $this -> company -> update ( $id , DolibarrApiAccess :: $user , 1 , 1 , 1 , 'update' , 1 ) > 0 ) {
2018-02-12 03:07:45 +00:00
return $this -> get ( $id );
2024-05-03 16:03:14 +00:00
} else {
throw new RestException ( 500 , $this -> company -> error );
2020-11-05 22:03:44 +00:00
}
2018-02-12 03:07:45 +00:00
}
/**
2025-05-07 09:20:14 +00:00
* Merge a third party into another third party
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* Merge content ( properties , notes ) and objects ( like invoices , events , orders , proposals , ... ) of a third party into a target third party ,
2024-03-16 15:21:43 +00:00
* then delete the merged third party .
2025-05-07 09:20:14 +00:00
* If a property has a defined value both in the third party to delete and the third party to keep , the value of the third party to
* delete will be ignored , the value of the target third party will remain , except for notes ( content is concatenated ) .
*
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:32:25 +00:00
* @ param int $id ID of thirdparty to keep ( the target third party )
* @ param int $idtodelete ID of thirdparty to remove ( the third party to delete ), once data has been merged into the target third party .
* @ return Object Return the resulted third party .
2025-05-07 09:28:30 +00:00
*
2025-03-03 13:23:57 +00:00
* @ phan - return Societe
* @ phpstan - return Societe
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url PUT { id } / merge / { idtodelete }
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function merge ( $id , $idtodelete )
2018-02-12 03:07:45 +00:00
{
2021-02-26 20:17:52 +00:00
if ( $id == $idtodelete ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 400 , 'Try to merge a thirdparty into itself' );
}
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2015-05-03 16:30:59 +00:00
}
2017-10-03 11:07:07 +00:00
2019-11-14 11:09:15 +00:00
$result = $this -> company -> fetch ( $id ); // include the fetch of extra fields
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
2017-10-03 11:07:07 +00:00
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2015-05-03 16:30:59 +00:00
}
2023-08-06 11:02:33 +00:00
$companytoremove = new Societe ( $this -> db );
$result = $companytoremove -> fetch ( $idtodelete ); // include the fetch of extra fields
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
2023-08-06 11:02:33 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $companytoremove -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
$user = DolibarrApiAccess :: $user ;
2023-10-26 14:30:38 +00:00
$result = $this -> company -> mergeCompany ( $companytoremove -> id );
2021-02-26 20:17:52 +00:00
if ( $result < 0 ) {
2023-08-06 11:02:33 +00:00
throw new RestException ( 500 , 'Error failed to merged thirdparty ' . $companytoremove -> id . ' into ' . $id . '. Enable and read log file for more information.' );
2018-01-31 17:01:56 +00:00
}
2018-02-12 03:07:45 +00:00
return $this -> get ( $id );
}
/**
2025-05-07 09:20:14 +00:00
* Delete a third party
*
* @ since 3.8 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ return array
2025-03-02 14:10:25 +00:00
* @ phan - return array { success : array { code : int , message : string }}
* @ phpstan - return array { success : array { code : int , message : string }}
2025-05-07 09:20:14 +00:00
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function delete ( $id )
2018-02-12 03:07:45 +00:00
{
2022-09-10 09:19:54 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'supprimer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2025-03-03 13:23:57 +00:00
$this -> company -> oldcopy = clone $this -> company ; // @phan-suppress-current-line PhanTypeMismatchProperty
2022-11-25 23:50:45 +00:00
$res = $this -> company -> delete ( $id );
2022-11-25 23:57:35 +00:00
if ( $res < 0 ) {
2022-11-25 23:50:45 +00:00
throw new RestException ( 500 , " Can't delete, error occurs " );
2022-11-25 23:57:35 +00:00
} elseif ( $res == 0 ) {
2022-11-25 23:50:45 +00:00
throw new RestException ( 409 , " Can't delete, that product is probably used " );
}
return array (
'success' => array (
'code' => 200 ,
'message' => 'Object deleted'
)
);
2020-10-31 13:32:18 +00:00
}
2020-07-31 15:48:44 +00:00
/**
2025-05-07 09:20:14 +00:00
* Set a new price level for the given third party
*
* @ since 13.0 . 0 Initial implementation
2020-07-31 15:48:44 +00:00
*
* @ param int $id ID of thirdparty
* @ param int $priceLevel Price level to apply to thirdparty
2024-03-16 15:21:43 +00:00
* @ return Object Thirdparty data without useless information
2020-07-31 15:48:44 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url PUT { id } / setpricelevel / { priceLevel }
2020-07-31 15:48:44 +00:00
*
* @ throws RestException 400 Price level out of bounds
* @ throws RestException 401 Access not allowed for your login
2025-05-07 09:20:14 +00:00
* @ throws RestException 404 Third party not found
2020-07-31 15:48:44 +00:00
* @ throws RestException 500 Error fetching / setting price level
* @ throws RestException 501 Request needs modules " Thirdparties " and " Products " and setting Multiprices activated
*/
public function setThirdpartyPriceLevel ( $id , $priceLevel )
{
global $conf ;
2022-08-29 07:29:56 +00:00
if ( ! isModEnabled ( 'societe' )) {
2020-07-31 15:48:44 +00:00
throw new RestException ( 501 , 'Module "Thirdparties" needed for this request' );
}
2023-04-18 18:16:02 +00:00
if ( ! isModEnabled ( " product " )) {
2020-07-31 15:48:44 +00:00
throw new RestException ( 501 , 'Module "Products" needed for this request' );
}
2026-05-26 14:00:28 +00:00
if ( ! getDolGlobalString ( 'PRODUIT_MULTIPRICES' ) && ! getDolGlobalString ( 'PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES' )) {
2020-07-31 15:48:44 +00:00
throw new RestException ( 501 , 'Multiprices features activation needed for this request' );
}
2024-02-09 14:58:49 +00:00
if ( $priceLevel < 1 || $priceLevel > getDolGlobalString ( 'PRODUIT_MULTIPRICES_LIMIT' )) {
2023-10-15 16:39:13 +00:00
throw new RestException ( 400 , 'Price level must be between 1 and ' . getDolGlobalString ( 'PRODUIT_MULTIPRICES_LIMIT' ));
2020-07-31 15:48:44 +00:00
}
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-04-07 12:59:25 +00:00
throw new RestException ( 403 , 'Access to thirdparty ' . $id . ' not allowed for login ' . DolibarrApiAccess :: $user -> login );
2020-07-31 15:48:44 +00:00
}
$result = $this -> company -> fetch ( $id );
if ( $result < 0 ) {
2020-10-31 13:32:18 +00:00
throw new RestException ( 404 , 'Thirdparty ' . $id . ' not found' );
2020-07-31 15:48:44 +00:00
}
if ( empty ( $result )) {
2020-10-31 13:32:18 +00:00
throw new RestException ( 500 , 'Error fetching thirdparty ' . $id , array_merge ( array ( $this -> company -> error ), $this -> company -> errors ));
2020-07-31 15:48:44 +00:00
}
if ( empty ( DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id ))) {
2024-04-07 12:59:25 +00:00
throw new RestException ( 403 , 'Access to thirdparty ' . $id . ' not allowed for login ' . DolibarrApiAccess :: $user -> login );
2020-07-31 15:48:44 +00:00
}
2021-04-01 08:05:37 +00:00
$result = $this -> company -> setPriceLevel ( $priceLevel , DolibarrApiAccess :: $user );
2020-07-31 15:48:44 +00:00
if ( $result <= 0 ) {
2020-10-31 13:32:18 +00:00
throw new RestException ( 500 , 'Error setting new price level for thirdparty ' . $id , array ( $this -> company -> db -> lasterror ()));
2020-07-31 15:48:44 +00:00
}
return $this -> _cleanObjectDatas ( $this -> company );
2018-02-12 03:07:45 +00:00
}
2026-07-31 21:51:57 +00:00
/**
* Get a customer representative to a third party
*
* @ since 24.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ return array < array { id : int , lastname : string , firstname : string , email : string , phone : string , office_phone : string , office_fax : string , user_mobile : string , personal_mobile : string , job : string , statut : int , status : int , entity : int , login : string , photo : string , gender : string } > Return array of representatives if OK , < 0 if KO
*
* @ url GET { id } / representative
*
* @ throws RestException 401 Access not allowed for your login
* @ throws RestException 404 User or Third party not found
*/
public function getRepresentative ( $id )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'reader' )) {
throw new RestException ( 403 );
}
$result = $this -> company -> fetch ( $id );
if ( ! $result ) {
throw new RestException ( 404 , 'Thirdparty not found' );
}
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
$result = $this -> company -> getSalesRepresentatives ( DolibarrApiAccess :: $user );
/** @var array<array{id:int,lastname:string,firstname:string,email:string,phone:string,office_phone:string,office_fax:string,user_mobile:string,personal_mobile:string,job:string,statut:int,status:int,entity:int,login:string,photo:string,gender:string}> $result */
return $result ;
}
2024-02-09 14:58:49 +00:00
/**
2025-05-07 09:20:14 +00:00
* Add a customer representative to a third party
*
* @ since 20.0 . 0 Initial implementation
2024-02-09 14:58:49 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param int $representative_id ID of representative
* @ return int Return integer <= 0 if KO , > 0 if OK
2024-02-09 14:58:49 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url POST { id } / representative / { representative_id }
2024-02-25 09:03:04 +00:00
*
* @ throws RestException 401 Access not allowed for your login
2025-05-07 09:20:14 +00:00
* @ throws RestException 404 User or Third party not found
2024-02-09 14:58:49 +00:00
*/
public function addRepresentative ( $id , $representative_id )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
throw new RestException ( 403 );
}
$result = $this -> company -> fetch ( $id );
if ( ! $result ) {
throw new RestException ( 404 , 'Thirdparty not found' );
}
$usertmp = new User ( $this -> db );
$result = $usertmp -> fetch ( $representative_id );
if ( ! $result ) {
throw new RestException ( 404 , 'User not found' );
}
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2024-02-09 14:58:49 +00:00
}
$result = $this -> company -> add_commercial ( DolibarrApiAccess :: $user , $representative_id );
return $result ;
}
/**
2025-05-07 09:20:14 +00:00
* Remove the link between a customer representative and a third party
2024-02-09 14:58:49 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 20.0 . 0 Initial implementation
2024-02-09 14:58:49 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param int $representative_id ID of representative
* @ return int Return integer <= 0 if KO , > 0 if OK
*
* @ url DELETE { id } / representative / { representative_id }
2024-02-25 09:03:04 +00:00
*
* @ throws RestException 401 Access not allowed for your login
2025-05-07 09:20:14 +00:00
* @ throws RestException 404 User or Third party not found
2024-02-09 14:58:49 +00:00
*/
public function deleteRepresentative ( $id , $representative_id )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'supprimer' )) {
throw new RestException ( 403 );
}
$result = $this -> company -> fetch ( $id );
if ( ! $result ) {
throw new RestException ( 404 , 'Thirdparty not found' );
}
$usertmp = new User ( $this -> db );
$result = $usertmp -> fetch ( $representative_id );
if ( ! $result ) {
throw new RestException ( 404 , 'User not found' );
}
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2024-02-09 14:58:49 +00:00
}
$result = $this -> company -> del_commercial ( DolibarrApiAccess :: $user , $representative_id );
return $result ;
}
2018-02-12 03:07:45 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get customer categories for a third party
*
* @ since 5.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param string $sortfield Sort field
* @ param string $sortorder Sort order
* @ param int $limit List limit
* @ param int $page Page number
* @ return array
2025-03-03 13:23:57 +00:00
* @ phan - return array < int , array { id : int , fk_parent : int , label : string , description : string , color : string , position : int , socid : int , type : string , entity : int , array_options : array < string , mixed > , visible : int , ref_ext : string , multilangs ? : array < string , array { label : string , description : string , note ? : string } > } >
* @ phpstan - return array < int , array { id : int , fk_parent : int , label : string , description : string , color : string , position : int , socid : int , type : string , entity : int , array_options : array < string , mixed > , visible : int , ref_ext : string , multilangs ? : array < string , array { label : string , description : string , note ? : string } > } >
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / categories
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getCategories ( $id , $sortfield = " s.rowid " , $sortorder = 'ASC' , $limit = 0 , $page = 0 )
2017-10-03 11:07:07 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'categorie' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2017-10-03 17:09:46 +00:00
}
2018-02-12 03:07:45 +00:00
$result = $this -> company -> fetch ( $id );
2021-02-26 20:17:52 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
2026-07-29 10:55:43 +00:00
// Check that user has permission on thirdparty ID
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company )) {
throw new RestException ( 404 , 'Third party not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
2017-10-03 17:01:54 +00:00
$categories = new Categorie ( $this -> db );
2017-10-03 11:07:07 +00:00
2023-04-30 01:10:20 +00:00
$arrayofcateg = $categories -> getListForItem ( $id , 'customer' , $sortfield , $sortorder , $limit , $page );
2017-10-03 11:07:07 +00:00
2023-04-30 01:10:20 +00:00
if ( is_numeric ( $arrayofcateg ) && $arrayofcateg < 0 ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 503 , 'Error when retrieve category list : ' . $categories -> error );
}
2023-05-02 01:38:57 +00:00
if ( is_numeric ( $arrayofcateg ) && $arrayofcateg >= 0 ) { // To fix a return of 0 instead of empty array of method getListForItem
2018-02-12 03:07:45 +00:00
return array ();
}
2023-04-30 01:10:20 +00:00
return $arrayofcateg ;
2018-02-12 03:07:45 +00:00
}
/**
2025-05-07 09:20:14 +00:00
* Add a customer category to a third party
*
* @ since 5.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param int $category_id ID of category
* @ return Object
2025-05-07 09:28:30 +00:00
*
2025-03-03 13:23:57 +00:00
* @ phan - return Societe
* @ phpstan - return Societe
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url PUT { id } / categories / { category_id }
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function addCategory ( $id , $category_id )
2018-02-12 03:07:45 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2026-07-29 10:55:43 +00:00
throw new RestException ( 404 , 'Third party not found' );
2018-02-12 03:07:45 +00:00
}
$category = new Categorie ( $this -> db );
$result = $category -> fetch ( $category_id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'category not found' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'category' , $category -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-01-27 10:55:16 +00:00
$category -> add_type ( $this -> company , 'customer' );
2018-02-12 03:07:45 +00:00
return $this -> _cleanObjectDatas ( $this -> company );
}
/**
2025-05-07 09:20:14 +00:00
* Remove the link between a customer category and the third party
*
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param int $category_id ID of category
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return Object
2025-03-03 13:23:57 +00:00
* @ phan - return Societe
* @ phpstan - return Societe
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url DELETE { id } / categories / { category_id }
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function deleteCategory ( $id , $category_id )
2018-02-12 03:07:45 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
$category = new Categorie ( $this -> db );
$result = $category -> fetch ( $category_id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'category not found' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'category' , $category -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-01-27 10:55:16 +00:00
$category -> del_type ( $this -> company , 'customer' );
2018-02-12 03:07:45 +00:00
return $this -> _cleanObjectDatas ( $this -> company );
}
/**
2025-05-07 09:20:14 +00:00
* Get supplier categories for a third party
*
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param string $sortfield Sort field
* @ param string $sortorder Sort order
* @ param int $limit List limit
* @ param int $page Page number
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array
2025-03-03 13:23:57 +00:00
* @ phan - return array < int , array { id : int , fk_parent : int , label : string , description : string , color : string , position : int , socid : int , type : string , entity : int , array_options : array < string , mixed > , visible : int , ref_ext : string , multilangs ? : array < string , array { label : string , description : string , note ? : string } > } >
* @ phpstan - return array < int , array { id : int , fk_parent : int , label : string , description : string , color : string , position : int , socid : int , type : string , entity : int , array_options : array < string , mixed > , visible : int , ref_ext : string , multilangs ? : array < string , array { label : string , description : string , note ? : string } > } >
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / supplier_categories
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getSupplierCategories ( $id , $sortfield = " s.rowid " , $sortorder = 'ASC' , $limit = 0 , $page = 0 )
2018-02-12 03:07:45 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'categorie' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2021-02-26 20:17:52 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
2017-10-03 17:01:54 +00:00
}
2026-07-29 10:55:43 +00:00
// Check that user has permission on thirdparty ID
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company )) {
throw new RestException ( 404 , 'Third party not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
2018-02-12 03:07:45 +00:00
$categories = new Categorie ( $this -> db );
$result = $categories -> getListForItem ( $id , 'supplier' , $sortfield , $sortorder , $limit , $page );
2021-02-26 20:17:52 +00:00
if ( is_numeric ( $result ) && $result < 0 ) {
2017-10-03 17:01:54 +00:00
throw new RestException ( 503 , 'Error when retrieve category list : ' . $categories -> error );
}
2021-02-26 20:17:52 +00:00
if ( is_numeric ( $result ) && $result == 0 ) { // To fix a return of 0 instead of empty array of method getListForItem
2018-02-12 03:07:45 +00:00
return array ();
}
2017-10-03 17:01:54 +00:00
return $result ;
2018-02-12 03:07:45 +00:00
}
/**
2025-05-07 09:20:14 +00:00
* Add a supplier category to a third party
*
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param int $category_id ID of category
* @ return mixed
2025-05-07 09:28:30 +00:00
*
2025-03-03 13:23:57 +00:00
* @ phan - return Societe
* @ phpstan - return Societe
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url PUT { id } / supplier_categories / { category_id }
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function addSupplierCategory ( $id , $category_id )
2018-02-12 03:07:45 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
$category = new Categorie ( $this -> db );
$result = $category -> fetch ( $category_id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'category not found' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'category' , $category -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-01-27 10:55:16 +00:00
$category -> add_type ( $this -> company , 'supplier' );
2018-02-12 03:07:45 +00:00
return $this -> _cleanObjectDatas ( $this -> company );
}
/**
2025-05-07 09:20:14 +00:00
* Remove the link between a category and the third party
*
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param int $category_id ID of category
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return mixed
2025-03-03 13:23:57 +00:00
* @ phan - return Societe
* @ phpstan - return Societe
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url DELETE { id } / supplier_categories / { category_id }
*
* @ throws RestException
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function deleteSupplierCategory ( $id , $category_id )
2018-02-12 03:07:45 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
$category = new Categorie ( $this -> db );
$result = $category -> fetch ( $category_id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'category not found' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'category' , $category -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
2019-01-27 10:55:16 +00:00
$category -> del_type ( $this -> company , 'supplier' );
2018-02-12 03:07:45 +00:00
return $this -> _cleanObjectDatas ( $this -> company );
}
/**
2025-05-07 09:20:14 +00:00
* Get outstanding proposals for a third party
*
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
2023-09-26 16:43:25 +00:00
* @ param string $mode 'customer' or 'supplier'
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / outstandingproposals
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array List of outstandings proposals of thirdparty
2025-03-03 13:23:57 +00:00
* @ phan - return array { opened ? : float }
* @ phpstan - return array { opened ? : float }
2018-02-12 03:07:45 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 400
* @ throws RestException 401
* @ throws RestException 404
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getOutStandingProposals ( $id , $mode = 'customer' )
2018-02-12 03:07:45 +00:00
{
2022-09-10 09:10:33 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( empty ( $id )) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
2018-02-01 01:29:41 +00:00
$result = $this -> company -> getOutstandingProposals ( $mode );
unset ( $result [ 'total_ht' ]);
unset ( $result [ 'total_ttc' ]);
return $result ;
2018-02-12 03:07:45 +00:00
}
/**
2025-05-07 09:20:14 +00:00
* Get outstanding orders for a third party
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 7.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
2023-09-26 16:43:25 +00:00
* @ param string $mode 'customer' or 'supplier'
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / outstandingorders
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array List of outstandings orders of the third party
2025-03-03 13:23:57 +00:00
* @ phan - return array { opened ? : float }
* @ phpstan - return array { opened ? : float }
2018-02-12 03:07:45 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 400
* @ throws RestException 401
* @ throws RestException 404
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getOutStandingOrder ( $id , $mode = 'customer' )
2018-02-12 03:07:45 +00:00
{
2022-09-10 09:10:33 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( empty ( $id )) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
$result = $this -> company -> getOutstandingOrders ( $mode );
unset ( $result [ 'total_ht' ]);
unset ( $result [ 'total_ttc' ]);
return $result ;
}
/**
2025-05-07 09:20:14 +00:00
* Get outstanding invoices for a third party
*
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
2023-09-26 16:43:25 +00:00
* @ param string $mode 'customer' or 'supplier'
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / outstandinginvoices
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array List of outstanding invoices of the third party
2025-03-03 13:23:57 +00:00
* @ phan - return array { opened ? : float }
* @ phpstan - return array { opened ? : float }
2018-02-12 03:07:45 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 400
* @ throws RestException 401
* @ throws RestException 404
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getOutStandingInvoices ( $id , $mode = 'customer' )
2018-02-12 03:07:45 +00:00
{
2022-09-10 09:10:33 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( empty ( $id )) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
$result = $this -> company -> getOutstandingBills ( $mode );
unset ( $result [ 'total_ht' ]);
unset ( $result [ 'total_ttc' ]);
return $result ;
}
2019-10-25 15:14:00 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get representatives of a third party
*
* @ since 11.0 . 0 Initial implementation
2019-10-25 15:14:00 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
2023-12-02 21:28:04 +00:00
* @ param int $mode 0 = Array with properties , 1 = Array of id .
2019-10-25 15:14:00 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / representatives
2019-10-25 15:14:00 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array List of representatives of the third party
2025-03-03 13:23:57 +00:00
* @ phan - return int [] | array < array { id : int , lastname : string , firstname : string , email : string , phone : string , office_phone : string , office_fax : string , user_mobile : string , personal_mobile : string , job : string , statut : int , status : int , entity : int , login : string , photo : string , gender : string } >
* @ phpstan - return int [] | array < array { id : int , lastname : string , firstname : string , email : string , phone : string , office_phone : string , office_fax : string , user_mobile : string , personal_mobile : string , job : string , statut : int , status : int , entity : int , login : string , photo : string , gender : string } >
2019-10-25 15:14:00 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 400
* @ throws RestException 401
* @ throws RestException 404
2019-10-25 15:14:00 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getSalesRepresentatives ( $id , $mode = 0 )
2019-10-25 15:14:00 +00:00
{
2022-09-10 09:10:33 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2019-10-25 15:14:00 +00:00
}
2019-11-14 11:09:15 +00:00
if ( empty ( $id )) {
2019-10-25 15:14:00 +00:00
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2019-10-25 15:14:00 +00:00
}
$result = $this -> company -> fetch ( $id );
2026-03-22 19:14:38 +00:00
if ( $result <= 0 ) {
2019-10-25 15:14:00 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
$result = $this -> company -> getSalesRepresentatives ( DolibarrApiAccess :: $user , $mode );
return $result ;
}
2018-02-12 03:07:45 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get fixed amount discount of a third party
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* all sources : deposit , credit note , commercial offers , etc .
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
2025-11-28 14:14:29 +00:00
* @ param string $mode 'customer' or 'supplier'
2025-05-07 09:20:14 +00:00
* @ param string $filter Filter exceptional discount . " none " will return every discount , " available " returns unapplied discounts , " used " returns applied discounts { @ choice none , available , used }
* @ param string $sortfield Sort field
* @ param string $sortorder Sort order
*
* @ url GET { id } / fixedamountdiscounts
*
* @ return array List of fixed discount of the third party
2025-03-03 13:23:57 +00:00
* @ phan - return stdClass []
* @ phpstan - return stdClass []
2018-02-12 03:07:45 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 400
* @ throws RestException 401
* @ throws RestException 404
* @ throws RestException 503
2018-02-12 03:07:45 +00:00
*/
2025-11-28 14:25:15 +00:00
public function getFixedAmountDiscounts ( $id , $mode = 'customer' , $filter = " none " , $sortfield = " f.type " , $sortorder = 'ASC' )
2018-02-12 03:07:45 +00:00
{
$obj_ret = array ();
2022-09-10 09:10:33 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
2019-11-16 22:24:29 +00:00
if ( empty ( $id )) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2019-11-16 22:24:29 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
$result = $this -> company -> fetch ( $id );
2019-11-16 22:24:29 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 404 , 'Thirdparty not found' );
}
2025-11-28 14:14:29 +00:00
$sql = '' ;
if ( $mode === 'customer' ) {
$sql = " SELECT f.ref, f.type as factype, re.fk_facture_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_facture, re.fk_facture_line " ;
2026-02-16 20:21:13 +00:00
$sql .= " FROM " . MAIN_DB_PREFIX . " societe_remise_except as re " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " facture as f ON f.rowid = re.fk_facture_source " ;
$sql .= " WHERE re.fk_soc = " . (( int ) $id );
2025-11-28 14:14:29 +00:00
if ( $filter == " available " ) {
$sql .= " AND re.fk_facture IS NULL AND re.fk_facture_line IS NULL " ;
}
if ( $filter == " used " ) {
$sql .= " AND (re.fk_facture IS NOT NULL OR re.fk_facture_line IS NOT NULL) " ;
}
2025-11-28 14:40:57 +00:00
} elseif ( $mode === 'supplier' ) {
2025-11-28 14:14:29 +00:00
$sql = " SELECT f.ref, f.type as factype, re.fk_invoice_supplier_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_invoice_supplier, re.fk_invoice_supplier_line " ;
2026-02-16 20:21:13 +00:00
$sql .= " FROM " . MAIN_DB_PREFIX . " societe_remise_except as re " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " facture_fourn as f ON f.rowid = re.fk_invoice_supplier_source " ;
2025-11-28 14:14:29 +00:00
$sql .= " WHERE f.rowid = re.fk_invoice_supplier_source AND re.fk_soc = " . (( int ) $id );
if ( $filter == " available " ) {
$sql .= " AND re.fk_invoice_supplier IS NULL AND re.fk_invoice_supplier_line IS NULL " ;
}
if ( $filter == " used " ) {
$sql .= " AND (re.fk_invoice_supplier IS NOT NULL OR re.fk_invoice_supplier_line IS NOT NULL) " ;
}
2021-02-26 20:17:52 +00:00
}
2018-02-12 03:07:45 +00:00
2019-11-14 11:09:15 +00:00
$sql .= $this -> db -> order ( $sortfield , $sortorder );
2018-02-12 03:07:45 +00:00
$result = $this -> db -> query ( $sql );
2019-11-14 11:09:15 +00:00
if ( ! $result ) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 503 , $this -> db -> lasterror ());
} else {
2025-09-28 20:20:44 +00:00
//$num = $this->db->num_rows($result);
2019-11-14 11:09:15 +00:00
while ( $obj = $this -> db -> fetch_object ( $result )) {
2018-02-12 03:07:45 +00:00
$obj_ret [] = $obj ;
}
}
return $obj_ret ;
}
2026-02-04 20:23:46 +00:00
/**
* Create a fixed amount discount for a thirdparty
*
2026-02-13 14:10:58 +00:00
* @ since 24.0 . 0 Initial implementation
*
2026-02-04 20:23:46 +00:00
* @ param int $id ID of thirdparty
* @ param array $request_data Request data
2026-02-13 14:10:58 +00:00
* - amount float Amount including tax ( required if price_base_type is TTC )
* - description string Description of the discount ( required )
* - tva_tx float VAT rate in percentage
* - discount_type int Type of discount : 0 = customer discount , 1 = supplier discount ( default : 0 )
* - price_base_type string Price base type : 'HT' or 'TTC' ( default : 'HT' )
2026-02-04 20:23:46 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
*
* @ url POST { id } / fixedamountdiscounts
*
* @ return int ID of the created discount
*
* @ throws RestException 400 Bad request
* @ throws RestException 401 Access not allowed for login
* @ throws RestException 404 Thirdparty not found
* @ throws RestException 500 Error creating discount
*/
public function createFixedAmountDiscount ( $id , $request_data = null )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
throw new RestException ( 403 );
}
// Check mandatory fields
if ( empty ( $id )) {
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
if ( ! isset ( $request_data [ 'amount' ])) {
throw new RestException ( 400 , 'Missing required field: amount' );
}
if ( ! isset ( $request_data [ 'description' ])) {
throw new RestException ( 400 , 'Missing required field: description' );
}
// Check access to resource
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
throw new RestException ( 401 , 'Access not allowed for login' . DolibarrApiAccess :: $user -> login );
}
// Fetch thirdparty to verify it exists
if ( $this -> company -> fetch ( $id ) <= 0 ) {
throw new RestException ( 404 , 'Error creating discount, thirdparty not found' );
}
// Validate amount
if ( ! is_numeric ( $request_data [ 'amount' ]) || $request_data [ 'amount' ] <= 0 ) {
throw new RestException ( 400 , 'Invalid amount_ht: must be a positive number' );
}
$amount = ( float ) $request_data [ 'amount' ];
// Validate VAT rate
if ( isset ( $request_data [ 'tva_tx' ]) && ( ! is_numeric ( $request_data [ 'tva_tx' ]) || $request_data [ 'tva_tx' ] < 0 )) {
throw new RestException ( 400 , 'Invalid tva_tx: must be a positive number or zero' );
}
$tva_tx = isset ( $request_data [ 'tva_tx' ]) ? ( float ) $request_data [ 'tva_tx' ] : 0 ;
// Get price base type (HT or TTC) : HT as default
$price_base_type = 'HT' ;
if ( isset ( $request_data [ 'price_base_type' ])) {
$price_base_type = strtoupper ( $request_data [ 'price_base_type' ]);
if ( $price_base_type !== 'HT' && $price_base_type !== 'TTC' ) {
throw new RestException ( 400 , 'Invalid price_base_type: must be "HT" or "TTC"' );
}
}
// Get discount type (0 = customer, 1 = supplier): 0 as default
$discount_type = 0 ;
if ( isset ( $request_data [ 'discount_type' ])) {
$discount_type = ( int ) $request_data [ 'discount_type' ];
if ( $discount_type !== 0 && $discount_type !== 1 ) {
throw new RestException ( 400 , 'Invalid discount_type: must be 0 (customer) or 1 (supplier)' );
}
}
// Get description
$description = $request_data [ 'description' ];
if ( empty ( trim ( $description ))) {
throw new RestException ( 400 , 'Description cannot be empty' );
}
// Prepare VAT rate with code if provided
$vatrate = " " ;
if ( isset ( $request_data [ 'vat_src_code' ]) && ! empty ( $request_data [ 'vat_src_code' ])) {
$vatrate = $tva_tx . ' (' . $request_data [ 'vat_src_code' ] . ')' ;
}
// Create the discount using Societe::set_remise_except()
$this -> db -> begin ();
$result = $this -> company -> set_remise_except ( $amount , DolibarrApiAccess :: $user , $description , $vatrate , $discount_type , $price_base_type );
if ( $result > 0 ) {
$this -> db -> commit ();
return $result ;
} else {
$this -> db -> rollback ();
throw new RestException ( 500 , 'Error creating discount: ' . $this -> company -> error , array_merge ( array ( $this -> company -> error ), $this -> company -> errors ));
}
}
2025-08-06 21:11:10 +00:00
/**
* Split a discount in 2 smaller discount
*
* @ param int $id ID of the thirdparty
* @ param int $discountid ID of a discount coming from a credit note
* @ param float $amount_ttc_1 Amount 1 ( inc . tax )
* @ param float $amount_ttc_2 Amount 2 ( inc . tax )
*
*
* @ url POST { id } / splitdiscount / { discountid }
*
* @ return array List of fixed discount of the third party
* @ phan - return stdClass []
* @ phpstan - return stdClass []
*
* @ throws RestException 400
* @ throws RestException 401
* @ throws RestException 403
* @ throws RestException 404
* @ throws RestException 405
* @ throws RestException 409
* @ throws RestException 500
*/
public function splitdiscount ( $id , $discountid , $amount_ttc_1 , $amount_ttc_2 )
{
$obj_ret = array ();
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' ) || ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
throw new RestException ( 403 );
}
if ( empty ( $id )) {
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
if ( empty ( $discountid )) {
throw new RestException ( 400 , 'Discount ID is mandatory' );
}
if ( empty ( $amount_ttc_1 ) || empty ( $amount_ttc_2 )) {
throw new RestException ( 400 , 'Amount are mandatory' );
}
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
$result = $this -> company -> fetch ( $id );
if ( ! $result ) {
throw new RestException ( 404 , 'Thirdparty not found' );
}
require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php' ;
$discount = new DiscountAbsolute ( $this -> db );
$res = $discount -> fetch ( $discountid );
if ( ! ( $res > 0 )) {
throw new RestException ( 404 , 'Discount not found' );
}
if ( $discount -> socid != $id ) {
throw new RestException ( 405 , 'Discount not owned by this thirdpartie' );
}
2026-07-23 17:06:39 +00:00
if ( price2num (( float ) $amount_ttc_1 + ( float ) $amount_ttc_2 ) != $discount -> amount_ttc ) {
2025-08-06 21:11:10 +00:00
throw new RestException ( 405 , 'Sum of the 2 discounts is different that the original discount' );
}
if ( $discount -> fk_facture_line ) {
throw new RestException ( 409 , 'Discount is already used' );
}
$newdiscount1 = new DiscountAbsolute ( $this -> db );
$newdiscount2 = new DiscountAbsolute ( $this -> db );
$newdiscount1 -> fk_facture_source = $discount -> fk_facture_source ;
$newdiscount2 -> fk_facture_source = $discount -> fk_facture_source ;
$newdiscount1 -> fk_facture = $discount -> fk_facture ;
$newdiscount2 -> fk_facture = $discount -> fk_facture ;
$newdiscount1 -> fk_facture_line = $discount -> fk_facture_line ;
$newdiscount2 -> fk_facture_line = $discount -> fk_facture_line ;
$newdiscount1 -> fk_invoice_supplier_source = $discount -> fk_invoice_supplier_source ;
$newdiscount2 -> fk_invoice_supplier_source = $discount -> fk_invoice_supplier_source ;
$newdiscount1 -> fk_invoice_supplier = $discount -> fk_invoice_supplier ;
$newdiscount2 -> fk_invoice_supplier = $discount -> fk_invoice_supplier ;
$newdiscount1 -> fk_invoice_supplier_line = $discount -> fk_invoice_supplier_line ;
$newdiscount2 -> fk_invoice_supplier_line = $discount -> fk_invoice_supplier_line ;
if ( $discount -> description == '(CREDIT_NOTE)' || $discount -> description == '(DEPOSIT)' ) {
$newdiscount1 -> description = $discount -> description ;
$newdiscount2 -> description = $discount -> description ;
} else {
$newdiscount1 -> description = $discount -> description . ' (1)' ;
$newdiscount2 -> description = $discount -> description . ' (2)' ;
}
$newdiscount1 -> fk_user = $discount -> fk_user ;
$newdiscount2 -> fk_user = $discount -> fk_user ;
$newdiscount1 -> fk_soc = $discount -> fk_soc ;
$newdiscount1 -> socid = $discount -> socid ;
$newdiscount2 -> fk_soc = $discount -> fk_soc ;
$newdiscount2 -> socid = $discount -> socid ;
$newdiscount1 -> discount_type = $discount -> discount_type ;
$newdiscount2 -> discount_type = $discount -> discount_type ;
$newdiscount1 -> datec = $discount -> datec ;
$newdiscount2 -> datec = $discount -> datec ;
$newdiscount1 -> tva_tx = $discount -> tva_tx ;
$newdiscount2 -> tva_tx = $discount -> tva_tx ;
$newdiscount1 -> vat_src_code = $discount -> vat_src_code ;
$newdiscount2 -> vat_src_code = $discount -> vat_src_code ;
$newdiscount1 -> amount_ttc = $amount_ttc_1 ;
$newdiscount2 -> amount_ttc = price2num ( $discount -> amount_ttc - $newdiscount1 -> amount_ttc );
$newdiscount1 -> amount_ht = price2num ( $newdiscount1 -> amount_ttc / ( 1 + $newdiscount1 -> tva_tx / 100 ), 'MT' );
$newdiscount2 -> amount_ht = price2num ( $newdiscount2 -> amount_ttc / ( 1 + $newdiscount2 -> tva_tx / 100 ), 'MT' );
$newdiscount1 -> amount_tva = price2num ( $newdiscount1 -> amount_ttc - $newdiscount1 -> amount_ht );
$newdiscount2 -> amount_tva = price2num ( $newdiscount2 -> amount_ttc - $newdiscount2 -> amount_ht );
$newdiscount1 -> multicurrency_amount_ttc = ( float ) $amount_ttc_1 * ( $discount -> multicurrency_amount_ttc / $discount -> amount_ttc );
$newdiscount2 -> multicurrency_amount_ttc = price2num ( $discount -> multicurrency_amount_ttc - $newdiscount1 -> multicurrency_amount_ttc );
$newdiscount1 -> multicurrency_amount_ht = price2num ( $newdiscount1 -> multicurrency_amount_ttc / ( 1 + $newdiscount1 -> tva_tx / 100 ), 'MT' );
$newdiscount2 -> multicurrency_amount_ht = price2num ( $newdiscount2 -> multicurrency_amount_ttc / ( 1 + $newdiscount2 -> tva_tx / 100 ), 'MT' );
$newdiscount1 -> multicurrency_amount_tva = price2num ( $newdiscount1 -> multicurrency_amount_ttc - $newdiscount1 -> multicurrency_amount_ht );
$newdiscount2 -> multicurrency_amount_tva = price2num ( $newdiscount2 -> multicurrency_amount_ttc - $newdiscount2 -> multicurrency_amount_ht );
// DiscountAbsolute->amount_ttc ->amount_ht ->amount_tva are marked as @deprecated but seems to yet be in use so we fill ->amout_xxx and ->total_xxx
// the same for multicurrency_amount_xxx and multicurrency_total_xxx
$newdiscount1 -> total_ttc = ( float ) price2num ( $newdiscount1 -> amount_ttc );
$newdiscount1 -> total_ht = ( float ) price2num ( $newdiscount1 -> amount_ht );
$newdiscount1 -> total_tva = ( float ) price2num ( $newdiscount1 -> amount_tva );
$newdiscount2 -> total_ttc = ( float ) price2num ( $newdiscount2 -> amount_ttc );
$newdiscount2 -> total_ht = ( float ) price2num ( $newdiscount2 -> amount_ht );
$newdiscount2 -> total_tva = ( float ) price2num ( $newdiscount2 -> amount_tva );
$newdiscount1 -> multicurrency_total_ttc = ( float ) price2num ( $newdiscount1 -> multicurrency_amount_ttc );
$newdiscount1 -> multicurrency_total_ht = ( float ) price2num ( $newdiscount1 -> multicurrency_amount_ht );
$newdiscount1 -> multicurrency_total_tva = ( float ) price2num ( $newdiscount1 -> multicurrency_amount_tva );
$newdiscount2 -> multicurrency_total_ttc = ( float ) price2num ( $newdiscount2 -> multicurrency_amount_ttc );
$newdiscount2 -> multicurrency_total_ht = ( float ) price2num ( $newdiscount2 -> multicurrency_amount_ht );
$newdiscount2 -> multicurrency_total_tva = ( float ) price2num ( $newdiscount2 -> multicurrency_amount_tva );
$this -> db -> begin ();
$discount -> fk_facture_source = 0 ; // This is to delete only the require record (that we will recreate with two records) and not all family with same fk_facture_source
// This is to delete only the require record (that we will recreate with two records) and not all family with same fk_invoice_supplier_source
$discount -> fk_invoice_supplier_source = 0 ;
$res = $discount -> delete ( DolibarrApiAccess :: $user );
$newid1 = $newdiscount1 -> create ( DolibarrApiAccess :: $user );
$newid2 = $newdiscount2 -> create ( DolibarrApiAccess :: $user );
if ( $res <= 0 || $newid1 <= 0 || $newid2 <= 0 ) {
$this -> db -> rollback ();
throw new RestException ( 500 , 'Operation fail' );
}
$this -> db -> commit ();
$sql = " SELECT f.ref, f.type as factype, re.fk_facture_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_facture, re.fk_facture_line " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " societe_remise_except as re, " . MAIN_DB_PREFIX . " facture as f " ;
2026-07-23 17:06:39 +00:00
$sql .= " WHERE re.rowid IN ( " . (( int ) $newid1 ) . " , " . (( int ) $newid2 ) . " ) AND f.rowid = re.fk_facture_source AND re.fk_soc = " . (( int ) $id );
2025-08-06 21:11:10 +00:00
$sql .= $this -> db -> order ( " f.type " , " ASC " );
$result = $this -> db -> query ( $sql );
if ( ! $result ) {
throw new RestException ( 503 , $this -> db -> lasterror ());
} else {
// $num = $this->db->num_rows($result);
while ( $obj = $this -> db -> fetch_object ( $result )) {
$obj_ret [] = $obj ;
}
}
return $obj_ret ;
}
2018-02-12 03:07:45 +00:00
/**
2025-05-07 09:20:14 +00:00
* Return invoices qualified to be replaced by another invoice
*
* @ since 7.0 . 0 Initial implementation
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of a third party
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / getinvoicesqualifiedforreplacement
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array
2025-03-03 13:23:57 +00:00
* @ phan - return array < int , array { id : int , ref : string , status : int , paid : int , alreadypaid : int } >| int
* @ phpstan - return array < int , array { id : int , ref : string , status : int , paid : int , alreadypaid : int } >| int
2020-02-20 12:42:43 +00:00
* @ throws RestException 400
* @ throws RestException 401
* @ throws RestException 404
* @ throws RestException 405
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getInvoicesQualifiedForReplacement ( $id )
{
2023-06-19 21:18:13 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'facture' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( empty ( $id )) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
/* $result = $this -> thirdparty -> fetch ( $id );
if ( ! $result ) {
throw new RestException ( 404 , 'Thirdparty not found' );
} */
2024-04-21 08:49:13 +00:00
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php' ;
2018-02-12 03:07:45 +00:00
$invoice = new Facture ( $this -> db );
$result = $invoice -> list_replacable_invoices ( $id );
2019-11-14 11:09:15 +00:00
if ( $result < 0 ) {
2022-10-23 09:19:23 +00:00
throw new RestException ( 405 , $invoice -> error );
2018-02-12 03:07:45 +00:00
}
return $result ;
}
/**
2025-05-07 09:20:14 +00:00
* Return invoices qualified to be corrected by a credit note
*
2018-02-12 03:07:45 +00:00
* Invoices matching the following rules are returned
2024-01-12 16:18:52 +00:00
* ( validated + payment on process ) or classified ( paid completely or paid partially ) + not already replaced + not already a credit note
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 7.0 . 0 Initial implementation
*
* @ param int $id ID of a third party
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / getinvoicesqualifiedforcreditnote
2018-02-12 03:07:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array
2025-03-03 13:23:57 +00:00
* @ phan - return array < int , array { ref : string , status : int , type : int , paye : int , paymentornot : int } >| int
* @ phpstan - return array < int , array { ref : string , status : int , type : int , paye : int , paymentornot : int } >| int
2020-02-20 12:42:43 +00:00
*
* @ throws RestException 400
* @ throws RestException 401
* @ throws RestException 404
* @ throws RestException 405
2018-02-12 03:07:45 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getInvoicesQualifiedForCreditNote ( $id )
{
2023-06-19 21:18:13 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'facture' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-02-12 03:07:45 +00:00
}
2019-11-14 11:09:15 +00:00
if ( empty ( $id )) {
2018-02-12 03:07:45 +00:00
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-02-12 03:07:45 +00:00
}
/* $result = $this -> thirdparty -> fetch ( $id );
if ( ! $result ) {
throw new RestException ( 404 , 'Thirdparty not found' );
} */
2024-04-21 08:49:13 +00:00
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php' ;
2018-02-12 03:07:45 +00:00
$invoice = new Facture ( $this -> db );
$result = $invoice -> list_qualified_avoir_invoices ( $id );
2025-03-03 13:23:57 +00:00
if ( ! is_array ( $result ) && $result < 0 ) {
2022-10-23 09:19:23 +00:00
throw new RestException ( 405 , $invoice -> error );
2018-02-12 03:07:45 +00:00
}
return $result ;
}
2018-08-26 16:15:14 +00:00
2024-03-11 21:36:07 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get company notifications for a third party
2024-03-11 21:36:07 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 20.0 . 0 Initial implementation
2024-03-11 21:36:07 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
*
* @ return array
2025-03-03 13:23:57 +00:00
* @ phan - return array < array { id : int , socid : int , event : string , contact_id : int , datec : int , tms : string , type : string } >
* @ phpstan - return array < array { id : int , socid : int , event : string , contact_id : int , datec : int , tms : string , type : string } >
2024-03-11 21:36:07 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / notifications
*
* @ throws RestException
2024-03-11 21:36:07 +00:00
*/
public function getCompanyNotification ( $id )
{
if ( empty ( $id )) {
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2024-03-19 14:55:23 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
throw new RestException ( 403 );
}
2024-03-11 21:36:07 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-03-19 14:55:23 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2024-03-11 21:36:07 +00:00
}
/**
* We select all the records that match the socid
*/
2024-08-07 00:58:05 +00:00
$sql = " SELECT rowid as id, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms " ;
2024-03-11 21:36:07 +00:00
$sql .= " FROM " . MAIN_DB_PREFIX . " notify_def " ;
if ( $id ) {
$sql .= " WHERE fk_soc = " . (( int ) $id );
}
$result = $this -> db -> query ( $sql );
if ( $this -> db -> num_rows ( $result ) == 0 ) {
throw new RestException ( 404 , 'Notification not found' );
}
$i = 0 ;
2024-03-13 22:31:27 +00:00
$notifications = array ();
2024-03-11 21:36:07 +00:00
if ( $result ) {
2025-09-28 20:20:44 +00:00
$i = 0 ;
2024-03-11 21:36:07 +00:00
$num = $this -> db -> num_rows ( $result );
2025-09-28 20:20:44 +00:00
//$min = min($num, ($limit <= 0 ? $num : $limit));
$min = $num ;
while ( $i < $min ) {
2024-03-11 21:36:07 +00:00
$obj = $this -> db -> fetch_object ( $result );
2024-03-13 21:13:57 +00:00
$notifications [] = $obj ;
2024-03-11 21:36:07 +00:00
$i ++ ;
}
} else {
2024-03-11 22:24:26 +00:00
throw new RestException ( 404 , 'No notifications found' );
2024-03-11 21:36:07 +00:00
}
2024-08-07 00:58:05 +00:00
$fields = array ( 'id' , 'socid' , 'event' , 'contact_id' , 'datec' , 'tms' , 'type' );
2024-03-11 21:36:07 +00:00
2024-03-11 22:24:26 +00:00
$returnNotifications = array ();
2024-03-11 21:36:07 +00:00
foreach ( $notifications as $notification ) {
$object = array ();
foreach ( $notification as $key => $value ) {
if ( in_array ( $key , $fields )) {
$object [ $key ] = $value ;
}
}
2024-03-11 22:24:26 +00:00
$returnNotifications [] = $object ;
2024-03-11 21:36:07 +00:00
}
2025-03-03 13:23:57 +00:00
// Too complex for phan ?: @phan-suppress-next-line PhanTypeMismatchReturn
2024-03-11 22:24:26 +00:00
return $returnNotifications ;
2024-03-11 21:36:07 +00:00
}
2024-03-16 08:46:32 +00:00
/**
2025-05-07 09:20:14 +00:00
* Create a company notification for a third party
2025-03-02 11:13:32 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 20.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param array $request_data Request data
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2024-03-16 08:46:32 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array | mixed Notification of the third party
*
* @ url POST { id } / notifications
2024-03-16 08:46:32 +00:00
*
2025-05-07 09:20:14 +00:00
* @ throws RestException
2024-03-16 08:46:32 +00:00
*/
public function createCompanyNotification ( $id , $request_data = null )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
throw new RestException ( 403 , " User has no right to update thirdparties " );
}
if ( $this -> company -> fetch ( $id ) <= 0 ) {
throw new RestException ( 404 , 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists' );
}
$notification = new Notify ( $this -> db );
$notification -> socid = $id ;
foreach ( $request_data as $field => $value ) {
2026-05-08 23:16:35 +00:00
$notification -> $field = $this -> _checkValForAPI ( $field , $value , $notification );
2024-03-16 08:46:32 +00:00
}
2024-08-10 22:20:45 +00:00
$event = $notification -> event ;
if ( ! $event ) {
throw new RestException ( 500 , 'Error creating Thirdparty Notification, request_data missing event' );
}
$socid = $notification -> socid ;
$contact_id = $notification -> contact_id ;
$exists_sql = " SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem " ;
$exists_sql .= " FROM " . MAIN_DB_PREFIX . " notify_def " ;
2025-03-03 13:23:57 +00:00
$exists_sql .= " WHERE fk_action = ' " . $this -> db -> escape (( string ) $event ) . " ' " ;
$exists_sql .= " AND fk_soc = ' " . $this -> db -> escape (( string ) $socid ) . " ' " ;
$exists_sql .= " AND fk_contact = ' " . $this -> db -> escape (( string ) $contact_id ) . " ' " ;
2024-08-10 22:20:45 +00:00
$exists_result = $this -> db -> query ( $exists_sql );
2024-08-13 23:24:55 +00:00
if ( $this -> db -> num_rows ( $exists_result ) > 0 ) {
2024-08-10 22:20:45 +00:00
throw new RestException ( 403 , 'Notification already exists' );
}
2024-03-16 08:46:32 +00:00
if ( $notification -> create ( DolibarrApiAccess :: $user ) < 0 ) {
throw new RestException ( 500 , 'Error creating Thirdparty Notification' );
}
2024-08-10 22:20:45 +00:00
if ( $notification -> update ( DolibarrApiAccess :: $user ) < 0 ) {
throw new RestException ( 500 , 'Error updating values' );
}
return $this -> _cleanObjectDatas ( $notification );
}
/**
2025-05-07 09:20:14 +00:00
* Create a company notification for a third party using action trigger code
2025-03-02 11:13:32 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 21.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param string $code Action Trigger code
* @ param array $request_data Request data
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2024-08-10 22:20:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array | mixed Notification for the third party
2024-08-13 23:24:55 +00:00
* @ phan - return Notify
2024-08-10 22:20:45 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url POST { id } / notificationsbycode / { code }
*
* @ throws RestException
2024-08-10 22:20:45 +00:00
*/
public function createCompanyNotificationByCode ( $id , $code , $request_data = null )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
throw new RestException ( 403 , " User has no right to update thirdparties " );
}
if ( $this -> company -> fetch ( $id ) <= 0 ) {
throw new RestException ( 404 , 'Error creating Thirdparty Notification, Thirdparty doesn\'t exists' );
}
$notification = new Notify ( $this -> db );
$notification -> socid = $id ;
$sql = " SELECT t.rowid as id FROM " . MAIN_DB_PREFIX . " c_action_trigger as t " ;
$sql .= " WHERE t.code = ' " . $this -> db -> escape ( $code ) . " ' " ;
$result = $this -> db -> query ( $sql );
if ( $this -> db -> num_rows ( $result ) == 0 ) {
throw new RestException ( 404 , 'Action Trigger code not found' );
}
$notification -> event = $this -> db -> fetch_row ( $result )[ 0 ];
foreach ( $request_data as $field => $value ) {
if ( $field === 'event' ) {
throw new RestException ( 500 , 'Error creating Thirdparty Notification, request_data contains event key' );
}
if ( $field === 'fk_action' ) {
throw new RestException ( 500 , 'Error creating Thirdparty Notification, request_data contains fk_action key' );
}
2026-05-08 23:16:35 +00:00
$notification -> $field = $this -> _checkValForAPI ( $field , $value , $notification );
2024-08-10 22:20:45 +00:00
}
$event = $notification -> event ;
$socid = $notification -> socid ;
$contact_id = $notification -> contact_id ;
$exists_sql = " SELECT rowid, fk_action as event, fk_soc as socid, fk_contact as contact_id, type, datec, tms as datem " ;
$exists_sql .= " FROM " . MAIN_DB_PREFIX . " notify_def " ;
2025-03-03 13:23:57 +00:00
$exists_sql .= " WHERE fk_action = ' " . $this -> db -> escape (( string ) $event ) . " ' " ;
$exists_sql .= " AND fk_soc = ' " . $this -> db -> escape (( string ) $socid ) . " ' " ;
$exists_sql .= " AND fk_contact = ' " . $this -> db -> escape (( string ) $contact_id ) . " ' " ;
2024-08-10 22:20:45 +00:00
$exists_result = $this -> db -> query ( $exists_sql );
2024-08-13 23:24:55 +00:00
if ( $this -> db -> num_rows ( $exists_result ) > 0 ) {
2024-08-10 22:20:45 +00:00
throw new RestException ( 403 , 'Notification already exists' );
}
if ( $notification -> create ( DolibarrApiAccess :: $user ) < 0 ) {
throw new RestException ( 500 , 'Error creating Thirdparty Notification, are request_data well formed?' );
}
2024-03-16 08:46:32 +00:00
if ( $notification -> update ( DolibarrApiAccess :: $user ) < 0 ) {
throw new RestException ( 500 , 'Error updating values' );
}
return $this -> _cleanObjectDatas ( $notification );
}
2024-03-11 21:36:07 +00:00
/**
2025-05-07 09:20:14 +00:00
* Delete a company notification attached to a third party
2024-03-11 21:36:07 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 20.0 . 0 Initial implementation
2024-03-11 21:36:07 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param int $notification_id ID of CompanyNotification
2024-03-11 21:36:07 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return int - 1 if error , 1 if correct deletion
*
* @ url DELETE { id } / notifications / { notification_id }
*
* @ throws RestException
2024-03-11 21:36:07 +00:00
*/
public function deleteCompanyNotification ( $id , $notification_id )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
throw new RestException ( 403 );
}
2024-03-13 22:14:49 +00:00
$notification = new Notify ( $this -> db );
2024-03-11 21:36:07 +00:00
$notification -> fetch ( $notification_id );
2024-03-15 21:40:43 +00:00
$socid = ( int ) $notification -> socid ;
2024-03-11 21:36:07 +00:00
2024-03-15 21:40:43 +00:00
if ( $socid == $id ) {
return $notification -> delete ( DolibarrApiAccess :: $user );
} else {
throw new RestException ( 403 , " Not allowed due to bad consistency of input data " );
}
2024-03-11 21:36:07 +00:00
}
2024-03-15 22:50:01 +00:00
/**
2025-05-07 09:20:14 +00:00
* Update a company notification for a third party
2024-03-15 22:50:01 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 20.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param int $notification_id ID of CompanyNotification
* @ param array $request_data Request data
2025-05-07 09:32:25 +00:00
* @ return array | mixed Notification for the third party
2025-05-07 09:28:30 +00:00
*
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2024-03-15 22:50:01 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url PUT { id } / notifications / { notification_id }
2024-03-15 22:50:01 +00:00
*
2025-05-07 09:20:14 +00:00
* @ throws RestException
2024-03-15 22:50:01 +00:00
*/
public function updateCompanyNotification ( $id , $notification_id , $request_data = null )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
throw new RestException ( 403 , " User has no right to update thirdparties " );
}
if ( $this -> company -> fetch ( $id ) <= 0 ) {
throw new RestException ( 404 , 'Error creating Company Notification, Company doesn\'t exists' );
}
$notification = new Notify ( $this -> db );
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2024-03-15 23:14:59 +00:00
$notification -> fetch ( $notification_id , $id );
2024-03-15 22:50:01 +00:00
if ( $notification -> socid != $id ) {
throw new RestException ( 403 , " Not allowed due to bad consistency of input data " );
}
foreach ( $request_data as $field => $value ) {
2026-05-08 23:16:35 +00:00
$notification -> $field = $this -> _checkValForAPI ( $field , $value , $notification );
2024-03-15 22:50:01 +00:00
}
if ( $notification -> update ( DolibarrApiAccess :: $user ) < 0 ) {
throw new RestException ( 500 , 'Error updating values' );
}
return $this -> _cleanObjectDatas ( $notification );
}
2018-06-27 08:33:57 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get company bank accounts of a third party
2018-06-29 23:34:51 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 9.0 . 0 Initial implementation
2018-06-29 23:34:51 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
*
* @ return array
2025-03-03 13:23:57 +00:00
* @ phan - return array < array { socid ? : int , default_rib ? : string , frstrecur ? : string , 1000110000001 ? : string , datec : string , datem : string , label : string , bank : string , bic : string , iban : string , id : int , rum : string } >
* @ phpstan - return array < array { socid ? : int , default_rib ? : string , frstrecur ? : string , 1000110000001 ? : string , datec : string , datem : string , label : string , bank : string , bic : string , iban : string , id : int , rum : string } >
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / bankaccounts
*
* @ throws RestException
2018-06-27 08:33:57 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getCompanyBankAccount ( $id )
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-06-27 08:33:57 +00:00
}
2019-11-14 11:09:15 +00:00
if ( empty ( $id )) {
2018-06-27 08:33:57 +00:00
throw new RestException ( 400 , 'Thirdparty ID is mandatory' );
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-06-27 08:33:57 +00:00
}
/**
2018-06-27 09:01:20 +00:00
* We select all the records that match the socid
2018-06-27 08:33:57 +00:00
*/
2024-02-21 15:43:41 +00:00
$sql = " SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation as address, proprio, " ;
2019-11-14 11:09:15 +00:00
$sql .= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " societe_rib " ;
2021-02-26 20:17:52 +00:00
if ( $id ) {
2021-03-30 17:12:07 +00:00
$sql .= " WHERE fk_soc = " . (( int ) $id );
2021-02-26 20:17:52 +00:00
}
2018-06-27 08:33:57 +00:00
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-06-27 08:33:57 +00:00
2022-10-23 09:19:23 +00:00
if ( $this -> db -> num_rows ( $result ) == 0 ) {
2018-06-27 08:33:57 +00:00
throw new RestException ( 404 , 'Account not found' );
2018-06-29 23:34:51 +00:00
}
2018-06-27 08:33:57 +00:00
2019-11-14 11:09:15 +00:00
$i = 0 ;
2018-06-27 08:33:57 +00:00
2019-07-13 22:31:28 +00:00
$accounts = array ();
2018-06-27 08:33:57 +00:00
2021-02-26 20:17:52 +00:00
if ( $result ) {
2025-09-28 20:20:44 +00:00
$i = 0 ;
2020-09-19 21:30:29 +00:00
$num = $this -> db -> num_rows ( $result );
2025-09-28 20:20:44 +00:00
//$min = min($num, ($limit <= 0 ? $num : $limit));
$min = $num ;
while ( $i < $min ) {
2020-09-19 21:30:29 +00:00
$obj = $this -> db -> fetch_object ( $result );
2024-11-25 02:11:31 +00:00
2020-09-19 21:30:29 +00:00
$account = new CompanyBankAccount ( $this -> db );
2019-11-14 11:09:15 +00:00
if ( $account -> fetch ( $obj -> rowid )) {
2018-06-27 08:33:57 +00:00
$accounts [] = $account ;
}
$i ++ ;
}
2020-05-21 13:05:19 +00:00
} else {
2018-06-27 08:33:57 +00:00
throw new RestException ( 404 , 'Account not found' );
}
2018-06-29 23:34:51 +00:00
2018-06-27 08:33:57 +00:00
2019-07-13 22:31:28 +00:00
$fields = array ( 'socid' , 'default_rib' , 'frstrecur' , '1000110000001' , 'datec' , 'datem' , 'label' , 'bank' , 'bic' , 'iban' , 'id' , 'rum' );
2018-06-27 08:33:57 +00:00
2019-07-13 22:31:28 +00:00
$returnAccounts = array ();
2018-06-27 08:33:57 +00:00
2019-10-27 16:01:23 +00:00
foreach ( $accounts as $account ) {
$object = array ();
foreach ( $account as $key => $value ) {
if ( in_array ( $key , $fields )) {
2024-10-24 11:03:52 +00:00
if ( $key == 'iban' ) {
$object [ $key ] = dolDecrypt ( $value );
} else {
$object [ $key ] = $value ;
}
2018-08-26 15:29:04 +00:00
}
2019-10-27 16:01:23 +00:00
}
2018-06-27 08:33:57 +00:00
$returnAccounts [] = $object ;
2018-06-29 23:34:51 +00:00
}
2018-06-27 08:33:57 +00:00
return $returnAccounts ;
}
/**
2025-05-07 09:20:14 +00:00
* Create a company bank account for a third party
2025-03-02 11:13:32 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 9.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param array $request_data Request data
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2018-06-29 23:34:51 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array | mixed BankAccount of the third party
2018-06-29 23:34:51 +00:00
*
2018-08-26 15:29:04 +00:00
* @ url POST { id } / bankaccounts
2025-05-07 09:20:14 +00:00
*
* @ throws RestException
2018-06-27 08:33:57 +00:00
*/
2020-10-31 13:32:18 +00:00
public function createCompanyBankAccount ( $id , $request_data = null )
2018-06-27 08:33:57 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-06-27 08:33:57 +00:00
}
2020-04-13 07:15:01 +00:00
if ( $this -> company -> fetch ( $id ) <= 0 ) {
throw new RestException ( 404 , 'Error creating Company Bank account, Company doesn\'t exists' );
}
2026-08-18 10:31:40 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
2018-06-27 08:33:57 +00:00
$account = new CompanyBankAccount ( $this -> db );
2018-08-26 15:29:04 +00:00
$account -> socid = $id ;
2018-06-27 08:33:57 +00:00
2019-11-14 11:09:15 +00:00
foreach ( $request_data as $field => $value ) {
2023-12-15 11:15:33 +00:00
if ( $field === 'caller' ) {
2024-01-12 16:18:52 +00:00
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2024-04-02 10:28:55 +00:00
$this -> company -> context [ 'caller' ] = sanitizeVal ( $request_data [ 'caller' ], 'aZ09' );
2023-12-15 11:15:33 +00:00
continue ;
}
2024-04-02 10:28:55 +00:00
$account -> $field = $this -> _checkValForAPI ( 'extrafields' , $value , $account );
2018-06-27 08:33:57 +00:00
}
2021-02-26 20:17:52 +00:00
if ( $account -> create ( DolibarrApiAccess :: $user ) < 0 ) {
2018-06-27 08:33:57 +00:00
throw new RestException ( 500 , 'Error creating Company Bank account' );
2021-02-26 20:17:52 +00:00
}
2018-06-27 08:33:57 +00:00
2020-04-13 07:15:01 +00:00
if ( empty ( $account -> rum )) {
require_once DOL_DOCUMENT_ROOT . '/compta/prelevement/class/bonprelevement.class.php' ;
$prelevement = new BonPrelevement ( $this -> db );
2026-01-20 16:39:40 +00:00
$account -> rum = $prelevement -> buildRumNumber (( string ) $this -> company -> code_client , $account -> datec , ( string ) $account -> id );
2020-04-13 07:15:01 +00:00
$account -> date_rum = dol_now ();
}
2018-06-27 08:33:57 +00:00
2021-02-26 20:17:52 +00:00
if ( $account -> update ( DolibarrApiAccess :: $user ) < 0 ) {
2018-06-27 08:33:57 +00:00
throw new RestException ( 500 , 'Error updating values' );
2021-02-26 20:17:52 +00:00
}
2018-06-29 23:34:51 +00:00
2020-04-13 07:25:06 +00:00
return $this -> _cleanObjectDatas ( $account );
2018-06-27 08:33:57 +00:00
}
/**
2025-05-07 09:20:14 +00:00
* Update a company bank account of a third party
2018-06-29 23:34:51 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 9.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param int $bankaccount_id ID of CompanyBankAccount
* @ param array $request_data Request data
2025-05-07 09:32:25 +00:00
* @ return array | mixed BankAccount of the third party
2025-05-07 09:28:30 +00:00
*
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2018-06-29 23:34:51 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url PUT { id } / bankaccounts / { bankaccount_id }
2018-06-29 23:34:51 +00:00
*
2025-05-07 09:20:14 +00:00
* @ throws RestException
2018-06-27 08:33:57 +00:00
*/
2020-10-31 13:32:18 +00:00
public function updateCompanyBankAccount ( $id , $bankaccount_id , $request_data = null )
2018-06-27 08:33:57 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-06-27 08:33:57 +00:00
}
2020-04-13 07:15:01 +00:00
if ( $this -> company -> fetch ( $id ) <= 0 ) {
throw new RestException ( 404 , 'Error creating Company Bank account, Company doesn\'t exists' );
}
2026-08-18 10:31:40 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
2018-06-27 08:33:57 +00:00
$account = new CompanyBankAccount ( $this -> db );
2024-03-07 19:16:48 +00:00
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2024-04-27 10:45:50 +00:00
$account -> fetch ( $bankaccount_id , '' , $id , - 1 , '' );
2018-06-27 08:33:57 +00:00
2019-11-14 11:09:15 +00:00
if ( $account -> socid != $id ) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-06-27 08:33:57 +00:00
}
2018-06-29 23:34:51 +00:00
2018-06-27 08:33:57 +00:00
2019-11-14 11:09:15 +00:00
foreach ( $request_data as $field => $value ) {
2023-12-15 11:15:33 +00:00
if ( $field === 'caller' ) {
2024-01-12 16:18:52 +00:00
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2024-04-02 10:28:55 +00:00
$account -> context [ 'caller' ] = sanitizeVal ( $request_data [ 'caller' ], 'aZ09' );
2023-12-15 11:15:33 +00:00
continue ;
}
2024-04-02 10:28:55 +00:00
$account -> $field = $this -> _checkValForAPI ( $field , $value , $account );
2018-06-27 08:33:57 +00:00
}
2020-04-13 07:39:31 +00:00
if ( empty ( $account -> rum )) {
require_once DOL_DOCUMENT_ROOT . '/compta/prelevement/class/bonprelevement.class.php' ;
$prelevement = new BonPrelevement ( $this -> db );
2026-01-20 16:39:40 +00:00
$account -> rum = $prelevement -> buildRumNumber (( string ) $this -> company -> code_client , $account -> datec , ( string ) $account -> id );
2020-04-13 07:39:31 +00:00
$account -> date_rum = dol_now ();
}
2021-02-26 20:17:52 +00:00
if ( $account -> update ( DolibarrApiAccess :: $user ) < 0 ) {
2018-06-27 08:33:57 +00:00
throw new RestException ( 500 , 'Error updating values' );
2021-02-26 20:17:52 +00:00
}
2018-06-29 23:34:51 +00:00
2020-04-13 07:25:06 +00:00
return $this -> _cleanObjectDatas ( $account );
2018-06-27 08:33:57 +00:00
}
/**
2025-05-07 09:20:14 +00:00
* Delete a bank account attached to a third party
*
* @ since 9.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param int $bankaccount_id ID of CompanyBankAccount
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return int - 1 if error , 1 if correct deletion
2018-06-29 23:34:51 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url DELETE { id } / bankaccounts / { bankaccount_id }
2018-06-29 23:34:51 +00:00
*
2025-05-07 09:20:14 +00:00
* @ throws RestException
2018-06-27 08:33:57 +00:00
*/
2020-10-31 13:32:18 +00:00
public function deleteCompanyBankAccount ( $id , $bankaccount_id )
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-06-27 08:33:57 +00:00
}
2026-08-18 10:31:40 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
2018-06-27 08:33:57 +00:00
$account = new CompanyBankAccount ( $this -> db );
2018-08-26 15:29:04 +00:00
$account -> fetch ( $bankaccount_id );
2018-06-27 08:33:57 +00:00
2024-03-15 19:04:03 +00:00
$socid = ( int ) $account -> socid ;
2018-06-27 08:33:57 +00:00
2024-03-15 19:07:56 +00:00
if ( $socid == $id ) {
2024-03-15 19:04:03 +00:00
return $account -> delete ( DolibarrApiAccess :: $user );
} else {
2024-03-15 21:30:55 +00:00
throw new RestException ( 403 , " Not allowed due to bad consistency of input data " );
2024-03-15 19:04:03 +00:00
}
2018-06-27 08:33:57 +00:00
}
2017-10-26 23:08:14 +00:00
2018-08-26 15:29:04 +00:00
/**
2025-05-07 09:20:14 +00:00
* Generate a document from a bank account record
*
* Like SEPA mandate
*
* @ since 9.0 . 0 Initial implementation
2018-09-19 16:33:11 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param int $companybankid ID of company bank
* @ param string $model Model of document to generate
* @ return array
2025-03-03 13:23:57 +00:00
* @ phan - return array { success : int < 0 , 1 > }
* @ phpstan - return array { success : int < 0 , 1 > }
2018-09-19 16:33:11 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / generateBankAccountDocument / { companybankid } / { model }
*
* @ throws RestException
2018-07-19 13:09:32 +00:00
*/
2018-09-19 12:47:11 +00:00
public function generateBankAccountDocument ( $id , $companybankid = null , $model = 'sepamandate' )
{
2020-11-24 23:16:36 +00:00
global $conf , $langs ;
2018-09-20 15:09:31 +00:00
2020-11-24 23:16:36 +00:00
$langs -> loadLangs ( array ( " main " , " dict " , " commercial " , " products " , " companies " , " banks " , " bills " , " withdrawals " ));
2018-07-19 13:09:32 +00:00
2020-11-24 23:16:36 +00:00
if ( $this -> company -> fetch ( $id ) <= 0 ) {
throw new RestException ( 404 , 'Thirdparty not found' );
}
2018-09-20 15:09:31 +00:00
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2020-11-24 23:16:36 +00:00
}
2018-09-20 15:09:31 +00:00
$this -> company -> setDocModel ( DolibarrApiAccess :: $user , $model );
2018-07-19 13:09:32 +00:00
$this -> company -> fk_bank = $this -> company -> fk_account ;
2024-03-12 21:24:29 +00:00
// $this->company->fk_account = $this->company->fk_account;
2018-09-20 15:09:31 +00:00
2020-11-24 23:16:36 +00:00
$outputlangs = $langs ;
2019-11-14 11:09:15 +00:00
$newlang = '' ;
2018-09-20 15:09:31 +00:00
2022-09-24 12:56:50 +00:00
//if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
if ( getDolGlobalInt ( 'MAIN_MULTILANGS' ) && empty ( $newlang )) {
2020-11-24 23:16:36 +00:00
if ( isset ( $this -> company -> thirdparty -> default_lang )) {
$newlang = $this -> company -> thirdparty -> default_lang ; // for proposal, order, invoice, ...
} elseif ( isset ( $this -> company -> default_lang )) {
$newlang = $this -> company -> default_lang ; // for thirdparty
}
}
2019-11-14 11:09:15 +00:00
if ( ! empty ( $newlang )) {
2019-01-27 10:55:16 +00:00
$outputlangs = new Translate ( " " , $conf );
2018-07-19 13:09:32 +00:00
$outputlangs -> setDefaultLang ( $newlang );
}
2018-09-20 15:09:31 +00:00
2018-07-19 13:09:32 +00:00
$sql = " SELECT rowid " ;
2019-11-14 11:09:15 +00:00
$sql .= " FROM " . MAIN_DB_PREFIX . " societe_rib " ;
2021-02-26 20:17:52 +00:00
if ( $id ) {
2021-03-22 12:31:06 +00:00
$sql .= " WHERE fk_soc = " . (( int ) $id );
2021-02-26 20:17:52 +00:00
}
if ( $companybankid ) {
2021-03-22 12:31:06 +00:00
$sql .= " AND rowid = " . (( int ) $companybankid );
2021-02-26 20:17:52 +00:00
}
2018-09-19 16:33:11 +00:00
2019-11-14 11:09:15 +00:00
$i = 0 ;
$accounts = array ();
2018-09-20 15:09:31 +00:00
$result = $this -> db -> query ( $sql );
2020-11-24 23:16:36 +00:00
if ( $result ) {
if ( $this -> db -> num_rows ( $result ) == 0 ) {
2018-09-20 15:09:31 +00:00
throw new RestException ( 404 , 'Bank account not found' );
}
2018-07-19 13:09:32 +00:00
$num = $this -> db -> num_rows ( $result );
2025-09-28 20:20:44 +00:00
//$min = min($num, ($limit <= 0 ? $num : $limit));
$min = $num ;
while ( $i < $min ) {
2018-07-19 13:09:32 +00:00
$obj = $this -> db -> fetch_object ( $result );
2018-09-20 15:09:31 +00:00
2018-07-19 13:09:32 +00:00
$account = new CompanyBankAccount ( $this -> db );
2018-09-20 15:09:31 +00:00
if ( $account -> fetch ( $obj -> rowid )) {
2018-07-19 13:09:32 +00:00
$accounts [] = $account ;
}
$i ++ ;
}
2020-05-21 13:05:19 +00:00
} else {
2020-11-24 23:16:36 +00:00
throw new RestException ( 500 , 'Sql error ' . $this -> db -> lasterror ());
2018-07-19 13:09:32 +00:00
}
$moreparams = array (
2020-11-24 23:16:36 +00:00
'use_companybankid' => $accounts [ 0 ] -> id ,
2024-09-06 11:50:27 +00:00
'force_dir_output' => $conf -> societe -> multidir_output [ $this -> company -> entity ] . '/' . dol_sanitizeFileName (( string ) $this -> company -> id )
2018-07-19 13:09:32 +00:00
);
2018-09-20 15:09:31 +00:00
2020-11-24 23:16:36 +00:00
$result = $this -> company -> generateDocument ( $model , $outputlangs , 0 , 0 , 0 , $moreparams );
2018-09-20 15:09:31 +00:00
2020-11-24 23:16:36 +00:00
if ( $result > 0 ) {
2018-07-19 13:09:32 +00:00
return array ( " success " => $result );
2020-05-21 13:05:19 +00:00
} else {
2022-10-23 09:19:23 +00:00
throw new RestException ( 500 , 'Error generating the document ' . $this -> company -> error );
2018-07-19 13:09:32 +00:00
}
2020-10-31 13:32:18 +00:00
}
2018-07-19 13:09:32 +00:00
2020-10-31 13:32:18 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get a specific account attached to a third party
*
* Specify the site key
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ since 9.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param string $site Site key
*
* @ return array | mixed
2018-08-26 15:29:04 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 401 Unauthorized : User does not have permission to read thirdparties
* @ throws RestException 404 Not Found : Specified thirdparty ID does not belongs to an existing thirdparty
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url GET { id } / accounts /
2018-08-26 15:29:04 +00:00
*/
2020-10-31 13:32:18 +00:00
public function getSocieteAccounts ( $id , $site = null )
{
2022-09-10 09:10:33 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-08-26 15:29:04 +00:00
}
2019-11-14 11:09:15 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
2018-08-26 15:29:04 +00:00
}
/**
* We select all the records that match the socid
*/
$sql = " SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM " . MAIN_DB_PREFIX . " societe_account " ;
2021-03-22 12:31:06 +00:00
$sql .= " WHERE fk_soc = " . (( int ) $id );
2021-02-26 20:17:52 +00:00
if ( $site ) {
2021-03-22 12:41:43 +00:00
$sql .= " AND site =' " . $this -> db -> escape ( $site ) . " ' " ;
2021-02-26 20:17:52 +00:00
}
2018-08-26 15:29:04 +00:00
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-08-26 15:29:04 +00:00
2020-10-31 10:57:35 +00:00
if ( $result && $this -> db -> num_rows ( $result ) == 0 ) {
2024-03-08 15:41:33 +00:00
throw new RestException ( 404 , 'This thirdparty does not have any account attached or does not exist.' );
2018-08-26 15:29:04 +00:00
}
2019-11-14 11:09:15 +00:00
$i = 0 ;
2018-08-26 15:29:04 +00:00
2019-07-13 22:31:28 +00:00
$accounts = array ();
2018-08-26 15:29:04 +00:00
2025-09-28 20:20:44 +00:00
$i = 0 ;
2020-09-19 21:30:29 +00:00
$num = $this -> db -> num_rows ( $result );
2025-09-28 20:20:44 +00:00
//$min = min($num, ($limit <= 0 ? $num : $limit));
$min = $num ;
while ( $i < $min ) {
2020-09-19 21:30:29 +00:00
$obj = $this -> db -> fetch_object ( $result );
$account = new SocieteAccount ( $this -> db );
2018-08-26 15:29:04 +00:00
2019-11-14 11:09:15 +00:00
if ( $account -> fetch ( $obj -> rowid )) {
2018-08-26 15:29:04 +00:00
$accounts [] = $account ;
}
$i ++ ;
}
2019-07-13 22:31:28 +00:00
$fields = array ( 'id' , 'fk_soc' , 'key_account' , 'site' , 'date_creation' , 'tms' );
2018-08-26 15:29:04 +00:00
2019-07-13 22:31:28 +00:00
$returnAccounts = array ();
2018-08-26 15:29:04 +00:00
2019-10-27 16:01:23 +00:00
foreach ( $accounts as $account ) {
$object = array ();
foreach ( $account as $key => $value ) {
2019-11-16 22:24:29 +00:00
if ( in_array ( $key , $fields )) {
2018-08-26 15:29:04 +00:00
$object [ $key ] = $value ;
}
2019-10-27 16:01:23 +00:00
}
2018-08-26 15:29:04 +00:00
$returnAccounts [] = $object ;
}
return $returnAccounts ;
}
2024-10-05 16:46:16 +00:00
/**
2025-05-07 09:20:14 +00:00
* Get a specific third party by account
*
* @ since 21.0 . 0 Initial implementation
2024-10-05 16:46:16 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param string $site Site key
* @ param string $key_account Key of the account
*
* @ return array | mixed
2024-10-05 16:46:16 +00:00
*
* @ throws RestException 401 Unauthorized : User does not have permission to read thirdparties
* @ throws RestException 404 Not Found : Specified thirdparty ID does not belongs to an existing thirdparty
*
2025-05-07 09:20:14 +00:00
* @ url GET / accounts / { site } / { key_account }
*
* @ throws RestException
2024-10-05 16:46:16 +00:00
*/
public function getSocieteByAccounts ( $site , $key_account )
{
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
throw new RestException ( 403 );
}
$sql = " SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM " . MAIN_DB_PREFIX . " societe_account " ;
$sql .= " WHERE site = ' " . $this -> db -> escape ( $site ) . " ' AND key_account = ' " . $this -> db -> escape ( $key_account ) . " ' " ;
$sql .= " AND entity IN ( " . getEntity ( 'societe' ) . " ) " ;
$result = $this -> db -> query ( $sql );
if ( $result && $this -> db -> num_rows ( $result ) == 1 ) {
2025-03-02 11:13:32 +00:00
$obj = $this -> db -> fetch_object ( $result );
$returnThirdparty = $this -> _fetch ( $obj -> fk_soc );
2024-10-05 16:46:16 +00:00
} else {
2025-03-02 11:13:32 +00:00
throw new RestException ( 404 , 'This account have many thirdparties attached or does not exist.' );
2024-10-05 16:46:16 +00:00
}
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $returnThirdparty -> id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
return $returnThirdparty ;
}
2018-08-26 15:29:04 +00:00
/**
2025-05-07 09:20:14 +00:00
* Create and attach a new account to an existing third party
2018-08-26 15:29:04 +00:00
*
* Possible fields for request_data ( request body ) are specified in < code > llx_societe_account </ code > table .< br >
* See < a href = " https://wiki.dolibarr.org/index.php/Table_llx_societe_account " > Table llx_societe_account </ a > wiki page for more information < br >< br >
* < u > Example body payload :</ u > < pre > { " key_account " : " cus_DAVkLSs1LYyYI " , " site " : " stripe " } </ pre >
*
2025-05-07 09:20:14 +00:00
* @ since 9.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param array $request_data Request data
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return array | mixed
2020-02-20 12:54:41 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 401 Unauthorized : User does not have permission to read thirdparties
2024-03-08 15:41:33 +00:00
* @ throws RestException 409 Conflict : An Account already exists for this company and site .
2020-02-20 12:42:43 +00:00
* @ throws RestException 422 Unprocessable Entity : You must pass the site attribute in your request data !
* @ throws RestException 500 Internal Server Error : Error creating SocieteAccount account
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url POST { id } / accounts
2018-08-26 15:29:04 +00:00
*/
2020-10-31 13:32:18 +00:00
public function createSocieteAccount ( $id , $request_data = null )
2018-08-26 15:29:04 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-08-26 15:29:04 +00:00
}
2019-11-14 11:09:15 +00:00
if ( ! isset ( $request_data [ 'site' ])) {
2018-08-26 15:29:04 +00:00
throw new RestException ( 422 , 'Unprocessable Entity: You must pass the site attribute in your request data !' );
}
2021-03-30 17:12:07 +00:00
$sql = " SELECT rowid FROM " . MAIN_DB_PREFIX . " societe_account WHERE fk_soc = " . (( int ) $id ) . " AND site = ' " . $this -> db -> escape ( $request_data [ 'site' ]) . " ' " ;
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-08-26 15:29:04 +00:00
2020-10-31 10:57:35 +00:00
if ( $result && $this -> db -> num_rows ( $result ) == 0 ) {
2018-08-26 15:29:04 +00:00
$account = new SocieteAccount ( $this -> db );
2019-11-14 11:09:15 +00:00
if ( ! isset ( $request_data [ 'login' ])) {
2018-08-26 15:29:04 +00:00
$account -> login = " " ;
}
$account -> fk_soc = $id ;
2019-11-14 11:09:15 +00:00
foreach ( $request_data as $field => $value ) {
2023-12-15 11:15:33 +00:00
if ( $field === 'caller' ) {
2024-01-12 16:18:52 +00:00
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2024-04-02 10:28:55 +00:00
$account -> context [ 'caller' ] = sanitizeVal ( $request_data [ 'caller' ], 'aZ09' );
2023-12-15 11:15:33 +00:00
continue ;
}
2024-04-02 10:28:55 +00:00
$account -> $field = $this -> _checkValForAPI ( $field , $value , $account );
2018-08-26 15:29:04 +00:00
}
2021-02-26 20:17:52 +00:00
if ( $account -> create ( DolibarrApiAccess :: $user ) < 0 ) {
2018-08-26 15:29:04 +00:00
throw new RestException ( 500 , 'Error creating SocieteAccount entity. Ensure that the ID of thirdparty provided does exist!' );
2021-02-26 20:17:52 +00:00
}
2018-08-26 15:29:04 +00:00
$this -> _cleanObjectDatas ( $account );
return $account ;
} else {
throw new RestException ( 409 , 'A SocieteAccount entity already exists for this company and site.' );
}
}
/**
2025-05-07 09:20:14 +00:00
* Create and attach a new ( or replace an existing ) specific site account for a third party
2018-08-26 15:29:04 +00:00
*
* You < strong > MUST </ strong > pass all values to keep ( otherwise , they will be deleted ) !< br >
2025-05-07 09:28:30 +00:00
* If you just need to update specific fields prefer < code > PUT / thirdparties / { id } / accounts / { site } </ code > endpoint .< br >< br >
2018-08-26 15:29:04 +00:00
* When a < strong > SocieteAccount </ strong > entity does not exist for the < code > id </ code > and < code > site </ code >
* supplied , a new one will be created . In that case < code > fk_soc </ code > and < code > site </ code > members form
* request body payload will be ignored and < code > id </ code > and < code > site </ code > query strings parameters
* will be used instead .
*
2025-05-07 09:20:14 +00:00
* @ since 9.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param string $site Site key
* @ param array $request_data Request data
2025-05-07 09:32:25 +00:00
* @ return array | mixed
2025-05-07 09:28:30 +00:00
*
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2018-08-26 15:29:04 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 401 Unauthorized : User does not have permission to read thirdparties
* @ throws RestException 422 Unprocessable Entity : You must pass the site attribute in your request data !
* @ throws RestException 500 Internal Server Error : Error updating SocieteAccount entity
*
2025-09-23 21:26:25 +00:00
* @ url POST { id } / accounts / { site }
2018-08-26 15:29:04 +00:00
*/
2025-05-07 09:28:30 +00:00
public function postSocieteAccount ( $id , $site , $request_data = null )
2018-08-26 15:29:04 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-08-26 15:29:04 +00:00
}
2026-08-16 04:29:55 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
2026-07-23 17:06:39 +00:00
$sql = " SELECT rowid, fk_user_creat, date_creation FROM " . MAIN_DB_PREFIX . " societe_account WHERE fk_soc = " . (( int ) $id ) . " AND site = ' " . $this -> db -> escape ( $site ) . " ' " ;
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-08-26 15:29:04 +00:00
// We do not found an existing SocieteAccount entity for this fk_soc and site ; we then create a new one.
2025-01-15 19:01:40 +00:00
if ( $result && $this -> db -> num_rows ( $result ) == 0 ) {
2019-11-14 11:09:15 +00:00
if ( ! isset ( $request_data [ 'key_account' ])) {
2018-08-26 15:29:04 +00:00
throw new RestException ( 422 , 'Unprocessable Entity: You must pass the key_account attribute in your request data !' );
}
$account = new SocieteAccount ( $this -> db );
2019-11-14 11:09:15 +00:00
if ( ! isset ( $request_data [ 'login' ])) {
2018-08-26 15:29:04 +00:00
$account -> login = " " ;
}
2019-11-14 11:09:15 +00:00
foreach ( $request_data as $field => $value ) {
2023-12-15 11:15:33 +00:00
if ( $field === 'caller' ) {
2024-01-12 16:18:52 +00:00
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2024-04-02 10:28:55 +00:00
$account -> context [ 'caller' ] = sanitizeVal ( $request_data [ 'caller' ], 'aZ09' );
2023-12-15 11:15:33 +00:00
continue ;
}
2024-04-02 10:28:55 +00:00
$account -> $field = $this -> _checkValForAPI ( $field , $value , $account );
2018-08-26 15:29:04 +00:00
}
$account -> fk_soc = $id ;
$account -> site = $site ;
2019-10-27 16:01:23 +00:00
if ( $account -> create ( DolibarrApiAccess :: $user ) < 0 ) {
2018-08-26 15:29:04 +00:00
throw new RestException ( 500 , 'Error creating SocieteAccount entity.' );
2019-10-27 16:01:23 +00:00
}
// We found an existing SocieteAccount entity, we are replacing it
2018-08-26 15:29:04 +00:00
} else {
2019-10-27 16:01:23 +00:00
if ( isset ( $request_data [ 'site' ]) && $request_data [ 'site' ] !== $site ) {
2021-03-30 17:12:07 +00:00
$sql = " SELECT rowid FROM " . MAIN_DB_PREFIX . " societe_account WHERE fk_soc = " . (( int ) $id ) . " AND site = ' " . $this -> db -> escape ( $request_data [ 'site' ]) . " ' " ;
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-08-26 15:29:04 +00:00
2020-10-31 10:57:35 +00:00
if ( $result && $this -> db -> num_rows ( $result ) !== 0 ) {
2024-03-08 15:41:33 +00:00
throw new RestException ( 409 , " You are trying to update this thirdparty Account for $site to " . $request_data [ 'site' ] . " but another Account already exists with this site key. " );
2019-10-27 16:01:23 +00:00
}
2018-08-26 15:29:04 +00:00
}
2020-09-19 21:30:29 +00:00
$obj = $this -> db -> fetch_object ( $result );
2018-08-26 15:29:04 +00:00
$account = new SocieteAccount ( $this -> db );
$account -> id = $obj -> rowid ;
$account -> fk_soc = $id ;
$account -> site = $site ;
2019-11-14 11:09:15 +00:00
if ( ! isset ( $request_data [ 'login' ])) {
2018-08-26 15:29:04 +00:00
$account -> login = " " ;
}
$account -> fk_user_creat = $obj -> fk_user_creat ;
$account -> date_creation = $obj -> date_creation ;
2019-11-14 11:09:15 +00:00
foreach ( $request_data as $field => $value ) {
2023-12-15 11:15:33 +00:00
if ( $field === 'caller' ) {
2024-01-12 16:18:52 +00:00
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2024-04-02 10:28:55 +00:00
$account -> context [ 'caller' ] = sanitizeVal ( $request_data [ 'caller' ], 'aZ09' );
2023-12-15 11:15:33 +00:00
continue ;
}
2024-04-02 10:28:55 +00:00
$account -> $field = $this -> _checkValForAPI ( $field , $value , $account );
2018-08-26 15:29:04 +00:00
}
2021-02-26 20:17:52 +00:00
if ( $account -> update ( DolibarrApiAccess :: $user ) < 0 ) {
2018-08-26 15:29:04 +00:00
throw new RestException ( 500 , 'Error updating SocieteAccount entity.' );
2021-02-26 20:17:52 +00:00
}
2018-08-26 15:29:04 +00:00
}
$this -> _cleanObjectDatas ( $account );
return $account ;
}
/**
2025-05-07 09:20:14 +00:00
* Update specified values of a specific account attached to a third party
*
* @ since 9.0 . 0 Initial implementation
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ param int $id ID of the third party
* @ param string $site Site key
* @ param array $request_data Request data
2025-05-07 09:32:25 +00:00
* @ return array | mixed
2025-05-07 09:28:30 +00:00
*
2025-03-02 11:13:32 +00:00
* @ phan - param ? array < string , string > $request_data
* @ phpstan - param ? array < string , string > $request_data
2018-08-26 15:29:04 +00:00
*
2020-02-20 12:42:43 +00:00
* @ throws RestException 401 Unauthorized : User does not have permission to read thirdparties
* @ throws RestException 404 Not Found : Specified thirdparty ID does not belongs to an existing thirdparty
* @ throws RestException 409 Conflict : Another SocieteAccount entity already exists for this thirdparty with this site key .
* @ throws RestException 500 Internal Server Error : Error updating SocieteAccount entity
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:32:25 +00:00
* @ url PUT { id } / accounts / { site }
2018-08-26 15:29:04 +00:00
*/
2025-05-07 09:28:30 +00:00
public function putSocieteAccount ( $id , $site , $request_data = null )
2018-08-26 15:29:04 +00:00
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-08-26 15:29:04 +00:00
}
2026-08-16 04:29:55 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
2021-04-30 08:57:21 +00:00
$sql = " SELECT rowid FROM " . MAIN_DB_PREFIX . " societe_account WHERE fk_soc = " . (( int ) $id ) . " AND site = ' " . $this -> db -> escape ( $site ) . " ' " ;
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-08-26 15:29:04 +00:00
2020-10-31 10:57:35 +00:00
if ( $result && $this -> db -> num_rows ( $result ) == 0 ) {
2024-03-08 15:41:33 +00:00
throw new RestException ( 404 , " This thirdparty does not have $site account attached or does not exist. " );
2018-08-26 15:29:04 +00:00
} else {
// If the user tries to edit the site member, we check first if
2019-11-14 11:09:15 +00:00
if ( isset ( $request_data [ 'site' ]) && $request_data [ 'site' ] !== $site ) {
2021-03-30 17:12:07 +00:00
$sql = " SELECT rowid FROM " . MAIN_DB_PREFIX . " societe_account WHERE fk_soc = " . (( int ) $id ) . " AND site = ' " . $this -> db -> escape ( $request_data [ 'site' ]) . " ' " ;
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-08-26 15:29:04 +00:00
2021-02-26 20:17:52 +00:00
if ( $result && $this -> db -> num_rows ( $result ) !== 0 ) {
2024-03-08 15:41:33 +00:00
throw new RestException ( 409 , " You are trying to update this thirdparty Account for " . $site . " to " . $request_data [ 'site' ] . " but another Account already exists for this thirdparty with this site key. " );
2021-02-26 20:17:52 +00:00
}
2018-08-26 15:29:04 +00:00
}
2020-09-19 21:30:29 +00:00
$obj = $this -> db -> fetch_object ( $result );
2018-08-26 15:29:04 +00:00
$account = new SocieteAccount ( $this -> db );
$account -> fetch ( $obj -> rowid );
2019-11-14 11:09:15 +00:00
foreach ( $request_data as $field => $value ) {
2023-12-15 11:15:33 +00:00
if ( $field === 'caller' ) {
2024-01-12 16:18:52 +00:00
// Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
2024-04-02 10:28:55 +00:00
$account -> context [ 'caller' ] = sanitizeVal ( $request_data [ 'caller' ], 'aZ09' );
2023-12-15 11:15:33 +00:00
continue ;
}
2024-04-02 10:28:55 +00:00
$account -> $field = $this -> _checkValForAPI ( $field , $value , $account );
2018-08-26 15:29:04 +00:00
}
2021-02-26 20:17:52 +00:00
if ( $account -> update ( DolibarrApiAccess :: $user ) < 0 ) {
2018-08-26 15:29:04 +00:00
throw new RestException ( 500 , 'Error updating SocieteAccount account' );
2021-02-26 20:17:52 +00:00
}
2018-08-26 15:29:04 +00:00
$this -> _cleanObjectDatas ( $account );
return $account ;
}
}
/**
2025-05-07 09:20:14 +00:00
* Delete a specific site account attached to a third party
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* by account id
*
* @ since 9.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
* @ param string $site Site key
*
* @ return void
2018-08-26 15:29:04 +00:00
*
2024-03-08 15:41:33 +00:00
* @ throws RestException 401 Unauthorized : User does not have permission to delete thirdparties accounts
2020-02-20 12:42:43 +00:00
* @ throws RestException 404 Not Found : Specified thirdparty ID does not belongs to an existing thirdparty
* @ throws RestException 500 Internal Server Error : Error deleting SocieteAccount entity
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url DELETE { id } / accounts / { site }
2018-08-26 15:29:04 +00:00
*/
2020-10-31 13:32:18 +00:00
public function deleteSocieteAccount ( $id , $site )
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-08-26 15:29:04 +00:00
}
2026-08-16 04:29:55 +00:00
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $id )) {
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login );
}
2026-07-23 17:06:39 +00:00
$sql = " SELECT rowid FROM " . MAIN_DB_PREFIX . " societe_account WHERE fk_soc = " . (( int ) $id ) . " AND site = ' " . $this -> db -> escape ( $site ) . " ' " ;
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-08-26 15:29:04 +00:00
2020-10-31 10:57:35 +00:00
if ( $result && $this -> db -> num_rows ( $result ) == 0 ) {
2018-08-26 15:29:04 +00:00
throw new RestException ( 404 );
} else {
2020-09-19 21:30:29 +00:00
$obj = $this -> db -> fetch_object ( $result );
2018-08-26 15:29:04 +00:00
$account = new SocieteAccount ( $this -> db );
$account -> fetch ( $obj -> rowid );
2019-11-14 11:09:15 +00:00
if ( $account -> delete ( DolibarrApiAccess :: $user ) < 0 ) {
2024-03-08 15:41:33 +00:00
throw new RestException ( 500 , " Error while deleting $site account attached to this third party " );
2018-08-26 15:29:04 +00:00
}
}
}
/**
2025-05-07 09:20:14 +00:00
* Delete all accounts attached to a third party
*
* @ since 9.0 . 0 Initial implementation
*
* @ param int $id ID of the third party
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ return void
2018-08-26 15:29:04 +00:00
*
2024-03-08 15:41:33 +00:00
* @ throws RestException 401 Unauthorized : User does not have permission to delete thirdparties accounts
2020-10-31 08:50:50 +00:00
* @ throws RestException 404 Not Found : Specified thirdparty ID does not belongs to an existing thirdparty
* @ throws RestException 500 Internal Server Error : Error deleting SocieteAccount entity
2018-08-26 15:29:04 +00:00
*
2025-05-07 09:20:14 +00:00
* @ url DELETE { id } / accounts
2018-08-26 15:29:04 +00:00
*/
2020-10-31 13:32:18 +00:00
public function deleteSocieteAccounts ( $id )
{
2024-02-09 14:58:49 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'creer' )) {
2024-02-01 18:16:58 +00:00
throw new RestException ( 403 );
2018-08-26 15:29:04 +00:00
}
/**
* We select all the records that match the socid
*/
$sql = " SELECT rowid, fk_soc, key_account, site, date_creation, tms " ;
2021-03-30 17:12:07 +00:00
$sql .= " FROM " . MAIN_DB_PREFIX . " societe_account WHERE fk_soc = " . (( int ) $id );
2018-08-26 15:29:04 +00:00
2020-09-19 21:30:29 +00:00
$result = $this -> db -> query ( $sql );
2018-08-26 15:29:04 +00:00
2020-10-31 10:57:35 +00:00
if ( $result && $this -> db -> num_rows ( $result ) == 0 ) {
2024-03-08 15:41:33 +00:00
throw new RestException ( 404 , 'This third party does not have any account attached or does not exist.' );
2018-08-26 15:29:04 +00:00
} else {
2019-11-14 11:09:15 +00:00
$i = 0 ;
2018-08-26 15:29:04 +00:00
2025-09-28 20:20:44 +00:00
$i = 0 ;
2020-09-19 21:30:29 +00:00
$num = $this -> db -> num_rows ( $result );
2025-09-28 20:20:44 +00:00
//$min = min($num, ($limit <= 0 ? $num : $limit));
$min = $num ;
while ( $i < $min ) {
2020-09-19 21:30:29 +00:00
$obj = $this -> db -> fetch_object ( $result );
$account = new SocieteAccount ( $this -> db );
2018-08-26 15:29:04 +00:00
$account -> fetch ( $obj -> rowid );
2019-11-14 11:09:15 +00:00
if ( $account -> delete ( DolibarrApiAccess :: $user ) < 0 ) {
2024-03-08 15:41:33 +00:00
throw new RestException ( 500 , 'Error while deleting account attached to this third party' );
2018-08-26 15:29:04 +00:00
}
$i ++ ;
}
}
}
2017-10-25 09:39:23 +00:00
2020-10-31 13:32:18 +00:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2017-05-24 13:24:35 +00:00
/**
* Clean sensible object datas
2025-11-20 00:47:46 +00:00
* @ phpstan - template T
2017-05-24 13:24:35 +00:00
*
2020-10-30 17:02:58 +00:00
* @ param Object $object Object to clean
2023-05-02 01:38:57 +00:00
* @ return Object Object with cleaned properties
2025-11-20 00:47:46 +00:00
* @ phpstan - param T $object
* @ phpstan - return T
2017-05-24 13:24:35 +00:00
*/
2019-03-04 18:57:46 +00:00
protected function _cleanObjectDatas ( $object )
2020-10-31 13:32:18 +00:00
{
// phpcs:enable
2018-02-12 03:07:45 +00:00
$object = parent :: _cleanObjectDatas ( $object );
2017-10-03 11:07:07 +00:00
2019-11-16 22:24:29 +00:00
unset ( $object -> nom ); // ->name already defined and nom deprecated
unset ( $object -> name_bis ); // ->name_alias already defined
unset ( $object -> note ); // ->note_private and note_public already defined
2019-11-02 13:20:43 +00:00
unset ( $object -> departement );
unset ( $object -> departement_code );
unset ( $object -> pays );
unset ( $object -> particulier );
2019-11-02 13:26:27 +00:00
unset ( $object -> prefix_comm );
2018-01-11 00:16:14 +00:00
2022-08-27 17:02:05 +00:00
unset ( $object -> siren );
unset ( $object -> siret );
unset ( $object -> ape );
2020-04-10 08:59:32 +00:00
unset ( $object -> commercial_id ); // This property is used in create/update only. It does not exists in read mode because there is several sales representatives.
2020-01-13 13:14:51 +00:00
2018-02-12 03:07:45 +00:00
unset ( $object -> total_ht );
unset ( $object -> total_tva );
unset ( $object -> total_localtax1 );
unset ( $object -> total_localtax2 );
unset ( $object -> total_ttc );
2017-10-03 11:07:07 +00:00
2018-02-12 03:07:45 +00:00
unset ( $object -> lines );
unset ( $object -> thirdparty );
2017-12-21 15:50:18 +00:00
2019-11-16 22:24:29 +00:00
unset ( $object -> fk_delivery_address ); // deprecated feature
2019-11-02 13:20:43 +00:00
2018-02-12 03:07:45 +00:00
return $object ;
2017-10-03 11:07:07 +00:00
}
2017-05-24 13:24:35 +00:00
/**
2018-02-12 03:07:45 +00:00
* Validate fields before create or update object
*
2025-03-02 14:10:25 +00:00
* @ param ? array < string , string > $data Data to validate
* @ return array < string , string >
2018-02-12 03:07:45 +00:00
*
* @ throws RestException
*/
2020-10-31 13:32:18 +00:00
private function _validate ( $data )
{
2025-03-02 14:10:25 +00:00
if ( $data === null ) {
$data = array ();
}
2020-10-31 13:32:18 +00:00
$thirdparty = array ();
foreach ( Thirdparties :: $FIELDS as $field ) {
2021-02-26 20:17:52 +00:00
if ( ! isset ( $data [ $field ])) {
2020-10-31 13:32:18 +00:00
throw new RestException ( 400 , " $field field missing " );
2021-02-26 20:17:52 +00:00
}
2020-10-31 13:32:18 +00:00
$thirdparty [ $field ] = $data [ $field ];
}
return $thirdparty ;
}
/**
* Fetch properties of a thirdparty object .
*
2024-01-12 16:18:52 +00:00
* Return an array with thirdparty information
2020-10-31 13:32:18 +00:00
*
2024-09-29 19:51:51 +00:00
* @ param ? int $rowid Id of third party to load ( Use 0 to get a specimen record , use null to use other search criteria )
2019-10-19 14:43:10 +00:00
* @ param string $ref Reference of third party , name ( Warning , this can return several records )
* @ param string $ref_ext External reference of third party ( Warning , this information is a free field not provided by Dolibarr )
2020-08-29 09:37:16 +00:00
* @ param string $barcode Barcode of third party to load
2019-10-19 14:43:10 +00:00
* @ param string $idprof1 Prof id 1 of third party ( Warning , this can return several records )
* @ param string $idprof2 Prof id 2 of third party ( Warning , this can return several records )
* @ param string $idprof3 Prof id 3 of third party ( Warning , this can return several records )
* @ param string $idprof4 Prof id 4 of third party ( Warning , this can return several records )
* @ param string $idprof5 Prof id 5 of third party ( Warning , this can return several records )
* @ param string $idprof6 Prof id 6 of third party ( Warning , this can return several records )
2023-09-26 16:43:25 +00:00
* @ param string $email Email of third party ( Warning , this can return several records )
2019-10-19 14:43:10 +00:00
* @ param string $ref_alias Name_alias of third party ( Warning , this can return several records )
2024-05-03 16:03:14 +00:00
* @ return object cleaned Societe object
2025-03-03 13:23:57 +00:00
* @ phan - return Societe
* @ phpstan - return Societe
2020-10-31 13:32:18 +00:00
*
* @ throws RestException
*/
private function _fetch ( $rowid , $ref = '' , $ref_ext = '' , $barcode = '' , $idprof1 = '' , $idprof2 = '' , $idprof3 = '' , $idprof4 = '' , $idprof5 = '' , $idprof6 = '' , $email = '' , $ref_alias = '' )
{
2022-09-10 09:10:33 +00:00
if ( ! DolibarrApiAccess :: $user -> hasRight ( 'societe' , 'lire' )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login . '. No read permission on thirdparties.' );
2020-10-31 13:32:18 +00:00
}
2021-04-08 17:05:28 +00:00
2025-05-22 16:57:32 +00:00
if ( $rowid === 0 ) {
2020-10-29 22:56:42 +00:00
$result = $this -> company -> initAsSpecimen ();
} else {
2025-05-22 16:57:32 +00:00
$result = $this -> company -> fetch (( int ) $rowid , $ref , $ref_ext , $barcode , $idprof1 , $idprof2 , $idprof3 , $idprof4 , $idprof5 , $idprof6 , $email , $ref_alias );
2020-10-29 22:56:42 +00:00
}
2020-10-31 13:32:18 +00:00
if ( ! $result ) {
throw new RestException ( 404 , 'Thirdparty not found' );
}
if ( ! DolibarrApi :: _checkAccessToResource ( 'societe' , $this -> company -> id )) {
2024-04-02 12:47:49 +00:00
throw new RestException ( 403 , 'Access not allowed for login ' . DolibarrApiAccess :: $user -> login . ' on this thirdparty' );
2020-10-31 13:32:18 +00:00
}
2022-08-29 12:46:26 +00:00
if ( isModEnabled ( 'mailing' )) {
$this -> company -> getNoEmail ();
}
2020-10-31 13:32:18 +00:00
2023-11-27 11:08:48 +00:00
if ( getDolGlobalString ( 'FACTURE_DEPOSITS_ARE_JUST_PAYMENTS' )) {
2024-01-12 16:18:52 +00:00
$filterabsolutediscount = " fk_facture_source IS NULL " ; // If we want deposit to be subtracted to payments only and not to total of final invoice
$filtercreditnote = " fk_facture_source IS NOT NULL " ; // If we want deposit to be subtracted to payments only and not to total of final invoice
2020-10-31 13:32:18 +00:00
} else {
$filterabsolutediscount = " fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%') " ;
$filtercreditnote = " fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%') " ;
}
2025-03-03 13:23:57 +00:00
$absolute_discount = $this -> company -> getAvailableDiscounts ( null , $filterabsolutediscount );
$absolute_creditnote = $this -> company -> getAvailableDiscounts ( null , $filtercreditnote );
2020-10-31 13:32:18 +00:00
$this -> company -> absolute_discount = price2num ( $absolute_discount , 'MT' );
$this -> company -> absolute_creditnote = price2num ( $absolute_creditnote , 'MT' );
return $this -> _cleanObjectDatas ( $this -> company );
}
2015-05-01 14:12:30 +00:00
}