forked from Wavyzz/dolibarr
Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop
This commit is contained in:
@@ -12,7 +12,7 @@ return [
|
||||
// PhanUndeclaredProperty : 420+ occurrences
|
||||
// PhanTypeMismatchProperty : 100+ occurrences
|
||||
// PhanTypeMismatchArgument : 70+ occurrences
|
||||
// PhanUndeclaredGlobalVariable : 70+ occurrences
|
||||
// PhanUndeclaredGlobalVariable : 65+ occurrences
|
||||
// PhanTypeMismatchArgumentNullable : 40+ occurrences
|
||||
// PhanTypeInvalidDimOffset : 15+ occurrences
|
||||
// PhanTypeMismatchDimFetch : 15+ occurrences
|
||||
@@ -230,7 +230,6 @@ return [
|
||||
'htdocs/projet/tasks.php' => ['PhanTypeMismatchArgument'],
|
||||
'htdocs/projet/tasks/time.php' => ['PhanTypeInvalidDimOffset', 'PhanUndeclaredProperty'],
|
||||
'htdocs/projet/tasks/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/public/eventorganization/subscriptionok.php' => ['PhanUndeclaredGlobalVariable'],
|
||||
'htdocs/public/members/new.php' => ['PhanUndeclaredGlobalVariable'],
|
||||
'htdocs/public/payment/newpayment.php' => ['PhanUndeclaredProperty'],
|
||||
'htdocs/public/payment/paymentok.php' => ['PhanTypeMismatchArgumentProbablyReal'],
|
||||
|
||||
@@ -505,7 +505,7 @@ class Documents extends DolibarrApi
|
||||
throw new RestException(404, 'Invoice not found');
|
||||
}
|
||||
|
||||
$upload_dir = getMultidirOutput($object) . "/facture/".get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').dol_sanitizeFileName($object->ref);
|
||||
$upload_dir = getMultidirOutput($object) . "/".get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').dol_sanitizeFileName($object->ref);
|
||||
} elseif ($modulepart == 'produit' || $modulepart == 'product' || $modulepart == 'service') {
|
||||
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
use Luracast\Restler\RestException;
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/mailing/class/mailing.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/mailing/class/mailing_targets.class.php';
|
||||
|
||||
/**
|
||||
* API class for mass mailings
|
||||
@@ -39,11 +40,24 @@ class Mailings extends DolibarrApi
|
||||
'body'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string[] Mandatory fields, checked when create and update object
|
||||
*/
|
||||
public static $TARGETFIELDS = array(
|
||||
'fk_mailing',
|
||||
'email'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var Mailing {@type Mailing}
|
||||
*/
|
||||
public $mailing;
|
||||
|
||||
/**
|
||||
* @var MailingTarget {@type MailingTarget}
|
||||
*/
|
||||
public $mailing_target;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@@ -52,6 +66,7 @@ class Mailings extends DolibarrApi
|
||||
global $db;
|
||||
$this->db = $db;
|
||||
$this->mailing = new Mailing($this->db);
|
||||
$this->mailing_target = new MailingTarget($this->db);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,7 +140,8 @@ class Mailings extends DolibarrApi
|
||||
* @phan-return Mailing[]|array{data:Mailing[],pagination:array{total:int,page:int,page_count:int,limit:int}}
|
||||
* @phpstan-return Mailing[]|array{data:Mailing[],pagination:array{total:int,page:int,page_count:int,limit:int}}
|
||||
*
|
||||
* @throws RestException
|
||||
* @throws RestException 400
|
||||
* @throws RestException 403
|
||||
*/
|
||||
public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $fk_projects = '', $sqlfilters = '', $properties = '', $pagination_data = false, $loadlinkedobjects = 0)
|
||||
{
|
||||
@@ -213,6 +229,114 @@ class Mailings extends DolibarrApi
|
||||
return $obj_ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* List mass mailing targets
|
||||
*
|
||||
* Get a list of mass mailing targets
|
||||
*
|
||||
* @since 23.0.0 Initial implementation
|
||||
*
|
||||
* @param int $id Mass mailing ID
|
||||
* @param string $sortfield Sort field
|
||||
* @param string $sortorder Sort order
|
||||
* @param int $limit Limit for list
|
||||
* @param int $page Page number
|
||||
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.lastname:like:'John Doe') and (t.statut:=:3)"
|
||||
* @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of properties names
|
||||
* @param bool $pagination_data If this parameter is set to true the response will include pagination data. Default value is false. Page starts from 0*
|
||||
* @return array Array of order objects
|
||||
* @phan-return Mailing[]|array{data:Mailing[],pagination:array{total:int,page:int,page_count:int,limit:int}}
|
||||
* @phpstan-return Mailing[]|array{data:Mailing[],pagination:array{total:int,page:int,page_count:int,limit:int}}
|
||||
*
|
||||
* @url GET {id}/targets
|
||||
*
|
||||
* @throws RestException 400
|
||||
* @throws RestException 403
|
||||
* @throws RestException 404
|
||||
*/
|
||||
public function indexTargets($id, $sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '', $properties = '', $pagination_data = false)
|
||||
{
|
||||
if (!DolibarrApiAccess::$user->hasRight('mailing', 'read')) {
|
||||
throw new RestException(403);
|
||||
}
|
||||
|
||||
$fetchMailingResult = $this->mailing->fetch($id);
|
||||
if ($fetchMailingResult < 0) {
|
||||
throw new RestException(404, 'Mass mailing not found, id='.$id);
|
||||
}
|
||||
|
||||
$fk_project = $this->mailing->fk_project;
|
||||
if (!DolibarrApi::_checkAccessToResource('project', ((int) $fk_project))) {
|
||||
throw new RestException(403, 'Access (project) not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
$obj_ret = array();
|
||||
|
||||
$sql = "SELECT t.rowid";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles AS t";
|
||||
$sql .= " WHERE t.fk_mailing = ".((int) $id);
|
||||
|
||||
// Add sql filters
|
||||
if ($sqlfilters) {
|
||||
$errormessage = '';
|
||||
$sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
|
||||
if ($errormessage) {
|
||||
throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
|
||||
}
|
||||
}
|
||||
|
||||
//this query will return total mass mailing targets with the filters given
|
||||
$sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql);
|
||||
|
||||
$sql .= $this->db->order($sortfield, $sortorder);
|
||||
if ($limit) {
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
}
|
||||
$offset = $limit * $page;
|
||||
|
||||
$sql .= $this->db->plimit($limit + 1, $offset);
|
||||
}
|
||||
|
||||
dol_syslog("API Rest request mass mailing target");
|
||||
$result = $this->db->query($sql);
|
||||
|
||||
if ($result) {
|
||||
$num = $this->db->num_rows($result);
|
||||
$min = min($num, ($limit <= 0 ? $num : $limit));
|
||||
$i = 0;
|
||||
while ($i < $min) {
|
||||
$obj = $this->db->fetch_object($result);
|
||||
$mailing_target = new MailingTarget($this->db);
|
||||
if ($mailing_target->fetch($obj->rowid) > 0) {
|
||||
$obj_ret[] = $this->_filterObjectProperties($this->_cleanTargetDatas($mailing_target), $properties);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
} else {
|
||||
throw new RestException(503, 'Error when retrieve list of mass mailing targetss : '.$this->db->lasterror());
|
||||
}
|
||||
|
||||
//if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit)
|
||||
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
|
||||
];
|
||||
}
|
||||
|
||||
return $obj_ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a mass mailing
|
||||
*
|
||||
@@ -264,7 +388,8 @@ class Mailings extends DolibarrApi
|
||||
* @phpstan-param ?array<string,string> $request_data
|
||||
* @return int ID of mass mailing
|
||||
*
|
||||
* @throws RestException
|
||||
* @throws RestException 403
|
||||
* @throws RestException 500 System error
|
||||
*/
|
||||
public function post($request_data = null)
|
||||
{
|
||||
@@ -307,7 +432,9 @@ class Mailings extends DolibarrApi
|
||||
* @phpstan-param ?array<string,string> $request_data
|
||||
* @return Object Object with cleaned properties
|
||||
*
|
||||
* @throws RestException
|
||||
* @throws RestException 403
|
||||
* @throws RestException 404
|
||||
* @throws RestException 500 System error
|
||||
*/
|
||||
public function put($id, $request_data = null)
|
||||
{
|
||||
@@ -397,6 +524,254 @@ class Mailings extends DolibarrApi
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a mass mailing general fields (won't change lines of mass mailing)
|
||||
*
|
||||
* @since 23.0.0 Initial implementation
|
||||
*
|
||||
* @param int $id Id of mass mailing with the targetid to update
|
||||
* @param int $targetid Id mass mailing target to update
|
||||
* @param array $request_data Datas
|
||||
* @phan-param ?array<string,string> $request_data
|
||||
* @phpstan-param ?array<string,string> $request_data
|
||||
* @return Object Object with cleaned properties
|
||||
*
|
||||
* @url PUT {id}/updateTarget/{targetid}
|
||||
*
|
||||
* @throws RestException 403
|
||||
* @throws RestException 404
|
||||
* @throws RestException 500 System error
|
||||
*/
|
||||
public function updateTarget($id, $targetid, $request_data = null)
|
||||
{
|
||||
if (!DolibarrApiAccess::$user->hasRight('mailing', 'write')) {
|
||||
throw new RestException(403);
|
||||
}
|
||||
|
||||
$fetchMailingResult = $this->mailing->fetch($id);
|
||||
if ($fetchMailingResult < 0) {
|
||||
throw new RestException(404, 'Mass mailing not found, id='.$id);
|
||||
}
|
||||
$result = $this->mailing_target->fetch($targetid);
|
||||
if ($result < 0) {
|
||||
throw new RestException(404, 'Mass mailing target not found, id='.$targetid);
|
||||
}
|
||||
if ($id != $this->mailing_target->fk_mailing) {
|
||||
throw new RestException(404, 'Target id='.$targetid.' is does not belong to mailing id='.$id);
|
||||
}
|
||||
|
||||
if (!DolibarrApi::_checkAccessToResource('project', ((int) $this->mailing->fk_project))) {
|
||||
throw new RestException(403, 'Access (project) not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
if (!DolibarrApi::_checkAccessToResource('mailing', $this->mailing->id)) {
|
||||
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
foreach ($request_data as $field => $value) {
|
||||
if ($field == 'id') {
|
||||
throw new RestException(400, 'Changing id field is forbidden');
|
||||
}
|
||||
if ($field == 'fk_mailing') {
|
||||
throw new RestException(400, 'Changing fk_mailing field is forbidden to protect inserting a wrong fk_mailing number. Use a POST to create a new mailing target with the correct mailing id, then an PUT to update the new target in the right mailing id, and finally a delete to remove the old target');
|
||||
}
|
||||
if ($field === 'caller') {
|
||||
// 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
|
||||
$this->mailing_target->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->mailing_target->$field = $this->_checkValForAPI($field, $value, $this->mailing_target);
|
||||
}
|
||||
|
||||
if ($this->mailing_target->update(DolibarrApiAccess::$user) > 0) {
|
||||
return $this->getTarget($id, $targetid);
|
||||
} else {
|
||||
throw new RestException(500, $this->mailing_target->error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mass mailing
|
||||
*
|
||||
* @since 23.0.0 Initial implementation
|
||||
*
|
||||
* @param int $id Id of mass mailing to create a target for
|
||||
* @param array $request_data Request data
|
||||
* @phan-param ?array<string,string> $request_data
|
||||
* @phpstan-param ?array<string,string> $request_data
|
||||
* @return int ID of mass mailing
|
||||
*
|
||||
* @url POST {id}/createTarget
|
||||
*
|
||||
* @throws RestException 400
|
||||
* @throws RestException 403
|
||||
* @throws RestException 404
|
||||
* @throws RestException 500 System error
|
||||
*/
|
||||
public function postTarget($id, $request_data = null)
|
||||
{
|
||||
if (!DolibarrApiAccess::$user->hasRight('mailing', 'write')) {
|
||||
throw new RestException(403, "Insufficiant rights");
|
||||
}
|
||||
// Check mandatory fields
|
||||
$result = $this->_validateTarget($request_data);
|
||||
|
||||
$fk_mailing_id = 0;
|
||||
|
||||
foreach ($request_data as $field => $value) {
|
||||
if ($field === 'caller') {
|
||||
// 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
|
||||
$this->mailing_target->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
|
||||
continue;
|
||||
}
|
||||
if ($field === 'fk_project') {
|
||||
if (!DolibarrApi::_checkAccessToResource('project', ((int) $value))) {
|
||||
throw new RestException(403, 'Access (project) not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
}
|
||||
|
||||
if ($field == 'id') {
|
||||
throw new RestException(400, 'Creating with id field is forbidden');
|
||||
}
|
||||
if ($field == 'fk_mailing') {
|
||||
$fetchMailingResult = $this->mailing->fetch((int) $value);
|
||||
if ($fetchMailingResult < 0) {
|
||||
throw new RestException(404, 'Mass mailing not found, id='.((int) $value));
|
||||
}
|
||||
if (!DolibarrApi::_checkAccessToResource('project', ((int) $this->mailing->fk_project))) {
|
||||
throw new RestException(403, 'Access (project) not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
$fk_mailing_id = ((int) $value);
|
||||
}
|
||||
|
||||
$this->mailing_target->$field = $this->_checkValForAPI($field, $value, $this->mailing_target);
|
||||
}
|
||||
|
||||
if (0 == $fk_mailing_id) {
|
||||
throw new RestException(404, 'Mass mailing not found, id='.((int) $fk_mailing_id));
|
||||
}
|
||||
|
||||
if ($this->mailing_target->create(DolibarrApiAccess::$user) < 0) {
|
||||
throw new RestException(500, "Error creating mass mailing target", array_merge(array($this->mailing->error), $this->mailing->errors));
|
||||
}
|
||||
|
||||
return ((int) $this->mailing_target->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a target in a mass mailing
|
||||
*
|
||||
* Return an array with info about a mass mailing target
|
||||
*
|
||||
* @since 23.0.0 Initial implementation
|
||||
*
|
||||
* @param int $id Id of mass mailing with the targetid to get
|
||||
* @param int $targetid Id mass mailing target to get
|
||||
* @return Object Object with cleaned properties
|
||||
*
|
||||
* @url GET {id}/getTarget/{targetid}
|
||||
*
|
||||
* @throws RestException
|
||||
*/
|
||||
public function getTarget($id, $targetid)
|
||||
{
|
||||
return $this->_fetchTarget($id, $targetid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get properties of an mailing object
|
||||
*
|
||||
* Return an array with mailing information
|
||||
*
|
||||
* @param int $id ID of mailing object
|
||||
* @param int $targetid Id mass mailing target
|
||||
* @return Object Object with cleaned properties
|
||||
*
|
||||
* @throws RestException 403
|
||||
* @throws RestException 404
|
||||
*/
|
||||
private function _fetchTarget($id, $targetid)
|
||||
{
|
||||
if (!DolibarrApiAccess::$user->hasRight('mailing', 'read')) {
|
||||
throw new RestException(403);
|
||||
}
|
||||
|
||||
$fetchMailingResult = $this->mailing->fetch($id);
|
||||
if ($fetchMailingResult < 0) {
|
||||
throw new RestException(404, 'Mass mailing not found, id='.$id);
|
||||
}
|
||||
$result = $this->mailing_target->fetch($targetid);
|
||||
if ($result < 0) {
|
||||
throw new RestException(404, 'Mass mailing target not found, id='.$targetid);
|
||||
}
|
||||
if ($id != $this->mailing_target->fk_mailing) {
|
||||
throw new RestException(404, 'Target id='.$targetid.' is does not belong to mailing id='.$id);
|
||||
}
|
||||
|
||||
if (!DolibarrApi::_checkAccessToResource('project', ((int) $this->mailing->fk_project))) {
|
||||
throw new RestException(403, 'Access (project) not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
if (!DolibarrApi::_checkAccessToResource('mailing', $this->mailing->id)) {
|
||||
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
return $this->_cleanTargetDatas($this->mailing_target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a mass mailing general fields (won't change lines of mass mailing)
|
||||
*
|
||||
* @since 23.0.0 Initial implementation
|
||||
*
|
||||
* @param int $id Id of mass mailing with the targetid to delete
|
||||
* @param int $targetid Id mass mailing target to delete
|
||||
* @return array
|
||||
* @phan-return array{success:array{code:int,message:string}}
|
||||
* @phpstan-return array{success:array{code:int,message:string}}
|
||||
*
|
||||
* @url DELETE {id}/deleteTarget/{targetid}
|
||||
*
|
||||
* @throws RestException 403
|
||||
* @throws RestException 404
|
||||
* @throws RestException 500 System error
|
||||
*/
|
||||
public function deleteTarget($id, $targetid)
|
||||
{
|
||||
if (!DolibarrApiAccess::$user->hasRight('mailing', 'delete')) {
|
||||
throw new RestException(403);
|
||||
}
|
||||
|
||||
$fetchMailingResult = $this->mailing->fetch($id);
|
||||
if ($fetchMailingResult < 0) {
|
||||
throw new RestException(404, 'Mass mailing not found, id='.$id);
|
||||
}
|
||||
$result = $this->mailing_target->fetch($targetid);
|
||||
if ($result < 0) {
|
||||
throw new RestException(404, 'Mass mailing target not found, id='.$targetid);
|
||||
}
|
||||
if ($id != $this->mailing_target->fk_mailing) {
|
||||
throw new RestException(404, 'Target id='.$targetid.' is does not belong to mailing id='.$id);
|
||||
}
|
||||
if (!DolibarrApi::_checkAccessToResource('project', ((int) $this->mailing->fk_project))) {
|
||||
throw new RestException(403, 'Access (project) not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
if (!DolibarrApi::_checkAccessToResource('mailing', $this->mailing->id)) {
|
||||
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
if (!$this->mailing_target->delete(DolibarrApiAccess::$user)) {
|
||||
throw new RestException(500, 'Error when delete Mass mailing target: '.$this->mailing->error);
|
||||
}
|
||||
|
||||
return array(
|
||||
'success' => array(
|
||||
'code' => 200,
|
||||
'message' => 'Deleting target id='.$targetid.' belonging to mailing id='.$id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete targets of a mass mailing
|
||||
*
|
||||
@@ -612,6 +987,162 @@ class Mailings extends DolibarrApi
|
||||
return $mailing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate fields before create or update object
|
||||
*
|
||||
* @param ?array<string,string> $data Array with data to verify
|
||||
* @return array<string,string>
|
||||
*
|
||||
* @throws RestException
|
||||
*/
|
||||
private function _validateTarget($data)
|
||||
{
|
||||
if ($data === null) {
|
||||
$data = array();
|
||||
}
|
||||
$mailing_target = array();
|
||||
foreach (Mailings::$TARGETFIELDS as $field) {
|
||||
if (!isset($data[$field])) {
|
||||
throw new RestException(400, "$field field missing");
|
||||
}
|
||||
$mailing_target[$field] = $data[$field];
|
||||
}
|
||||
return $mailing_target;
|
||||
}
|
||||
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
|
||||
/**
|
||||
* Clean sensible object (mailing target) datas
|
||||
*
|
||||
* @param Object $object Object to clean
|
||||
* @return Object Object with cleaned properties
|
||||
*/
|
||||
protected function _cleanTargetDatas($object)
|
||||
{
|
||||
// phpcs:enable
|
||||
$object = parent::_cleanObjectDatas($object);
|
||||
|
||||
unset($object->TRIGGER_PREFIX);
|
||||
unset($object->actionmsg);
|
||||
unset($object->actionmsg2);
|
||||
unset($object->actiontypecode);
|
||||
unset($object->alreadypaid);
|
||||
unset($object->array_options);
|
||||
unset($object->array_languages);
|
||||
unset($object->barcode_type_code);
|
||||
unset($object->barcode_type_coder);
|
||||
unset($object->barcode_type_label);
|
||||
unset($object->barcode_type);
|
||||
unset($object->canvas);
|
||||
unset($object->civility_code);
|
||||
unset($object->civility_id);
|
||||
unset($object->comments);
|
||||
unset($object->cond_reglement_id);
|
||||
unset($object->cond_reglement_supplier_id);
|
||||
unset($object->contact_id);
|
||||
unset($object->contact);
|
||||
unset($object->contacts_ids_internal);
|
||||
unset($object->contacts_ids);
|
||||
unset($object->context);
|
||||
unset($object->country_code);
|
||||
unset($object->country_id);
|
||||
unset($object->country);
|
||||
unset($object->date_cloture);
|
||||
unset($object->date_creation);
|
||||
unset($object->date_validation);
|
||||
unset($object->db);
|
||||
unset($object->demand_reason_id);
|
||||
unset($object->deposit_percent);
|
||||
unset($object->element_for_permission);
|
||||
unset($object->element);
|
||||
unset($object->entity);
|
||||
unset($object->error);
|
||||
unset($object->errorhidden);
|
||||
unset($object->errors);
|
||||
unset($object->extraparams);
|
||||
unset($object->fields);
|
||||
unset($object->fk_account);
|
||||
unset($object->fk_bank);
|
||||
unset($object->fk_delivery_address);
|
||||
unset($object->fk_element);
|
||||
unset($object->fk_multicurrency);
|
||||
unset($object->fk_projet);
|
||||
unset($object->fk_project);
|
||||
unset($object->fk_user_creat);
|
||||
unset($object->fk_user_modif);
|
||||
unset($object->import_key);
|
||||
unset($object->isextrafieldmanaged);
|
||||
unset($object->ismultientitymanaged);
|
||||
unset($object->last_main_doc);
|
||||
unset($object->lines);
|
||||
unset($object->linked_objects);
|
||||
unset($object->linkedObjects);
|
||||
unset($object->linkedObjectsIds);
|
||||
unset($object->mode_reglement_id);
|
||||
unset($object->model_pdf);
|
||||
unset($object->module);
|
||||
unset($object->multicurrency_code);
|
||||
unset($object->multicurrency_total_ht);
|
||||
unset($object->multicurrency_total_localtax1);
|
||||
unset($object->multicurrency_total_localtax2);
|
||||
unset($object->multicurrency_total_ttc);
|
||||
unset($object->multicurrency_total_tva);
|
||||
unset($object->multicurrency_tx);
|
||||
unset($object->name);
|
||||
unset($object->nb);
|
||||
unset($object->nbphoto);
|
||||
unset($object->newref);
|
||||
unset($object->next_prev_filter);
|
||||
unset($object->note);
|
||||
unset($object->note_public);
|
||||
unset($object->note_private);
|
||||
unset($object->oldcopy);
|
||||
unset($object->oldref);
|
||||
unset($object->origin_id);
|
||||
unset($object->origin_object);
|
||||
unset($object->origin_type);
|
||||
unset($object->origin);
|
||||
unset($object->output);
|
||||
unset($object->product);
|
||||
unset($object->project);
|
||||
unset($object->ref_ext);
|
||||
unset($object->ref_next);
|
||||
unset($object->ref_previous);
|
||||
unset($object->ref);
|
||||
unset($object->region_code);
|
||||
unset($object->region_id);
|
||||
unset($object->region);
|
||||
unset($object->restrictiononfksoc);
|
||||
unset($object->retained_warranty_fk_cond_reglement);
|
||||
unset($object->sendtoid);
|
||||
unset($object->shipping_method_id);
|
||||
unset($object->shipping_method);
|
||||
unset($object->showphoto_on_popup);
|
||||
unset($object->specimen);
|
||||
unset($object->state_code);
|
||||
unset($object->state_id);
|
||||
unset($object->state);
|
||||
unset($object->table_element_line);
|
||||
unset($object->table_element);
|
||||
unset($object->thirdparty);
|
||||
unset($object->total_ht);
|
||||
unset($object->total_localtax1);
|
||||
unset($object->total_localtax2);
|
||||
unset($object->total_ttc);
|
||||
unset($object->total_tva);
|
||||
unset($object->totalpaid_multicurrency);
|
||||
unset($object->totalpaid);
|
||||
unset($object->tpl);
|
||||
unset($object->transport_mode_id);
|
||||
unset($object->user);
|
||||
unset($object->user_creation_id);
|
||||
unset($object->user_validation_id);
|
||||
unset($object->user_closing_id);
|
||||
unset($object->user_modification_id);
|
||||
unset($object->warehouse_id);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
|
||||
/**
|
||||
@@ -666,8 +1197,6 @@ class Mailings extends DolibarrApi
|
||||
unset($object->import_key);
|
||||
unset($object->isextrafieldmanaged);
|
||||
unset($object->ismultientitymanaged);
|
||||
unset($object->labelStatus);
|
||||
unset($object->labelStatusShort);
|
||||
unset($object->last_main_doc);
|
||||
unset($object->lastname);
|
||||
unset($object->lines);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/mailing/class/mailing_targets.class.php';
|
||||
|
||||
/**
|
||||
* Class to manage emailings module
|
||||
@@ -174,6 +174,11 @@ class Mailing extends CommonObject
|
||||
*/
|
||||
public $substitutionarrayfortest;
|
||||
|
||||
/**
|
||||
* @var MailingTarget[]
|
||||
*/
|
||||
public $targets = array();
|
||||
|
||||
/**
|
||||
* @var ?int The related project ID
|
||||
* @see setProject(), project
|
||||
@@ -621,7 +626,7 @@ class Mailing extends CommonObject
|
||||
$now = dol_now();
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing ";
|
||||
$sql .= " SET statut = 0, fk_user_modif=".$user->id;
|
||||
$sql .= " SET statut = 0, tms = '".$this->db->idate($now)."', fk_user_modif=".$user->id;
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
dol_syslog("Mailing::valid", LOG_DEBUG);
|
||||
|
||||
505
htdocs/comm/mailing/class/mailing_targets.class.php
Normal file
505
htdocs/comm/mailing/class/mailing_targets.class.php
Normal file
@@ -0,0 +1,505 @@
|
||||
<?php
|
||||
/* Copyright (C) 2025 Cloned from htdocs/comm/mailing/class/mailing.class.php then modified
|
||||
* Copyright (C) 2025 Jon Bendtsen <jon.bendtsen.github@jonb.dk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/comm/mailing/class/mailing_target.class.php
|
||||
* \ingroup mailing
|
||||
* \brief File of class to manage emailing targets module
|
||||
*/
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage emailings module
|
||||
*/
|
||||
class MailingTarget extends CommonObject
|
||||
{
|
||||
/**
|
||||
* @var string ID to identify managed object
|
||||
*/
|
||||
public $element = 'mailing_target';
|
||||
|
||||
/**
|
||||
* @var string Name of table without prefix where object is stored
|
||||
*/
|
||||
public $table_element = 'mailing_cibles';
|
||||
|
||||
/**
|
||||
* @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
|
||||
*/
|
||||
public $picto = 'contact';
|
||||
|
||||
/**
|
||||
* @var int Mailing id that this mailing_target is related to.
|
||||
*/
|
||||
public $fk_mailing;
|
||||
|
||||
/**
|
||||
* @var int Contact id that this mailing_target is related to.
|
||||
*/
|
||||
public $fk_contact;
|
||||
|
||||
/**
|
||||
* @var string lastname of the mailing_target
|
||||
*/
|
||||
public $lastname;
|
||||
|
||||
/**
|
||||
* @var string firstname of the mailing_target
|
||||
*/
|
||||
public $firstname;
|
||||
|
||||
/**
|
||||
* @var string email of the mailing_target
|
||||
*/
|
||||
public $email;
|
||||
|
||||
/**
|
||||
* @var string other
|
||||
*/
|
||||
public $other;
|
||||
|
||||
/**
|
||||
* @var string tag
|
||||
*/
|
||||
public $tag;
|
||||
|
||||
/**
|
||||
* @var int status
|
||||
* @deprecated Use $status
|
||||
*/
|
||||
public $statut; // Status 0=Not sent, 1=Sent, 2=Read, 3=Read and unsubscribed, -1=Error
|
||||
|
||||
/**
|
||||
* @var int status
|
||||
*/
|
||||
public $status; // Status 0=Not sent, 1=Sent, 2=Read, 3=Read and unsubscribed, -1=Error
|
||||
|
||||
/**
|
||||
* @var array<int,string> statut dest
|
||||
*/
|
||||
public $statut_dest = array();
|
||||
|
||||
/**
|
||||
* @var string source_url of the mailing_target
|
||||
*/
|
||||
public $source_url;
|
||||
|
||||
/**
|
||||
* @var int source_id of the mailing_target
|
||||
*/
|
||||
public $source_id;
|
||||
|
||||
/**
|
||||
* @var string source_type
|
||||
*/
|
||||
public $source_type;
|
||||
|
||||
/**
|
||||
* @var integer|''|null date sending
|
||||
*/
|
||||
public $date_envoi;
|
||||
|
||||
/**
|
||||
* Update timestamp record (tms)
|
||||
* @var integer
|
||||
* @deprecated Use $date_modification
|
||||
*/
|
||||
public $tms;
|
||||
|
||||
/**
|
||||
* @var string error_text from trying to send email
|
||||
*/
|
||||
public $error_text;
|
||||
|
||||
const STATUS_NOTSENT = 0;
|
||||
const STATUS_SENT = 1;
|
||||
const STATUS_READ = 2;
|
||||
const STATUS_READANDUNSUBSCRIBED = 3;
|
||||
const STATUS_ERROR = -1;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DoliDB $db Database handler
|
||||
*/
|
||||
public function __construct($db)
|
||||
{
|
||||
$this->db = $db;
|
||||
|
||||
// List of language codes for status
|
||||
$this->labelStatus[0] = 'TargetStatusNotSent';
|
||||
$this->labelStatus[1] = 'TargetStatusSent';
|
||||
$this->labelStatus[2] = 'TargetStatusRead';
|
||||
$this->labelStatus[3] = 'TargetStatusReadAndUnsubscribed';
|
||||
$this->labelStatus[-1] = 'TargetStatusError';
|
||||
|
||||
$this->statut_dest[0] = 'TargetStatusNotSent';
|
||||
$this->statut_dest[1] = 'TargetStatusSent';
|
||||
$this->statut_dest[2] = 'TargetStatusRead';
|
||||
$this->statut_dest[3] = 'TargetStatusReadAndUnsubscribed'; // Read but ask to not be contacted anymore
|
||||
$this->statut_dest[-1] = 'TargetStatusError';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Mailing Target
|
||||
*
|
||||
* @param User $user Object of user making creation
|
||||
* @return int Return integer <0 if KO, Id of created object if OK
|
||||
*/
|
||||
public function create($user)
|
||||
{
|
||||
global $conf, $langs;
|
||||
|
||||
if (empty($this->fk_mailing)) {
|
||||
$this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Mailing"));
|
||||
return -2;
|
||||
// we probably should also check that this number actually exists in ".MAIN_DB_PREFIX."mailing";
|
||||
}
|
||||
if (0 == $this->fk_mailing) {
|
||||
$this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Mailing"));
|
||||
return -4;
|
||||
}
|
||||
if (empty($this->email)) {
|
||||
$this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Email"));
|
||||
return -3;
|
||||
}
|
||||
if (empty($this->statut)) {
|
||||
$statut = 0;
|
||||
}
|
||||
if (empty($this->status)) {
|
||||
$status = 0;
|
||||
}
|
||||
if ($this->status !== $this->statut) {
|
||||
$this->error = 'Status='.$this->status.' and Statut='.$this->statut.' field must be identical';
|
||||
return -4;
|
||||
}
|
||||
if (empty($this->fk_contact)) {
|
||||
$fk_contact = 0;
|
||||
}
|
||||
|
||||
$error = 0;
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
|
||||
// 2025-10-09 06:33:26 DEBUG 192.168.127.1 52 33 sql=INSERT INTO llx_mailing_cibles (fk_mailing, fk_contact, email, statut) VALUES ('4', .((int) 0)., 'jon@jonb.dk', .((int) )).
|
||||
//2025-10-09 06:35:13 DEBUG 192.168.127.1 54 33 sql=INSERT INTO llx_mailing_cibles (fk_mailing, fk_contact, email, statut) VALUES (4, .((int) 0)., 'jon@jonb.dk', .((int) )).
|
||||
|
||||
$sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_cibles";
|
||||
$sql .= " (fk_mailing, fk_contact, email, statut)";
|
||||
$sql .= " VALUES (".((int) $this->fk_mailing).", ";
|
||||
$sql .= ((int) $this->fk_contact).", ";
|
||||
$sql .= "'".$this->db->escape($this->email)."', ";
|
||||
$sql .= ((int) $conf->statut)." )";
|
||||
|
||||
dol_syslog(__METHOD__, LOG_DEBUG);
|
||||
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."mailing_cibles");
|
||||
|
||||
$result = $this->update($user);
|
||||
if ($result < 0) {
|
||||
$error++;
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$this->db->commit();
|
||||
return $this->id;
|
||||
} else {
|
||||
$this->db->rollback();
|
||||
dol_syslog(__METHOD__ . ' ' . $this->error, LOG_ERR);
|
||||
return -2;
|
||||
}
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
$this->db->rollback();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Mailing target
|
||||
*
|
||||
* @param User $user User that delete
|
||||
* @return int >0 if OK, <0 if KO
|
||||
*/
|
||||
public function delete($user)
|
||||
{
|
||||
$error = 0;
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
$sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles";
|
||||
$sql .= " WHERE rowid = " . ((int) $this->id);
|
||||
|
||||
dol_syslog(__METHOD__, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
dol_syslog(__METHOD__ . ' success');
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
} else {
|
||||
$this->db->rollback();
|
||||
$this->error = $this->db->lasterror();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set notsent mailing target
|
||||
*
|
||||
* @return int Return integer <0 if KO, >0 if OK
|
||||
*/
|
||||
public function setNotSent()
|
||||
{
|
||||
$now = dol_now();
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles ";
|
||||
$sql .= " SET statut = ".((int) self::STATUS_NOTSENT).", tms = '".$this->db->idate($now)."'";
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
dol_syslog("Mailing::valid", LOG_DEBUG);
|
||||
if ($this->db->query($sql)) {
|
||||
return 1;
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sent mailing target
|
||||
*
|
||||
* @return int Return integer <0 if KO, >0 if OK
|
||||
*/
|
||||
public function setSent()
|
||||
{
|
||||
$now = dol_now();
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles ";
|
||||
$sql .= " SET statut = ".((int) self::STATUS_SENT).", tms = '".$this->db->idate($now)."'";
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
dol_syslog("Mailing::valid", LOG_DEBUG);
|
||||
if ($this->db->query($sql)) {
|
||||
return 1;
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set read mailing target
|
||||
*
|
||||
* @return int Return integer <0 if KO, >0 if OK
|
||||
*/
|
||||
public function setRead()
|
||||
{
|
||||
$now = dol_now();
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles ";
|
||||
$sql .= " SET statut = ".((int) self::STATUS_READ).", tms = '".$this->db->idate($now)."'";
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
dol_syslog("Mailing::valid", LOG_DEBUG);
|
||||
if ($this->db->query($sql)) {
|
||||
return 1;
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set read and unsubscribed mailing target
|
||||
*
|
||||
* @return int Return integer <0 if KO, >0 if OK
|
||||
*/
|
||||
public function setReadAndUnsubscribed()
|
||||
{
|
||||
$now = dol_now();
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles ";
|
||||
$sql .= " SET statut = ".((int) self::STATUS_READANDUNSUBSCRIBED).", tms = '".$this->db->idate($now)."'";
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
dol_syslog("Mailing::valid", LOG_DEBUG);
|
||||
if ($this->db->query($sql)) {
|
||||
return 1;
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set error mailing target
|
||||
*
|
||||
* @return int Return integer <0 if KO, >0 if OK
|
||||
*/
|
||||
public function setError()
|
||||
{
|
||||
$now = dol_now();
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles ";
|
||||
$sql .= " SET statut = ".((int) self::STATUS_ERROR).", tms = '".$this->db->idate($now)."'";
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
dol_syslog("Mailing::valid", LOG_DEBUG);
|
||||
if ($this->db->query($sql)) {
|
||||
return 1;
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an Mailing Target
|
||||
*
|
||||
* @param User $user Object of user making change
|
||||
* @return int Return integer < 0 if KO, > 0 if OK
|
||||
*/
|
||||
public function update($user)
|
||||
{
|
||||
global $langs;
|
||||
|
||||
if (empty($this->fk_mailing)) {
|
||||
return -2;
|
||||
// we probably should also check that this number actually exists in ".MAIN_DB_PREFIX."mailing";
|
||||
}
|
||||
if (empty($this->email)) {
|
||||
return -3;
|
||||
}
|
||||
if (empty($this->statut)) {
|
||||
$statut = 0;
|
||||
}
|
||||
if (empty($this->status)) {
|
||||
$status = 0;
|
||||
}
|
||||
if ($this->status !== $this->statut) {
|
||||
return -4;
|
||||
}
|
||||
if (empty($this->fk_contact)) {
|
||||
$fk_contact = 0;
|
||||
}
|
||||
|
||||
$now = dol_now();
|
||||
$error = 0;
|
||||
$this->db->begin();
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
|
||||
$sql .= " SET fk_mailing = '".((int) $this->fk_mailing)."'";
|
||||
$sql .= ", fk_contact = '".((int) $this->fk_contact)."'";
|
||||
$sql .= ", lastname = '".$this->db->escape($this->lastname)."'";
|
||||
$sql .= ", firstname = '".$this->db->escape($this->firstname)."'";
|
||||
$sql .= ", email = '".$this->db->escape($this->email)."'";
|
||||
$sql .= ", other = '".$this->db->escape($this->other)."'";
|
||||
$sql .= ", tag = '".$this->db->escape($this->tag)."'";
|
||||
$sql .= ", statut = '".((int) $this->statut)."'";
|
||||
$sql .= ", source_url = '".$this->db->escape($this->source_url)."'";
|
||||
$sql .= ", source_id = '".((int) $this->source_id)."'";
|
||||
$sql .= ", source_type = '".$this->db->escape($this->source_type)."'";
|
||||
if ($this->date_envoi) {
|
||||
$sql .= ", date_envoi = '".$this->db->idate($this->date_envoi)."'";
|
||||
}
|
||||
$sql .= ", error_text = '".($this->error_text ? $this->db->escape($this->error_text) : null)."'";
|
||||
$sql .= " WHERE rowid = ".(int) $this->id;
|
||||
|
||||
dol_syslog(__METHOD__, LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
dol_syslog(__METHOD__ . ' success');
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
} else {
|
||||
if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
|
||||
$this->error = $langs->trans("ErrorRecordAlreadyExists", $this->email);
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
}
|
||||
$this->db->rollback();
|
||||
return -6;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object from database
|
||||
*
|
||||
* @param int $rowid Id of Mailing Target
|
||||
* @return int Return integer <0 if KO, >0 if OK
|
||||
*/
|
||||
public function fetch($rowid)
|
||||
{
|
||||
$sql = "SELECT t.rowid";
|
||||
$sql .= ", t.fk_mailing";
|
||||
$sql .= ", t.fk_contact";
|
||||
$sql .= ", t.lastname";
|
||||
$sql .= ", t.firstname";
|
||||
$sql .= ", t.email";
|
||||
$sql .= ", t.other";
|
||||
$sql .= ", t.tag";
|
||||
$sql .= ", t.statut as status";
|
||||
$sql .= ", t.source_url";
|
||||
$sql .= ", t.source_id";
|
||||
$sql .= ", t.source_type";
|
||||
$sql .= ", t.date_envoi";
|
||||
$sql .= ", t.tms as date_modification";
|
||||
$sql .= ", t.error_text";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as t";
|
||||
$sql .= " WHERE t.rowid = ".(int) $rowid;
|
||||
|
||||
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
|
||||
$result = $this->db->query($sql);
|
||||
if ($result) {
|
||||
if ($this->db->num_rows($result)) {
|
||||
$obj = $this->db->fetch_object($result);
|
||||
|
||||
$this->id = $obj->rowid;
|
||||
$this->fk_mailing = $obj->fk_mailing;
|
||||
$this->fk_contact = $obj->fk_contact;
|
||||
$this->lastname = $obj->lastname;
|
||||
$this->firstname = $obj->firstname;
|
||||
$this->email = $obj->email;
|
||||
$this->other = $obj->other;
|
||||
$this->tag = $obj->tag;
|
||||
$this->statut = $obj->status; // deprecated
|
||||
$this->status = $obj->status;
|
||||
$this->source_url = $obj->source_url;
|
||||
$this->source_id = $obj->source_id;
|
||||
$this->source_type = $obj->source_type;
|
||||
$this->date_envoi = $this->db->jdate($obj->date_envoi);
|
||||
$this->date_modification = $this->db->jdate($obj->date_modification); // tms
|
||||
$this->tms = $this->db->jdate($obj->date_modification); // tms
|
||||
$this->error_text = $obj->error_text;
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
dol_syslog(get_class($this)."::fetch Error -1");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
dol_syslog(get_class($this)."::fetch Error -2");
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1062,7 +1062,7 @@ abstract class CommonInvoice extends CommonObject
|
||||
$statusdispute = $moreparams['dispute_status'] ? img_picto($langs->trans("DisputeOpen"), 'warning') : '';
|
||||
}
|
||||
*/
|
||||
if ($moreparams['dispute_status']) {
|
||||
if (isset($moreparams['dispute_status']) && $moreparams['dispute_status']) {
|
||||
$labelStatus .= ' - '.$langs->trans("DisputeOpen");
|
||||
$statusType = 'status8';
|
||||
}
|
||||
|
||||
@@ -2345,8 +2345,8 @@ function get_left_menu_mrp($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu =
|
||||
$langs->load("mrp");
|
||||
|
||||
$newmenu->add("", $langs->trans("MenuMRP"), 0, $user->hasRight('mrp', 'read'), '', $mainmenu, 'mrp', 0, '', '', '', img_picto('', 'mrp', 'class="paddingright pictofixedwidth"'));
|
||||
$newmenu->add("/mrp/mo_card.php?leftmenu=mo&action=create", $langs->trans("NewMO"), 1, $user->hasRight('mrp', 'write'), '', $mainmenu, '');
|
||||
$newmenu->add("/mrp/mo_list.php?leftmenu=mo", $langs->trans("List"), 1, $user->hasRight('mrp', 'read'), '', $mainmenu, '');
|
||||
$newmenu->add("/mrp/mo_card.php?leftmenu=mrp&action=create", $langs->trans("NewMO"), 1, $user->hasRight('mrp', 'write'), '', $mainmenu, '');
|
||||
$newmenu->add("/mrp/mo_list.php?leftmenu=mrp", $langs->trans("List"), 1, $user->hasRight('mrp', 'read'), '', $mainmenu, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,7 +934,7 @@ if (empty($reshook)) {
|
||||
$object->fk_incoterms = GETPOSTINT('incoterm_id');
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
||||
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
|
||||
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
|
||||
$object->transport_mode_id = GETPOSTINT('transport_mode_id');
|
||||
|
||||
// Proprietes particulieres a facture avoir
|
||||
@@ -1037,7 +1037,7 @@ if (empty($reshook)) {
|
||||
$object->fk_incoterms = GETPOSTINT('incoterm_id');
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
||||
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
|
||||
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
|
||||
|
||||
// Source facture
|
||||
$object->fac_rec = $fac_recid;
|
||||
@@ -1104,7 +1104,7 @@ if (empty($reshook)) {
|
||||
$object->fk_incoterms = GETPOSTINT('incoterm_id');
|
||||
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
|
||||
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
|
||||
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
|
||||
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
|
||||
$object->transport_mode_id = GETPOSTINT('transport_mode_id');
|
||||
|
||||
// Auto calculation of date due if not filled by user
|
||||
|
||||
@@ -234,4 +234,8 @@ ALTER TABLE llx_accounting_bookkeeping_piece ADD INDEX idx_accounting_bookkeepin
|
||||
|
||||
ALTER TABLE llx_mailing ADD COLUMN fk_project integer DEFAULT NULL;
|
||||
UPDATE llx_c_units SET label = 'unitP' WHERE code = 'P';
|
||||
|
||||
ALTER TABLE llx_receptiondet_batch ADD COLUMN description text AFTER fk_product;
|
||||
ALTER TABLE llx_receptiondet_batch ADD COLUMN fk_unit integer AFTER qty;
|
||||
ALTER TABLE llx_receptiondet_batch ADD COLUMN rang integer DEFAULT 0 AFTER cost_price;
|
||||
-- end of migration
|
||||
|
||||
@@ -30,7 +30,9 @@ create table llx_receptiondet_batch
|
||||
fk_elementdet integer, -- ID of line of main source object.
|
||||
element_type varchar(50) DEFAULT 'supplier_order' NOT NULL, -- Type of source object ('supplier_order', ...)
|
||||
fk_product integer,
|
||||
description text, -- Product description/label of non origin
|
||||
qty float, -- qty to move
|
||||
fk_unit integer, -- ID of unit code
|
||||
fk_entrepot integer, -- ID of warehouse to use for the stock change
|
||||
fk_projet integer DEFAULT NULL,
|
||||
comment varchar(255), -- comment on movement
|
||||
@@ -42,5 +44,6 @@ create table llx_receptiondet_batch
|
||||
datec datetime,
|
||||
tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
cost_price double(24,8) DEFAULT 0,
|
||||
rang integer DEFAULT 0, -- Position of line
|
||||
extraparams varchar(255) -- to stock other parameters in json format
|
||||
)ENGINE=innodb;
|
||||
|
||||
187
test/hurl/api/mailings/10_mailings.hurl
Normal file
187
test/hurl/api/mailings/10_mailings.hurl
Normal file
@@ -0,0 +1,187 @@
|
||||
# GET mass mailings
|
||||
GET http://{{hostnport}}/api/index.php/mailings
|
||||
HTTP 200
|
||||
|
||||
# GET mass sorted mailings
|
||||
GET http://{{hostnport}}/api/index.php/mailings?sortfield=t.rowid&sortorder=ASC
|
||||
HTTP 200
|
||||
|
||||
# GET mass sorted mailings
|
||||
GET http://{{hostnport}}/api/index.php/mailings?sortfield=t.rowid&sortorder=ASC
|
||||
HTTP 200
|
||||
|
||||
# GET with limit and page
|
||||
GET http://{{hostnport}}/api/index.php/mailings?limit=100&page=1
|
||||
HTTP 200
|
||||
|
||||
# GET with fk_project
|
||||
GET http://{{hostnport}}/api/index.php/mailings?fk_projects=1
|
||||
HTTP 200
|
||||
|
||||
# GET with properties=id%2Cstatus
|
||||
GET http://{{hostnport}}/api/index.php/mailings?properties=id%2Cstatus
|
||||
HTTP 200
|
||||
|
||||
# GET with pagination_data=false
|
||||
GET http://{{hostnport}}/api/index.php/mailings?pagination_data=false
|
||||
HTTP 200
|
||||
|
||||
# GET with pagination_data=true
|
||||
GET http://{{hostnport}}/api/index.php/mailings?pagination_data=true
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.data" exists
|
||||
jsonpath "$.pagination.total" >= 0
|
||||
jsonpath "$.pagination.page" >= 0
|
||||
jsonpath "$.pagination.page_count" >= 0
|
||||
jsonpath "$.pagination.limit" == 100
|
||||
|
||||
# GET mailing with ID 0 - which should not exist
|
||||
GET http://{{hostnport}}/api/index.php/mailings/0
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing not found, id=0"}}
|
||||
|
||||
# POST {}
|
||||
POST http://{{hostnport}}/api/index.php/mailings
|
||||
{}
|
||||
HTTP 400
|
||||
{"error":{"code":400,"message":"Bad Request: title field missing"}}
|
||||
|
||||
# DELETE
|
||||
DELETE http://{{hostnport}}/api/index.php/mailings/
|
||||
HTTP 405
|
||||
|
||||
# DELETE mailing with ID 0 - which should not exist
|
||||
DELETE http://{{hostnport}}/api/index.php/mailings/0
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing not found, id=0"}}
|
||||
|
||||
# PUT
|
||||
PUT http://{{hostnport}}/api/index.php/mailings/
|
||||
{}
|
||||
HTTP 405
|
||||
|
||||
# PUT
|
||||
PUT http://{{hostnport}}/api/index.php/mailings/0
|
||||
{}
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing not found, id=0"}}
|
||||
|
||||
DELETE http://{{hostnport}}/api/index.php/mailings//deleteTargets
|
||||
HTTP 400
|
||||
|
||||
# DELETE targets of mailing with ID 0 - which should not exist
|
||||
DELETE http://{{hostnport}}/api/index.php/mailings/0/deleteTargets
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing not found, id=0"}}
|
||||
|
||||
|
||||
PUT http://{{hostnport}}/api/index.php/mailings//resetTargetsStatus
|
||||
HTTP 400
|
||||
|
||||
# reset target status of mailing with ID 0 - which should not exist
|
||||
PUT http://{{hostnport}}/api/index.php/mailings/0/resetTargetsStatus
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing not found, id=0"}}
|
||||
|
||||
|
||||
PUT http://{{hostnport}}/api/index.php/mailings//settodraft
|
||||
HTTP 400
|
||||
|
||||
# set mailing to draft with ID 0 - which should not exist
|
||||
PUT http://{{hostnport}}/api/index.php/mailings/0/settodraft
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing not found, id=0"}}
|
||||
|
||||
|
||||
PUT http://{{hostnport}}/api/index.php/mailings//validate
|
||||
HTTP 400
|
||||
|
||||
# validate mailing with ID 0 - which should not exist
|
||||
PUT http://{{hostnport}}/api/index.php/mailings/0/validate
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing not found, id=0"}}
|
||||
|
||||
GET http://{{hostnport}}/api/index.php/mailings/clone/
|
||||
HTTP 400
|
||||
|
||||
GET http://{{hostnport}}/api/index.php/mailings/clone/0
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing to clone not found, id=0"}}
|
||||
|
||||
|
||||
GET http://{{hostnport}}/api/index.php/mailings//targets
|
||||
HTTP 400
|
||||
|
||||
# get targets of mailing with ID 0 - which should not exist
|
||||
GET http://{{hostnport}}/api/index.php/mailings/0/targets
|
||||
HTTP 404
|
||||
{"error":{"code":404,"message":"Not Found: Mass mailing not found, id=0"}}
|
||||
|
||||
# get a target in a mailing
|
||||
GET http://{{hostnport}}/api/index.php/mailings/0/getTarget/0
|
||||
HTTP 404
|
||||
|
||||
# get a target in a mailing
|
||||
PUT http://{{hostnport}}/api/index.php/mailings/0/updateTarget/0
|
||||
{}
|
||||
HTTP 404
|
||||
|
||||
# Delete a target in a mailing
|
||||
DELETE http://{{hostnport}}/api/index.php/mailings/0/deleteTarget/0
|
||||
{}
|
||||
HTTP 404
|
||||
|
||||
# Create a target in a mailing
|
||||
POST http://{{hostnport}}/api/index.php/mailings/0/createTarget
|
||||
{}
|
||||
HTTP 400
|
||||
|
||||
# Create a target in a mailing
|
||||
POST http://{{hostnport}}/api/index.php/mailings/0/createTarget
|
||||
{
|
||||
"statut": "0",
|
||||
"status": "0",
|
||||
"lastname": "Example",
|
||||
"firstname": "Bad",
|
||||
"date_modification": 1759051258,
|
||||
"tms": 1759051258,
|
||||
"fk_mailing": "0",
|
||||
"fk_contact": "0",
|
||||
"email": "bad@example.com",
|
||||
"other": "",
|
||||
"tag": "acaa266a6b12a85a7db47a377a10333b",
|
||||
"source_url": "",
|
||||
"source_id": null,
|
||||
"source_type": "file",
|
||||
"date_envoi": "",
|
||||
"error_text": null
|
||||
}
|
||||
HTTP 404
|
||||
|
||||
# Create a target in a mailing
|
||||
POST http://{{hostnport}}/api/index.php/mailings/0/createTarget
|
||||
{
|
||||
"id": "0"
|
||||
}
|
||||
HTTP 400
|
||||
{"error":{"code":400,"message":"Bad Request: fk_mailing field missing"}}
|
||||
|
||||
# Create a target in a mailing
|
||||
POST http://{{hostnport}}/api/index.php/mailings/0/createTarget
|
||||
{
|
||||
"id": "0",
|
||||
"fk_mailing" : "0"
|
||||
}
|
||||
HTTP 400
|
||||
{"error":{"code":400,"message":"Bad Request: email field missing"}}
|
||||
|
||||
# Create a target in a mailing
|
||||
POST http://{{hostnport}}/api/index.php/mailings/0/createTarget
|
||||
{
|
||||
"id": "0",
|
||||
"email": "bad@example.com",
|
||||
"fk_mailing" : "0"
|
||||
}
|
||||
HTTP 400
|
||||
{"error":{"code":400,"message":"Bad Request: Creating with id field is forbidden"}}
|
||||
@@ -17,14 +17,14 @@ if [[ "" != "${DOLISUBURL}" ]]; then
|
||||
fi
|
||||
|
||||
echo "First we run tests that do not require authentication"
|
||||
find api/ gui/ public/ -type f -iname '00*.hurl' -exec hurl --variable "hostnport=${hostnport}" --test "{}" \;
|
||||
find api/ gui/ public/ -type f -iname '00*.hurl' -exec hurl --variable "hostnport=${hostnport}" --test "{}" + || exit 1
|
||||
|
||||
# Now we get ready to run tests that do require authentication
|
||||
if [[ -z ${DOLAPIKEY+x} ]]; then
|
||||
echo "DOLAPIKEY bash variable is unset, no API tests that require authentication"
|
||||
else
|
||||
echo "Now we are ready to run API tests that do require authentication"
|
||||
find api/ -type f -iname '10*.hurl' -not -iname '00*.hurl' -exec hurl --variable "hostnport=${hostnport}" --header "${DOLAPIKEY}" --test "{}" \;
|
||||
find api/ -type f -iname '10*.hurl' -not -iname '00*.hurl' -exec hurl --variable "hostnport=${hostnport}" --header "${DOLAPIKEY}" --test "{}" + || exit 2
|
||||
fi
|
||||
|
||||
./save_login_cookie.sh
|
||||
@@ -32,5 +32,5 @@ if [[ -z ${COOKIEJAR+x} ]]; then
|
||||
COOKIEJAR=/tmp/cookie.jar
|
||||
fi
|
||||
echo "Now we are ready to run GUI tests that do require authentication"
|
||||
find gui/ -type f -iname '10*.hurl' -not -iname 'save_login_cookie.hurl' -not -iname '00*.hurl' -exec hurl --variable "hostnport=${hostnport}" --cookie "${COOKIEJAR}" --test "{}" \;
|
||||
find gui/ -type f -iname '10*.hurl' -not -iname 'save_login_cookie.hurl' -not -iname '00*.hurl' -exec hurl --variable "hostnport=${hostnport}" --cookie "${COOKIEJAR}" --test "{}" + || exit 3
|
||||
rm -rf "${COOKIEJAR}"
|
||||
|
||||
@@ -17,9 +17,11 @@ if [[ "" != "${DOLISUBURL}" ]]; then
|
||||
fi
|
||||
|
||||
if [[ -z ${DOLIUSERNAME+x} ]]; then
|
||||
echo "To do GUI tests we need:"
|
||||
read -rp " Your Dolibarr Username: " DOLIUSERNAME
|
||||
fi
|
||||
if [[ -z ${DOLIPASSWORD+x} ]]; then
|
||||
echo "To do GUI tests we need:"
|
||||
read -rsp " Your Dolibarr Password: " DOLIPASSWORD
|
||||
echo ""
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user