adherent.class.php 92 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891
  1. <?php
  2. /* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org>
  4. * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
  6. * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
  7. * Copyright (C) 2009-2017 Regis Houssin <regis.houssin@inodbox.com>
  8. * Copyright (C) 2014-2018 Alexandre Spangaro <aspangaro@open-dsi.fr>
  9. * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
  10. * Copyright (C) 2015-2018 Frédéric France <frederic.france@netlogic.fr>
  11. * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
  12. * Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 3 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  26. */
  27. /**
  28. * \file htdocs/adherents/class/adherent.class.php
  29. * \ingroup member
  30. * \brief File of class to manage members of a foundation
  31. */
  32. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  33. require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  34. require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
  35. /**
  36. * Class to manage members of a foundation
  37. */
  38. class Adherent extends CommonObject
  39. {
  40. /**
  41. * @var string ID to identify managed object
  42. */
  43. public $element='member';
  44. /**
  45. * @var string Name of table without prefix where object is stored
  46. */
  47. public $table_element='adherent';
  48. /**
  49. * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  50. * @var int
  51. */
  52. public $ismultientitymanaged = 1;
  53. public $mesgs;
  54. /**
  55. * @var string login of member
  56. */
  57. public $login;
  58. //! Clear password in memory
  59. public $pass;
  60. //! Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
  61. public $pass_indatabase;
  62. //! Encrypted password in database (always defined)
  63. public $pass_indatabase_crypted;
  64. /**
  65. * @var string company name
  66. * @deprecated
  67. */
  68. public $societe;
  69. /**
  70. * @var string company name
  71. */
  72. public $company;
  73. /**
  74. * @var int Thirdparty ID
  75. */
  76. public $fk_soc;
  77. /**
  78. * @var string Address
  79. */
  80. public $address;
  81. /**
  82. * @var string zipcode
  83. */
  84. public $zip;
  85. /**
  86. * @var string town
  87. */
  88. public $town;
  89. /**
  90. * @var int Id of state
  91. */
  92. public $state_id;
  93. /**
  94. * @var string Code of state
  95. */
  96. public $state_code;
  97. /**
  98. * @var string Label of state
  99. */
  100. public $state;
  101. /**
  102. * @var string email
  103. */
  104. public $email;
  105. /**
  106. * @var string skype account
  107. */
  108. public $skype;
  109. /**
  110. * @var string twitter account
  111. */
  112. public $twitter;
  113. /**
  114. * @var string facebook account
  115. */
  116. public $facebook;
  117. /**
  118. * @var string Phone number
  119. */
  120. public $phone;
  121. /**
  122. * @var string Private Phone number
  123. */
  124. public $phone_perso;
  125. /**
  126. * @var string Mobile phone number
  127. */
  128. public $phone_mobile;
  129. /**
  130. * @var string Fax number
  131. */
  132. public $fax;
  133. /**
  134. * @var string Function
  135. */
  136. public $poste;
  137. public $morphy;
  138. public $public;
  139. // -1:brouillon, 0:resilie, >=1:valide,paye
  140. // def in common object
  141. //public $statut;
  142. public $photo;
  143. public $datec;
  144. public $datem;
  145. public $datevalid;
  146. public $gender;
  147. public $birth;
  148. /**
  149. * @var int id type member
  150. */
  151. public $typeid;
  152. /**
  153. * @var string label type member
  154. */
  155. public $type;
  156. public $need_subscription;
  157. public $user_id;
  158. public $user_login;
  159. public $datefin; // From member table
  160. // Fields loaded by fetch_subscriptions()
  161. public $first_subscription_date;
  162. public $first_subscription_amount;
  163. public $last_subscription_date;
  164. public $last_subscription_date_start;
  165. public $last_subscription_date_end;
  166. public $last_subscription_amount;
  167. public $subscriptions=array();
  168. /**
  169. * @var Adherent To contains a clone of this when we need to save old properties of object
  170. */
  171. public $oldcopy;
  172. /**
  173. * @var int Entity
  174. */
  175. public $entity;
  176. /**
  177. * Constructor
  178. *
  179. * @param DoliDB $db Database handler
  180. */
  181. function __construct($db)
  182. {
  183. $this->db = $db;
  184. $this->statut = -1;
  185. // l'adherent n'est pas public par defaut
  186. $this->public = 0;
  187. // les champs optionnels sont vides
  188. $this->array_options=array();
  189. }
  190. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  191. /**
  192. * Function sending an email to the current member with the text supplied in parameter.
  193. *
  194. * @param string $text Content of message (not html entities encoded)
  195. * @param string $subject Subject of message
  196. * @param array $filename_list Array of attached files
  197. * @param array $mimetype_list Array of mime types of attached files
  198. * @param array $mimefilename_list Array of public names of attached files
  199. * @param string $addr_cc Email cc
  200. * @param string $addr_bcc Email bcc
  201. * @param int $deliveryreceipt Ask a delivery receipt
  202. * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
  203. * @param string $errors_to erros to
  204. * @param string $moreinheader Add more html headers
  205. * @return int <0 if KO, >0 if OK
  206. */
  207. 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 = '')
  208. {
  209. // phpcs:enable
  210. global $conf,$langs;
  211. // Detect if message is HTML
  212. if ($msgishtml == -1)
  213. {
  214. $msgishtml = 0;
  215. if (dol_textishtml($text,0)) $msgishtml = 1;
  216. }
  217. dol_syslog('send_an_email msgishtml='.$msgishtml);
  218. $texttosend=$this->makeSubstitution($text);
  219. $subjecttosend=$this->makeSubstitution($subject);
  220. if ($msgishtml) $texttosend=dol_htmlentitiesbr($texttosend);
  221. // Envoi mail confirmation
  222. $from=$conf->email_from;
  223. if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM;
  224. $trackid = 'mem'.$this->id;
  225. // Send email (substitutionarray must be done just before this)
  226. include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
  227. $mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, '', '', $trackid, $moreinheader);
  228. if ($mailfile->sendfile())
  229. {
  230. return 1;
  231. }
  232. else
  233. {
  234. $this->error=$langs->trans("ErrorFailedToSendMail",$from,$this->email).'. '.$mailfile->error;
  235. return -1;
  236. }
  237. }
  238. /**
  239. * Make substitution of tags into text with value of current object.
  240. *
  241. * @param string $text Text to make substitution to
  242. * @return string Value of input text string with substitutions done
  243. */
  244. function makeSubstitution($text)
  245. {
  246. global $conf,$langs;
  247. $birthday = dol_print_date($this->birth,'day');
  248. $msgishtml = 0;
  249. if (dol_textishtml($text,1)) $msgishtml = 1;
  250. $infos='';
  251. if ($this->civility_id) $infos.= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
  252. $infos.= $langs->transnoentities("id").": ".$this->id."\n";
  253. $infos.= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
  254. $infos.= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
  255. $infos.= $langs->transnoentities("Company").": ".$this->societe."\n";
  256. $infos.= $langs->transnoentities("Address").": ".$this->address."\n";
  257. $infos.= $langs->transnoentities("Zip").": ".$this->zip."\n";
  258. $infos.= $langs->transnoentities("Town").": ".$this->town."\n";
  259. $infos.= $langs->transnoentities("Country").": ".$this->country."\n";
  260. $infos.= $langs->transnoentities("EMail").": ".$this->email."\n";
  261. $infos.= $langs->transnoentities("PhonePro").": ".$this->phone."\n";
  262. $infos.= $langs->transnoentities("PhonePerso").": ".$this->phone_perso."\n";
  263. $infos.= $langs->transnoentities("PhoneMobile").": ".$this->phone_mobile."\n";
  264. if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
  265. {
  266. $infos.= $langs->transnoentities("Login").": ".$this->login."\n";
  267. $infos.= $langs->transnoentities("Password").": ".$this->pass."\n";
  268. }
  269. $infos.= $langs->transnoentities("Birthday").": ".$birthday."\n";
  270. $infos.= $langs->transnoentities("Photo").": ".$this->photo."\n";
  271. $infos.= $langs->transnoentities("Public").": ".yn($this->public);
  272. // Substitutions
  273. $substitutionarray=array(
  274. '__ID__'=>$this->id,
  275. '__MEMBER_ID__'=>$this->id,
  276. '__CIVILITY__'=>$this->getCivilityLabel(),
  277. '__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):($this->firstname?$this->firstname:''),
  278. '__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):($this->lastname?$this->lastname:''),
  279. '__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs),
  280. '__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):($this->societe?$this->societe:''),
  281. '__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):($this->address?$this->address:''),
  282. '__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):($this->zip?$this->zip:''),
  283. '__TOWN__'=>$msgishtml?dol_htmlentitiesbr($this->town):($this->town?$this->town:''),
  284. '__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):($this->country?$this->country:''),
  285. '__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):($this->email?$this->email:''),
  286. '__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):($birthday?$birthday:''),
  287. '__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):($this->photo?$this->photo:''),
  288. '__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):($this->login?$this->login:''),
  289. '__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):($this->pass?$this->pass:''),
  290. '__PHONE__'=>$msgishtml?dol_htmlentitiesbr($this->phone):($this->phone?$this->phone:''),
  291. '__PHONEPRO__'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):($this->phone_perso?$this->phone_perso:''),
  292. '__PHONEMOBILE__'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):($this->phone_mobile?$this->phone_mobile:'')
  293. );
  294. complete_substitutions_array($substitutionarray, $langs, $this);
  295. return make_substitutions($text, $substitutionarray, $langs);
  296. }
  297. /**
  298. * Return translated label by the nature of a adherent (physical or moral)
  299. *
  300. * @param string $morphy Nature of the adherent (physical or moral)
  301. * @return string Label
  302. */
  303. function getmorphylib($morphy = '')
  304. {
  305. global $langs;
  306. if (! $morphy) { $morphy=$this->morphy; }
  307. if ($morphy == 'phy') { return $langs->trans("Physical"); }
  308. if ($morphy == 'mor') { return $langs->trans("Moral"); }
  309. return $morphy;
  310. }
  311. /**
  312. * Create a member into database
  313. *
  314. * @param User $user Objet user qui demande la creation
  315. * @param int $notrigger 1 ne declenche pas les triggers, 0 sinon
  316. * @return int <0 if KO, >0 if OK
  317. */
  318. function create($user, $notrigger = 0)
  319. {
  320. global $conf,$langs;
  321. $error=0;
  322. $now=dol_now();
  323. // Clean parameters
  324. $this->import_key = trim($this->import_key);
  325. // Check parameters
  326. if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
  327. {
  328. $langs->load("errors");
  329. $this->error = $langs->trans("ErrorBadEMail",$this->email);
  330. return -1;
  331. }
  332. if (! $this->datec) $this->datec=$now;
  333. if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
  334. {
  335. if (empty($this->login))
  336. {
  337. $this->error = $langs->trans("ErrorWrongValueForParameterX","Login");
  338. return -1;
  339. }
  340. }
  341. $this->db->begin();
  342. // Insert member
  343. $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
  344. $sql.= " (datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key)";
  345. $sql.= " VALUES (";
  346. $sql.= " '".$this->db->idate($this->datec)."'";
  347. $sql.= ", ".($this->login?"'".$this->db->escape($this->login)."'":"null");
  348. $sql.= ", ".($user->id>0?$user->id:"null"); // Can be null because member can be created by a guest or a script
  349. $sql.= ", null, null, '".$this->db->escape($this->morphy)."'";
  350. $sql.= ", ".$this->typeid;
  351. $sql.= ", ".$conf->entity;
  352. $sql.= ", ".(! empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'":"null");
  353. $sql.= ")";
  354. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  355. $result = $this->db->query($sql);
  356. if ($result)
  357. {
  358. $id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
  359. if ($id > 0)
  360. {
  361. $this->id=$id;
  362. $this->ref=(string) $id;
  363. // Update minor fields
  364. $result=$this->update($user,1,1,0,0,'add'); // nosync is 1 to avoid update data of user
  365. if ($result < 0)
  366. {
  367. $this->db->rollback();
  368. return -1;
  369. }
  370. // Add link to user
  371. if ($this->user_id)
  372. {
  373. // Add link to user
  374. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
  375. $sql.= " fk_member = ".$this->id;
  376. $sql.= " WHERE rowid = ".$this->user_id;
  377. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  378. $resql = $this->db->query($sql);
  379. if (! $resql)
  380. {
  381. $this->error='Failed to update user to make link with member';
  382. $this->db->rollback();
  383. return -4;
  384. }
  385. }
  386. if (! $notrigger)
  387. {
  388. // Call trigger
  389. $result=$this->call_trigger('MEMBER_CREATE',$user);
  390. if ($result < 0) { $error++; }
  391. // End call triggers
  392. }
  393. if (count($this->errors))
  394. {
  395. dol_syslog(get_class($this)."::create ".implode(',',$this->errors), LOG_ERR);
  396. $this->db->rollback();
  397. return -3;
  398. }
  399. else
  400. {
  401. $this->db->commit();
  402. return $this->id;
  403. }
  404. }
  405. else
  406. {
  407. $this->error='Failed to get last insert id';
  408. dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
  409. $this->db->rollback();
  410. return -2;
  411. }
  412. }
  413. else
  414. {
  415. $this->error=$this->db->error();
  416. $this->db->rollback();
  417. return -1;
  418. }
  419. }
  420. /**
  421. * Update a member in database (standard information and password)
  422. *
  423. * @param User $user User making update
  424. * @param int $notrigger 1=disable trigger UPDATE (when called by create)
  425. * @param int $nosyncuser 0=Synchronize linked user (standard info), 1=Do not synchronize linked user
  426. * @param int $nosyncuserpass 0=Synchronize linked user (password), 1=Do not synchronize linked user
  427. * @param int $nosyncthirdparty 0=Synchronize linked thirdparty (standard info), 1=Do not synchronize linked thirdparty
  428. * @param string $action Current action for hookmanager
  429. * @return int <0 if KO, >0 if OK
  430. */
  431. function update($user, $notrigger = 0, $nosyncuser = 0, $nosyncuserpass = 0, $nosyncthirdparty = 0, $action = 'update')
  432. {
  433. global $conf, $langs, $hookmanager;
  434. $nbrowsaffected=0;
  435. $error=0;
  436. dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
  437. // Clean parameters
  438. $this->lastname = trim($this->lastname)?trim($this->lastname):trim($this->lastname);
  439. $this->firstname = trim($this->firstname)?trim($this->firstname):trim($this->firstname);
  440. $this->gender = trim($this->gender);
  441. $this->address = ($this->address?$this->address:$this->address);
  442. $this->zip = ($this->zip?$this->zip:$this->zip);
  443. $this->town = ($this->town?$this->town:$this->town);
  444. $this->country_id = ($this->country_id > 0?$this->country_id:$this->country_id);
  445. $this->state_id = ($this->state_id > 0?$this->state_id:$this->state_id);
  446. if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname=ucwords(trim($this->lastname));
  447. if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname=ucwords(trim($this->firstname));
  448. $this->note_public = ($this->note_public?$this->note_public:$this->note_public);
  449. $this->note_private = ($this->note_private?$this->note_private:$this->note_private);
  450. // Check parameters
  451. if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
  452. {
  453. $langs->load("errors");
  454. $this->error = $langs->trans("ErrorBadEMail",$this->email);
  455. return -1;
  456. }
  457. $this->db->begin();
  458. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
  459. $sql.= " civility = ".($this->civility_id?"'".$this->db->escape($this->civility_id)."'":"null");
  460. $sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null");
  461. $sql.= ", lastname = ".($this->lastname?"'".$this->db->escape($this->lastname)."'":"null");
  462. $sql.= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman'
  463. $sql.= ", login = ".($this->login?"'".$this->db->escape($this->login)."'":"null");
  464. $sql.= ", societe = ".($this->societe?"'".$this->db->escape($this->societe)."'":"null");
  465. $sql.= ", fk_soc = ".($this->fk_soc > 0?$this->db->escape($this->fk_soc):"null");
  466. $sql.= ", address = ".($this->address?"'".$this->db->escape($this->address)."'":"null");
  467. $sql.= ", zip = ".($this->zip?"'".$this->db->escape($this->zip)."'":"null");
  468. $sql.= ", town = ".($this->town?"'".$this->db->escape($this->town)."'":"null");
  469. $sql.= ", country = ".($this->country_id>0?$this->db->escape($this->country_id):"null");
  470. $sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null");
  471. $sql.= ", email = '".$this->db->escape($this->email)."'";
  472. $sql.= ", skype = '".$this->db->escape($this->skype)."'";
  473. $sql.= ", twitter = '".$this->db->escape($this->twitter)."'";
  474. $sql.= ", facebook = '".$this->db->escape($this->facebook)."'";
  475. $sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null");
  476. $sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null");
  477. $sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null");
  478. $sql.= ", note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
  479. $sql.= ", note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
  480. $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null");
  481. $sql.= ", public = '".$this->db->escape($this->public)."'";
  482. $sql.= ", statut = ".$this->db->escape($this->statut);
  483. $sql.= ", fk_adherent_type = ".$this->db->escape($this->typeid);
  484. $sql.= ", morphy = '".$this->db->escape($this->morphy)."'";
  485. $sql.= ", birth = ".($this->birth?"'".$this->db->idate($this->birth)."'":"null");
  486. if ($this->datefin) $sql.= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
  487. if ($this->datevalid) $sql.= ", datevalid = '".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member
  488. $sql.= ", fk_user_mod = ".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest
  489. $sql.= " WHERE rowid = ".$this->id;
  490. dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
  491. $resql = $this->db->query($sql);
  492. if ($resql)
  493. {
  494. unset($this->country_code);
  495. unset($this->country);
  496. unset($this->state_code);
  497. unset($this->state);
  498. $nbrowsaffected+=$this->db->affected_rows($resql);
  499. $action='update';
  500. // Actions on extra fields
  501. if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
  502. {
  503. $result=$this->insertExtraFields();
  504. if ($result < 0)
  505. {
  506. $error++;
  507. }
  508. }
  509. // Update password
  510. if (! $error && $this->pass)
  511. {
  512. dol_syslog(get_class($this)."::update update password");
  513. if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted)
  514. {
  515. $isencrypted = empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1;
  516. // If password to set differs from the one found into database
  517. $result=$this->setPassword($user,$this->pass,$isencrypted,$notrigger,$nosyncuserpass);
  518. if (! $nbrowsaffected) $nbrowsaffected++;
  519. }
  520. }
  521. // Remove links to user and replace with new one
  522. if (! $error)
  523. {
  524. dol_syslog(get_class($this)."::update update link to user");
  525. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id;
  526. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  527. $resql = $this->db->query($sql);
  528. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
  529. // If there is a user linked to this member
  530. if ($this->user_id > 0)
  531. {
  532. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id." WHERE rowid = ".$this->user_id;
  533. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  534. $resql = $this->db->query($sql);
  535. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
  536. }
  537. }
  538. if (! $error && $nbrowsaffected) // If something has change in main data
  539. {
  540. // Update information on linked user if it is an update
  541. if (! $error && $this->user_id > 0 && ! $nosyncuser)
  542. {
  543. require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
  544. dol_syslog(get_class($this)."::update update linked user");
  545. $luser=new User($this->db);
  546. $result=$luser->fetch($this->user_id);
  547. if ($result >= 0)
  548. {
  549. //var_dump($this->user_login);exit;
  550. //var_dump($this->login);exit;
  551. // 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.
  552. if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED)) $luser->login=$this->login;
  553. $luser->civility_id=$this->civility_id;
  554. $luser->firstname=$this->firstname;
  555. $luser->lastname=$this->lastname;
  556. $luser->gender=$this->gender;
  557. $luser->pass=$this->pass;
  558. $luser->societe_id=$this->societe;
  559. $luser->birth=$this->birth;
  560. $luser->address=$this->address;
  561. $luser->zip=$this->zip;
  562. $luser->town=$this->town;
  563. $luser->country_id=$this->country_id;
  564. $luser->state_id=$this->state_id;
  565. $luser->email=$this->email;
  566. $luser->skype=$this->skype;
  567. $luser->twitter=$this->twitter;
  568. $luser->facebook=$this->facebook;
  569. $luser->office_phone=$this->phone;
  570. $luser->user_mobile=$this->phone_mobile;
  571. $luser->fk_member=$this->id;
  572. $result=$luser->update($user,0,1,1); // Use nosync to 1 to avoid cyclic updates
  573. if ($result < 0)
  574. {
  575. $this->error=$luser->error;
  576. dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR);
  577. $error++;
  578. }
  579. }
  580. else
  581. {
  582. $this->error=$luser->error;
  583. $error++;
  584. }
  585. }
  586. // Update information on linked thirdparty if it is an update
  587. if (! $error && $this->fk_soc > 0 && ! $nosyncthirdparty)
  588. {
  589. require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
  590. dol_syslog(get_class($this)."::update update linked thirdparty");
  591. // This member is linked with a thirdparty, so we also update thirdparty informations
  592. // if this is an update.
  593. $lthirdparty=new Societe($this->db);
  594. $result=$lthirdparty->fetch($this->fk_soc);
  595. if ($result >= 0)
  596. {
  597. $lthirdparty->address=$this->address;
  598. $lthirdparty->zip=$this->zip;
  599. $lthirdparty->town=$this->town;
  600. $lthirdparty->email=$this->email;
  601. $lthirdparty->skype=$this->skype;
  602. $lthirdparty->twitter=$this->twitter;
  603. $lthirdparty->facebook=$this->facebook;
  604. $lthirdparty->phone=$this->phone;
  605. $lthirdparty->state_id=$this->state_id;
  606. $lthirdparty->country_id=$this->country_id;
  607. //$lthirdparty->phone_mobile=$this->phone_mobile;
  608. $result=$lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates
  609. if ($result < 0)
  610. {
  611. $this->error=$lthirdparty->error;
  612. $this->errors=$lthirdparty->errors;
  613. dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR);
  614. $error++;
  615. }
  616. }
  617. else
  618. {
  619. $this->error=$lthirdparty->error;
  620. $error++;
  621. }
  622. }
  623. }
  624. if (! $error && ! $notrigger)
  625. {
  626. // Call trigger
  627. $result=$this->call_trigger('MEMBER_MODIFY',$user);
  628. if ($result < 0) { $error++; }
  629. // End call triggers
  630. }
  631. if (! $error)
  632. {
  633. $this->db->commit();
  634. return $nbrowsaffected;
  635. }
  636. else
  637. {
  638. $this->db->rollback();
  639. return -1;
  640. }
  641. }
  642. else
  643. {
  644. $this->db->rollback();
  645. $this->error=$this->db->lasterror();
  646. return -2;
  647. }
  648. }
  649. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  650. /**
  651. * Update denormalized last subscription date.
  652. * This function is called when we delete a subscription for example.
  653. *
  654. * @param User $user User making change
  655. * @return int <0 if KO, >0 if OK
  656. */
  657. function update_end_date($user)
  658. {
  659. // phpcs:enable
  660. $this->db->begin();
  661. // Search for last subscription id and end date
  662. $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
  663. $sql.= " FROM ".MAIN_DB_PREFIX."subscription";
  664. $sql.= " WHERE fk_adherent=".$this->id;
  665. $sql.= " ORDER by dateadh DESC"; // Sort by start subscription date
  666. dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
  667. $resql=$this->db->query($sql);
  668. if ($resql)
  669. {
  670. $obj=$this->db->fetch_object($resql);
  671. $dateop=$this->db->jdate($obj->dateop);
  672. $datedeb=$this->db->jdate($obj->datedeb);
  673. $datefin=$this->db->jdate($obj->datefin);
  674. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
  675. $sql.= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
  676. $sql.= " WHERE rowid = ".$this->id;
  677. dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
  678. $resql=$this->db->query($sql);
  679. if ($resql)
  680. {
  681. $this->last_subscription_date=$dateop;
  682. $this->last_subscription_date_start=$datedeb;
  683. $this->last_subscription_date_end=$datefin;
  684. $this->datefin=$datefin;
  685. $this->db->commit();
  686. return 1;
  687. }
  688. else
  689. {
  690. $this->db->rollback();
  691. return -1;
  692. }
  693. }
  694. else
  695. {
  696. $this->error=$this->db->lasterror();
  697. $this->db->rollback();
  698. return -1;
  699. }
  700. }
  701. /**
  702. * Fonction qui supprime l'adherent et les donnees associees
  703. *
  704. * @param int $rowid Id of member to delete
  705. * @param User $user User object
  706. * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
  707. * @return int <0 if KO, 0=nothing to do, >0 if OK
  708. */
  709. function delete($rowid, $user, $notrigger = 0)
  710. {
  711. global $conf, $langs;
  712. $result = 0;
  713. $error=0;
  714. $errorflag=0;
  715. // Check parameters
  716. if (empty($rowid)) $rowid=$this->id;
  717. $this->db->begin();
  718. if (! $error && ! $notrigger)
  719. {
  720. // Call trigger
  721. $result=$this->call_trigger('MEMBER_DELETE',$user);
  722. if ($result < 0) $error++;
  723. // End call triggers
  724. }
  725. // Remove category
  726. $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid;
  727. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  728. $resql=$this->db->query($sql);
  729. if (! $resql)
  730. {
  731. $error++;
  732. $this->error .= $this->db->lasterror();
  733. $errorflag=-1;
  734. }
  735. // Remove subscription
  736. if (! $error)
  737. {
  738. $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid;
  739. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  740. $resql=$this->db->query($sql);
  741. if (! $resql)
  742. {
  743. $error++;
  744. $this->error .= $this->db->lasterror();
  745. $errorflag=-2;
  746. }
  747. }
  748. // Remove linked user
  749. if (! $error)
  750. {
  751. $ret=$this->setUserId(0);
  752. if ($ret < 0)
  753. {
  754. $error++;
  755. $this->error .= $this->db->lasterror();
  756. $errorflag=-3;
  757. }
  758. }
  759. // Removed extrafields
  760. if (! $error)
  761. {
  762. if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
  763. {
  764. $result=$this->deleteExtraFields();
  765. if ($result < 0)
  766. {
  767. $error++;
  768. $errorflag=-4;
  769. dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
  770. }
  771. }
  772. }
  773. // Remove adherent
  774. if (! $error)
  775. {
  776. $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid;
  777. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  778. $resql=$this->db->query($sql);
  779. if (! $resql)
  780. {
  781. $error++;
  782. $this->error .= $this->db->lasterror();
  783. $errorflag=-5;
  784. }
  785. }
  786. if (! $error)
  787. {
  788. $this->db->commit();
  789. return 1;
  790. }
  791. else
  792. {
  793. $this->db->rollback();
  794. return $errorflag;
  795. }
  796. }
  797. /**
  798. * Change password of a user
  799. *
  800. * @param User $user Object user de l'utilisateur qui fait la modification
  801. * @param string $password New password (to generate if empty)
  802. * @param int $isencrypted 0 ou 1 si il faut crypter le mot de passe en base (0 par defaut)
  803. * @param int $notrigger 1=Ne declenche pas les triggers
  804. * @param int $nosyncuser Do not synchronize linked user
  805. * @return string If OK return clear password, 0 if no change, < 0 if error
  806. */
  807. function setPassword($user, $password = '', $isencrypted = 0, $notrigger = 0, $nosyncuser = 0)
  808. {
  809. global $conf, $langs;
  810. $error=0;
  811. dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i','*',$password)." isencrypted=".$isencrypted);
  812. // If new password not provided, we generate one
  813. if (! $password)
  814. {
  815. require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
  816. $password=getRandomPassword(false);
  817. }
  818. // Crypt password
  819. $password_crypted = dol_hash($password);
  820. $password_indatabase = '';
  821. if (! $isencrypted)
  822. {
  823. $password_indatabase = $password;
  824. }
  825. $this->db->begin();
  826. // Mise a jour
  827. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
  828. $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
  829. //if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
  830. if ($isencrypted)
  831. {
  832. $sql.= ", pass = null";
  833. }
  834. else
  835. {
  836. $sql.= ", pass = '".$this->db->escape($password_indatabase)."'";
  837. }
  838. $sql.= " WHERE rowid = ".$this->id;
  839. //dol_syslog("Adherent::Password sql=hidden");
  840. dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
  841. $result = $this->db->query($sql);
  842. if ($result)
  843. {
  844. $nbaffectedrows=$this->db->affected_rows($result);
  845. if ($nbaffectedrows)
  846. {
  847. $this->pass=$password;
  848. $this->pass_indatabase=$password_indatabase;
  849. $this->pass_indatabase_crypted=$password_crypted;
  850. if ($this->user_id && ! $nosyncuser)
  851. {
  852. require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
  853. // This member is linked with a user, so we also update users informations
  854. // if this is an update.
  855. $luser=new User($this->db);
  856. $result=$luser->fetch($this->user_id);
  857. if ($result >= 0)
  858. {
  859. $result=$luser->setPassword($user,$this->pass,0,0,1);
  860. if ($result < 0)
  861. {
  862. $this->error=$luser->error;
  863. dol_syslog(get_class($this)."::setPassword ".$this->error,LOG_ERR);
  864. $error++;
  865. }
  866. }
  867. else
  868. {
  869. $this->error=$luser->error;
  870. $error++;
  871. }
  872. }
  873. if (! $error && ! $notrigger)
  874. {
  875. // Call trigger
  876. $result=$this->call_trigger('MEMBER_NEW_PASSWORD',$user);
  877. if ($result < 0) { $error++; $this->db->rollback(); return -1; }
  878. // End call triggers
  879. }
  880. $this->db->commit();
  881. return $this->pass;
  882. }
  883. else
  884. {
  885. $this->db->rollback();
  886. return 0;
  887. }
  888. }
  889. else
  890. {
  891. $this->db->rollback();
  892. dol_print_error($this->db);
  893. return -1;
  894. }
  895. }
  896. /**
  897. * Set link to a user
  898. *
  899. * @param int $userid Id of user to link to
  900. * @return int 1=OK, -1=KO
  901. */
  902. function setUserId($userid)
  903. {
  904. global $conf, $langs;
  905. $this->db->begin();
  906. // If user is linked to this member, remove old link to this member
  907. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id;
  908. dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
  909. $resql = $this->db->query($sql);
  910. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -1; }
  911. // Set link to user
  912. if ($userid > 0)
  913. {
  914. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id;
  915. $sql.= " WHERE rowid = ".$userid;
  916. dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
  917. $resql = $this->db->query($sql);
  918. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -2; }
  919. }
  920. $this->db->commit();
  921. return 1;
  922. }
  923. /**
  924. * Set link to a third party
  925. *
  926. * @param int $thirdpartyid Id of user to link to
  927. * @return int 1=OK, -1=KO
  928. */
  929. function setThirdPartyId($thirdpartyid)
  930. {
  931. global $conf, $langs;
  932. $this->db->begin();
  933. // Remove link to third party onto any other members
  934. if ($thirdpartyid > 0)
  935. {
  936. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
  937. $sql.= " WHERE fk_soc = '".$thirdpartyid."'";
  938. $sql.= " AND entity = ".$conf->entity;
  939. dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
  940. $resql = $this->db->query($sql);
  941. }
  942. // Add link to third party for current member
  943. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid>0 ? $thirdpartyid : 'null');
  944. $sql.= " WHERE rowid = ".$this->id;
  945. dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
  946. $resql = $this->db->query($sql);
  947. if ($resql)
  948. {
  949. $this->db->commit();
  950. return 1;
  951. }
  952. else
  953. {
  954. $this->error=$this->db->error();
  955. $this->db->rollback();
  956. return -1;
  957. }
  958. }
  959. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  960. /**
  961. * Method to load member from its login
  962. *
  963. * @param string $login login of member
  964. * @return void
  965. */
  966. function fetch_login($login)
  967. {
  968. // phpcs:enable
  969. global $conf;
  970. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
  971. $sql.= " WHERE login='".$this->db->escape($login)."'";
  972. $sql.= " AND entity = ".$conf->entity;
  973. $resql=$this->db->query($sql);
  974. if ($resql)
  975. {
  976. if ($this->db->num_rows($resql))
  977. {
  978. $obj = $this->db->fetch_object($resql);
  979. $this->fetch($obj->rowid);
  980. }
  981. }
  982. else
  983. {
  984. dol_print_error($this->db);
  985. }
  986. }
  987. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  988. /**
  989. * Method to load member from its name
  990. *
  991. * @param string $firstname Firstname
  992. * @param string $lastname Lastname
  993. * @return void
  994. */
  995. function fetch_name($firstname, $lastname)
  996. {
  997. // phpcs:enable
  998. global $conf;
  999. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
  1000. $sql.= " WHERE firstname='".$this->db->escape($firstname)."'";
  1001. $sql.= " AND lastname='".$this->db->escape($lastname)."'";
  1002. $sql.= " AND entity = ".$conf->entity;
  1003. $resql=$this->db->query($sql);
  1004. if ($resql)
  1005. {
  1006. if ($this->db->num_rows($resql))
  1007. {
  1008. $obj = $this->db->fetch_object($resql);
  1009. $this->fetch($obj->rowid);
  1010. }
  1011. }
  1012. else
  1013. {
  1014. dol_print_error($this->db);
  1015. }
  1016. }
  1017. /**
  1018. * Load member from database
  1019. *
  1020. * @param int $rowid Id of object to load
  1021. * @param string $ref To load member from its ref
  1022. * @param int $fk_soc To load member from its link to third party
  1023. * @param string $ref_ext External reference
  1024. * @param bool $fetch_optionals To load optionals (extrafields)
  1025. * @param bool $fetch_subscriptions To load member subscriptions
  1026. * @return int >0 if OK, 0 if not found, <0 if KO
  1027. */
  1028. function fetch($rowid, $ref = '', $fk_soc = '', $ref_ext = '', $fetch_optionals = true, $fetch_subscriptions = true)
  1029. {
  1030. global $langs;
  1031. $sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.gender, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
  1032. $sql.= " d.note_public,";
  1033. $sql.= " d.email, d.skype, d.twitter, d.facebook, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
  1034. $sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
  1035. $sql.= " d.datec as datec,";
  1036. $sql.= " d.tms as datem,";
  1037. $sql.= " d.datefin as datefin,";
  1038. $sql.= " d.birth as birthday,";
  1039. $sql.= " d.datevalid as datev,";
  1040. $sql.= " d.country,";
  1041. $sql.= " d.state_id,";
  1042. $sql.= " d.model_pdf,";
  1043. $sql.= " c.rowid as country_id, c.code as country_code, c.label as country,";
  1044. $sql.= " dep.nom as state, dep.code_departement as state_code,";
  1045. $sql.= " t.libelle as type, t.subscription as subscription,";
  1046. $sql.= " u.rowid as user_id, u.login as user_login";
  1047. $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
  1048. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
  1049. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
  1050. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
  1051. $sql.= " WHERE d.fk_adherent_type = t.rowid";
  1052. if ($rowid) $sql.= " AND d.rowid=".$rowid;
  1053. elseif ($ref || $fk_soc) {
  1054. $sql.= " AND d.entity IN (".getEntity('adherent').")";
  1055. if ($ref) $sql.= " AND d.rowid='".$this->db->escape($ref)."'";
  1056. elseif ($fk_soc > 0) $sql.= " AND d.fk_soc=".$fk_soc;
  1057. }
  1058. elseif ($ref_ext)
  1059. {
  1060. $sql.= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
  1061. }
  1062. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  1063. $resql=$this->db->query($sql);
  1064. if ($resql)
  1065. {
  1066. if ($this->db->num_rows($resql))
  1067. {
  1068. $obj = $this->db->fetch_object($resql);
  1069. $this->entity = $obj->entity;
  1070. $this->ref = $obj->rowid;
  1071. $this->id = $obj->rowid;
  1072. $this->ref_ext = $obj->ref_ext;
  1073. $this->civility_id = $obj->civility_id;
  1074. $this->firstname = $obj->firstname;
  1075. $this->lastname = $obj->lastname;
  1076. $this->gender = $obj->gender;
  1077. $this->login = $obj->login;
  1078. $this->societe = $obj->company;
  1079. $this->company = $obj->company;
  1080. $this->fk_soc = $obj->fk_soc;
  1081. $this->address = $obj->address;
  1082. $this->zip = $obj->zip;
  1083. $this->town = $obj->town;
  1084. $this->pass = $obj->pass;
  1085. $this->pass_indatabase = $obj->pass;
  1086. $this->pass_indatabase_crypted = $obj->pass_crypted;
  1087. $this->state_id = $obj->state_id;
  1088. $this->state_code = $obj->state_id?$obj->state_code:'';
  1089. $this->state = $obj->state_id?$obj->state:'';
  1090. $this->country_id = $obj->country_id;
  1091. $this->country_code = $obj->country_code;
  1092. if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code)
  1093. $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
  1094. else
  1095. $this->country=$obj->country;
  1096. $this->phone = $obj->phone;
  1097. $this->phone_perso = $obj->phone_perso;
  1098. $this->phone_mobile = $obj->phone_mobile;
  1099. $this->email = $obj->email;
  1100. $this->skype = $obj->skype;
  1101. $this->twitter = $obj->twitter;
  1102. $this->facebook = $obj->facebook;
  1103. $this->photo = $obj->photo;
  1104. $this->statut = $obj->statut;
  1105. $this->public = $obj->public;
  1106. $this->datec = $this->db->jdate($obj->datec);
  1107. $this->datem = $this->db->jdate($obj->datem);
  1108. $this->datefin = $this->db->jdate($obj->datefin);
  1109. $this->datevalid = $this->db->jdate($obj->datev);
  1110. $this->birth = $this->db->jdate($obj->birthday);
  1111. $this->note_private = $obj->note_private;
  1112. $this->note_public = $obj->note_public;
  1113. $this->morphy = $obj->morphy;
  1114. $this->typeid = $obj->fk_adherent_type;
  1115. $this->type = $obj->type;
  1116. $this->need_subscription = $obj->subscription;
  1117. $this->user_id = $obj->user_id;
  1118. $this->user_login = $obj->user_login;
  1119. $this->model_pdf = $obj->model_pdf;
  1120. // Retreive all extrafield
  1121. // fetch optionals attributes and labels
  1122. if ($fetch_optionals) {
  1123. $this->fetch_optionals();
  1124. }
  1125. // Load other properties
  1126. if ($fetch_subscriptions) {
  1127. $result=$this->fetch_subscriptions();
  1128. }
  1129. return $this->id;
  1130. }
  1131. else
  1132. {
  1133. return 0;
  1134. }
  1135. }
  1136. else
  1137. {
  1138. $this->error=$this->db->lasterror();
  1139. return -1;
  1140. }
  1141. }
  1142. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  1143. /**
  1144. * Function to get member subscriptions data
  1145. * first_subscription_date, first_subscription_date_start, first_subscription_date_end, first_subscription_amount
  1146. * last_subscription_date, last_subscription_date_start, last_subscription_date_end, last_subscription_amount
  1147. *
  1148. * @return int <0 si KO, >0 si OK
  1149. */
  1150. function fetch_subscriptions()
  1151. {
  1152. // phpcs:enable
  1153. global $langs;
  1154. require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
  1155. $sql = "SELECT c.rowid, c.fk_adherent, c.subscription, c.note, c.fk_bank,";
  1156. $sql.= " c.tms as datem,";
  1157. $sql.= " c.datec as datec,";
  1158. $sql.= " c.dateadh as dateh,";
  1159. $sql.= " c.datef as datef";
  1160. $sql.= " FROM ".MAIN_DB_PREFIX."subscription as c";
  1161. $sql.= " WHERE c.fk_adherent = ".$this->id;
  1162. $sql.= " ORDER BY c.dateadh";
  1163. dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
  1164. $resql=$this->db->query($sql);
  1165. if ($resql)
  1166. {
  1167. $this->subscriptions=array();
  1168. $i=0;
  1169. while ($obj = $this->db->fetch_object($resql))
  1170. {
  1171. if ($i==0)
  1172. {
  1173. $this->first_subscription_date=$this->db->jdate($obj->datec);
  1174. $this->first_subscription_date_start=$this->db->jdate($obj->dateh);
  1175. $this->first_subscription_date_end=$this->db->jdate($obj->datef);
  1176. $this->first_subscription_amount=$obj->subscription;
  1177. }
  1178. $this->last_subscription_date=$this->db->jdate($obj->datec);
  1179. $this->last_subscription_date_start=$this->db->jdate($obj->datef);
  1180. $this->last_subscription_date_end=$this->db->jdate($obj->datef);
  1181. $this->last_subscription_amount=$obj->subscription;
  1182. $subscription=new Subscription($this->db);
  1183. $subscription->id=$obj->rowid;
  1184. $subscription->fk_adherent=$obj->fk_adherent;
  1185. $subscription->amount=$obj->subscription;
  1186. $subscription->note=$obj->note;
  1187. $subscription->fk_bank=$obj->fk_bank;
  1188. $subscription->datem=$this->db->jdate($obj->datem);
  1189. $subscription->datec=$this->db->jdate($obj->datec);
  1190. $subscription->dateh=$this->db->jdate($obj->dateh);
  1191. $subscription->datef=$this->db->jdate($obj->datef);
  1192. $this->subscriptions[]=$subscription;
  1193. $i++;
  1194. }
  1195. return 1;
  1196. }
  1197. else
  1198. {
  1199. $this->error=$this->db->error().' sql='.$sql;
  1200. return -1;
  1201. }
  1202. }
  1203. /**
  1204. * Insert subscription into database and eventually add links to banks, mailman, etc...
  1205. *
  1206. * @param int $date Date of effect of subscription
  1207. * @param double $amount Amount of subscription (0 accepted for some members)
  1208. * @param int $accountid Id bank account
  1209. * @param string $operation Type of payment (if Id bank account provided). Example: 'CB', ...
  1210. * @param string $label Label operation (if Id bank account provided)
  1211. * @param string $num_chq Numero cheque (if Id bank account provided)
  1212. * @param string $emetteur_nom Name of cheque writer
  1213. * @param string $emetteur_banque Name of bank of cheque
  1214. * @param int $datesubend Date end subscription
  1215. * @return int rowid of record added, <0 if KO
  1216. */
  1217. function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0)
  1218. {
  1219. global $conf,$langs,$user;
  1220. require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
  1221. $error=0;
  1222. // Clean parameters
  1223. if (! $amount) $amount=0;
  1224. $this->db->begin();
  1225. if ($datesubend)
  1226. {
  1227. $datefin=$datesubend;
  1228. }
  1229. else
  1230. {
  1231. // If no end date, end date = date + 1 year - 1 day
  1232. $datefin = dol_time_plus_duree($date,1,'y');
  1233. $datefin = dol_time_plus_duree($datefin,-1,'d');
  1234. }
  1235. // Create subscription
  1236. $subscription=new Subscription($this->db);
  1237. $subscription->fk_adherent=$this->id;
  1238. $subscription->dateh=$date; // Date of new subscription
  1239. $subscription->datef=$datefin; // End data of new subscription
  1240. $subscription->amount=$amount;
  1241. $subscription->note=$label; // deprecated
  1242. $subscription->note_public=$label;
  1243. $rowid=$subscription->create($user);
  1244. if ($rowid > 0)
  1245. {
  1246. // Update denormalized subscription end date (read database subscription to find values)
  1247. // This will also update this->datefin
  1248. $result=$this->update_end_date($user);
  1249. if ($result > 0)
  1250. {
  1251. // Change properties of object (used by triggers)
  1252. $this->last_subscription_date=dol_now();
  1253. $this->last_subscription_date_start=$date;
  1254. $this->last_subscription_date_end=$datefin;
  1255. $this->last_subscription_amount=$amount;
  1256. }
  1257. if (! $error)
  1258. {
  1259. $this->db->commit();
  1260. return $rowid;
  1261. }
  1262. else
  1263. {
  1264. $this->db->rollback();
  1265. return -2;
  1266. }
  1267. }
  1268. else
  1269. {
  1270. $this->error=$subscription->error;
  1271. $this->errors=$subscription->errors;
  1272. $this->db->rollback();
  1273. return -1;
  1274. }
  1275. }
  1276. /**
  1277. * Do complementary actions after subscription recording.
  1278. *
  1279. * @param int $subscriptionid Id of created subscription
  1280. * @param string $option Which action ('bankdirect', 'bankviainvoice', 'invoiceonly', ...)
  1281. * @param int $accountid Id bank account
  1282. * @param int $datesubscription Date of subscription
  1283. * @param int $paymentdate Date of payment
  1284. * @param string $operation Code of type of operation (if Id bank account provided). Example 'CB', ...
  1285. * @param string $label Label operation (if Id bank account provided)
  1286. * @param double $amount Amount of subscription (0 accepted for some members)
  1287. * @param string $num_chq Numero cheque (if Id bank account provided)
  1288. * @param string $emetteur_nom Name of cheque writer
  1289. * @param string $emetteur_banque Name of bank of cheque
  1290. * @param string $autocreatethirdparty Auto create new thirdparty if member not yet linked to a thirdparty and we request an option that generate invoice.
  1291. * @return int <0 if KO, >0 if OK
  1292. */
  1293. function subscriptionComplementaryActions($subscriptionid, $option, $accountid, $datesubscription, $paymentdate, $operation, $label, $amount, $num_chq, $emetteur_nom = '', $emetteur_banque = '', $autocreatethirdparty = 0)
  1294. {
  1295. global $conf, $langs, $user, $mysoc;
  1296. $error = 0;
  1297. $this->invoice = null; // This will contains invoice if an invoice is created
  1298. dol_syslog("subscriptionComplementaryActions subscriptionid=".$subscriptionid." option=".$option." accountid=".$accountid." datesubscription=".$datesubscription." paymentdate=".$paymentdate." label=".$label." amount=".$amount." num_chq=".$num_chq." autocreatethirdparty=".$autocreatethirdparty);
  1299. // Insert into bank account directlty (if option choosed for) + link to llx_subscription if option is 'bankdirect'
  1300. if ($option == 'bankdirect' && $accountid)
  1301. {
  1302. require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
  1303. $acct=new Account($this->db);
  1304. $result=$acct->fetch($accountid);
  1305. $dateop=$paymentdate;
  1306. $insertid=$acct->addline($dateop, $operation, $label, $amount, $num_chq, '', $user, $emetteur_nom, $emetteur_banque);
  1307. if ($insertid > 0)
  1308. {
  1309. $inserturlid=$acct->add_url_line($insertid, $this->id, DOL_URL_ROOT.'/adherents/card.php?rowid=', $this->getFullname($langs), 'member');
  1310. if ($inserturlid > 0)
  1311. {
  1312. // Update table subscription
  1313. $sql ="UPDATE ".MAIN_DB_PREFIX."subscription SET fk_bank=".$insertid;
  1314. $sql.=" WHERE rowid=".$subscriptionid;
  1315. dol_syslog("subscription::subscription", LOG_DEBUG);
  1316. $resql = $this->db->query($sql);
  1317. if (! $resql)
  1318. {
  1319. $error++;
  1320. $this->error=$this->db->lasterror();
  1321. $this->errors[]=$this->error;
  1322. }
  1323. }
  1324. else
  1325. {
  1326. $error++;
  1327. $this->error=$acct->error;
  1328. $this->errors=$acct->errors;
  1329. }
  1330. }
  1331. else
  1332. {
  1333. $error++;
  1334. $this->error=$acct->error;
  1335. $this->errors=$acct->errors;
  1336. }
  1337. }
  1338. // If option choosed, we create invoice
  1339. if (($option == 'bankviainvoice' && $accountid) || $option == 'invoiceonly')
  1340. {
  1341. require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  1342. require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
  1343. $invoice=new Facture($this->db);
  1344. $customer=new Societe($this->db);
  1345. if (! $error)
  1346. {
  1347. if (! ($this->fk_soc > 0)) // If not yet linked to a company
  1348. {
  1349. if ($autocreatethirdparty)
  1350. {
  1351. // Create a linked thirdparty to member
  1352. $companyalias='';
  1353. $fullname = $this->getFullName($langs);
  1354. if ($this->morphy == 'mor')
  1355. {
  1356. $companyname=$this->societe;
  1357. if (! empty($fullname)) $companyalias=$fullname;
  1358. }
  1359. else
  1360. {
  1361. $companyname=$fullname;
  1362. if (! empty($this->societe)) $companyalias=$this->societe;
  1363. }
  1364. $result=$customer->create_from_member($this, $companyname, $companyalias);
  1365. if ($result < 0)
  1366. {
  1367. $this->error = $customer->error;
  1368. $this->errors = $customer->errors;
  1369. $error++;
  1370. }
  1371. else
  1372. {
  1373. $this->fk_soc = $result;
  1374. }
  1375. }
  1376. else
  1377. {
  1378. $langs->load("errors");
  1379. $this->error=$langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst");
  1380. $this->errors[]=$this->error;
  1381. $error++;
  1382. }
  1383. }
  1384. }
  1385. if (! $error)
  1386. {
  1387. $result=$customer->fetch($this->fk_soc);
  1388. if ($result <= 0)
  1389. {
  1390. $this->error=$customer->error;
  1391. $this->errors=$customer->errors;
  1392. $error++;
  1393. }
  1394. }
  1395. if (! $error)
  1396. {
  1397. // Create draft invoice
  1398. $invoice->type=Facture::TYPE_STANDARD;
  1399. $invoice->cond_reglement_id=$customer->cond_reglement_id;
  1400. if (empty($invoice->cond_reglement_id))
  1401. {
  1402. $paymenttermstatic=new PaymentTerm($this->db);
  1403. $invoice->cond_reglement_id=$paymenttermstatic->getDefaultId();
  1404. if (empty($invoice->cond_reglement_id))
  1405. {
  1406. $error++;
  1407. $this->error='ErrorNoPaymentTermRECEPFound';
  1408. $this->errors[]=$this->error;
  1409. }
  1410. }
  1411. $invoice->socid=$this->fk_soc;
  1412. $invoice->date=$datesubscription;
  1413. // Possibility to add external linked objects with hooks
  1414. $invoice->linked_objects['subscription'] = $subscriptionid;
  1415. if (! empty($_POST['other_linked_objects']) && is_array($_POST['other_linked_objects']))
  1416. {
  1417. $invoice->linked_objects = array_merge($invoice->linked_objects, $_POST['other_linked_objects']);
  1418. }
  1419. $result=$invoice->create($user);
  1420. if ($result <= 0)
  1421. {
  1422. $this->error=$invoice->error;
  1423. $this->errors=$invoice->errors;
  1424. $error++;
  1425. }
  1426. else
  1427. {
  1428. $this->invoice = $invoice;
  1429. }
  1430. }
  1431. if (! $error)
  1432. {
  1433. // Add line to draft invoice
  1434. $idprodsubscription=0;
  1435. if (! empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) && (! empty($conf->product->enabled) || ! empty($conf->service->enabled))) $idprodsubscription = $conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS;
  1436. $vattouse=0;
  1437. if (isset($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) && $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS == 'defaultforfoundationcountry')
  1438. {
  1439. $vattouse=get_default_tva($mysoc, $mysoc, $idprodsubscription);
  1440. }
  1441. //print xx".$vattouse." - ".$mysoc." - ".$customer;exit;
  1442. $result=$invoice->addline($label,0,1,$vattouse,0,0,$idprodsubscription,0,$datesubscription,'',0,0,'','TTC',$amount,1);
  1443. if ($result <= 0)
  1444. {
  1445. $this->error=$invoice->error;
  1446. $this->errors=$invoice->errors;
  1447. $error++;
  1448. }
  1449. }
  1450. if (! $error)
  1451. {
  1452. // Validate invoice
  1453. $result=$invoice->validate($user);
  1454. if ($result <= 0)
  1455. {
  1456. $this->error=$invoice->error;
  1457. $this->errors=$invoice->errors;
  1458. $error++;
  1459. }
  1460. }
  1461. if (! $error)
  1462. {
  1463. // TODO Link invoice with subscription ?
  1464. }
  1465. // Add payment onto invoice
  1466. if (! $error && $option == 'bankviainvoice' && $accountid)
  1467. {
  1468. require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
  1469. require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
  1470. require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
  1471. $amounts = array();
  1472. $amounts[$invoice->id] = price2num($amount);
  1473. $paiement = new Paiement($this->db);
  1474. $paiement->datepaye = $paymentdate;
  1475. $paiement->amounts = $amounts;
  1476. $paiement->paiementid = dol_getIdFromCode($this->db,$operation,'c_paiement','code','id',1);
  1477. $paiement->num_paiement = $num_chq;
  1478. $paiement->note = $label;
  1479. $paiement->note_public = $label;
  1480. if (! $error)
  1481. {
  1482. // Create payment line for invoice
  1483. $paiement_id = $paiement->create($user);
  1484. if (! $paiement_id > 0)
  1485. {
  1486. $this->error=$paiement->error;
  1487. $this->errors=$paiement->errors;
  1488. $error++;
  1489. }
  1490. }
  1491. if (! $error)
  1492. {
  1493. // Add transaction into bank account
  1494. $bank_line_id=$paiement->addPaymentToBank($user,'payment','(SubscriptionPayment)',$accountid,$emetteur_nom,$emetteur_banque);
  1495. if (! ($bank_line_id > 0))
  1496. {
  1497. $this->error=$paiement->error;
  1498. $this->errors=$paiement->errors;
  1499. $error++;
  1500. }
  1501. }
  1502. if (! $error && !empty($bank_line_id))
  1503. {
  1504. // Update fk_bank into subscription table
  1505. $sql = 'UPDATE '.MAIN_DB_PREFIX.'subscription SET fk_bank='.$bank_line_id;
  1506. $sql.= ' WHERE rowid='.$subscriptionid;
  1507. $result = $this->db->query($sql);
  1508. if (! $result)
  1509. {
  1510. $error++;
  1511. }
  1512. }
  1513. if (! $error)
  1514. {
  1515. // Set invoice as paid
  1516. $invoice->set_paid($user);
  1517. }
  1518. }
  1519. if (! $error)
  1520. {
  1521. // Define output language
  1522. $outputlangs = $langs;
  1523. $newlang = '';
  1524. $lang_id=GETPOST('lang_id');
  1525. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($lang_id))
  1526. $newlang = $lang_id;
  1527. if ($conf->global->MAIN_MULTILANGS && empty($newlang))
  1528. $newlang = $customer->default_lang;
  1529. if (! empty($newlang)) {
  1530. $outputlangs = new Translate("", $conf);
  1531. $outputlangs->setDefaultLang($newlang);
  1532. }
  1533. // Generate PDF (whatever is option MAIN_DISABLE_PDF_AUTOUPDATE) so we can include it into email
  1534. //if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
  1535. $invoice->generateDocument($invoice->modelpdf, $outputlangs);
  1536. }
  1537. }
  1538. if ($error)
  1539. {
  1540. return -1;
  1541. }
  1542. else
  1543. {
  1544. return 1;
  1545. }
  1546. }
  1547. /**
  1548. * Function that validate a member
  1549. *
  1550. * @param User $user user adherent qui valide
  1551. * @return int <0 if KO, 0 if nothing done, >0 if OK
  1552. */
  1553. function validate($user)
  1554. {
  1555. global $langs,$conf;
  1556. $error=0;
  1557. $now=dol_now();
  1558. // Check parameters
  1559. if ($this->statut == 1)
  1560. {
  1561. dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
  1562. return 0;
  1563. }
  1564. $this->db->begin();
  1565. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
  1566. $sql.= " statut = 1";
  1567. $sql.= ", datevalid = '".$this->db->idate($now)."'";
  1568. $sql.= ", fk_user_valid=".$user->id;
  1569. $sql.= " WHERE rowid = ".$this->id;
  1570. dol_syslog(get_class($this)."::validate", LOG_DEBUG);
  1571. $result = $this->db->query($sql);
  1572. if ($result)
  1573. {
  1574. $this->statut=1;
  1575. // Call trigger
  1576. $result=$this->call_trigger('MEMBER_VALIDATE',$user);
  1577. if ($result < 0) { $error++; $this->db->rollback(); return -1; }
  1578. // End call triggers
  1579. $this->datevalid = $now;
  1580. $this->db->commit();
  1581. return 1;
  1582. }
  1583. else
  1584. {
  1585. $this->error=$this->db->error();
  1586. $this->db->rollback();
  1587. return -1;
  1588. }
  1589. }
  1590. /**
  1591. * Fonction qui resilie un adherent
  1592. *
  1593. * @param User $user User making change
  1594. * @return int <0 if KO, >0 if OK
  1595. */
  1596. function resiliate($user)
  1597. {
  1598. global $langs,$conf;
  1599. $error=0;
  1600. // Check paramaters
  1601. if ($this->statut == 0)
  1602. {
  1603. dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
  1604. return 0;
  1605. }
  1606. $this->db->begin();
  1607. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
  1608. $sql.= " statut = 0";
  1609. $sql.= ", fk_user_valid=".$user->id;
  1610. $sql.= " WHERE rowid = ".$this->id;
  1611. $result = $this->db->query($sql);
  1612. if ($result)
  1613. {
  1614. $this->statut=0;
  1615. // Call trigger
  1616. $result=$this->call_trigger('MEMBER_RESILIATE',$user);
  1617. if ($result < 0) { $error++; $this->db->rollback(); return -1; }
  1618. // End call triggers
  1619. $this->db->commit();
  1620. return 1;
  1621. }
  1622. else
  1623. {
  1624. $this->error=$this->db->error();
  1625. $this->db->rollback();
  1626. return -1;
  1627. }
  1628. }
  1629. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  1630. /**
  1631. * Function to add member into external tools mailing-list, spip, etc.
  1632. *
  1633. * @return int <0 if KO, >0 if OK
  1634. */
  1635. function add_to_abo()
  1636. {
  1637. // phpcs:enable
  1638. global $conf,$langs;
  1639. include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
  1640. $mailmanspip=new MailmanSpip($this->db);
  1641. $err=0;
  1642. // mailman
  1643. if (! empty($conf->global->ADHERENT_USE_MAILMAN) && ! empty($conf->mailmanspip->enabled))
  1644. {
  1645. $result=$mailmanspip->add_to_mailman($this);
  1646. if ($result < 0)
  1647. {
  1648. if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error;
  1649. $err+=1;
  1650. }
  1651. foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail)
  1652. {
  1653. $langs->load("errors");
  1654. $this->errors[]=$langs->trans("ErrorFailedToAddToMailmanList",$tmpemail,$tmplist);
  1655. }
  1656. foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail)
  1657. {
  1658. $langs->load("mailmanspip");
  1659. $this->mesgs[]=$langs->trans("SuccessToAddToMailmanList",$tmpemail,$tmplist);
  1660. }
  1661. }
  1662. // spip
  1663. if (! empty($conf->global->ADHERENT_USE_SPIP) && ! empty($conf->mailmanspip->enabled))
  1664. {
  1665. $result=$mailmanspip->add_to_spip($this);
  1666. if ($result < 0)
  1667. {
  1668. $this->errors[]=$mailmanspip->error;
  1669. $err+=1;
  1670. }
  1671. }
  1672. if ($err)
  1673. {
  1674. return -$err;
  1675. }
  1676. else
  1677. {
  1678. return 1;
  1679. }
  1680. }
  1681. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  1682. /**
  1683. * Function to delete a member from external tools like mailing-list, spip, etc.
  1684. *
  1685. * @return int <0 if KO, >0 if OK
  1686. */
  1687. function del_to_abo()
  1688. {
  1689. // phpcs:enable
  1690. global $conf,$langs;
  1691. include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
  1692. $mailmanspip=new MailmanSpip($this->db);
  1693. $err=0;
  1694. // mailman
  1695. if (! empty($conf->global->ADHERENT_USE_MAILMAN))
  1696. {
  1697. $result=$mailmanspip->del_to_mailman($this);
  1698. if ($result < 0)
  1699. {
  1700. if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error;
  1701. $err+=1;
  1702. }
  1703. foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail)
  1704. {
  1705. $langs->load("errors");
  1706. $this->errors[]=$langs->trans("ErrorFailedToRemoveToMailmanList",$tmpemail,$tmplist);
  1707. }
  1708. foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail)
  1709. {
  1710. $langs->load("mailmanspip");
  1711. $this->mesgs[]=$langs->trans("SuccessToRemoveToMailmanList",$tmpemail,$tmplist);
  1712. }
  1713. }
  1714. if ($conf->global->ADHERENT_USE_SPIP && ! empty($conf->mailmanspip->enabled))
  1715. {
  1716. $result=$mailmanspip->del_to_spip($this);
  1717. if ($result < 0)
  1718. {
  1719. $this->errors[]=$mailmanspip->error;
  1720. $err+=1;
  1721. }
  1722. }
  1723. if ($err)
  1724. {
  1725. // error
  1726. return -$err;
  1727. }
  1728. else
  1729. {
  1730. return 1;
  1731. }
  1732. }
  1733. /**
  1734. * Return civility label of a member
  1735. *
  1736. * @return string Translated name of civility (translated with transnoentitiesnoconv)
  1737. */
  1738. function getCivilityLabel()
  1739. {
  1740. global $langs;
  1741. $langs->load("dict");
  1742. $code=(empty($this->civility_id)?'':$this->civility_id);
  1743. if (empty($code)) return '';
  1744. return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
  1745. }
  1746. /**
  1747. * Return clicable name (with picto eventually)
  1748. *
  1749. * @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)
  1750. * @param int $maxlen length max label
  1751. * @param string $option Page for link ('card', 'category', 'subscription', ...)
  1752. * @param string $mode ''=Show firstname+lastname as label (using default order), 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref
  1753. * @param string $morecss Add more css on link
  1754. * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
  1755. * @return string Chaine avec URL
  1756. */
  1757. function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1)
  1758. {
  1759. global $conf, $langs;
  1760. if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0;
  1761. $notooltip=0;
  1762. $result=''; $label='';
  1763. $link=''; $linkstart=''; $linkend='';
  1764. if (! empty($this->photo))
  1765. {
  1766. $label.= '<div class="photointooltip">';
  1767. $label.= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1);
  1768. $label.= '</div><div style="clear: both;"></div>';
  1769. }
  1770. $label.= '<div class="centpercent">';
  1771. $label.= '<u>' . $langs->trans("Member") . '</u>';
  1772. if (! empty($this->ref))
  1773. $label.= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
  1774. if (! empty($this->firstname) || ! empty($this->lastname))
  1775. $label.= '<br><b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs);
  1776. if (! empty($this->company))
  1777. $label.= '<br><b>' . $langs->trans('Company') . ':</b> ' . $this->company;
  1778. $label.='</div>';
  1779. $url = DOL_URL_ROOT.'/adherents/card.php?rowid='.$this->id;
  1780. if ($option == 'subscription')
  1781. {
  1782. $url = DOL_URL_ROOT.'/adherents/subscription.php?rowid='.$this->id;
  1783. }
  1784. if ($option != 'nolink')
  1785. {
  1786. // Add param to save lastsearch_values or not
  1787. $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
  1788. if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
  1789. if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
  1790. }
  1791. $link = '<a href="'.$url.'"';
  1792. $linkclose="";
  1793. if (empty($notooltip))
  1794. {
  1795. if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
  1796. {
  1797. $langs->load("users");
  1798. $label=$langs->trans("ShowUser");
  1799. $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
  1800. }
  1801. $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
  1802. $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
  1803. }
  1804. $link.=$linkclose.'>';
  1805. $linkend='</a>';
  1806. //if ($withpictoimg == -1) $result.='<div class="nowrap">';
  1807. $result.=$link;
  1808. if ($withpictoimg)
  1809. {
  1810. $paddafterimage='';
  1811. if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"';
  1812. // Only picto
  1813. if ($withpictoimg > 0) $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</div>';
  1814. // Picto must be a photo
  1815. else $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</div>';
  1816. $result.=$picto;
  1817. }
  1818. if ($withpictoimg > -2 && $withpictoimg != 2)
  1819. {
  1820. if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='<div class="inline-block nopadding valignmiddle'.((! isset($this->statut) || $this->statut)?'':' strikefordisabled').($morecss?' usertext'.$morecss:'').'">';
  1821. if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen);
  1822. elseif ($mode == 'ref') $result.=$this->id;
  1823. else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen);
  1824. if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='</div>';
  1825. }
  1826. $result.=$linkend;
  1827. //if ($withpictoimg == -1) $result.='</div>';
  1828. return $result;
  1829. }
  1830. /**
  1831. * Retourne le libelle du statut d'un adherent (brouillon, valide, resilie)
  1832. *
  1833. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  1834. * @return string Label
  1835. */
  1836. function getLibStatut($mode = 0)
  1837. {
  1838. return $this->LibStatut($this->statut,$this->need_subscription,$this->datefin,$mode);
  1839. }
  1840. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  1841. /**
  1842. * Renvoi le libelle d'un statut donne
  1843. *
  1844. * @param int $statut Id statut
  1845. * @param int $need_subscription 1 if member type need subscription, 0 otherwise
  1846. * @param int $date_end_subscription Date fin adhesion
  1847. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  1848. * @return string Label
  1849. */
  1850. function LibStatut($statut, $need_subscription, $date_end_subscription, $mode = 0)
  1851. {
  1852. // phpcs:enable
  1853. global $langs;
  1854. $langs->load("members");
  1855. if ($mode == 0)
  1856. {
  1857. if ($statut == -1) return $langs->trans("MemberStatusDraft");
  1858. elseif ($statut >= 1) {
  1859. if (! $date_end_subscription) return $langs->trans("MemberStatusActive");
  1860. elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLate");
  1861. else return $langs->trans("MemberStatusPaid");
  1862. }
  1863. elseif ($statut == 0) return $langs->trans("MemberStatusResiliated");
  1864. }
  1865. elseif ($mode == 1)
  1866. {
  1867. if ($statut == -1) return $langs->trans("MemberStatusDraftShort");
  1868. elseif ($statut >= 1) {
  1869. if (! $date_end_subscription) return $langs->trans("MemberStatusActiveShort");
  1870. elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLateShort");
  1871. else return $langs->trans("MemberStatusPaidShort");
  1872. }
  1873. elseif ($statut == 0) return $langs->trans("MemberStatusResiliatedShort");
  1874. }
  1875. elseif ($mode == 2)
  1876. {
  1877. if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraftShort");
  1878. elseif ($statut >= 1) {
  1879. if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActiveShort");
  1880. elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLateShort");
  1881. else return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaidShort");
  1882. }
  1883. elseif ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliatedShort");
  1884. }
  1885. elseif ($mode == 3)
  1886. {
  1887. if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0');
  1888. elseif ($statut >= 1) {
  1889. if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1');
  1890. elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
  1891. else return img_picto($langs->trans('MemberStatusPaid'),'statut4');
  1892. }
  1893. elseif ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5');
  1894. }
  1895. elseif ($mode == 4)
  1896. {
  1897. if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraft");
  1898. elseif ($statut >= 1) {
  1899. if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActive");
  1900. elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLate");
  1901. else return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaid");
  1902. }
  1903. if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliated");
  1904. }
  1905. elseif ($mode == 5)
  1906. {
  1907. if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0');
  1908. elseif ($statut >= 1) {
  1909. if (! $date_end_subscription) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveShort").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1');
  1910. elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLateShort").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
  1911. else return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaidShort").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4');
  1912. }
  1913. if ($statut == 0) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5');
  1914. }
  1915. elseif ($mode == 6)
  1916. {
  1917. if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0');
  1918. if ($statut >= 1) {
  1919. if (! $date_end_subscription) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActive").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1');
  1920. elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLate").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
  1921. else return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaid").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4');
  1922. }
  1923. if ($statut == 0) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5');
  1924. }
  1925. }
  1926. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  1927. /**
  1928. * Charge indicateurs this->nb de tableau de bord
  1929. *
  1930. * @return int <0 if KO, >0 if OK
  1931. */
  1932. function load_state_board()
  1933. {
  1934. // phpcs:enable
  1935. global $conf;
  1936. $this->nb = array();
  1937. $sql = "SELECT count(a.rowid) as nb";
  1938. $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
  1939. $sql.= " WHERE a.statut > 0";
  1940. $sql.= " AND a.entity IN (".getEntity('adherent').")";
  1941. $resql=$this->db->query($sql);
  1942. if ($resql)
  1943. {
  1944. while ($obj=$this->db->fetch_object($resql))
  1945. {
  1946. $this->nb["members"]=$obj->nb;
  1947. }
  1948. $this->db->free($resql);
  1949. return 1;
  1950. }
  1951. else
  1952. {
  1953. dol_print_error($this->db);
  1954. $this->error=$this->db->error();
  1955. return -1;
  1956. }
  1957. }
  1958. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  1959. /**
  1960. * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
  1961. *
  1962. * @param User $user Objet user
  1963. * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
  1964. */
  1965. function load_board($user)
  1966. {
  1967. // phpcs:enable
  1968. global $conf, $langs;
  1969. if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe
  1970. $now=dol_now();
  1971. $sql = "SELECT a.rowid, a.datefin, a.statut";
  1972. $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
  1973. $sql.= " WHERE a.statut = 1";
  1974. $sql.= " AND a.entity IN (".getEntity('adherent').")";
  1975. $sql.= " AND (a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."')";
  1976. $resql=$this->db->query($sql);
  1977. if ($resql)
  1978. {
  1979. $langs->load("members");
  1980. $response = new WorkboardResponse();
  1981. $response->warning_delay=$conf->adherent->subscription->warning_delay/60/60/24;
  1982. $response->label=$langs->trans("MembersWithSubscriptionToReceive");
  1983. $response->url=DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut=1&amp;filter=outofdate';
  1984. $response->img=img_object('',"user");
  1985. $adherentstatic = new Adherent($this->db);
  1986. while ($obj=$this->db->fetch_object($resql))
  1987. {
  1988. $response->nbtodo++;
  1989. $adherentstatic->datefin = $this->db->jdate($obj->datefin);
  1990. $adherentstatic->statut = $obj->statut;
  1991. if ($adherentstatic->hasDelay()) {
  1992. $response->nbtodolate++;
  1993. }
  1994. }
  1995. return $response;
  1996. }
  1997. else
  1998. {
  1999. dol_print_error($this->db);
  2000. $this->error=$this->db->error();
  2001. return -1;
  2002. }
  2003. }
  2004. /**
  2005. * Create a document onto disk according to template module.
  2006. *
  2007. * @param string $modele Force template to use ('' to not force)
  2008. * @param Translate $outputlangs objet lang a utiliser pour traduction
  2009. * @param int $hidedetails Hide details of lines
  2010. * @param int $hidedesc Hide description
  2011. * @param int $hideref Hide ref
  2012. * @param null|array $moreparams Array to provide more information
  2013. * @return int 0 if KO, 1 if OK
  2014. */
  2015. public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
  2016. {
  2017. global $conf,$langs;
  2018. $langs->load("orders");
  2019. if (! dol_strlen($modele)) {
  2020. $modele = 'standard';
  2021. if ($this->modelpdf) {
  2022. $modele = $this->modelpdf;
  2023. } elseif (! empty($conf->global->ADHERENT_ADDON_PDF)) {
  2024. $modele = $conf->global->ADHERENT_ADDON_PDF;
  2025. }
  2026. }
  2027. $modelpath = "core/modules/member/doc/";
  2028. return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
  2029. }
  2030. /**
  2031. * Initialise an instance with random values.
  2032. * Used to build previews or test instances.
  2033. * id must be 0 if object instance is a specimen.
  2034. *
  2035. * @return void
  2036. */
  2037. function initAsSpecimen()
  2038. {
  2039. global $user,$langs;
  2040. // Initialise parametres
  2041. $this->id=0;
  2042. $this->specimen=1;
  2043. $this->civility_id = 0;
  2044. $this->lastname = 'DOLIBARR';
  2045. $this->firstname = 'SPECIMEN';
  2046. $this->gender='man';
  2047. $this->login='dolibspec';
  2048. $this->pass='dolibspec';
  2049. $this->societe = 'Societe ABC';
  2050. $this->address = '61 jump street';
  2051. $this->zip = '75000';
  2052. $this->town = 'Paris';
  2053. $this->country_id = 1;
  2054. $this->country_code = 'FR';
  2055. $this->country = 'France';
  2056. $this->morphy = 1;
  2057. $this->email = 'specimen@specimen.com';
  2058. $this->skype = 'skypepseudo';
  2059. $this->twitter = 'twitterpseudo';
  2060. $this->facebook = 'facebookpseudo';
  2061. $this->phone = '0999999999';
  2062. $this->phone_perso = '0999999998';
  2063. $this->phone_mobile = '0999999997';
  2064. $this->note_private='No comment';
  2065. $this->birth=time();
  2066. $this->photo='';
  2067. $this->public=1;
  2068. $this->statut=0;
  2069. $this->datefin=time();
  2070. $this->datevalid=time();
  2071. $this->typeid=1; // Id type adherent
  2072. $this->type='Type adherent'; // Libelle type adherent
  2073. $this->need_subscription=0;
  2074. $this->first_subscription_date=time();
  2075. $this->first_subscription_date_start=$this->first_subscription_date;
  2076. $this->first_subscription_date_end=dol_time_plus_duree($this->first_subscription_date_start, 1, 'y');
  2077. $this->first_subscription_amount=10;
  2078. $this->last_subscription_date=$this->first_subscription_date;
  2079. $this->last_subscription_date_start=$this->first_subscription_date;
  2080. $this->last_subscription_date_end=dol_time_plus_duree($this->last_subscription_date_start, 1, 'y');
  2081. $this->last_subscription_amount=10;
  2082. }
  2083. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  2084. /**
  2085. * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
  2086. *
  2087. * @param array $info Info array loaded by _load_ldap_info
  2088. * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
  2089. * 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
  2090. * 2=Return key only (uid=qqq)
  2091. * @return string DN
  2092. */
  2093. function _load_ldap_dn($info, $mode = 0)
  2094. {
  2095. // phpcs:enable
  2096. global $conf;
  2097. $dn='';
  2098. if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS].",".$conf->global->LDAP_MEMBER_DN;
  2099. if ($mode==1) $dn=$conf->global->LDAP_MEMBER_DN;
  2100. if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS];
  2101. return $dn;
  2102. }
  2103. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  2104. /**
  2105. * Initialise tableau info (tableau des attributs LDAP)
  2106. *
  2107. * @return array Tableau info des attributs
  2108. */
  2109. function _load_ldap_info()
  2110. {
  2111. // phpcs:enable
  2112. global $conf,$langs;
  2113. $info=array();
  2114. $keymodified=false;
  2115. // Object classes
  2116. $info["objectclass"]=explode(',',$conf->global->LDAP_MEMBER_OBJECT_CLASS);
  2117. $this->fullname=$this->getFullName($langs);
  2118. // For avoid ldap error when firstname and lastname are empty
  2119. if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->societe)) {
  2120. $this->fullname = $this->societe;
  2121. $this->lastname = $this->societe;
  2122. }
  2123. // Possible LDAP KEY (constname => varname)
  2124. $ldapkey = array(
  2125. 'LDAP_MEMBER_FIELD_FULLNAME' => 'fullname',
  2126. 'LDAP_MEMBER_FIELD_NAME' => 'lastname',
  2127. 'LDAP_MEMBER_FIELD_LOGIN' => 'login',
  2128. 'LDAP_MEMBER_FIELD_LOGIN_SAMBA' => 'login',
  2129. 'LDAP_MEMBER_FIELD_MAIL' => 'email'
  2130. );
  2131. // Member
  2132. foreach ($ldapkey as $constname => $varname)
  2133. {
  2134. if (! empty($this->$varname) && ! empty($conf->global->$constname))
  2135. {
  2136. $info[$conf->global->$constname] = $this->$varname;
  2137. // Check if it is the LDAP key and if its value has been changed
  2138. if (! empty($conf->global->LDAP_KEY_MEMBERS) && $conf->global->LDAP_KEY_MEMBERS == $conf->global->$constname)
  2139. {
  2140. if (! empty($this->oldcopy) && $this->$varname != $this->oldcopy->$varname) $keymodified=true; // For check if LDAP key has been modified
  2141. }
  2142. }
  2143. }
  2144. if ($this->firstname && ! empty($conf->global->LDAP_MEMBER_FIELD_FIRSTNAME)) $info[$conf->global->LDAP_MEMBER_FIELD_FIRSTNAME] = $this->firstname;
  2145. if ($this->poste && ! empty($conf->global->LDAP_MEMBER_FIELD_TITLE)) $info[$conf->global->LDAP_MEMBER_FIELD_TITLE] = $this->poste;
  2146. if ($this->societe && ! empty($conf->global->LDAP_MEMBER_FIELD_COMPANY)) $info[$conf->global->LDAP_MEMBER_FIELD_COMPANY] = $this->societe;
  2147. if ($this->address && ! empty($conf->global->LDAP_MEMBER_FIELD_ADDRESS)) $info[$conf->global->LDAP_MEMBER_FIELD_ADDRESS] = $this->address;
  2148. if ($this->zip && ! empty($conf->global->LDAP_MEMBER_FIELD_ZIP)) $info[$conf->global->LDAP_MEMBER_FIELD_ZIP] = $this->zip;
  2149. if ($this->town && ! empty($conf->global->LDAP_MEMBER_FIELD_TOWN)) $info[$conf->global->LDAP_MEMBER_FIELD_TOWN] = $this->town;
  2150. if ($this->country_code && ! empty($conf->global->LDAP_MEMBER_FIELD_COUNTRY)) $info[$conf->global->LDAP_MEMBER_FIELD_COUNTRY] = $this->country_code;
  2151. if ($this->skype && ! empty($conf->global->LDAP_MEMBER_FIELD_SKYPE)) $info[$conf->global->LDAP_MEMBER_FIELD_SKYPE] = $this->skype;
  2152. if ($this->twitter && ! empty($conf->global->LDAP_MEMBER_FIELD_TWITTER)) $info[$conf->global->LDAP_MEMBER_FIELD_TWITTER] = $this->twitter;
  2153. if ($this->facebook && ! empty($conf->global->LDAP_MEMBER_FIELD_FACEBOOK)) $info[$conf->global->LDAP_MEMBER_FIELD_FACEBOOK] = $this->facebook;
  2154. if ($this->phone && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE)) $info[$conf->global->LDAP_MEMBER_FIELD_PHONE] = $this->phone;
  2155. if ($this->phone_perso && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO)) $info[$conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO] = $this->phone_perso;
  2156. if ($this->phone_mobile && ! empty($conf->global->LDAP_MEMBER_FIELD_MOBILE)) $info[$conf->global->LDAP_MEMBER_FIELD_MOBILE] = $this->phone_mobile;
  2157. if ($this->fax && ! empty($conf->global->LDAP_MEMBER_FIELD_FAX)) $info[$conf->global->LDAP_MEMBER_FIELD_FAX] = $this->fax;
  2158. if ($this->note_private && ! empty($conf->global->LDAP_MEMBER_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_MEMBER_FIELD_DESCRIPTION] = dol_string_nohtmltag($this->note_private, 2);
  2159. if ($this->note_public && ! empty($conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC)) $info[$conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC] = dol_string_nohtmltag($this->note_public, 2);
  2160. if ($this->birth && ! empty($conf->global->LDAP_MEMBER_FIELD_BIRTHDATE)) $info[$conf->global->LDAP_MEMBER_FIELD_BIRTHDATE] = dol_print_date($this->birth,'dayhourldap');
  2161. if (isset($this->statut) && ! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) $info[$conf->global->LDAP_FIELD_MEMBER_STATUS] = $this->statut;
  2162. if ($this->datefin && ! empty($conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION)) $info[$conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION] = dol_print_date($this->datefin,'dayhourldap');
  2163. // When password is modified
  2164. if (! empty($this->pass))
  2165. {
  2166. if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte
  2167. if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // Create OpenLDAP MD5 password (TODO add type of encryption)
  2168. }
  2169. // Set LDAP password if possible
  2170. elseif ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
  2171. {
  2172. if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
  2173. {
  2174. // Just for the default MD5 !
  2175. if (empty($conf->global->MAIN_SECURITY_HASH_ALGO))
  2176. {
  2177. if ($this->pass_indatabase_crypted && ! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED)) {
  2178. // Create OpenLDAP MD5 password from Dolibarr MD5 password
  2179. // Note: This suppose that "pass_indatabase_crypted" is a md5 (guaranted by the previous test if "(empty($conf->global->MAIN_SECURITY_HASH_ALGO))"
  2180. $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = '{md5}'.base64_encode(hex2bin($this->pass_indatabase_crypted));
  2181. }
  2182. }
  2183. }
  2184. // Use $this->pass_indatabase value if exists
  2185. elseif (! empty($this->pass_indatabase))
  2186. {
  2187. if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD] = $this->pass_indatabase; // $this->pass_indatabase = mot de passe non crypte
  2188. if (! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase, 4); // md5 for OpenLdap TODO add type of encryption
  2189. }
  2190. }
  2191. // Subscriptions
  2192. if ($this->first_subscription_date && ! empty($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE)) $info[$conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE] = dol_print_date($this->first_subscription_date,'dayhourldap');
  2193. if (isset($this->first_subscription_amount) && ! empty($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT)) $info[$conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT] = $this->first_subscription_amount;
  2194. if ($this->last_subscription_date && ! empty($conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE)) $info[$conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE] = dol_print_date($this->last_subscription_date,'dayhourldap');
  2195. if (isset($this->last_subscription_amount) && ! empty($conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT)) $info[$conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT] = $this->last_subscription_amount;
  2196. return $info;
  2197. }
  2198. /**
  2199. * Charge les informations d'ordre info dans l'objet adherent
  2200. *
  2201. * @param int $id Id of member to load
  2202. * @return void
  2203. */
  2204. function info($id)
  2205. {
  2206. $sql = 'SELECT a.rowid, a.datec as datec,';
  2207. $sql.= ' a.datevalid as datev,';
  2208. $sql.= ' a.tms as datem,';
  2209. $sql.= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
  2210. $sql.= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
  2211. $sql.= ' WHERE a.rowid = '.$id;
  2212. dol_syslog(get_class($this)."::info", LOG_DEBUG);
  2213. $result=$this->db->query($sql);
  2214. if ($result)
  2215. {
  2216. if ($this->db->num_rows($result))
  2217. {
  2218. $obj = $this->db->fetch_object($result);
  2219. $this->id = $obj->rowid;
  2220. if ($obj->fk_user_author)
  2221. {
  2222. $cuser = new User($this->db);
  2223. $cuser->fetch($obj->fk_user_author);
  2224. $this->user_creation = $cuser;
  2225. }
  2226. if ($obj->fk_user_valid)
  2227. {
  2228. $vuser = new User($this->db);
  2229. $vuser->fetch($obj->fk_user_valid);
  2230. $this->user_validation = $vuser;
  2231. }
  2232. if ($obj->fk_user_mod)
  2233. {
  2234. $muser = new User($this->db);
  2235. $muser->fetch($obj->fk_user_mod);
  2236. $this->user_modification = $muser;
  2237. }
  2238. $this->date_creation = $this->db->jdate($obj->datec);
  2239. $this->date_validation = $this->db->jdate($obj->datev);
  2240. $this->date_modification = $this->db->jdate($obj->datem);
  2241. }
  2242. $this->db->free($result);
  2243. }
  2244. else
  2245. {
  2246. dol_print_error($this->db);
  2247. }
  2248. }
  2249. /**
  2250. * Return number of mass Emailing received by this member with its email
  2251. *
  2252. * @return int Number of EMailings
  2253. */
  2254. function getNbOfEMailings()
  2255. {
  2256. $sql = "SELECT count(mc.email) as nb";
  2257. $sql.= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc";
  2258. $sql.= " WHERE mc.email = '".$this->db->escape($this->email)."'";
  2259. $sql.= " AND mc.statut NOT IN (-1,0)"; // -1 erreur, 0 non envoye, 1 envoye avec succes
  2260. $resql=$this->db->query($sql);
  2261. if ($resql)
  2262. {
  2263. $obj = $this->db->fetch_object($resql);
  2264. $nb=$obj->nb;
  2265. $this->db->free($resql);
  2266. return $nb;
  2267. }
  2268. else
  2269. {
  2270. $this->error=$this->db->error();
  2271. return -1;
  2272. }
  2273. }
  2274. /**
  2275. * Sets object to supplied categories.
  2276. *
  2277. * Deletes object from existing categories not supplied.
  2278. * Adds it to non existing supplied categories.
  2279. * Existing categories are left untouch.
  2280. *
  2281. * @param int[]|int $categories Category or categories IDs
  2282. * @return void
  2283. */
  2284. public function setCategories($categories)
  2285. {
  2286. // Handle single category
  2287. if (!is_array($categories)) {
  2288. $categories = array($categories);
  2289. }
  2290. // Get current categories
  2291. require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
  2292. $c = new Categorie($this->db);
  2293. $existing = $c->containing($this->id, Categorie::TYPE_MEMBER, 'id');
  2294. // Diff
  2295. if (is_array($existing)) {
  2296. $to_del = array_diff($existing, $categories);
  2297. $to_add = array_diff($categories, $existing);
  2298. } else {
  2299. $to_del = array(); // Nothing to delete
  2300. $to_add = $categories;
  2301. }
  2302. // Process
  2303. foreach ($to_del as $del) {
  2304. if ($c->fetch($del) > 0) {
  2305. $c->del_type($this, 'member');
  2306. }
  2307. }
  2308. foreach ($to_add as $add) {
  2309. if ($c->fetch($add) > 0) {
  2310. $c->add_type($this, 'member');
  2311. }
  2312. }
  2313. return;
  2314. }
  2315. /**
  2316. * Function used to replace a thirdparty id with another one.
  2317. *
  2318. * @param DoliDB $db Database handler
  2319. * @param int $origin_id Old thirdparty id
  2320. * @param int $dest_id New thirdparty id
  2321. * @return bool
  2322. */
  2323. public static function replaceThirdparty($db, $origin_id, $dest_id)
  2324. {
  2325. $tables = array(
  2326. 'adherent'
  2327. );
  2328. return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
  2329. }
  2330. /**
  2331. * Return if a member is late (subscription late) or not
  2332. *
  2333. * @return boolean True if late, False if not late
  2334. */
  2335. public function hasDelay()
  2336. {
  2337. global $conf;
  2338. //Only valid members
  2339. if ($this->statut <= 0) return false;
  2340. if (! $this->datefin) return false;
  2341. $now = dol_now();
  2342. return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
  2343. }
  2344. /**
  2345. * Send reminders by emails before subscription end
  2346. * CAN BE A CRON TASK
  2347. *
  2348. * @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'
  2349. * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK)
  2350. */
  2351. public function sendReminderForExpiredSubscription($daysbeforeendlist = '10')
  2352. {
  2353. global $conf, $langs, $mysoc, $user;
  2354. $error = 0;
  2355. $this->output = '';
  2356. $this->error='';
  2357. $blockingerrormsg = '';
  2358. if (empty($conf->adherent->enabled)) // Should not happen. If module disabled, cron job should not be visible.
  2359. {
  2360. $langs->load("agenda");
  2361. $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
  2362. return 0;
  2363. }
  2364. if (empty($conf->global->MEMBER_REMINDER_EMAIL))
  2365. {
  2366. $langs->load("agenda");
  2367. $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Adherent"));
  2368. return 0;
  2369. }
  2370. $now = dol_now();
  2371. $nbok = 0;
  2372. $nbko = 0;
  2373. $arraydaysbeforeend=explode(';',$daysbeforeendlist);
  2374. foreach($arraydaysbeforeend as $daysbeforeend) // Loop on each delay
  2375. {
  2376. dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
  2377. if (! is_numeric($daysbeforeend))
  2378. {
  2379. $blockingerrormsg="Value for delta is not a positive or negative numeric";
  2380. $nbko++;
  2381. break;
  2382. }
  2383. $tmp=dol_getdate($now);
  2384. $datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year']), $daysbeforeend, 'd');
  2385. $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
  2386. $sql.= " WHERE datefin = '".$this->db->idate($datetosearchfor)."'";
  2387. $resql = $this->db->query($sql);
  2388. if ($resql)
  2389. {
  2390. $num_rows = $this->db->num_rows($resql);
  2391. include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
  2392. $adherent = new Adherent($this->db);
  2393. $formmail = new FormMail($this->db);
  2394. $i=0;
  2395. while ($i < $num_rows)
  2396. {
  2397. $obj = $this->db->fetch_object($resql);
  2398. $adherent->fetch($obj->rowid, '', '', '', true, true);
  2399. if (empty($adherent->email))
  2400. {
  2401. $nbko++;
  2402. }
  2403. else
  2404. {
  2405. $adherent->fetch_thirdparty();
  2406. // Send reminder email
  2407. $outputlangs = new Translate('', $conf);
  2408. $outputlangs->setDefaultLang(empty($adherent->thirdparty->default_lang) ? $mysoc->default_lang : $adherent->thirdparty->default_lang);
  2409. $outputlangs->loadLangs(array("main", "members"));
  2410. dol_syslog("sendReminderForExpiredSubscription Language set to ".$outputlangs->defaultlang);
  2411. $arraydefaultmessage=null;
  2412. $labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION;
  2413. if (! empty($labeltouse)) $arraydefaultmessage=$formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
  2414. if (! empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0)
  2415. {
  2416. $substitutionarray=getCommonSubstitutionArray($outputlangs, 0, null, $adherent);
  2417. //if (is_array($adherent->thirdparty)) $substitutionarraycomp = ...
  2418. complete_substitutions_array($substitutionarray, $outputlangs, $adherent);
  2419. $subject = make_substitutions($arraydefaultmessage->topic, $substitutionarray, $outputlangs);
  2420. $msg = make_substitutions($arraydefaultmessage->content, $substitutionarray, $outputlangs);
  2421. $from = $conf->global->ADHERENT_MAIL_FROM;
  2422. $to = $adherent->email;
  2423. $trackid = 'mem'.$adherent->id;
  2424. $moreinheader='X-Dolibarr-Info: sendReminderForExpiredSubscription'."\r\n";
  2425. include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
  2426. $cmail = new CMailFile($subject, $to, $from, $msg, array(), array(), array(), '', '', 0, 1, '', '', $trackid, $moreinheader);
  2427. $result = $cmail->sendfile();
  2428. if (! $result)
  2429. {
  2430. $error++;
  2431. $this->error = $cmail->error;
  2432. $this->errors += $cmail->errors;
  2433. $nbko++;
  2434. }
  2435. else
  2436. {
  2437. $nbok++;
  2438. $message = $msg;
  2439. $sendto = $to;
  2440. $sendtocc = '';
  2441. $sendtobcc = '';
  2442. $actioncode='EMAIL';
  2443. $extraparams='';
  2444. $actionmsg='';
  2445. $actionmsg2=$langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($from,4,0,1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($sendto,4,0,1);
  2446. if ($message)
  2447. {
  2448. $actionmsg=$langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
  2449. $actionmsg=dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
  2450. if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . dol_escape_htmltag($sendtocc));
  2451. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
  2452. $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
  2453. $actionmsg = dol_concatdesc($actionmsg, $message);
  2454. }
  2455. require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
  2456. // Insert record of emails sent
  2457. $actioncomm = new ActionComm($this->db);
  2458. $actioncomm->type_code = 'AC_OTH_AUTO'; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
  2459. $actioncomm->code = 'AC_'.$actioncode;
  2460. $actioncomm->label = $actionmsg2;
  2461. $actioncomm->note = $actionmsg;
  2462. $actioncomm->fk_project = 0;
  2463. $actioncomm->datep = $now;
  2464. $actioncomm->datef = $now;
  2465. $actioncomm->percentage = -1; // Not applicable
  2466. $actioncomm->socid = $adherent->thirdparty->id;
  2467. $actioncomm->contactid = 0;
  2468. $actioncomm->authorid = $user->id; // User saving action
  2469. $actioncomm->userownerid = $user->id; // Owner of action
  2470. // Fields when action is en email (content should be added into note)
  2471. $actioncomm->email_msgid = $cmail->msgid;
  2472. $actioncomm->email_from = $from;
  2473. $actioncomm->email_sender= '';
  2474. $actioncomm->email_to = $to;
  2475. $actioncomm->email_tocc = $sendtocc;
  2476. $actioncomm->email_tobcc = $sendtobcc;
  2477. $actioncomm->email_subject = $subject;
  2478. $actioncomm->errors_to = '';
  2479. $actioncomm->fk_element = $adherent->id;
  2480. $actioncomm->elementtype = $adherent->element;
  2481. $actioncomm->extraparams = $extraparams;
  2482. $actioncomm->create($user);
  2483. }
  2484. }
  2485. else
  2486. {
  2487. $blockingerrormsg="Can't find email template, defined into member module setup, to use for reminding";
  2488. $nbko++;
  2489. break;
  2490. }
  2491. }
  2492. $i++;
  2493. }
  2494. }
  2495. else
  2496. {
  2497. $this->error = $this->db->lasterror();
  2498. return 1;
  2499. }
  2500. }
  2501. if ($blockingerrormsg)
  2502. {
  2503. $this->error = $blockingerrormsg;
  2504. return 1;
  2505. }
  2506. else
  2507. {
  2508. $this->output = 'Found '.($nbok + $nbko).' members to send reminder to.';
  2509. $this->output.= ' Send email successfuly to '.$nbok.' members';
  2510. if ($nbko) $this->output.= ' - Canceled for '.$nbko.' member (no email or email sending error)';
  2511. }
  2512. return 0;
  2513. }
  2514. }