mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-12-07 18:18:18 +01:00
3515 lines
123 KiB
PHP
3515 lines
123 KiB
PHP
<?php
|
|
/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
|
|
* Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org>
|
|
* Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
|
|
* Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
|
|
* Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
|
|
* Copyright (C) 2009-2017 Regis Houssin <regis.houssin@inodbox.com>
|
|
* Copyright (C) 2014-2018 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
|
* Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
|
|
* Copyright (C) 2015-2025 Frédéric France <frederic.france@free.fr>
|
|
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
|
* Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
|
|
* Copyright (C) 2018-2019 Thibault FOUCART <support@ptibogxiv.net>
|
|
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
|
|
* Copyright (C) 2020 Josep Lluís Amador <joseplluis@lliuretic.cat>
|
|
* Copyright (C) 2021 Waël Almoman <info@almoman.com>
|
|
* Copyright (C) 2021 Philippe Grand <philippe.grand@atoo-net.com>
|
|
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
|
|
*
|
|
* 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/adherents/class/adherent.class.php
|
|
* \ingroup member
|
|
* \brief File of class to manage members of a foundation
|
|
*/
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/commonpeople.class.php';
|
|
|
|
|
|
/**
|
|
* Class to manage members of a foundation.
|
|
*/
|
|
class Adherent extends CommonObject
|
|
{
|
|
use CommonPeople;
|
|
|
|
/**
|
|
* @var string ID to identify managed object
|
|
*/
|
|
public $element = 'member';
|
|
|
|
/**
|
|
* @var string Name of table without prefix where object is stored
|
|
*/
|
|
public $table_element = 'adherent';
|
|
|
|
/**
|
|
* @var string picto
|
|
*/
|
|
public $picto = 'member';
|
|
|
|
/**
|
|
* @var string[] array of messages
|
|
*/
|
|
public $mesgs;
|
|
|
|
/**
|
|
* @var ?string login of member
|
|
*/
|
|
public $login;
|
|
|
|
/**
|
|
* @var ?string Clear password in memory
|
|
*/
|
|
public $pass;
|
|
|
|
/**
|
|
* @var string Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
|
|
*/
|
|
public $pass_indatabase;
|
|
|
|
/**
|
|
* @var string Encrypted password in database (always defined)
|
|
*/
|
|
public $pass_indatabase_crypted;
|
|
|
|
/**
|
|
* @var string fullname
|
|
*/
|
|
public $fullname;
|
|
|
|
/**
|
|
* @var string
|
|
* @deprecated Use $civility_code
|
|
*/
|
|
public $civility_id;
|
|
|
|
/**
|
|
* @var string The civility code, not an integer (ex: 'MR', 'MME', 'MLE', 'DR', etc.)
|
|
*/
|
|
public $civility_code;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
public $civility;
|
|
|
|
/**
|
|
* @var ?string company name
|
|
* @deprecated Use $company
|
|
* @see $company
|
|
*/
|
|
public $societe;
|
|
|
|
/**
|
|
* @var ?string company name
|
|
*/
|
|
public $company;
|
|
|
|
/**
|
|
* @var int Thirdparty ID
|
|
* @deprecated Use $socid
|
|
* @see $socid
|
|
*/
|
|
public $fk_soc;
|
|
|
|
/**
|
|
* @var int socid
|
|
*/
|
|
public $socid;
|
|
|
|
/**
|
|
* @var array<string,string> array of socialnetworks
|
|
*/
|
|
public $socialnetworks;
|
|
|
|
/**
|
|
* @var string Phone number
|
|
*/
|
|
public $phone;
|
|
|
|
/**
|
|
* @var string Private Phone number
|
|
*/
|
|
public $phone_perso;
|
|
|
|
/**
|
|
* @var string Professional Phone number
|
|
*/
|
|
public $phone_pro;
|
|
|
|
/**
|
|
* @var string Mobile phone number
|
|
*/
|
|
public $phone_mobile;
|
|
|
|
/**
|
|
* @var string Fax number
|
|
*/
|
|
public $fax;
|
|
|
|
/**
|
|
* @var string Function
|
|
*/
|
|
public $poste;
|
|
|
|
/**
|
|
* @var string mor or phy
|
|
*/
|
|
public $morphy;
|
|
|
|
/**
|
|
* @var ?int<0,1> Info can be public
|
|
*/
|
|
public $public;
|
|
|
|
/**
|
|
* Default language code of member (en_US, ...)
|
|
* @var string
|
|
*/
|
|
public $default_lang;
|
|
|
|
/**
|
|
* @var ?string photo of member
|
|
*/
|
|
public $photo;
|
|
|
|
/**
|
|
* Date creation record (datec)
|
|
*
|
|
* @var integer
|
|
*/
|
|
public $datec;
|
|
|
|
/**
|
|
* Date modification record (tms)
|
|
*
|
|
* @var integer
|
|
*/
|
|
public $datem;
|
|
|
|
/**
|
|
* @var string|int
|
|
*/
|
|
public $datevalid;
|
|
|
|
/**
|
|
* @var string gender
|
|
*/
|
|
public $gender;
|
|
|
|
/**
|
|
* @var int|string date of birth
|
|
*/
|
|
public $birth;
|
|
|
|
/**
|
|
* @var int id type member
|
|
*/
|
|
public $typeid;
|
|
|
|
/**
|
|
* @var ?string label type member
|
|
*/
|
|
public $type;
|
|
|
|
/**
|
|
* @var int need_subscription
|
|
*/
|
|
public $need_subscription;
|
|
|
|
/**
|
|
* @var int|null user_id
|
|
*/
|
|
public $user_id;
|
|
|
|
/**
|
|
* @var string|null user_login
|
|
*/
|
|
public $user_login;
|
|
|
|
/**
|
|
* @var string|int
|
|
*/
|
|
public $datefin;
|
|
|
|
|
|
// Fields loaded by fetch_subscriptions() from member table
|
|
|
|
/**
|
|
* @var int|string|null date
|
|
*/
|
|
public $first_subscription_date;
|
|
|
|
/**
|
|
* @var int|string|null date
|
|
*/
|
|
public $first_subscription_date_start;
|
|
|
|
/**
|
|
* @var int|string|null date
|
|
*/
|
|
public $first_subscription_date_end;
|
|
|
|
/**
|
|
* @var int|string|null date
|
|
*/
|
|
public $first_subscription_amount;
|
|
|
|
/**
|
|
* @var int|string|null date
|
|
*/
|
|
public $last_subscription_date;
|
|
|
|
/**
|
|
* @var int|string|null date
|
|
*/
|
|
public $last_subscription_date_start;
|
|
|
|
/**
|
|
* @var int|string|null date
|
|
*/
|
|
public $last_subscription_date_end;
|
|
|
|
/**
|
|
* @var null|float|string date, null until set
|
|
*/
|
|
public $last_subscription_amount;
|
|
|
|
/**
|
|
* @var Subscription[]
|
|
*/
|
|
public $subscriptions = array();
|
|
|
|
/**
|
|
* @var string ip
|
|
*/
|
|
public $ip;
|
|
|
|
// Fields loaded by fetchPartnerships() from partnership table
|
|
|
|
/**
|
|
* @var array<array<mixed>>
|
|
*/
|
|
public $partnerships = array();
|
|
|
|
/**
|
|
* @var ?Facture To store the created invoice into subscriptionComplementaryActions()
|
|
*/
|
|
public $invoice;
|
|
|
|
|
|
/**
|
|
* 'type' field format:
|
|
* 'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',
|
|
* 'select' (list of values are in 'options'. for integer list of values are in 'arrayofkeyval'),
|
|
* 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:CategoryIdType[:CategoryIdList[:SortField]]]]]]',
|
|
* 'chkbxlst:...',
|
|
* 'varchar(x)',
|
|
* 'text', 'text:none', 'html',
|
|
* 'double(24,8)', 'real', 'price', 'stock',
|
|
* 'date', 'datetime', 'timestamp', 'duration',
|
|
* 'boolean', 'checkbox', 'radio', 'array',
|
|
* 'mail', 'phone', 'url', 'password', 'ip'
|
|
* Note: Filter must be a Dolibarr Universal Filter syntax string. Example: "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.status:!=:0) or (t.nature:is:NULL)"
|
|
* 'length' the length of field. Example: 255, '24,8'
|
|
* 'label' the translation key.
|
|
* 'alias' the alias used into some old hard coded SQL requests
|
|
* 'picto' is code of a picto to show before value in forms
|
|
* 'enabled' is a condition when the field must be managed (Example: 1 or 'getDolGlobalInt("MY_SETUP_PARAM")' or 'isModEnabled("multicurrency")' ...)
|
|
* 'position' is the sort order of field.
|
|
* 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
|
|
* 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
|
|
* 'noteditable' says if field is not editable (1 or 0)
|
|
* 'alwayseditable' says if field can be modified also when status is not draft ('1' or '0')
|
|
* 'default' is a default value for creation (can still be overwritten by the Setup of Default Values if the field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
|
|
* 'index' if we want an index in database.
|
|
* 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...).
|
|
* 'searchall' is 1 if we want to search in this field when making a search from the quick search button.
|
|
* 'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage)
|
|
* 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200'
|
|
* 'placeholder' to set the placeholder of a varchar field.
|
|
* 'help' and 'helplist' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
|
|
* 'showoncombobox' if value of the field must be visible into the label of the combobox that list record
|
|
* 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code like the constructor of the class.
|
|
* 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar'
|
|
* 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1.
|
|
* 'comment' is not used. You can store here any text of your choice. It is not used by application.
|
|
* 'validate' is 1 if you need to validate the field with $this->validateField(). Need MAIN_ACTIVATE_VALIDATION_RESULT.
|
|
* 'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value)
|
|
*
|
|
* Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
|
|
*/
|
|
public $fields = array(
|
|
'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
|
|
'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'default' => '1', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 12, 'index' => 1),
|
|
'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 15, 'index' => 1),
|
|
'ref_ext' => array('type' => 'varchar(128)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 20),
|
|
'civility' => array('type' => 'varchar(6)', 'label' => 'Civility', 'enabled' => 1, 'visible' => -1, 'position' => 25),
|
|
'lastname' => array('type' => 'varchar(50)', 'label' => 'Lastname', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'showoncombobox' => 1),
|
|
'firstname' => array('type' => 'varchar(50)', 'label' => 'Firstname', 'enabled' => 1, 'visible' => 1, 'position' => 35, 'showoncombobox' => 1),
|
|
'login' => array('type' => 'varchar(50)', 'label' => 'Login', 'enabled' => 1, 'visible' => 1, 'position' => 40),
|
|
'pass' => array('type' => 'varchar(50)', 'label' => 'Pass', 'enabled' => 1, 'visible' => 3, 'position' => 45),
|
|
'pass_crypted' => array('type' => 'varchar(128)', 'label' => 'Pass crypted', 'enabled' => 1, 'visible' => 3, 'position' => 50),
|
|
'morphy' => array('type' => 'varchar(3)', 'label' => 'MemberNature', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 55),
|
|
'fk_adherent_type' => array('type' => 'integer', 'label' => 'MemberType', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 60),
|
|
'societe' => array('type' => 'varchar(128)', 'label' => 'Societe', 'enabled' => 1, 'visible' => 1, 'position' => 65, 'showoncombobox' => 2),
|
|
'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 70),
|
|
'address' => array('type' => 'text', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
|
|
'zip' => array('type' => 'varchar(10)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
|
|
'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
|
|
'state_id' => array('type' => 'integer', 'label' => 'State', 'enabled' => 1, 'visible' => -1, 'position' => 90),
|
|
'country' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => 1, 'position' => 95),
|
|
'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 115),
|
|
'phone_perso' => array('type' => 'varchar(30)', 'label' => 'Phone perso', 'enabled' => 1, 'visible' => -1, 'position' => 120),
|
|
'phone_mobile' => array('type' => 'varchar(30)', 'label' => 'Phone mobile', 'enabled' => 1, 'visible' => -1, 'position' => 125),
|
|
'email' => array('type' => 'varchar(255)', 'label' => 'Email', 'enabled' => 1, 'visible' => 1, 'position' => 126),
|
|
'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 127),
|
|
'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => 3, 'position' => 128),
|
|
'birth' => array('type' => 'date', 'label' => 'DateOfBirth', 'enabled' => 1, 'visible' => -1, 'position' => 130),
|
|
'gender' => array('type' => 'varchar(10)', 'label' => 'Gender', 'enabled' => 1, 'visible' => -1, 'position' => 132),
|
|
'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135),
|
|
'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => 3, 'notnull' => 1, 'position' => 145),
|
|
'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => 1, 'position' => 150),
|
|
'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 153),
|
|
'note_public' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155),
|
|
'note_private' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160),
|
|
'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165),
|
|
'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 170),
|
|
'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 175),
|
|
'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserCreation', 'enabled' => 1, 'visible' => 3, 'position' => 180),
|
|
'fk_user_mod' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModification', 'enabled' => 1, 'visible' => 3, 'position' => 185),
|
|
'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => 3, 'position' => 190),
|
|
'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => 0, 'position' => 195),
|
|
'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 800),
|
|
'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 805),
|
|
'statut' => array('type' => 'smallint(6)', 'label' => 'Statut', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 1000, 'arrayofkeyval' => array(-1 => 'Draft', 1 => 'Validated', 0 => 'MemberStatusResiliatedShort', -2 => 'MemberStatusExcludedShort'))
|
|
);
|
|
|
|
/**
|
|
* Draft status
|
|
*/
|
|
const STATUS_DRAFT = -1;
|
|
/**
|
|
* Validated status
|
|
*/
|
|
const STATUS_VALIDATED = 1;
|
|
/**
|
|
* Resiliated (membership end and was not renew)
|
|
*/
|
|
const STATUS_RESILIATED = 0;
|
|
/**
|
|
* Excluded
|
|
*/
|
|
const STATUS_EXCLUDED = -2;
|
|
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param DoliDB $db Database handler
|
|
*/
|
|
public function __construct($db)
|
|
{
|
|
$this->db = $db;
|
|
$this->statut = self::STATUS_DRAFT;
|
|
$this->status = self::STATUS_DRAFT;
|
|
// l'adherent n'est pas public par default
|
|
$this->public = 0;
|
|
$this->ismultientitymanaged = 1;
|
|
$this->isextrafieldmanaged = 1;
|
|
// les champs optionnels sont vides
|
|
$this->array_options = array();
|
|
|
|
$this->fields['ref_ext']['visible'] = getDolGlobalInt('MAIN_LIST_SHOW_REF_EXT');
|
|
}
|
|
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Function sending an email to the current member with the text supplied in parameter.
|
|
*
|
|
* @param string $text Content of message (not html entities encoded)
|
|
* @param string $subject Subject of message
|
|
* @param string[] $filename_list Array of attached files
|
|
* @param string[] $mimetype_list Array of mime types of attached files
|
|
* @param string[] $mimefilename_list Array of public names of attached files
|
|
* @param string $addr_cc Email cc
|
|
* @param string $addr_bcc Email bcc
|
|
* @param int $deliveryreceipt Ask a delivery receipt
|
|
* @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
|
|
* @param string $errors_to errors to
|
|
* @param string $moreinheader Add more html headers
|
|
* @deprecated since V18
|
|
* @see sendEmail()
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function send_an_email($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '')
|
|
{
|
|
// phpcs:enable
|
|
dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING);
|
|
|
|
return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader);
|
|
}
|
|
|
|
/**
|
|
* Function sending an email to the current member with the text supplied in parameter.
|
|
*
|
|
* @param string $text Content of message (not html entities encoded)
|
|
* @param string $subject Subject of message
|
|
* @param string[] $filename_list Array of attached files
|
|
* @param string[] $mimetype_list Array of mime types of attached files
|
|
* @param string[] $mimefilename_list Array of public names of attached files
|
|
* @param string $addr_cc Email cc
|
|
* @param string $addr_bcc Email bcc
|
|
* @param int $deliveryreceipt Ask a delivery receipt
|
|
* @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
|
|
* @param string $errors_to errors to
|
|
* @param string $moreinheader Add more html headers
|
|
* @since V18
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function sendEmail($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '')
|
|
{
|
|
global $conf, $langs;
|
|
|
|
// Detect if message is HTML
|
|
if ($msgishtml == -1) {
|
|
$msgishtml = 0;
|
|
if (dol_textishtml($text, 0)) {
|
|
$msgishtml = 1;
|
|
}
|
|
}
|
|
|
|
dol_syslog('sendEmail msgishtml='.$msgishtml);
|
|
|
|
$texttosend = $this->makeSubstitution($text);
|
|
$subjecttosend = $this->makeSubstitution($subject);
|
|
if ($msgishtml) {
|
|
$texttosend = dol_htmlentitiesbr($texttosend);
|
|
}
|
|
|
|
// Send mail confirmation
|
|
$from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
|
|
|
|
$trackid = 'mem'.$this->id;
|
|
|
|
// Send email (substitutionarray must be done just before this)
|
|
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
|
|
$mailfile = new CMailFile($subjecttosend, (string) $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
|
|
if ($mailfile->sendfile()) {
|
|
return 1;
|
|
} else {
|
|
$this->error = $langs->trans("ErrorFailedToSendMail", $from, (string) $this->email).'. '.$mailfile->error;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Make substitution of tags into text with value of current object.
|
|
*
|
|
* @param string $text Text to make substitution to
|
|
* @return string Value of input text string with substitutions done
|
|
*/
|
|
public function makeSubstitution($text)
|
|
{
|
|
global $langs;
|
|
|
|
$birthday = dol_print_date($this->birth, 'day');
|
|
$photo = isset($this->photo) ? $this->photo : '';
|
|
$login = isset($this->login) ? $this->login : '';
|
|
$type = isset($this->type) ? $this->type : '';
|
|
$pass = isset($this->pass) ? $this->pass : '';
|
|
|
|
$msgishtml = 0;
|
|
if (dol_textishtml($text, 1)) {
|
|
$msgishtml = 1;
|
|
}
|
|
|
|
$infos = '';
|
|
if ($this->civility_id) {
|
|
$infos .= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
|
|
}
|
|
$infos .= $langs->transnoentities("Id").": ".$this->id."\n";
|
|
$infos .= $langs->transnoentities("Ref").": ".$this->ref."\n";
|
|
$infos .= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
|
|
$infos .= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
|
|
$infos .= $langs->transnoentities("Company").": ".$this->company."\n";
|
|
$infos .= $langs->transnoentities("Address").": ".$this->address."\n";
|
|
$infos .= $langs->transnoentities("Zip").": ".$this->zip."\n";
|
|
$infos .= $langs->transnoentities("Town").": ".$this->town."\n";
|
|
$infos .= $langs->transnoentities("Country").": ".$this->country."\n";
|
|
$infos .= $langs->transnoentities("EMail").": ".$this->email."\n";
|
|
$infos .= $langs->transnoentities("PhonePro").": ".$this->phone."\n";
|
|
$infos .= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n";
|
|
$infos .= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n";
|
|
if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
|
|
$infos .= $langs->transnoentities("Login").": ".$login."\n";
|
|
$infos .= $langs->transnoentities("Password").": ".$pass."\n";
|
|
}
|
|
$infos .= $langs->transnoentities("Birthday").": ".$birthday."\n";
|
|
$infos .= $langs->transnoentities("Photo").": ".$photo."\n";
|
|
$infos .= $langs->transnoentities("Public").": ".yn($this->public);
|
|
|
|
// Substitutions
|
|
$substitutionarray = array(
|
|
'__ID__' => $this->id,
|
|
'__REF__' => $this->ref,
|
|
'__MEMBER_ID__' => $this->id,
|
|
'__CIVILITY__' => $this->getCivilityLabel(),
|
|
'__FIRSTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->firstname) : ($this->firstname ? $this->firstname : ''),
|
|
'__LASTNAME__' => $msgishtml ? dol_htmlentitiesbr($this->lastname) : ($this->lastname ? $this->lastname : ''),
|
|
'__FULLNAME__' => $msgishtml ? dol_htmlentitiesbr($this->getFullName($langs)) : $this->getFullName($langs),
|
|
'__COMPANY__' => $msgishtml ? dol_htmlentitiesbr((string) $this->company) : ($this->company ? $this->company : ''),
|
|
'__ADDRESS__' => $msgishtml ? dol_htmlentitiesbr((string) $this->address) : ($this->address ? $this->address : ''),
|
|
'__ZIP__' => $msgishtml ? dol_htmlentitiesbr((string) $this->zip) : ($this->zip ? $this->zip : ''),
|
|
'__TOWN__' => $msgishtml ? dol_htmlentitiesbr((string) $this->town) : ($this->town ? $this->town : ''),
|
|
'__COUNTRY__' => $msgishtml ? dol_htmlentitiesbr($this->country) : ($this->country ? $this->country : ''),
|
|
'__EMAIL__' => $msgishtml ? dol_htmlentitiesbr((string) $this->email) : ($this->email ? $this->email : ''),
|
|
'__BIRTH__' => $msgishtml ? dol_htmlentitiesbr($birthday) : ($birthday ? $birthday : ''),
|
|
'__PHOTO__' => $msgishtml ? dol_htmlentitiesbr($photo) : $photo,
|
|
'__LOGIN__' => $msgishtml ? dol_htmlentitiesbr($login) : $login,
|
|
'__PASSWORD__' => $msgishtml ? dol_htmlentitiesbr($pass) : $pass,
|
|
'__PHONE__' => $msgishtml ? dol_htmlentitiesbr($this->phone) : ($this->phone ? $this->phone : ''),
|
|
'__PHONEPRO__' => $msgishtml ? dol_htmlentitiesbr($this->phone_perso) : ($this->phone_perso ? $this->phone_perso : ''),
|
|
'__PHONEMOBILE__' => $msgishtml ? dol_htmlentitiesbr($this->phone_mobile) : ($this->phone_mobile ? $this->phone_mobile : ''),
|
|
'__TYPE__' => $msgishtml ? dol_htmlentitiesbr($type) : $type,
|
|
);
|
|
|
|
complete_substitutions_array($substitutionarray, $langs, $this);
|
|
|
|
return make_substitutions($text, $substitutionarray, $langs);
|
|
}
|
|
|
|
|
|
/**
|
|
* Return translated label by the nature of a adherent (physical or moral)
|
|
*
|
|
* @param string $morphy Nature of the adherent (physical or moral)
|
|
* @param int<0,2> $addbadge Add badge (1=Full label, 2=First letters only)
|
|
* @return string Label
|
|
*/
|
|
public function getmorphylib($morphy = '', $addbadge = 0)
|
|
{
|
|
global $langs;
|
|
$s = '';
|
|
|
|
// Clean var
|
|
if (!$morphy) {
|
|
$morphy = $this->morphy;
|
|
}
|
|
|
|
if ($addbadge) {
|
|
$labeltoshowm = $langs->trans("Moral");
|
|
$labeltoshowp = $langs->trans("Physical");
|
|
if ($morphy == 'phy') {
|
|
$labeltoshow = $labeltoshowp;
|
|
if ($addbadge == 2) {
|
|
$labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp));
|
|
if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowm))) {
|
|
$labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowp, 2));
|
|
}
|
|
}
|
|
$s .= '<span class="member-individual-back paddingleftimp paddingrightimp" title="'.$langs->trans("Physical").'">'.$labeltoshow.'</span>';
|
|
}
|
|
if ($morphy == 'mor') {
|
|
$labeltoshow = $labeltoshowm;
|
|
if ($addbadge == 2) {
|
|
$labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm));
|
|
if ($labeltoshow == dol_strtoupper(dolGetFirstLetters($labeltoshowp))) {
|
|
$labeltoshow = dol_strtoupper(dolGetFirstLetters($labeltoshowm, 2));
|
|
}
|
|
}
|
|
$s .= '<span class="member-company-back paddingleftimp paddingrightimp" title="'.$langs->trans("Moral").'">'.$labeltoshow.'</span>';
|
|
}
|
|
} else {
|
|
if ($morphy == 'phy') {
|
|
$s = $langs->trans("Physical");
|
|
} elseif ($morphy == 'mor') {
|
|
$s = $langs->trans("Moral");
|
|
}
|
|
}
|
|
|
|
return $s;
|
|
}
|
|
|
|
/**
|
|
* Create a member into database
|
|
*
|
|
* @param User $user Object user qui demande la creation
|
|
* @param int $notrigger 1 ne declenche pas les triggers, 0 sinon
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function create($user, $notrigger = 0)
|
|
{
|
|
global $langs, $mysoc;
|
|
|
|
$error = 0;
|
|
|
|
$now = dol_now();
|
|
|
|
// Clean parameters
|
|
if (isset($this->import_key)) {
|
|
$this->import_key = trim($this->import_key);
|
|
}
|
|
|
|
// Check parameters
|
|
if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail((string) $this->email)) {
|
|
$langs->load("errors");
|
|
$this->error = $langs->trans("ErrorBadEMail", (string) $this->email);
|
|
return -1;
|
|
}
|
|
if (!$this->datec) {
|
|
$this->datec = $now;
|
|
}
|
|
if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
|
|
if (empty($this->login)) {
|
|
$this->error = $langs->trans("ErrorWrongValueForParameterX", "Login");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// setEntity will set entity with the right value if empty or change it for the right value if multicompany module is active
|
|
$this->entity = setEntity($this);
|
|
|
|
$this->db->begin();
|
|
|
|
// Insert member
|
|
$sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
|
|
$sql .= " (ref, datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key, ip)";
|
|
$sql .= " VALUES (";
|
|
$sql .= " '(PROV)'";
|
|
$sql .= ", '".$this->db->idate($this->datec)."'";
|
|
$sql .= ", ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
|
|
$sql .= ", ".($user->id > 0 ? $user->id : "null"); // Can be null because member can be created by a guest or a script
|
|
$sql .= ", null, null, '".$this->db->escape($this->morphy)."'";
|
|
$sql .= ", ".((int) $this->typeid);
|
|
$sql .= ", ".((int) $this->entity);
|
|
$sql .= ", ".(!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null");
|
|
$sql .= ", ".(!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
|
|
$sql .= ")";
|
|
|
|
dol_syslog(get_class($this)."::create", LOG_DEBUG);
|
|
$result = $this->db->query($sql);
|
|
if ($result) {
|
|
$id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
|
|
if ($id > 0) {
|
|
$this->id = $id;
|
|
if (getDolGlobalString('MEMBER_CODEMEMBER_ADDON') == '') {
|
|
// keep old numbering
|
|
$this->ref = (string) $id;
|
|
} else {
|
|
// auto code
|
|
$modfile = dol_buildpath('core/modules/member/'.getDolGlobalString('MEMBER_CODEMEMBER_ADDON').'.php', 0);
|
|
try {
|
|
require_once $modfile;
|
|
$modname = getDolGlobalString('MEMBER_CODEMEMBER_ADDON');
|
|
$modCodeMember = new $modname();
|
|
'@phan-var-force ModeleNumRefMembers $modCodeMember';
|
|
/** @var ModeleNumRefMembers $modCodeMember */
|
|
$this->ref = $modCodeMember->getNextValue($mysoc, $this);
|
|
} catch (Exception $e) {
|
|
dol_syslog($e->getMessage(), LOG_ERR);
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
// Update minor fields
|
|
$result = $this->update($user, 1, 1, 0, 0, 'add'); // nosync is 1 to avoid update data of user
|
|
if ($result < 0) {
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
|
|
// Add link to user
|
|
if ($this->user_id) {
|
|
// Add link to user
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
|
|
$sql .= " fk_member = ".((int) $this->id);
|
|
$sql .= " WHERE rowid = ".((int) $this->user_id);
|
|
dol_syslog(get_class($this)."::create", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$this->error = 'Failed to update user to make link with member';
|
|
$this->db->rollback();
|
|
return -4;
|
|
}
|
|
}
|
|
|
|
if (!$notrigger) {
|
|
// Call trigger
|
|
$result = $this->call_trigger('MEMBER_CREATE', $user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
}
|
|
// End call triggers
|
|
}
|
|
|
|
if (count($this->errors)) {
|
|
dol_syslog(get_class($this)."::create ".implode(',', $this->errors), LOG_ERR);
|
|
$this->db->rollback();
|
|
return -3;
|
|
} else {
|
|
$this->db->commit();
|
|
return $this->id;
|
|
}
|
|
} else {
|
|
$this->error = 'Failed to get last insert id';
|
|
dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
|
|
$this->db->rollback();
|
|
return -2;
|
|
}
|
|
} else {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Update a member in database (standard information and password)
|
|
*
|
|
* @param User $user User making update
|
|
* @param int $notrigger 1=disable trigger UPDATE (when called by create)
|
|
* @param int $nosyncuser 0=Synchronize linked user (standard info), 1=Do not synchronize linked user
|
|
* @param int $nosyncuserpass 0=Synchronize linked user (password), 1=Do not synchronize linked user
|
|
* @param int $nosyncthirdparty 0=Synchronize linked thirdparty (standard info), 1=Do not synchronize linked thirdparty
|
|
* @param string $action Current action for hookmanager
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function update($user, $notrigger = 0, $nosyncuser = 0, $nosyncuserpass = 0, $nosyncthirdparty = 0, $action = 'update')
|
|
{
|
|
global $langs, $hookmanager;
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
|
|
|
if (empty($this->country_id) && !empty($this->country_code)) {
|
|
$country_id = getCountry($this->country_code, '3');
|
|
$this->country_id = is_int($country_id) ? $country_id : 0;
|
|
}
|
|
|
|
$nbrowsaffected = 0;
|
|
$error = 0;
|
|
|
|
dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
|
|
|
|
// Clean parameters
|
|
$this->lastname = trim($this->lastname) ? trim($this->lastname) : trim($this->lastname);
|
|
$this->firstname = trim($this->firstname) ? trim($this->firstname) : trim($this->firstname);
|
|
$this->gender = trim($this->gender);
|
|
// $this->address = ($this->address ? $this->address : $this->address);
|
|
// $this->zip = ($this->zip ? $this->zip : $this->zip);
|
|
// $this->town = ($this->town ? $this->town : $this->town);
|
|
// $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
|
|
// $this->state_id = ($this->state_id > 0 ? $this->state_id : $this->state_id);
|
|
// $this->note_public = ($this->note_public ? $this->note_public : $this->note_public);
|
|
// $this->note_private = ($this->note_private ? $this->note_private : $this->note_private);
|
|
$this->url = $this->url ? clean_url($this->url, 0) : '';
|
|
$this->setUpperOrLowerCase();
|
|
|
|
// Check parameters
|
|
if (getDolGlobalString('ADHERENT_MAIL_REQUIRED') && !isValidEmail((string) $this->email)) {
|
|
$langs->load("errors");
|
|
$this->error = $langs->trans("ErrorBadEMail", (string) $this->email);
|
|
return -1;
|
|
}
|
|
|
|
$this->db->begin();
|
|
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
|
|
$sql .= " ref = '".$this->db->escape($this->ref)."'";
|
|
$sql .= ", ref_ext = ".(empty($this->ref_ext) ? "null" : "'".$this->db->escape($this->ref_ext)."'");
|
|
$sql .= ", civility = ".($this->civility_id ? "'".$this->db->escape($this->civility_id)."'" : "null");
|
|
$sql .= ", firstname = ".($this->firstname ? "'".$this->db->escape($this->firstname)."'" : "null");
|
|
$sql .= ", lastname = ".($this->lastname ? "'".$this->db->escape($this->lastname)."'" : "null");
|
|
$sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
|
|
$sql .= ", login = ".($this->login ? "'".$this->db->escape($this->login)."'" : "null");
|
|
$sql .= ", societe = ".($this->company ? "'".$this->db->escape($this->company)."'" : ($this->societe ? "'".$this->db->escape($this->societe)."'" : "null"));
|
|
if ($this->socid) {
|
|
$sql .= ", fk_soc = ".($this->socid > 0 ? (int) $this->socid : "null"); // Must be modified only when creating from a third-party
|
|
}
|
|
$sql .= ", address = ".($this->address ? "'".$this->db->escape($this->address)."'" : "null");
|
|
$sql .= ", zip = ".($this->zip ? "'".$this->db->escape($this->zip)."'" : "null");
|
|
$sql .= ", town = ".($this->town ? "'".$this->db->escape($this->town)."'" : "null");
|
|
$sql .= ", country = ".($this->country_id > 0 ? (int) $this->country_id : "null");
|
|
$sql .= ", state_id = ".($this->state_id > 0 ? (int) $this->state_id : "null");
|
|
$sql .= ", email = '".$this->db->escape((string) $this->email)."'";
|
|
$sql .= ", url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null");
|
|
$sql .= ", socialnetworks = ".($this->socialnetworks ? "'".$this->db->escape(json_encode($this->socialnetworks))."'" : "null");
|
|
$sql .= ", phone = ".($this->phone ? "'".$this->db->escape($this->phone)."'" : "null");
|
|
$sql .= ", phone_perso = ".($this->phone_perso ? "'".$this->db->escape($this->phone_perso)."'" : "null");
|
|
$sql .= ", phone_mobile = ".($this->phone_mobile ? "'".$this->db->escape($this->phone_mobile)."'" : "null");
|
|
$sql .= ", note_private = ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
|
|
$sql .= ", note_public = ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null");
|
|
$sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null");
|
|
$sql .= ", public = ".(int) $this->public;
|
|
$sql .= ", statut = ".(int) $this->statut;
|
|
$sql .= ", default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null");
|
|
$sql .= ", fk_adherent_type = ".(int) $this->typeid;
|
|
$sql .= ", morphy = '".$this->db->escape($this->morphy)."'";
|
|
$sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null");
|
|
|
|
if ($this->datefin) {
|
|
$sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
|
|
}
|
|
if ($this->datevalid) {
|
|
$sql .= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member
|
|
}
|
|
$sql .= ", fk_user_mod = ".($user->id > 0 ? $user->id : 'null'); // Can be null because member can be create by a guest
|
|
$sql .= " WHERE rowid = ".((int) $this->id);
|
|
|
|
// If we change the type of membership, we set also label of new type..
|
|
'@phan-var-force Adherent $oldcopy';
|
|
if (!empty($this->oldcopy) && $this->typeid != $this->oldcopy->typeid) {
|
|
$sql2 = "SELECT libelle as label";
|
|
$sql2 .= " FROM ".MAIN_DB_PREFIX."adherent_type";
|
|
$sql2 .= " WHERE rowid = ".((int) $this->typeid);
|
|
$resql2 = $this->db->query($sql2);
|
|
if ($resql2) {
|
|
while ($obj = $this->db->fetch_object($resql2)) {
|
|
$this->type = $obj->label;
|
|
}
|
|
}
|
|
}
|
|
|
|
dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
unset($this->country_code);
|
|
unset($this->country);
|
|
unset($this->state_code);
|
|
unset($this->state);
|
|
|
|
$nbrowsaffected += $this->db->affected_rows($resql);
|
|
|
|
$action = 'update';
|
|
|
|
// Actions on extra fields
|
|
$result = $this->insertExtraFields();
|
|
if ($result < 0) {
|
|
$error++;
|
|
}
|
|
|
|
// Update password
|
|
if (!$error && $this->pass) {
|
|
dol_syslog(get_class($this)."::update update password");
|
|
if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted) {
|
|
$isencrypted = getDolGlobalString('DATABASE_PWD_ENCRYPTED') ? 1 : 0;
|
|
|
|
// If password to set differs from the one found into database
|
|
$result = $this->setPassword($user, $this->pass, $isencrypted, $notrigger, $nosyncuserpass);
|
|
if (!$nbrowsaffected) {
|
|
$nbrowsaffected++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove links to user and replace with new one
|
|
if (!$error) {
|
|
dol_syslog(get_class($this)."::update update link to user");
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
|
|
dol_syslog(get_class($this)."::update", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -5;
|
|
}
|
|
// If there is a user linked to this member
|
|
if ($this->user_id > 0) {
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id)." WHERE rowid = ".((int) $this->user_id);
|
|
dol_syslog(get_class($this)."::update", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -5;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error && $nbrowsaffected) { // If something has change in main data
|
|
// Update information on linked user if it is an update
|
|
if ($this->user_id > 0 && !$nosyncuser) {
|
|
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
|
|
|
|
dol_syslog(get_class($this)."::update update linked user");
|
|
|
|
$luser = new User($this->db);
|
|
$result = $luser->fetch($this->user_id);
|
|
|
|
if ($result >= 0) {
|
|
// If option ADHERENT_LOGIN_NOT_REQUIRED is on, there is no login of member, so we do not overwrite user login to keep existing one.
|
|
if (!getDolGlobalString('ADHERENT_LOGIN_NOT_REQUIRED')) {
|
|
$luser->login = $this->login;
|
|
}
|
|
|
|
$luser->ref = $this->ref;
|
|
$luser->civility_id = $this->civility_id;
|
|
$luser->firstname = $this->firstname;
|
|
$luser->lastname = $this->lastname;
|
|
$luser->gender = $this->gender;
|
|
$luser->pass = isset($this->pass) ? $this->pass : '';
|
|
//$luser->socid=$this->fk_soc; // We do not enable this. This may transform a user into an external user.
|
|
|
|
$luser->birth = $this->birth;
|
|
|
|
$luser->address = $this->address;
|
|
$luser->zip = $this->zip;
|
|
$luser->town = $this->town;
|
|
$luser->country_id = $this->country_id;
|
|
$luser->state_id = $this->state_id;
|
|
|
|
$luser->email = $this->email;
|
|
$luser->socialnetworks = $this->socialnetworks;
|
|
$luser->office_phone = $this->phone;
|
|
$luser->user_mobile = $this->phone_mobile;
|
|
|
|
$luser->lang = $this->default_lang;
|
|
|
|
$luser->fk_member = $this->id;
|
|
|
|
$result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates
|
|
if ($result < 0) {
|
|
$this->error = $luser->error;
|
|
dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
|
|
$error++;
|
|
}
|
|
} else {
|
|
$this->error = $luser->error;
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
// Update information on linked thirdparty if it is an update
|
|
if (!$error && $this->socid > 0 && !$nosyncthirdparty) {
|
|
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
|
|
|
|
dol_syslog(get_class($this)."::update update linked thirdparty");
|
|
|
|
// This member is linked with a thirdparty, so we also update thirdparty information
|
|
// if this is an update.
|
|
$lthirdparty = new Societe($this->db);
|
|
$result = $lthirdparty->fetch($this->socid);
|
|
|
|
if ($result > 0) {
|
|
$lthirdparty->address = $this->address;
|
|
$lthirdparty->zip = $this->zip;
|
|
$lthirdparty->town = $this->town;
|
|
$lthirdparty->email = $this->email;
|
|
$lthirdparty->socialnetworks = $this->socialnetworks;
|
|
$lthirdparty->phone = $this->phone;
|
|
$lthirdparty->state_id = $this->state_id;
|
|
$lthirdparty->country_id = $this->country_id;
|
|
//$lthirdparty->phone_mobile=$this->phone_mobile;
|
|
$lthirdparty->default_lang = $this->default_lang;
|
|
|
|
$result = $lthirdparty->update($this->socid, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
|
|
|
|
if ($result < 0) {
|
|
$this->error = $lthirdparty->error;
|
|
$this->errors = $lthirdparty->errors;
|
|
dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
|
|
$error++;
|
|
}
|
|
} elseif ($result < 0) {
|
|
$this->error = $lthirdparty->error;
|
|
$error++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error && !$notrigger) {
|
|
// Call trigger
|
|
$result = $this->call_trigger('MEMBER_MODIFY', $user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
}
|
|
// End call triggers
|
|
}
|
|
|
|
if (!$error) {
|
|
$this->db->commit();
|
|
return $nbrowsaffected;
|
|
} else {
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
} else {
|
|
$this->db->rollback();
|
|
$this->error = $this->db->lasterror();
|
|
return -2;
|
|
}
|
|
}
|
|
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Update denormalized last subscription date.
|
|
* This function is called when we delete a subscription for example.
|
|
*
|
|
* @param User $user User making change
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function update_end_date($user)
|
|
{
|
|
// phpcs:enable
|
|
$this->db->begin();
|
|
|
|
// Search for last subscription id and end date
|
|
$sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."subscription";
|
|
$sql .= " WHERE fk_adherent = ".((int) $this->id);
|
|
$sql .= " ORDER by dateadh DESC"; // Sort by start subscription date
|
|
|
|
dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$obj = $this->db->fetch_object($resql);
|
|
$dateop = $this->db->jdate($obj->dateop);
|
|
$datedeb = $this->db->jdate($obj->datedeb);
|
|
$datefin = $this->db->jdate($obj->datefin);
|
|
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
|
|
$sql .= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
|
|
$sql .= " WHERE rowid = ".((int) $this->id);
|
|
|
|
dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$this->last_subscription_date = $dateop;
|
|
$this->last_subscription_date_start = $datedeb;
|
|
$this->last_subscription_date_end = $datefin;
|
|
$this->datefin = $datefin;
|
|
$this->db->commit();
|
|
return 1;
|
|
} else {
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
} else {
|
|
$this->error = $this->db->lasterror();
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fonction to delete a member and its data
|
|
*
|
|
* @param User $user User object
|
|
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
* @return int Return integer <0 if KO, 0=nothing to do, >0 if OK
|
|
*/
|
|
public function delete($user, $notrigger = 0)
|
|
{
|
|
$result = 0;
|
|
$error = 0;
|
|
$errorflag = 0;
|
|
|
|
// Check parameters
|
|
$rowid = $this->id;
|
|
|
|
$this->db->begin();
|
|
|
|
if (!$notrigger) {
|
|
// Call trigger
|
|
$result = $this->call_trigger('MEMBER_DELETE', $user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
}
|
|
// End call triggers
|
|
}
|
|
|
|
// Remove category
|
|
$sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".((int) $rowid);
|
|
dol_syslog(get_class($this)."::delete", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$this->error .= $this->db->lasterror();
|
|
$errorflag = -1;
|
|
}
|
|
|
|
// Remove subscription
|
|
if (!$error) {
|
|
$sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".((int) $rowid);
|
|
dol_syslog(get_class($this)."::delete", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$this->error .= $this->db->lasterror();
|
|
$errorflag = -2;
|
|
}
|
|
}
|
|
|
|
// Remove linked user
|
|
if (!$error) {
|
|
$ret = $this->setUserId(0);
|
|
if ($ret < 0) {
|
|
$error++;
|
|
$this->error .= $this->db->lasterror();
|
|
$errorflag = -3;
|
|
}
|
|
}
|
|
|
|
// Removed extrafields
|
|
if (!$error) {
|
|
$result = $this->deleteExtraFields();
|
|
if ($result < 0) {
|
|
$error++;
|
|
$errorflag = -4;
|
|
dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
|
|
}
|
|
}
|
|
|
|
// Remove adherent
|
|
if (!$error) {
|
|
$sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".((int) $rowid);
|
|
dol_syslog(get_class($this)."::delete", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$this->error .= $this->db->lasterror();
|
|
$errorflag = -5;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$this->db->commit();
|
|
return 1;
|
|
} else {
|
|
$this->db->rollback();
|
|
return $errorflag;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Merge a member with current one, deleting the given company $member_origin_id.
|
|
* The member given in parameter will be removed.
|
|
* This is called for example by the adherent/card.php file.
|
|
* It calls the method replaceMember() of each object with relation with member,
|
|
* including hook 'replaceMember' for external modules.
|
|
*
|
|
* @param int $member_origin_id Member to merge the data from
|
|
* @return int -1 if error, >=0 if OK
|
|
*/
|
|
public function mergeMembers($member_origin_id)
|
|
{
|
|
global $conf, $langs, $hookmanager, $user, $action;
|
|
|
|
$error = 0;
|
|
$member_origin = new Adherent($this->db); // The member that we will delete
|
|
|
|
dol_syslog("mergeMembers merge member id=".$member_origin_id." (will be deleted) into the member id=".$this->id);
|
|
if ($member_origin->fetch($member_origin_id) < 1) {
|
|
$this->error = $langs->trans('ErrorRecordNotFound');
|
|
$error++;
|
|
}
|
|
|
|
if (!$error) {
|
|
$this->db->begin();
|
|
$listofproperties = array(
|
|
'ref_ext', 'civility', 'lastname', 'firstname', 'morphy', 'societe', 'socid', 'user_id','address',
|
|
'zip', 'town', 'state_id', 'country', 'phone', 'phone_perso', 'phone_mobile', 'email',
|
|
'url', 'socialnetworks', 'birth', 'gender', 'photo', 'public', 'datefin', 'default_lang',
|
|
'canvas', 'model_pdf', 'import_key'
|
|
);
|
|
foreach ($listofproperties as $property) {
|
|
if (empty($this->$property)) {
|
|
$this->$property = $member_origin->$property;
|
|
}
|
|
}
|
|
|
|
// Concat some data
|
|
$listofproperties = array(
|
|
'note_public', 'note_private'
|
|
);
|
|
foreach ($listofproperties as $property) {
|
|
$this->$property = dol_concatdesc($this->$property, $member_origin->$property);
|
|
}
|
|
|
|
// Merge extrafields
|
|
if (is_array($member_origin->array_options)) {
|
|
foreach ($member_origin->array_options as $key => $val) {
|
|
if (empty($this->array_options[$key])) {
|
|
$this->array_options[$key] = $val;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Merge categories
|
|
include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
|
|
$static_cat = new Categorie($this->db);
|
|
$custcats_ori = $static_cat->containing($member_origin->id, 'member', 'id');
|
|
$custcats = $static_cat->containing($this->id, 'member', 'id');
|
|
$custcats = array_merge($custcats, $custcats_ori);
|
|
$this->setCategories($custcats);
|
|
|
|
$result = $this->update($user, 1, 1, 1, 1, 'merge');
|
|
if ($result < 0) {
|
|
$error++;
|
|
}
|
|
|
|
// Merge subscriptions
|
|
if (!$error && $member_origin->fetch_subscriptions() < 1) {
|
|
$error++;
|
|
}
|
|
|
|
if (!$error) {
|
|
foreach ($member_origin->subscriptions as $key => $subscription) {
|
|
$subscription->fk_adherent = $this->id;
|
|
$result = $subscription->update($user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// External modules should update their ones too
|
|
if (!$error) {
|
|
$parameters = array('member_origin' => $member_origin->id, 'member_dest' => $this->id);
|
|
$reshook = $hookmanager->executeHooks('replaceMember', $parameters, $this, $action);
|
|
|
|
if ($reshook < 0) {
|
|
$this->setErrorsFromObject($hookmanager);
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$this->context = array('merge' => 1, 'mergefromid' => $member_origin->id);
|
|
|
|
// Call trigger
|
|
$result = $this->call_trigger('MEMBER_MODIFY', $user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
}
|
|
// End call triggers
|
|
}
|
|
|
|
if (!$error) {
|
|
// We finally remove the old member
|
|
if ($member_origin->delete($user) < 1) {
|
|
$this->setErrorsFromObject($member_origin);
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
// Move files from the dir of the third party to delete into the dir of the third party to keep
|
|
if (!empty($conf->adherent->multidir_output[$this->entity])) {
|
|
$srcdir = $conf->adherent->multidir_output[$this->entity]."/".$member_origin->id;
|
|
$destdir = $conf->adherent->multidir_output[$this->entity]."/".$this->id;
|
|
|
|
if (dol_is_dir($srcdir)) {
|
|
$dirlist = dol_dir_list($srcdir, 'files', 1);
|
|
foreach ($dirlist as $filetomove) {
|
|
$destfile = $destdir.'/'.$filetomove['relativename'];
|
|
$result = dol_move($filetomove['fullname'], $destfile, '0', 0, 0, 1);
|
|
if (!$result) {
|
|
$error++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
$this->db->commit();
|
|
return 0;
|
|
} else {
|
|
$langs->load("errors");
|
|
$this->error = $langs->trans('ErrorMembersMerge');
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Change password of a user
|
|
*
|
|
* @param User $user Object user de l'utilisateur qui fait la modification
|
|
* @param string $password New password (to generate if empty)
|
|
* @param int $isencrypted 0 ou 1 if the password needs to be encrypted in the DB (default: 0)
|
|
* @param int $notrigger 1=Does not raise the triggers
|
|
* @param int $nosyncuser Do not synchronize linked user
|
|
* @return string|int Clear password if change ok, 0 if no change, <0 if error
|
|
*/
|
|
public function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
|
|
{
|
|
global $conf, $langs;
|
|
|
|
$error = 0;
|
|
|
|
dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i', '*', $password)." isencrypted=".$isencrypted);
|
|
|
|
// If new password not provided, we generate one
|
|
if (!$password) {
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
|
|
$password = getRandomPassword(false);
|
|
}
|
|
|
|
// Crypt password
|
|
$password_crypted = dol_hash($password);
|
|
|
|
$password_indatabase = '';
|
|
if (!$isencrypted) {
|
|
$password_indatabase = $password;
|
|
}
|
|
|
|
$this->db->begin();
|
|
|
|
// Mise a jour
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
|
|
$sql .= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
|
|
if ($isencrypted) {
|
|
$sql .= ", pass = null";
|
|
} else {
|
|
$sql .= ", pass = '".$this->db->escape($password_indatabase)."'";
|
|
}
|
|
$sql .= " WHERE rowid = ".((int) $this->id);
|
|
|
|
//dol_syslog("Adherent::Password sql=hidden");
|
|
dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
|
|
$result = $this->db->query($sql);
|
|
if ($result) {
|
|
$nbaffectedrows = $this->db->affected_rows($result);
|
|
|
|
if ($nbaffectedrows) {
|
|
$this->pass = $password;
|
|
$this->pass_indatabase = $password_indatabase;
|
|
$this->pass_indatabase_crypted = $password_crypted;
|
|
|
|
if ($this->user_id && !$nosyncuser) {
|
|
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
|
|
|
|
// This member is linked with a user, so we also update users information
|
|
// if this is an update.
|
|
$luser = new User($this->db);
|
|
$result = $luser->fetch($this->user_id);
|
|
|
|
if ($result >= 0) {
|
|
$result = $luser->setPassword($user, $this->pass, 0, 0, 1);
|
|
if (is_int($result) && $result < 0) {
|
|
$this->error = $luser->error;
|
|
dol_syslog(get_class($this)."::setPassword ".$this->error, LOG_ERR);
|
|
$error++;
|
|
}
|
|
} else {
|
|
$this->error = $luser->error;
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error && !$notrigger) {
|
|
// Call trigger
|
|
$result = $this->call_trigger('MEMBER_NEW_PASSWORD', $user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
// End call triggers
|
|
}
|
|
|
|
$this->db->commit();
|
|
return $this->pass;
|
|
} else {
|
|
$this->db->rollback();
|
|
return 0;
|
|
}
|
|
} else {
|
|
$this->db->rollback();
|
|
dol_print_error($this->db);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Set link to a user
|
|
*
|
|
* @param int $userid Id of user to link to
|
|
* @return int 1=OK, -1=KO
|
|
*/
|
|
public function setUserId($userid)
|
|
{
|
|
global $conf, $langs;
|
|
|
|
$this->db->begin();
|
|
|
|
// If user is linked to this member, remove old link to this member
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".((int) $this->id);
|
|
dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
|
|
// Set link to user
|
|
if ($userid > 0) {
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".((int) $this->id);
|
|
$sql .= " WHERE rowid = ".((int) $userid);
|
|
dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -2;
|
|
}
|
|
}
|
|
|
|
$this->db->commit();
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
/**
|
|
* Set link to a third party
|
|
*
|
|
* @param int $thirdpartyid Id of user to link to
|
|
* @return int 1=OK, -1=KO
|
|
*/
|
|
public function setThirdPartyId($thirdpartyid)
|
|
{
|
|
global $conf, $langs;
|
|
|
|
$this->db->begin();
|
|
|
|
// Remove link to third party onto any other members
|
|
if ($thirdpartyid > 0) {
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
|
|
$sql .= " WHERE fk_soc = ".((int) $thirdpartyid);
|
|
$sql .= " AND entity = ".$conf->entity;
|
|
dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
}
|
|
|
|
// Add link to third party for current member
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid > 0 ? (int) $thirdpartyid : 'null');
|
|
$sql .= " WHERE rowid = ".((int) $this->id);
|
|
|
|
dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$this->db->commit();
|
|
return 1;
|
|
} else {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Method to load member from its login
|
|
*
|
|
* @param string $login login of member
|
|
* @return void
|
|
*/
|
|
public function fetch_login($login)
|
|
{
|
|
// phpcs:enable
|
|
global $conf;
|
|
|
|
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
|
|
$sql .= " WHERE login='".$this->db->escape($login)."'";
|
|
$sql .= " AND entity = ".$conf->entity;
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
if ($this->db->num_rows($resql)) {
|
|
$obj = $this->db->fetch_object($resql);
|
|
$this->fetch($obj->rowid);
|
|
}
|
|
} else {
|
|
dol_print_error($this->db);
|
|
}
|
|
}
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Method to load member from its name
|
|
*
|
|
* @param string $firstname Firstname
|
|
* @param string $lastname Lastname
|
|
* @return void
|
|
*/
|
|
public function fetch_name($firstname, $lastname)
|
|
{
|
|
// phpcs:enable
|
|
global $conf;
|
|
|
|
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
|
|
$sql .= " WHERE firstname='".$this->db->escape($firstname)."'";
|
|
$sql .= " AND lastname='".$this->db->escape($lastname)."'";
|
|
$sql .= " AND entity = ".$conf->entity;
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
if ($this->db->num_rows($resql)) {
|
|
$obj = $this->db->fetch_object($resql);
|
|
$this->fetch($obj->rowid);
|
|
}
|
|
} else {
|
|
dol_print_error($this->db);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load member from database
|
|
*
|
|
* @param int $rowid Id of object to load
|
|
* @param string $ref To load member from its ref
|
|
* @param int $socid To load member from its link to third party
|
|
* @param string $ref_ext External reference
|
|
* @param bool $fetch_optionals To load optionals (extrafields)
|
|
* @param bool $fetch_subscriptions To load member subscriptions
|
|
* @return int >0 if OK, 0 if not found, <0 if KO
|
|
*/
|
|
public function fetch($rowid, $ref = '', $socid = 0, $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
|
|
{
|
|
global $langs;
|
|
|
|
$sql = "SELECT d.rowid, d.ref, d.ref_ext, d.civility as civility_code, d.gender, d.firstname, d.lastname,";
|
|
$sql .= " d.societe as company, d.fk_soc as socid, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
|
|
$sql .= " d.note_public,";
|
|
$sql .= " d.email, d.url, d.socialnetworks, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
|
|
$sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
|
|
$sql .= " d.datec as datec,";
|
|
$sql .= " GREATEST(d.tms, aef.tms) as datem,";
|
|
$sql .= " d.datefin as datefin, d.default_lang,";
|
|
$sql .= " d.birth as birthday,";
|
|
$sql .= " d.datevalid as datev,";
|
|
$sql .= " d.country,";
|
|
$sql .= " d.state_id,";
|
|
$sql .= " d.model_pdf,";
|
|
$sql .= " c.rowid as country_id, c.code as country_code, c.label as country,";
|
|
$sql .= " dep.nom as state, dep.code_departement as state_code,";
|
|
$sql .= " t.libelle as type, t.subscription as subscription,";
|
|
$sql .= " u.rowid as user_id, u.login as user_login";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
|
|
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'adherent_extrafields as aef ON aef.fk_object = d.rowid';
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
|
|
$sql .= " WHERE d.fk_adherent_type = t.rowid";
|
|
if ($rowid) {
|
|
$sql .= " AND d.rowid=".((int) $rowid);
|
|
} elseif ($ref || $socid) {
|
|
$sql .= " AND d.entity IN (".getEntity('adherent').")";
|
|
if ($ref) {
|
|
$sql .= " AND d.ref='".$this->db->escape($ref)."'";
|
|
} elseif ($socid > 0) {
|
|
$sql .= " AND d.fk_soc=".((int) $socid);
|
|
}
|
|
} elseif ($ref_ext) {
|
|
$sql .= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
|
|
}
|
|
|
|
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
if ($this->db->num_rows($resql)) {
|
|
$obj = $this->db->fetch_object($resql);
|
|
|
|
$this->entity = $obj->entity;
|
|
$this->id = $obj->rowid;
|
|
$this->ref = $obj->ref;
|
|
$this->ref_ext = $obj->ref_ext;
|
|
|
|
$this->civility_id = $obj->civility_code; // Bad. Kept for backward compatibility
|
|
$this->civility_code = $obj->civility_code;
|
|
$this->civility = $obj->civility_code ? ($langs->trans("Civility".$obj->civility_code) != "Civility".$obj->civility_code ? $langs->trans("Civility".$obj->civility_code) : $obj->civility_code) : '';
|
|
|
|
$this->firstname = $obj->firstname;
|
|
$this->lastname = $obj->lastname;
|
|
$this->gender = $obj->gender;
|
|
$this->login = $obj->login;
|
|
$this->societe = $obj->company;
|
|
$this->company = $obj->company;
|
|
$this->socid = $obj->socid;
|
|
$this->fk_soc = $obj->socid; // For backward compatibility
|
|
$this->address = $obj->address;
|
|
$this->zip = $obj->zip;
|
|
$this->town = $obj->town;
|
|
|
|
$this->pass = $obj->pass;
|
|
$this->pass_indatabase = $obj->pass;
|
|
$this->pass_indatabase_crypted = $obj->pass_crypted;
|
|
|
|
$this->state_id = $obj->state_id;
|
|
$this->state_code = $obj->state_id ? $obj->state_code : '';
|
|
$this->state = $obj->state_id ? $obj->state : '';
|
|
|
|
$this->country_id = $obj->country_id;
|
|
$this->country_code = $obj->country_code;
|
|
if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code) {
|
|
$this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
|
|
} else {
|
|
$this->country = $obj->country;
|
|
}
|
|
|
|
$this->phone = $obj->phone;
|
|
$this->phone_perso = $obj->phone_perso;
|
|
$this->phone_mobile = $obj->phone_mobile;
|
|
$this->email = $obj->email;
|
|
$this->url = $obj->url;
|
|
|
|
$this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
|
|
|
|
$this->photo = $obj->photo;
|
|
$this->statut = $obj->statut;
|
|
$this->status = $obj->statut;
|
|
$this->public = $obj->public;
|
|
|
|
$this->datec = $this->db->jdate($obj->datec);
|
|
$this->date_creation = $this->db->jdate($obj->datec);
|
|
$this->datem = $this->db->jdate($obj->datem);
|
|
$this->date_modification = $this->db->jdate($obj->datem);
|
|
$this->datefin = $this->db->jdate($obj->datefin);
|
|
$this->datevalid = $this->db->jdate($obj->datev);
|
|
$this->date_validation = $this->db->jdate($obj->datev);
|
|
$this->birth = $this->db->jdate($obj->birthday);
|
|
|
|
$this->default_lang = $obj->default_lang;
|
|
|
|
$this->note_private = $obj->note_private;
|
|
$this->note_public = $obj->note_public;
|
|
$this->morphy = $obj->morphy;
|
|
|
|
$this->typeid = $obj->fk_adherent_type;
|
|
$this->type = $obj->type;
|
|
$this->need_subscription = $obj->subscription;
|
|
|
|
$this->user_id = $obj->user_id;
|
|
$this->user_login = $obj->user_login;
|
|
|
|
$this->model_pdf = $obj->model_pdf;
|
|
|
|
// Retrieve all extrafield
|
|
// fetch optionals attributes and labels
|
|
if ($fetch_optionals) {
|
|
$this->fetch_optionals();
|
|
}
|
|
|
|
// Load other properties
|
|
if ($fetch_subscriptions) {
|
|
$result = $this->fetch_subscriptions();
|
|
}
|
|
|
|
return $this->id;
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else {
|
|
$this->error = $this->db->lasterror();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Function to get member subscriptions data:
|
|
* subscriptions,
|
|
* first_subscription_date, first_subscription_date_start, first_subscription_date_end, first_subscription_amount
|
|
* last_subscription_date, last_subscription_date_start, last_subscription_date_end, last_subscription_amount
|
|
*
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function fetch_subscriptions()
|
|
{
|
|
// phpcs:enable
|
|
require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
|
|
|
|
$sql = "SELECT c.rowid, c.fk_adherent, c.fk_type, c.subscription, c.note as note_public, c.fk_bank,";
|
|
$sql .= " c.tms as datem,";
|
|
$sql .= " c.datec as datec,";
|
|
$sql .= " c.dateadh as dateh,";
|
|
$sql .= " c.datef as datef";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."subscription as c";
|
|
$sql .= " WHERE c.fk_adherent = ".((int) $this->id);
|
|
$sql .= " ORDER BY c.dateadh";
|
|
dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$this->subscriptions = array();
|
|
|
|
$i = 0;
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
if ($i == 0) {
|
|
$this->first_subscription_date = $this->db->jdate($obj->datec);
|
|
$this->first_subscription_date_start = $this->db->jdate($obj->dateh);
|
|
$this->first_subscription_date_end = $this->db->jdate($obj->datef);
|
|
$this->first_subscription_amount = $obj->subscription;
|
|
}
|
|
$this->last_subscription_date = $this->db->jdate($obj->datec);
|
|
$this->last_subscription_date_start = $this->db->jdate($obj->dateh);
|
|
$this->last_subscription_date_end = $this->db->jdate($obj->datef);
|
|
$this->last_subscription_amount = (float) $obj->subscription;
|
|
|
|
$subscription = new Subscription($this->db);
|
|
$subscription->id = $obj->rowid;
|
|
$subscription->fk_adherent = $obj->fk_adherent;
|
|
$subscription->fk_type = $obj->fk_type;
|
|
$subscription->amount = (float) $obj->subscription;
|
|
$subscription->note = $obj->note_public;
|
|
$subscription->note_public = $obj->note_public;
|
|
$subscription->fk_bank = $obj->fk_bank;
|
|
$subscription->datem = $this->db->jdate($obj->datem);
|
|
$subscription->datec = $this->db->jdate($obj->datec);
|
|
$subscription->dateh = $this->db->jdate($obj->dateh);
|
|
$subscription->datef = $this->db->jdate($obj->datef);
|
|
|
|
$this->subscriptions[] = $subscription;
|
|
|
|
$i++;
|
|
}
|
|
return 1;
|
|
} else {
|
|
$this->error = $this->db->error().' sql='.$sql;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Function to get partnerships array
|
|
*
|
|
* @param string $mode 'member' or 'thirdparty'
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function fetchPartnerships($mode)
|
|
{
|
|
require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php';
|
|
|
|
|
|
$this->partnerships[] = array();
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
/**
|
|
* Insert subscription into database and eventually add links to banks, mailman, etc...
|
|
*
|
|
* @param int $date Date of effect of subscription
|
|
* @param double $amount Amount of subscription (0 accepted for some members)
|
|
* @param int $accountid Id bank account. NOT USED.
|
|
* @param string $operation Code of payment mode (if Id bank account provided). Example: 'CB', ... NOT USED.
|
|
* @param string $label Label operation stored into public note.
|
|
* @param string $num_chq Numero cheque (if Id bank account provided). NOT USED.
|
|
* @param string $emetteur_nom Name of cheque writer
|
|
* @param string $emetteur_banque Name of bank of cheque
|
|
* @param int $datesubend Date end subscription
|
|
* @param int $fk_type Member type id
|
|
* @param string $ref_ext To save an external ref
|
|
* @return int rowid of record added, <0 if KO
|
|
*/
|
|
public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null, $ref_ext = '')
|
|
{
|
|
global $user;
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
|
|
|
|
$error = 0;
|
|
|
|
// Clean parameters
|
|
if (!$amount) {
|
|
$amount = 0;
|
|
}
|
|
|
|
$this->db->begin();
|
|
|
|
if ($datesubend) {
|
|
$datefin = $datesubend;
|
|
} else {
|
|
// If no end date, end date = date + 1 year - 1 day
|
|
$datefin = dol_time_plus_duree($date, 1, 'y');
|
|
$datefin = dol_time_plus_duree($datefin, -1, 'd');
|
|
}
|
|
|
|
// Create subscription
|
|
$subscription = new Subscription($this->db);
|
|
$subscription->fk_adherent = $this->id;
|
|
$subscription->dateh = $date; // Date of new subscription
|
|
$subscription->datef = $datefin; // End data of new subscription
|
|
$subscription->amount = $amount;
|
|
$subscription->note_public = $label;
|
|
$subscription->note_private = '';
|
|
$subscription->fk_type = $fk_type;
|
|
$subscription->ref_ext = $ref_ext;
|
|
|
|
if (empty($subscription->user_creation_id)) {
|
|
$subscription->user_creation_id = $user->id;
|
|
}
|
|
|
|
$rowid = $subscription->create($user);
|
|
if ($rowid > 0) {
|
|
// Update denormalized subscription end date (read database subscription to find values)
|
|
// This will also update this->datefin
|
|
$result = $this->update_end_date($user);
|
|
if ($result > 0) {
|
|
// Change properties of object (used by triggers)
|
|
$this->last_subscription_date = dol_now();
|
|
$this->last_subscription_date_start = $date;
|
|
$this->last_subscription_date_end = $datefin;
|
|
$this->last_subscription_amount = $amount;
|
|
} else {
|
|
$error++;
|
|
}
|
|
|
|
if (!$error) {
|
|
$this->db->commit();
|
|
return $rowid;
|
|
} else {
|
|
$this->db->rollback();
|
|
return -2;
|
|
}
|
|
} else {
|
|
$this->setErrorsFromObject($subscription);
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Do complementary actions after subscription recording.
|
|
*
|
|
* @param int $subscriptionid Id of created subscription
|
|
* @param string $option Which action ('bankdirect', 'bankviainvoice', 'invoiceonly', ...)
|
|
* @param int $accountid Id bank account
|
|
* @param int $datesubscription Date of subscription
|
|
* @param int $paymentdate Date of payment
|
|
* @param string $operation Code of type of operation (if Id bank account provided). Example 'CB', ...
|
|
* @param string $label Label operation (if Id bank account provided)
|
|
* @param double $amount Amount of subscription (0 accepted for some members)
|
|
* @param string $num_chq Numero cheque (if Id bank account provided)
|
|
* @param string $emetteur_nom Name of cheque writer
|
|
* @param string $emetteur_banque Name of bank of cheque
|
|
* @param int $autocreatethirdparty Auto create new thirdparty if member not yet linked to a thirdparty and we request an option that generate invoice.
|
|
* @param string $ext_payment_id External id of payment (for example Stripe charge id)
|
|
* @param string $ext_payment_site Name of external paymentmode (for example 'StripeLive', 'StripeTest', 'paypal', ...)
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function subscriptionComplementaryActions($subscriptionid, $option, $accountid, $datesubscription, $paymentdate, $operation, $label, $amount, $num_chq, $emetteur_nom = '', $emetteur_banque = '', $autocreatethirdparty = 0, $ext_payment_id = '', $ext_payment_site = '')
|
|
{
|
|
global $conf, $langs, $user, $mysoc;
|
|
|
|
$error = 0;
|
|
|
|
$this->invoice = null; // This will contains invoice if an invoice is created
|
|
|
|
dol_syslog("subscriptionComplementaryActions subscriptionid=".$subscriptionid." option=".$option." accountid=".$accountid." datesubscription=".$datesubscription." paymentdate=".
|
|
$paymentdate." label=".$label." amount=".$amount." num_chq=".$num_chq." autocreatethirdparty=".$autocreatethirdparty);
|
|
|
|
// Insert into bank account directlty (if option chosen for) + link to llx_subscription if option is 'bankdirect'
|
|
if ($option == 'bankdirect' && $accountid) {
|
|
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
|
|
|
|
$acct = new Account($this->db);
|
|
$result = $acct->fetch($accountid);
|
|
|
|
$dateop = $paymentdate;
|
|
|
|
$insertid = $acct->addline($dateop, $operation, $label, $amount, $num_chq, 0, $user, $emetteur_nom, $emetteur_banque);
|
|
if ($insertid > 0) {
|
|
$inserturlid = $acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullName($langs), 'member');
|
|
if ($inserturlid > 0) {
|
|
// Update table subscription
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".((int) $insertid);
|
|
$sql .= " WHERE rowid=".((int) $subscriptionid);
|
|
|
|
dol_syslog("subscription::subscription", LOG_DEBUG);
|
|
$resql = $this->db->query($sql);
|
|
if (!$resql) {
|
|
$error++;
|
|
$this->error = $this->db->lasterror();
|
|
$this->errors[] = $this->error;
|
|
}
|
|
} else {
|
|
$error++;
|
|
$this->setErrorsFromObject($acct);
|
|
}
|
|
} else {
|
|
$error++;
|
|
$this->setErrorsFromObject($acct);
|
|
}
|
|
}
|
|
|
|
// If option chosen, we create invoice
|
|
if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly') {
|
|
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
|
|
|
|
$invoice = new Facture($this->db);
|
|
$customer = new Societe($this->db);
|
|
|
|
if (!$error) {
|
|
if (!($this->socid > 0)) { // If not yet linked to a company
|
|
if ($autocreatethirdparty) {
|
|
// Create a linked thirdparty to member
|
|
$companyalias = '';
|
|
$fullname = $this->getFullName($langs);
|
|
|
|
if ($this->morphy == 'mor') {
|
|
$companyname = $this->company;
|
|
if (!empty($fullname)) {
|
|
$companyalias = $fullname;
|
|
}
|
|
} else {
|
|
$companyname = $fullname;
|
|
if (!empty($this->company)) {
|
|
$companyalias = $this->company;
|
|
}
|
|
}
|
|
|
|
$result = $customer->create_from_member($this, (string) $companyname, $companyalias);
|
|
if ($result < 0) {
|
|
$this->error = $customer->error;
|
|
$this->errors = $customer->errors;
|
|
$error++;
|
|
} else {
|
|
$this->fk_soc = $result;
|
|
$this->socid = $result;
|
|
}
|
|
} else {
|
|
$langs->load("errors");
|
|
$this->error = $langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
|
|
$this->errors[] = $this->error;
|
|
$error++;
|
|
}
|
|
}
|
|
}
|
|
if (!$error) {
|
|
$result = $customer->fetch($this->socid);
|
|
if ($result <= 0) {
|
|
$this->error = $customer->error;
|
|
$this->errors = $customer->errors;
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
// Create draft invoice
|
|
$invoice->type = Facture::TYPE_STANDARD;
|
|
$invoice->cond_reglement_id = $customer->cond_reglement_id;
|
|
if (empty($invoice->cond_reglement_id)) {
|
|
$paymenttermstatic = new PaymentTerm($this->db);
|
|
$invoice->cond_reglement_id = $paymenttermstatic->getDefaultId();
|
|
if (empty($invoice->cond_reglement_id)) {
|
|
$error++;
|
|
$this->error = 'ErrorNoPaymentTermRECEPFound';
|
|
$this->errors[] = $this->error;
|
|
}
|
|
}
|
|
$invoice->socid = $this->socid;
|
|
// set customer's payment bank account on the invoice
|
|
if (!empty($customer->fk_account)) {
|
|
$invoice->fk_account = $customer->fk_account;
|
|
} elseif (getDolGlobalString('FACTURE_RIB_NUMBER')) {
|
|
// set default bank account from invoice module settings
|
|
$invoice->fk_account = (int) getDolGlobalString('FACTURE_RIB_NUMBER');
|
|
}
|
|
//set customer's payment method on the invoice
|
|
if (!empty($customer->mode_reglement_id)) {
|
|
$invoice->mode_reglement_id = $customer->mode_reglement_id;
|
|
}
|
|
//$invoice->date = $datesubscription;
|
|
$invoice->date = dol_now();
|
|
|
|
// Possibility to add external linked objects with hooks
|
|
$invoice->linked_objects['subscription'] = $subscriptionid;
|
|
if (GETPOSTISARRAY('other_linked_objects')) {
|
|
$invoice->linked_objects = array_merge($invoice->linked_objects, GETPOST('other_linked_objects', 'array:int'));
|
|
}
|
|
|
|
$result = $invoice->create($user);
|
|
if ($result <= 0) {
|
|
$this->setErrorsFromObject($invoice);
|
|
$error++;
|
|
} else {
|
|
$this->invoice = $invoice;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
// Add line to draft invoice
|
|
$idprodsubscription = 0;
|
|
if (getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS') && (isModEnabled("product") || isModEnabled("service"))) {
|
|
$idprodsubscription = getDolGlobalString('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
|
|
}
|
|
|
|
$vattouse = 0;
|
|
if (getDolGlobalString('ADHERENT_VAT_FOR_SUBSCRIPTIONS') == 'defaultforfoundationcountry') {
|
|
$vattouse = get_default_tva($mysoc, $mysoc, $idprodsubscription);
|
|
}
|
|
//print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
|
|
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
|
|
$result = $invoice->addline($label, 0, 1, $vattouse, 0, 0, $idprodsubscription, 0, $datesubscription, '', 0, 0, 0, 'TTC', $amount, 1);
|
|
if ($result <= 0) {
|
|
$this->setErrorsFromObject($invoice);
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
// Validate invoice
|
|
$result = $invoice->validate($user);
|
|
if ($result <= 0) {
|
|
$this->setErrorsFromObject($invoice);
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
// TODO Link invoice with subscription ?
|
|
}
|
|
|
|
// Add payment onto invoice
|
|
if (!$error && $option == 'bankviainvoice' && $accountid) {
|
|
require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
|
|
|
|
$amounts = array();
|
|
$amounts[$invoice->id] = (float) price2num($amount);
|
|
|
|
$paiement = new Paiement($this->db);
|
|
$paiement->datepaye = $paymentdate;
|
|
$paiement->amounts = $amounts;
|
|
$paiement->paiementcode = $operation;
|
|
$paiement->paiementid = dol_getIdFromCode($this->db, $operation, 'c_paiement', 'code', 'id', 1);
|
|
$paiement->num_payment = $num_chq;
|
|
$paiement->note_public = $label;
|
|
$paiement->ext_payment_id = $ext_payment_id;
|
|
$paiement->ext_payment_site = $ext_payment_site;
|
|
|
|
// Create payment line for invoice
|
|
$paiement_id = $paiement->create($user);
|
|
if (!($paiement_id > 0)) {
|
|
$this->setErrorsFromObject($paiement);
|
|
$error++;
|
|
}
|
|
|
|
if (!$error) {
|
|
// Add transaction into bank account
|
|
$bank_line_id = $paiement->addPaymentToBank($user, 'payment', '(SubscriptionPayment)', $accountid, $emetteur_nom, $emetteur_banque);
|
|
if (!($bank_line_id > 0)) {
|
|
$this->setErrorsFromObject($paiement);
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error && !empty($bank_line_id)) {
|
|
// Update fk_bank into subscription table
|
|
$sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.((int) $bank_line_id);
|
|
$sql .= ' WHERE rowid='.((int) $subscriptionid);
|
|
|
|
$result = $this->db->query($sql);
|
|
if (!$result) {
|
|
$error++;
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
// Set invoice as paid
|
|
$invoice->setPaid($user);
|
|
}
|
|
}
|
|
|
|
if (!$error) {
|
|
// Define output language
|
|
$outputlangs = $langs;
|
|
$newlang = '';
|
|
$lang_id = GETPOST('lang_id');
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && !empty($lang_id)) {
|
|
$newlang = $lang_id;
|
|
}
|
|
if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
|
|
$newlang = $customer->default_lang;
|
|
}
|
|
if (!empty($newlang)) {
|
|
$outputlangs = new Translate("", $conf);
|
|
$outputlangs->setDefaultLang($newlang);
|
|
}
|
|
// Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
|
|
//if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE'))
|
|
|
|
$invoice->generateDocument($invoice->model_pdf, $outputlangs);
|
|
}
|
|
}
|
|
|
|
if ($error) {
|
|
return -1;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Function that validate a member
|
|
*
|
|
* @param User $user user adherent qui valide
|
|
* @return int Return integer <0 if KO, 0 if nothing done, >0 if OK
|
|
*/
|
|
public function validate($user)
|
|
{
|
|
global $langs, $conf;
|
|
|
|
$error = 0;
|
|
$now = dol_now();
|
|
|
|
// Check parameters
|
|
if ($this->statut == self::STATUS_VALIDATED) {
|
|
dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
|
|
return 0;
|
|
}
|
|
|
|
$this->db->begin();
|
|
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
|
|
$sql .= " statut = ".self::STATUS_VALIDATED;
|
|
$sql .= ", datevalid = '".$this->db->idate($now)."'";
|
|
$sql .= ", fk_user_valid = ".((int) $user->id);
|
|
$sql .= " WHERE rowid = ".((int) $this->id);
|
|
|
|
dol_syslog(get_class($this)."::validate", LOG_DEBUG);
|
|
$result = $this->db->query($sql);
|
|
if ($result) {
|
|
$this->statut = self::STATUS_VALIDATED;
|
|
|
|
// Call trigger
|
|
$result = $this->call_trigger('MEMBER_VALIDATE', $user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
// End call triggers
|
|
|
|
$this->datevalid = $now;
|
|
|
|
$this->db->commit();
|
|
return 1;
|
|
} else {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Fonction qui resilie un adherent
|
|
*
|
|
* @param User $user User making change
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function resiliate($user)
|
|
{
|
|
global $langs, $conf;
|
|
|
|
$error = 0;
|
|
|
|
// Check parameters
|
|
if ($this->statut == self::STATUS_RESILIATED) {
|
|
dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
|
|
return 0;
|
|
}
|
|
|
|
$this->db->begin();
|
|
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
|
|
$sql .= " statut = ".self::STATUS_RESILIATED;
|
|
$sql .= ", fk_user_valid=".$user->id;
|
|
$sql .= " WHERE rowid = ".((int) $this->id);
|
|
|
|
$result = $this->db->query($sql);
|
|
if ($result) {
|
|
$this->statut = self::STATUS_RESILIATED;
|
|
|
|
// Call trigger
|
|
$result = $this->call_trigger('MEMBER_RESILIATE', $user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
// End call triggers
|
|
|
|
$this->db->commit();
|
|
return 1;
|
|
} else {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Functiun to exclude (set adherent.status to -2) a member
|
|
* TODO
|
|
* A private note should be added to know why the member has been excluded
|
|
* For historical purpose it add an "extra-subscription" type excluded
|
|
*
|
|
* @param User $user User making change
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function exclude($user)
|
|
{
|
|
$error = 0;
|
|
|
|
// Check parameters
|
|
if ($this->statut == self::STATUS_EXCLUDED) {
|
|
dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
|
|
return 0;
|
|
}
|
|
|
|
$this->db->begin();
|
|
|
|
$sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
|
|
$sql .= " statut = ".self::STATUS_EXCLUDED;
|
|
$sql .= ", fk_user_valid=".$user->id;
|
|
$sql .= " WHERE rowid = ".((int) $this->id);
|
|
|
|
$result = $this->db->query($sql);
|
|
if ($result) {
|
|
$this->statut = self::STATUS_EXCLUDED;
|
|
|
|
// Call trigger
|
|
$result = $this->call_trigger('MEMBER_EXCLUDE', $user);
|
|
if ($result < 0) {
|
|
$error++;
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
// End call triggers
|
|
|
|
$this->db->commit();
|
|
return 1;
|
|
} else {
|
|
$this->error = $this->db->error();
|
|
$this->db->rollback();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Function to add member into external tools mailing-list, spip, etc.
|
|
*
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function add_to_abo()
|
|
{
|
|
// phpcs:enable
|
|
global $langs;
|
|
|
|
include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
|
|
$mailmanspip = new MailmanSpip($this->db);
|
|
|
|
$err = 0;
|
|
|
|
// mailman
|
|
if (getDolGlobalString('ADHERENT_USE_MAILMAN') && isModEnabled('mailmanspip')) {
|
|
$result = $mailmanspip->add_to_mailman($this);
|
|
|
|
if ($result < 0) {
|
|
if (!empty($mailmanspip->error)) {
|
|
$this->errors[] = $mailmanspip->error;
|
|
}
|
|
$err += 1;
|
|
}
|
|
foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail) {
|
|
$langs->load("errors");
|
|
$this->errors[] = $langs->trans("ErrorFailedToAddToMailmanList", $tmpemail, $tmplist);
|
|
}
|
|
foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail) {
|
|
$langs->load("mailmanspip");
|
|
$this->mesgs[] = $langs->trans("SuccessToAddToMailmanList", $tmpemail, $tmplist);
|
|
}
|
|
}
|
|
|
|
// spip
|
|
if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
|
|
$result = $mailmanspip->add_to_spip($this);
|
|
if ($result < 0) {
|
|
$this->errors[] = $mailmanspip->error;
|
|
$err += 1;
|
|
}
|
|
}
|
|
if ($err) {
|
|
return -$err;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Function to delete a member from external tools like mailing-list, spip, etc.
|
|
*
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function del_to_abo()
|
|
{
|
|
// phpcs:enable
|
|
global $conf, $langs;
|
|
|
|
include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
|
|
$mailmanspip = new MailmanSpip($this->db);
|
|
|
|
$err = 0;
|
|
|
|
// mailman
|
|
if (getDolGlobalString('ADHERENT_USE_MAILMAN')) {
|
|
$result = $mailmanspip->del_to_mailman($this);
|
|
if ($result < 0) {
|
|
if (!empty($mailmanspip->error)) {
|
|
$this->errors[] = $mailmanspip->error;
|
|
}
|
|
$err += 1;
|
|
}
|
|
|
|
foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail) {
|
|
$langs->load("errors");
|
|
$this->errors[] = $langs->trans("ErrorFailedToRemoveToMailmanList", $tmpemail, $tmplist);
|
|
}
|
|
foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail) {
|
|
$langs->load("mailmanspip");
|
|
$this->mesgs[] = $langs->trans("SuccessToRemoveToMailmanList", $tmpemail, $tmplist);
|
|
}
|
|
}
|
|
|
|
if (getDolGlobalString('ADHERENT_USE_SPIP') && isModEnabled('mailmanspip')) {
|
|
$result = $mailmanspip->del_to_spip($this);
|
|
if ($result < 0) {
|
|
$this->errors[] = $mailmanspip->error;
|
|
$err += 1;
|
|
}
|
|
}
|
|
if ($err) {
|
|
// error
|
|
return -$err;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Return civility label of a member
|
|
*
|
|
* @return string Translated name of civility (translated with transnoentitiesnoconv)
|
|
*/
|
|
public function getCivilityLabel()
|
|
{
|
|
global $langs;
|
|
$langs->load("dict");
|
|
|
|
$code = (empty($this->civility_id) ? '' : $this->civility_id);
|
|
if (empty($code)) {
|
|
return '';
|
|
}
|
|
return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
|
|
}
|
|
|
|
/**
|
|
* getTooltipContentArray
|
|
* @param array<string,mixed> $params params to construct tooltip data
|
|
* @since v18
|
|
* @return array{picto?:string,ref?:string,refsupplier?:string,label?:string,date?:string,date_echeance?:string,amountht?:string,total_ht?:string,totaltva?:string,amountlt1?:string,amountlt2?:string,amountrevenustamp?:string,totalttc?:string}|array{optimize:string}
|
|
*/
|
|
public function getTooltipContentArray($params)
|
|
{
|
|
global $langs;
|
|
|
|
$langs->loadLangs(['members', 'companies']);
|
|
$nofetch = !empty($params['nofetch']);
|
|
|
|
$datas = array();
|
|
|
|
if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
|
|
$langs->load("users");
|
|
return ['optimize' => $langs->trans("ShowUser")];
|
|
}
|
|
if (!empty($this->photo)) {
|
|
$photo = '<div class="photointooltip floatright">';
|
|
$photo .= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photoref photowithmargin photologintooltip', 'small', 0, 1);
|
|
$photo .= '</div>';
|
|
$datas['photo'] = $photo;
|
|
}
|
|
|
|
$datas['divopen'] = '<div class="centpercent">';
|
|
$datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Member").'</u> '.$this->getLibStatut(4);
|
|
if (!empty($this->morphy)) {
|
|
$datas['picto'] .= ' ' . $this->getmorphylib('', 1);
|
|
}
|
|
if (!empty($this->ref)) {
|
|
$datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
|
|
}
|
|
if (!empty($this->login)) {
|
|
$datas['login'] = '<br><b>'.$langs->trans('Login').':</b> '.$this->login;
|
|
}
|
|
if (!empty($this->firstname) || !empty($this->lastname)) {
|
|
$datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.$this->getFullName($langs);
|
|
}
|
|
if (!empty($this->company)) {
|
|
$datas['company'] = '<br><b>'.$langs->trans('Company').':</b> '.$this->company;
|
|
}
|
|
if (!empty($this->email)) {
|
|
$datas['email'] = '<br><b>'.$langs->trans("EMail").':</b> '.$this->email;
|
|
}
|
|
$datas['address'] = '<br><b>'.$langs->trans("Address").':</b> '.dol_format_address($this, 1, ' ', $langs);
|
|
// show categories for this record only in ajax to not overload lists
|
|
if (isModEnabled('category') && !$nofetch) {
|
|
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
|
|
$form = new Form($this->db);
|
|
$datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_MEMBER, 1);
|
|
}
|
|
$datas['divclose'] = '</div>';
|
|
|
|
return $datas;
|
|
}
|
|
|
|
/**
|
|
* Return clickable name (with picto eventually)
|
|
*
|
|
* @param int $withpictoimg 0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small, -4=???)
|
|
* @param int $maxlen length max label
|
|
* @param string $option Page for link ('card', 'category', 'subscription', ...)
|
|
* @param string $mode ''=Show firstname+lastname as label (using default order), 'firstname'=Show only firstname, 'lastname'=Show only lastname, 'login'=Show login, 'ref'=Show ref
|
|
* @param string $morecss Add more css on link
|
|
* @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
|
|
* @param int $notooltip 1=Disable tooltip
|
|
* @param int $addlinktonotes 1=Add link to notes
|
|
* @return string Chaine avec URL
|
|
*/
|
|
public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0)
|
|
{
|
|
global $conf, $langs, $hookmanager;
|
|
|
|
if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') && $withpictoimg) {
|
|
$withpictoimg = 0;
|
|
}
|
|
|
|
$result = '';
|
|
$linkstart = '';
|
|
$linkend = '';
|
|
$classfortooltip = 'classfortooltip';
|
|
$dataparams = '';
|
|
$params = [
|
|
'id' => $this->id,
|
|
'objecttype' => $this->element,
|
|
'option' => $option,
|
|
'nofetch' => 1,
|
|
];
|
|
if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
|
|
$classfortooltip = 'classforajaxtooltip';
|
|
$dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
|
|
$label = '';
|
|
} else {
|
|
$label = implode($this->getTooltipContentArray($params));
|
|
}
|
|
|
|
$baseurl = DOL_URL_ROOT . '/adherents/card.php';
|
|
if ($option == 'subscription') {
|
|
$baseurl = DOL_URL_ROOT . '/adherents/subscription.php';
|
|
}
|
|
$query = ['rowid' => $this->id];
|
|
|
|
if ($option != 'nolink') {
|
|
// Add param to save lastsearch_values or not
|
|
$add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
|
|
if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
|
|
$add_save_lastsearch_values = 1;
|
|
}
|
|
if ($add_save_lastsearch_values) {
|
|
$query = array_merge($query, ['save_lastsearch_values' => 1]);
|
|
}
|
|
}
|
|
$url = dolBuildUrl($baseurl, $query);
|
|
|
|
$linkstart .= '<a href="'.$url.'"';
|
|
$linkclose = "";
|
|
if (empty($notooltip)) {
|
|
if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
|
|
$langs->load("users");
|
|
$label = $langs->trans("ShowUser");
|
|
$linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
|
|
}
|
|
$linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
|
|
$linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
|
|
}
|
|
|
|
$linkstart .= $linkclose.'>';
|
|
$linkend = '</a>';
|
|
|
|
$result .= $linkstart;
|
|
|
|
if ($withpictoimg) {
|
|
if (abs($withpictoimg) == 1 || abs($withpictoimg) == 4) {
|
|
$morecss .= ' paddingrightonly';
|
|
}
|
|
// Only picto
|
|
if ($withpictoimg > 0) {
|
|
$picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'">'.img_object('', 'user', ' '.($notooltip ? '' : $dataparams), 0, 0, $notooltip ? 0 : 1).'</span>';
|
|
} else {
|
|
// Picto must be a photo
|
|
$picto = '<span class="nopadding'.($morecss ? ' userimg'.$morecss : '').'">';
|
|
$picto .= Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.(($withpictoimg == -3 || $withpictoimg == -4) ? 'small' : ''), 'mini', 0, 1);
|
|
$picto .= '</span>';
|
|
}
|
|
$result .= $picto;
|
|
}
|
|
if (($withpictoimg > -2 && $withpictoimg != 2) || $withpictoimg == -4) {
|
|
if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
|
|
$result .= '<span class="nopadding valignmiddle'.((!isset($this->status) || $this->status) ? '' : ' strikefordisabled').
|
|
($morecss ? ' usertext'.$morecss : '').'">';
|
|
}
|
|
if ($mode == 'login') {
|
|
$result .= dol_trunc(isset($this->login) ? $this->login : '', $maxlen);
|
|
} elseif ($mode == 'ref') {
|
|
$result .= $this->ref;
|
|
} else {
|
|
$result .= $this->getFullName($langs, 0, ($mode == 'firstname' ? 2 : ($mode == 'lastname' ? 4 : -1)), $maxlen);
|
|
}
|
|
if (!getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
|
|
$result .= '</span>';
|
|
}
|
|
}
|
|
|
|
$result .= $linkend;
|
|
|
|
if ($addlinktonotes) {
|
|
if ($this->note_private) {
|
|
$notetoshow = $langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($this->note_private, 1);
|
|
$result .= ' <span class="note inline-block">';
|
|
$result .= '<a href="'.DOL_URL_ROOT.'/adherents/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
|
|
$result .= img_picto('', 'note');
|
|
$result .= '</a>';
|
|
$result .= '</span>';
|
|
}
|
|
}
|
|
global $action;
|
|
$hookmanager->initHooks(array($this->element . 'dao'));
|
|
$parameters = array('id' => $this->id, 'getnomurl' => &$result);
|
|
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
|
|
if ($reshook > 0) {
|
|
$result = $hookmanager->resPrint;
|
|
} else {
|
|
$result .= $hookmanager->resPrint;
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Retourne le libelle du statut d'un adherent (brouillon, valide, resilie, exclu)
|
|
*
|
|
* @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
|
|
* @return string Label
|
|
*/
|
|
public function getLibStatut($mode = 0)
|
|
{
|
|
return $this->LibStatut($this->status, $this->need_subscription, $this->datefin, $mode);
|
|
}
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Renvoi le libelle d'un statut donne
|
|
*
|
|
* @param int $status Id status
|
|
* @param int $need_subscription 1 if member type need subscription, 0 otherwise
|
|
* @param int $date_end_subscription Date fin adhesion
|
|
* @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
|
|
* @return string Label
|
|
*/
|
|
public function LibStatut($status, $need_subscription, $date_end_subscription, $mode = 0)
|
|
{
|
|
// phpcs:enable
|
|
global $langs;
|
|
$langs->load("members");
|
|
|
|
$statusType = '';
|
|
$labelStatus = '';
|
|
$labelStatusShort = '';
|
|
|
|
if ($status == self::STATUS_DRAFT) {
|
|
$statusType = 'status0';
|
|
$labelStatus = $langs->trans("MemberStatusDraft");
|
|
$labelStatusShort = $langs->trans("MemberStatusDraftShort");
|
|
} elseif ($status >= self::STATUS_VALIDATED) {
|
|
if ($need_subscription === 0) {
|
|
$statusType = 'status4';
|
|
$labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusNoSubscription");
|
|
$labelStatusShort = $langs->trans("MemberStatusNoSubscriptionShort");
|
|
} elseif (!$date_end_subscription) {
|
|
$statusType = 'status1';
|
|
$labelStatus = $langs->trans("Validated").' - '.$langs->trans("WaitingSubscription");
|
|
$labelStatusShort = $langs->trans("WaitingSubscriptionShort");
|
|
} elseif ($date_end_subscription < dol_now()) { // expired
|
|
$statusType = 'status2';
|
|
$labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusActiveLate");
|
|
$labelStatusShort = $langs->trans("MemberStatusActiveLateShort");
|
|
} else {
|
|
$statusType = 'status4';
|
|
$labelStatus = $langs->trans("Validated").' - '.$langs->trans("MemberStatusPaid");
|
|
$labelStatusShort = $langs->trans("MemberStatusPaidShort");
|
|
}
|
|
} elseif ($status == self::STATUS_RESILIATED) {
|
|
$statusType = 'status6';
|
|
$labelStatus = $langs->transnoentitiesnoconv("MemberStatusResiliated");
|
|
$labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusResiliatedShort");
|
|
} elseif ($status == self::STATUS_EXCLUDED) {
|
|
$statusType = 'status10';
|
|
$labelStatus = $langs->transnoentitiesnoconv("MemberStatusExcluded");
|
|
$labelStatusShort = $langs->transnoentitiesnoconv("MemberStatusExcludedShort");
|
|
}
|
|
|
|
return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
|
|
}
|
|
|
|
|
|
/**
|
|
* Load indicators this->nb in state board
|
|
*
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function loadStateBoard()
|
|
{
|
|
global $conf;
|
|
|
|
$this->nb = array();
|
|
|
|
$sql = "SELECT count(a.rowid) as nb";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
|
|
$sql .= " WHERE a.statut > 0";
|
|
$sql .= " AND a.entity IN (".getEntity('adherent').")";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$this->nb["members"] = $obj->nb;
|
|
}
|
|
$this->db->free($resql);
|
|
return 1;
|
|
} else {
|
|
dol_print_error($this->db);
|
|
$this->error = $this->db->error();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
/**
|
|
* Load indicators for dashboard (this->nbtodo and this->nbtodolate)
|
|
*
|
|
* @param User $user Object user
|
|
* @param string $mode "expired" for membership to renew, "shift" for member to validate
|
|
* @return WorkboardResponse|int Return integer <0 if KO, WorkboardResponse if OK
|
|
*/
|
|
public function load_board($user, $mode)
|
|
{
|
|
// phpcs:enable
|
|
global $conf, $langs;
|
|
|
|
if ($user->socid) {
|
|
return -1; // protection pour eviter appel par utilisateur externe
|
|
}
|
|
|
|
$now = dol_now();
|
|
|
|
$sql = "SELECT a.rowid, a.datefin, a.statut as status";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
|
|
$sql .= ", ".MAIN_DB_PREFIX."adherent_type as t";
|
|
$sql .= " WHERE a.fk_adherent_type = t.rowid";
|
|
if ($mode == 'expired') {
|
|
$sql .= " AND a.statut = ".self::STATUS_VALIDATED;
|
|
$sql .= " AND a.entity IN (".getEntity('adherent').")";
|
|
$sql .= " AND ((a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."') AND t.subscription = '1')";
|
|
} elseif ($mode == 'shift') {
|
|
$sql .= " AND a.statut = ".self::STATUS_DRAFT;
|
|
$sql .= " AND a.entity IN (".getEntity('adherent').")";
|
|
}
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$langs->load("members");
|
|
|
|
$warning_delay = 0;
|
|
$url = '';
|
|
$label = '';
|
|
$labelShort = '';
|
|
|
|
if ($mode == 'expired') {
|
|
$warning_delay = getWarningDelay('member', 'subscription') / 60 / 60 / 24;
|
|
$label = $langs->trans("MembersWithSubscriptionToReceive");
|
|
$labelShort = $langs->trans("MembersWithSubscriptionToReceiveShort");
|
|
$url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&statut='.self::STATUS_VALIDATED.'&filter=outofdate';
|
|
} elseif ($mode == 'shift') {
|
|
$warning_delay = getWarningDelay('member', 'subscription') / 60 / 60 / 24;
|
|
$url = DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&statut='.self::STATUS_DRAFT;
|
|
$label = $langs->trans("MembersListToValid");
|
|
$labelShort = $langs->trans("ToValidate");
|
|
}
|
|
|
|
$response = new WorkboardResponse();
|
|
$response->warning_delay = $warning_delay;
|
|
$response->label = $label;
|
|
$response->labelShort = $labelShort;
|
|
$response->url = $url;
|
|
$response->img = img_object('', "user");
|
|
|
|
$adherentstatic = new Adherent($this->db);
|
|
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$response->nbtodo++;
|
|
|
|
$adherentstatic->datefin = $this->db->jdate($obj->datefin);
|
|
$adherentstatic->statut = $obj->status;
|
|
$adherentstatic->status = $obj->status;
|
|
|
|
if ($adherentstatic->hasDelay()) {
|
|
$response->nbtodolate++;
|
|
}
|
|
}
|
|
|
|
return $response;
|
|
} else {
|
|
dol_print_error($this->db);
|
|
$this->error = $this->db->error();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Create a document onto disk according to template module.
|
|
*
|
|
* @param string $modele Force template to use ('' to not force)
|
|
* @param Translate $outputlangs object lang a utiliser pour traduction
|
|
* @param int<0,1> $hidedetails Hide details of lines
|
|
* @param int<0,1> $hidedesc Hide description
|
|
* @param int<0,1> $hideref Hide ref
|
|
* @param ?array<string,mixed> $moreparams Array to provide more information
|
|
* @return int<0,1> 0 if KO, 1 if OK
|
|
*/
|
|
public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
|
|
{
|
|
global $conf, $langs;
|
|
|
|
$langs->load("orders");
|
|
|
|
if (!dol_strlen($modele)) {
|
|
$modele = 'standard';
|
|
|
|
if ($this->model_pdf) {
|
|
$modele = $this->model_pdf;
|
|
} elseif (getDolGlobalString('ADHERENT_ADDON_PDF')) {
|
|
$modele = getDolGlobalString('ADHERENT_ADDON_PDF');
|
|
}
|
|
}
|
|
|
|
$modelpath = "core/modules/member/doc/";
|
|
|
|
return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
|
|
}
|
|
|
|
|
|
/**
|
|
* Initialise an instance with random values.
|
|
* Used to build previews or test instances.
|
|
* id must be 0 if object instance is a specimen.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function initAsSpecimen()
|
|
{
|
|
global $user, $langs;
|
|
$now = dol_now();
|
|
|
|
// Initialise parameters
|
|
$this->id = 0;
|
|
$this->ref = 'ABC001';
|
|
$this->entity = 1;
|
|
$this->specimen = 1;
|
|
$this->civility_id = 'MR';
|
|
$this->lastname = 'DOLIBARR';
|
|
$this->firstname = 'SPECIMEN';
|
|
$this->gender = 'man';
|
|
$this->login = 'dolibspec';
|
|
$this->pass = 'dolibspec';
|
|
$this->company = 'Societe ABC';
|
|
$this->address = '61 jump street';
|
|
$this->zip = '75000';
|
|
$this->town = 'Paris';
|
|
$this->country_id = 1;
|
|
$this->country_code = 'FR';
|
|
$this->country = 'France';
|
|
$this->morphy = 'mor';
|
|
$this->email = 'specimen@specimen.com';
|
|
$this->socialnetworks = array(
|
|
'skype' => 'skypepseudo',
|
|
'twitter' => 'twitterpseudo',
|
|
'facebook' => 'facebookpseudo',
|
|
'linkedin' => 'linkedinpseudo',
|
|
);
|
|
$this->phone = '0999999999';
|
|
$this->phone_perso = '0999999998';
|
|
$this->phone_mobile = '0999999997';
|
|
$this->note_public = 'This is a public note';
|
|
$this->note_private = 'This is a private note';
|
|
$this->birth = $now;
|
|
$this->photo = '';
|
|
$this->public = 1;
|
|
$this->statut = self::STATUS_DRAFT;
|
|
$this->status = self::STATUS_DRAFT;
|
|
|
|
$this->datefin = $now;
|
|
$this->datevalid = $now;
|
|
$this->default_lang = '';
|
|
|
|
$this->typeid = 1; // Id type adherent
|
|
$this->type = 'Type adherent'; // Libelle type adherent
|
|
$this->need_subscription = 0;
|
|
|
|
$this->first_subscription_date = $now;
|
|
$this->first_subscription_date_start = $this->first_subscription_date;
|
|
$this->first_subscription_date_end = dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
|
|
$this->first_subscription_amount = 10;
|
|
|
|
$this->last_subscription_date = $this->first_subscription_date;
|
|
$this->last_subscription_date_start = $this->first_subscription_date;
|
|
$this->last_subscription_date_end = dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
|
|
$this->last_subscription_amount = 10;
|
|
return 1;
|
|
}
|
|
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
|
|
/**
|
|
* Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
|
|
*
|
|
* @param array<string,mixed> $info Info array loaded by _load_ldap_info
|
|
* @param int<0,2> $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
|
|
* 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
|
|
* 2=Return key only (uid=qqq)
|
|
* @return string DN
|
|
*/
|
|
public function _load_ldap_dn($info, $mode = 0)
|
|
{
|
|
// phpcs:enable
|
|
global $conf;
|
|
$dn = '';
|
|
if ($mode == 0) {
|
|
$dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')]."," . getDolGlobalString('LDAP_MEMBER_DN');
|
|
}
|
|
if ($mode == 1) {
|
|
$dn = getDolGlobalString('LDAP_MEMBER_DN');
|
|
}
|
|
if ($mode == 2) {
|
|
$dn = getDolGlobalString('LDAP_KEY_MEMBERS') . "=".$info[getDolGlobalString('LDAP_KEY_MEMBERS')];
|
|
}
|
|
return $dn;
|
|
}
|
|
|
|
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
|
|
/**
|
|
* Initialise tableau info (tableau des attributes LDAP)
|
|
*
|
|
* @return array<string,mixed> Tableau info des attributes
|
|
*/
|
|
public function _load_ldap_info()
|
|
{
|
|
// phpcs:enable
|
|
global $conf, $langs;
|
|
|
|
$info = array();
|
|
$socialnetworks = getArrayOfSocialNetworks();
|
|
$keymodified = false;
|
|
|
|
// Object classes
|
|
$info["objectclass"] = explode(',', getDolGlobalString('LDAP_MEMBER_OBJECT_CLASS'));
|
|
|
|
$this->fullname = $this->getFullName($langs);
|
|
|
|
// For avoid ldap error when firstname and lastname are empty
|
|
if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->company)) {
|
|
$this->fullname = $this->company;
|
|
$this->lastname = $this->company;
|
|
}
|
|
|
|
// Possible LDAP KEY (constname => varname)
|
|
$ldapkey = array(
|
|
'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
|
|
'LDAP_MEMBER_FIELD_NAME' => 'lastname',
|
|
'LDAP_MEMBER_FIELD_LOGIN' => 'login',
|
|
'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
|
|
'LDAP_MEMBER_FIELD_MAIL' => 'email'
|
|
);
|
|
|
|
// Member
|
|
foreach ($ldapkey as $constname => $varname) {
|
|
if (!empty($this->$varname) && getDolGlobalString($constname)) {
|
|
$info[getDolGlobalString($constname)] = $this->$varname;
|
|
|
|
// Check if it is the LDAP key and if its value has been changed
|
|
if (getDolGlobalString('LDAP_KEY_MEMBERS') && getDolGlobalString('LDAP_KEY_MEMBERS') == getDolGlobalString($constname)) {
|
|
if (!empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) {
|
|
$keymodified = true; // For check if LDAP key has been modified
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($this->firstname && getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_FIRSTNAME')] = $this->firstname;
|
|
}
|
|
if ($this->poste && getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_TITLE')] = $this->poste;
|
|
}
|
|
if ($this->company && getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_COMPANY')] = $this->company;
|
|
}
|
|
if ($this->address && getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_ADDRESS')] = $this->address;
|
|
}
|
|
if ($this->zip && getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_ZIP')] = $this->zip;
|
|
}
|
|
if ($this->town && getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_TOWN')] = $this->town;
|
|
}
|
|
if ($this->country_code && getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_COUNTRY')] = $this->country_code;
|
|
}
|
|
foreach ($socialnetworks as $key => $value) {
|
|
if ($this->socialnetworks[$value['label']] && getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_'.strtoupper($value['label']))] = $this->socialnetworks[$value['label']];
|
|
}
|
|
}
|
|
if ($this->phone && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE')] = $this->phone;
|
|
}
|
|
if ($this->phone_perso && getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_PHONE_PERSO')] = $this->phone_perso;
|
|
}
|
|
if ($this->phone_mobile && getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_MOBILE')] = $this->phone_mobile;
|
|
}
|
|
if ($this->fax && getDolGlobalString('LDAP_MEMBER_FIELD_FAX')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_FAX')] = $this->fax;
|
|
}
|
|
if ($this->note_private && getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note_private, 2);
|
|
}
|
|
if ($this->note_public && getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_NOTE_PUBLIC')] = dol_string_nohtmltag($this->note_public, 2);
|
|
}
|
|
if ($this->birth && getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_BIRTHDATE')] = dol_print_date($this->birth, 'dayhourldap');
|
|
}
|
|
if (isset($this->statut) && getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')) {
|
|
$info[getDolGlobalString('LDAP_FIELD_MEMBER_STATUS')] = $this->statut;
|
|
}
|
|
if ($this->datefin && getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')) {
|
|
$info[getDolGlobalString('LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION')] = dol_print_date($this->datefin, 'dayhourldap');
|
|
}
|
|
|
|
// When password is modified
|
|
if (!empty($this->pass)) {
|
|
if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass; // this->pass = Unencrypted password
|
|
}
|
|
if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
|
|
}
|
|
} elseif (getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION') !== '3') {
|
|
// Set LDAP password if possible
|
|
// If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
|
|
if (getDolGlobalString('DATABASE_PWD_ENCRYPTED')) { // This should be on on default installation
|
|
// Just for the case we use old md5 encryption (deprecated, no more used, kept for compatibility)
|
|
if (!getDolGlobalString('MAIN_SECURITY_HASH_ALGO') || getDolGlobalString('MAIN_SECURITY_HASH_ALGO') == 'md5') {
|
|
if ($this->pass_indatabase_crypted && getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
|
|
// Create OpenLDAP MD5 password from Dolibarr MD5 password
|
|
// Note: This suppose that "pass_indatabase_crypted" is a md5 (this should not happen anymore)"
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dolGetLdapPasswordHash($this->pass_indatabase_crypted, 'md5frommd5');
|
|
}
|
|
}
|
|
} elseif (!empty($this->pass_indatabase)) {
|
|
// Use $this->pass_indatabase value if exists
|
|
if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')] = $this->pass_indatabase; // $this->pass_indatabase = Unencrypted password
|
|
}
|
|
if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')) {
|
|
$info[getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD_CRYPTED')] = dol_hash($this->pass_indatabase, 'openldap'); // Create OpenLDAP password (see LDAP_PASSWORD_HASH_TYPE)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Subscriptions
|
|
if ($this->first_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')) {
|
|
$info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE')] = dol_print_date($this->first_subscription_date, 'dayhourldap');
|
|
}
|
|
if (isset($this->first_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')) {
|
|
$info[getDolGlobalString('LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT')] = $this->first_subscription_amount;
|
|
}
|
|
if ($this->last_subscription_date && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')) {
|
|
$info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE')] = dol_print_date($this->last_subscription_date, 'dayhourldap');
|
|
}
|
|
if (isset($this->last_subscription_amount) && getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')) {
|
|
$info[getDolGlobalString('LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT')] = $this->last_subscription_amount;
|
|
}
|
|
|
|
return $info;
|
|
}
|
|
|
|
|
|
/**
|
|
* Load type info information in the member object
|
|
*
|
|
* @param int $id Id of member to load
|
|
* @return void
|
|
*/
|
|
public function info($id)
|
|
{
|
|
$sql = 'SELECT a.rowid, a.datec as datec,';
|
|
$sql .= ' a.datevalid as datev,';
|
|
$sql .= ' GREATEST(a.tms, aef.tms) as datem,';
|
|
$sql .= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
|
|
$sql .= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
|
|
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'adherent_extrafields as aef ON aef.fk_object = a.rowid';
|
|
$sql .= ' WHERE a.rowid = '.((int) $id);
|
|
|
|
dol_syslog(get_class($this)."::info", 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->user_creation_id = $obj->fk_user_author;
|
|
$this->user_validation_id = $obj->fk_user_valid;
|
|
$this->user_modification_id = $obj->fk_user_mod;
|
|
$this->date_creation = $this->db->jdate($obj->datec);
|
|
$this->date_validation = $this->db->jdate($obj->datev);
|
|
$this->date_modification = $this->db->jdate($obj->datem);
|
|
}
|
|
|
|
$this->db->free($result);
|
|
} else {
|
|
dol_print_error($this->db);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return number of mass Emailing received by this member with its email
|
|
*
|
|
* @return int Number of EMailings
|
|
*/
|
|
public function getNbOfEMailings()
|
|
{
|
|
$sql = "SELECT count(mc.email) as nb";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
|
|
$sql .= " WHERE mc.email = '".$this->db->escape($this->email)."'";
|
|
$sql .= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec success
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$obj = $this->db->fetch_object($resql);
|
|
$nb = (int) $obj->nb;
|
|
|
|
$this->db->free($resql);
|
|
return $nb;
|
|
} else {
|
|
$this->error = $this->db->error();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets object to supplied categories.
|
|
*
|
|
* Deletes object from existing categories not supplied.
|
|
* Adds it to non existing supplied categories.
|
|
* Existing categories are left untouch.
|
|
*
|
|
* @param int[]|int $categories Category or categories IDs
|
|
* @return int Return integer <0 if KO, >0 if OK
|
|
*/
|
|
public function setCategories($categories)
|
|
{
|
|
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
|
|
return parent::setCategoriesCommon($categories, Categorie::TYPE_MEMBER);
|
|
}
|
|
|
|
/**
|
|
* Function used to replace a thirdparty id with another one.
|
|
*
|
|
* @param DoliDB $db Database handler
|
|
* @param int $origin_id Old thirdparty id
|
|
* @param int $dest_id New thirdparty id
|
|
* @return bool
|
|
*/
|
|
public static function replaceThirdparty($db, $origin_id, $dest_id)
|
|
{
|
|
$tables = array('adherent');
|
|
|
|
return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
|
|
}
|
|
|
|
/**
|
|
* Return if a member is late (subscription late) or not
|
|
*
|
|
* @return boolean True if late, False if not late
|
|
*/
|
|
public function hasDelay()
|
|
{
|
|
global $conf;
|
|
|
|
//Only valid members
|
|
if ($this->statut != self::STATUS_VALIDATED) {
|
|
return false;
|
|
}
|
|
if (!$this->datefin) {
|
|
return false;
|
|
}
|
|
|
|
$now = dol_now();
|
|
|
|
return $this->datefin < ($now - getWarningDelay('member', 'subscription'));
|
|
}
|
|
|
|
|
|
/**
|
|
* Send reminders by emails before subscription end
|
|
* CAN BE A CRON TASK
|
|
*
|
|
* @param string $daysbeforeendlist Nb of days before end of subscription (negative number = after subscription). Can be a list of delay, separated by a semicolon, for example '10;5;0;-5'
|
|
* @param int $fk_adherent_type Type of Member (In order to restrict the sending of emails only to this type of member)
|
|
* @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK)
|
|
*/
|
|
public function sendReminderForExpiredSubscription($daysbeforeendlist = '10', $fk_adherent_type = 0)
|
|
{
|
|
global $conf, $langs, $mysoc, $user;
|
|
|
|
$error = 0;
|
|
$this->output = '';
|
|
$this->error = '';
|
|
|
|
$blockingerrormsg = '';
|
|
|
|
if (!isModEnabled('member')) { // Should not happen. If module disabled, cron job should not be visible.
|
|
$langs->load("agenda");
|
|
$this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
|
|
return 0;
|
|
}
|
|
if (!getDolGlobalString('MEMBER_REMINDER_EMAIL')) {
|
|
$langs->load("agenda");
|
|
$this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
|
|
return 0;
|
|
}
|
|
|
|
$now = dol_now();
|
|
$nbok = 0;
|
|
$nbko = 0;
|
|
|
|
$listofmembersok = array();
|
|
$listofmembersko = array();
|
|
|
|
$arraydaysbeforeend = explode(';', $daysbeforeendlist);
|
|
foreach ($arraydaysbeforeend as $daysbeforeend) { // Loop on each delay
|
|
dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
|
|
|
|
if (!is_numeric($daysbeforeend)) {
|
|
$blockingerrormsg = "Value for delta is not a numeric value";
|
|
$nbko++;
|
|
break;
|
|
}
|
|
|
|
$tmp = dol_getdate($now);
|
|
$datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
|
|
$datetosearchforend = dol_time_plus_duree(dol_mktime(23, 59, 59, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), (int) $daysbeforeend, 'd');
|
|
|
|
$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
|
|
$sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
|
|
$sql .= " AND statut = 1";
|
|
$sql .= " AND datefin >= '".$this->db->idate($datetosearchfor)."'";
|
|
$sql .= " AND datefin <= '".$this->db->idate($datetosearchforend)."'";
|
|
if ((int) $fk_adherent_type > 0) {
|
|
$sql .= " AND fk_adherent_type = ".((int) $fk_adherent_type);
|
|
}
|
|
//$sql .= " LIMIT 10000";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$num_rows = $this->db->num_rows($resql);
|
|
|
|
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
|
|
$adherent = new Adherent($this->db);
|
|
$formmail = new FormMail($this->db);
|
|
|
|
$i = 0;
|
|
while ($i < $num_rows) {
|
|
$obj = $this->db->fetch_object($resql);
|
|
|
|
$adherent->fetch($obj->rowid, '', 0, '', true, true);
|
|
|
|
if (empty($adherent->email)) {
|
|
$nbko++;
|
|
$listofmembersko[$adherent->id] = $adherent->id;
|
|
} else {
|
|
$thirdpartyres = $adherent->fetch_thirdparty();
|
|
if ($thirdpartyres === -1) {
|
|
$languagecodeformember = $mysoc->default_lang;
|
|
} else {
|
|
// Language code to use ($languagecodeformember) is default language of thirdparty, if no thirdparty, the language found from country of member then country of thirdparty, and if still not found we use the language of company.
|
|
$languagefromcountrycode = getLanguageCodeFromCountryCode($adherent->country_code ? $adherent->country_code : $adherent->thirdparty->country_code);
|
|
$languagecodeformember = (empty($adherent->thirdparty->default_lang) ? ($languagefromcountrycode ? $languagefromcountrycode : $mysoc->default_lang) : $adherent->thirdparty->default_lang);
|
|
}
|
|
|
|
// Send reminder email
|
|
$outputlangs = new Translate('', $conf);
|
|
$outputlangs->setDefaultLang($languagecodeformember);
|
|
$outputlangs->loadLangs(array("main", "members"));
|
|
dol_syslog("sendReminderForExpiredSubscription Language for member id ".$adherent->id." set to ".$outputlangs->defaultlang." mysoc->default_lang=".$mysoc->default_lang);
|
|
|
|
$arraydefaultmessage = null;
|
|
$labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION');
|
|
|
|
if (!empty($labeltouse)) {
|
|
$arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
|
|
}
|
|
|
|
if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) {
|
|
$substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
|
|
//if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
|
|
complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
|
|
|
|
$subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
|
|
$msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
|
|
$from = getDolGlobalString('ADHERENT_MAIL_FROM', $conf->email_from);
|
|
$to = $adherent->email;
|
|
$cc = getDolGlobalString('ADHERENT_CC_MAIL_FROM');
|
|
|
|
$trackid = 'mem'.$adherent->id;
|
|
$moreinheader = 'X-Dolibarr-Info: sendReminderForExpiredSubscription'."\r\n";
|
|
|
|
include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
|
|
$cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), $cc, '', 0, 1, '', '', $trackid, $moreinheader);
|
|
$result = $cmail->sendfile();
|
|
if (!$result) {
|
|
$error++;
|
|
$this->error .= $cmail->error.' ';
|
|
if (!is_null($cmail->errors)) {
|
|
$this->errors += $cmail->errors;
|
|
}
|
|
$nbko++;
|
|
$listofmembersko[$adherent->id] = $adherent->id;
|
|
} else {
|
|
$nbok++;
|
|
$listofmembersok[$adherent->id] = $adherent->id;
|
|
|
|
$message = $msg;
|
|
$sendto = $to;
|
|
$sendtocc = '';
|
|
$sendtobcc = '';
|
|
$actioncode = 'EMAIL';
|
|
$extraparams = array();
|
|
|
|
$actionmsg = '';
|
|
$actionmsg2 = $langs->transnoentities('MailSentByTo', CMailFile::getValidAddress($from, 4, 0, 1), CMailFile::getValidAddress($sendto, 4, 0, 1));
|
|
if ($message) {
|
|
$actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
|
|
$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
|
|
// if ($sendtocc) {
|
|
// $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc').": ".dol_escape_htmltag($sendtocc));
|
|
// }
|
|
$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject);
|
|
$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":");
|
|
$actionmsg = dol_concatdesc($actionmsg, $message);
|
|
}
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
|
|
|
// Insert record of emails sent
|
|
$actioncomm = new ActionComm($this->db);
|
|
|
|
$actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
|
|
$actioncomm->code = 'AC_'.$actioncode;
|
|
$actioncomm->label = $actionmsg2;
|
|
$actioncomm->note_private = $actionmsg;
|
|
$actioncomm->fk_project = 0;
|
|
$actioncomm->datep = $now;
|
|
$actioncomm->datef = $now;
|
|
$actioncomm->percentage = -1; // Not applicable
|
|
$actioncomm->socid = $adherent->thirdparty->id;
|
|
$actioncomm->contact_id = 0;
|
|
$actioncomm->authorid = $user->id; // User saving action
|
|
$actioncomm->userownerid = $user->id; // Owner of action
|
|
// Fields when action is an email (content should be added into note)
|
|
$actioncomm->email_msgid = $cmail->msgid;
|
|
$actioncomm->email_from = $from;
|
|
$actioncomm->email_sender = '';
|
|
$actioncomm->email_to = $to;
|
|
$actioncomm->email_tocc = $sendtocc;
|
|
$actioncomm->email_tobcc = $sendtobcc;
|
|
$actioncomm->email_subject = $subject;
|
|
$actioncomm->errors_to = '';
|
|
|
|
$actioncomm->fk_element = $adherent->id;
|
|
$actioncomm->elementid = $adherent->id;
|
|
$actioncomm->elementtype = $adherent->element;
|
|
|
|
$actioncomm->extraparams = $extraparams;
|
|
|
|
$actioncomm->create($user);
|
|
}
|
|
} else {
|
|
//$blockingerrormsg = "Can't find email template with label=".$labeltouse.", to use for the reminding email";
|
|
|
|
$error++;
|
|
$this->error .= "Can't find email template with label=".$labeltouse.", to use for the reminding email ";
|
|
|
|
$nbko++;
|
|
$listofmembersko[$adherent->id] = $adherent->id;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
$i++;
|
|
}
|
|
} else {
|
|
$this->error = $this->db->lasterror();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if ($blockingerrormsg) {
|
|
$this->error = $blockingerrormsg;
|
|
return 1;
|
|
} else {
|
|
$this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
|
|
$this->output .= ' Send email successfully to '.$nbok.' members';
|
|
$listofids = '';
|
|
$i = 0;
|
|
foreach ($listofmembersok as $idmember) {
|
|
if ($i > 100) {
|
|
$listofids .= ', ...';
|
|
break;
|
|
}
|
|
if (empty($listofids)) {
|
|
$listofids .= ' [';
|
|
} else {
|
|
$listofids .= ', ';
|
|
}
|
|
$listofids .= $idmember;
|
|
$i++;
|
|
}
|
|
if ($listofids) {
|
|
$listofids .= ']';
|
|
}
|
|
$this->output .= ($listofids ? ' ids='.$listofids : '');
|
|
|
|
if ($nbko) {
|
|
$this->output .= ' - Canceled for '.$nbko.' member (no email or email sending error)';
|
|
$listofids = '';
|
|
$i = 0;
|
|
foreach ($listofmembersko as $idmember) {
|
|
if ($i > 100) {
|
|
$listofids .= ', ...';
|
|
break;
|
|
}
|
|
if (empty($listofids)) {
|
|
$listofids .= ' [';
|
|
} else {
|
|
$listofids .= ', ';
|
|
}
|
|
$listofids .= $idmember;
|
|
$i++;
|
|
}
|
|
if ($listofids) {
|
|
$listofids .= ']';
|
|
}
|
|
$this->output .= ($listofids ? ' ids='.$listofids : '');
|
|
}
|
|
}
|
|
|
|
return $nbko;
|
|
}
|
|
|
|
/**
|
|
* Return clickable link of object (with eventually picto)
|
|
*
|
|
* @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
|
|
* @param ?array<string,mixed> $arraydata Array of data
|
|
* @return string HTML Code for Kanban thumb.
|
|
*/
|
|
public function getKanbanView($option = '', $arraydata = null)
|
|
{
|
|
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
|
|
|
|
$return = '<div class="box-flex-item box-flex-grow-zero">';
|
|
$return .= '<div class="info-box info-box-sm">';
|
|
$return .= '<span class="info-box-icon bg-infobox-action">';
|
|
if (!empty($this->photo)) {
|
|
$return .= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photowithmargin photologintooltip', 'small', 0, 1);
|
|
} else {
|
|
$return .= img_picto('', 'user');
|
|
}
|
|
$return .= '</span>';
|
|
$return .= '<div class="info-box-content">';
|
|
$return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->getNomUrl() . '</span>';
|
|
if ($selected >= 0) {
|
|
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
|
|
}
|
|
$return .= '<br><span class="info-box-label paddingright">'.$this->getmorphylib('', 2).'</span>';
|
|
$return .= '<span class="info-box-label opacitymedium">'.$this->type.'</span>';
|
|
|
|
$return .= '<br><div class="info-box-status paddingtop">';
|
|
$return .= $this->LibStatut($this->status, $this->need_subscription, $this->datefin, 5);
|
|
$return .= '</div>';
|
|
$return .= '</div>';
|
|
$return .= '</div>';
|
|
$return .= '</div>';
|
|
return $return;
|
|
}
|
|
}
|