societe.class.php 194 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609
  1. <?php
  2. /* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2021 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
  5. * Copyright (C) 2003 Brian Fraval <brian@fraval.org>
  6. * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
  7. * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
  8. * Copyright (C) 2008 Patrick Raguin <patrick.raguin@auguria.net>
  9. * Copyright (C) 2010-2018 Juanjo Menent <jmenent@2byte.es>
  10. * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
  11. * Copyright (C) 2013-2023 Alexandre Spangaro <aspangaro@open-dsi.fr>
  12. * Copyright (C) 2013 Peter Fontaine <contact@peterfontaine.fr>
  13. * Copyright (C) 2014-2015 Marcos García <marcosgdf@gmail.com>
  14. * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
  15. * Copyright (C) 2017 Rui Strecht <rui.strecht@aliartalentos.com>
  16. * Copyright (C) 2018 Philippe Grand <philippe.grand@atoo-net.com>
  17. * Copyright (C) 2019-2020 Josep Lluís Amador <joseplluis@lliuretic.cat>
  18. * Copyright (C) 2019-2023 Frédéric France <frederic.france@netlogic.fr>
  19. * Copyright (C) 2020 Open-Dsi <support@open-dsi.fr>
  20. * Copyright (C) 2022 ButterflyOfFire <butterflyoffire+dolibarr@protonmail.com>
  21. * Copyright (C) 2023 Alexandre Janniaux <alexandre.janniaux@gmail.com>
  22. *
  23. * This program is free software; you can redistribute it and/or modify
  24. * it under the terms of the GNU General Public License as published by
  25. * the Free Software Foundation; either version 3 of the License, or
  26. * (at your option) any later version.
  27. *
  28. * This program is distributed in the hope that it will be useful,
  29. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  31. * GNU General Public License for more details.
  32. *
  33. * You should have received a copy of the GNU General Public License
  34. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  35. */
  36. /**
  37. * \file htdocs/societe/class/societe.class.php
  38. * \ingroup societe
  39. * \brief File for third party class
  40. */
  41. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  42. require_once DOL_DOCUMENT_ROOT.'/core/class/commonincoterm.class.php';
  43. require_once DOL_DOCUMENT_ROOT.'/core/class/commonsocialnetworks.class.php';
  44. require_once DOL_DOCUMENT_ROOT.'/core/class/commonpeople.class.php';
  45. require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
  46. /**
  47. * Class to manage third parties objects (customers, suppliers, prospects...)
  48. */
  49. class Societe extends CommonObject
  50. {
  51. use CommonIncoterm;
  52. use CommonSocialNetworks;
  53. use CommonPeople;
  54. /**
  55. * @var string ID of module.
  56. */
  57. public $module = 'societe';
  58. /**
  59. * @var string ID to identify managed object
  60. */
  61. public $element = 'societe';
  62. /**
  63. * @var string Name of table without prefix where object is stored
  64. */
  65. public $table_element = 'societe';
  66. /**
  67. * @var string Field with ID of parent key if this field has a parent or for child tables
  68. */
  69. public $fk_element = 'fk_soc';
  70. /**
  71. * @var string Fields for combobox
  72. */
  73. public $fieldsforcombobox = 'nom,name_alias';
  74. /**
  75. * @var array List of child tables. To test if we can delete object.
  76. */
  77. protected $childtables = array(
  78. 'supplier_proposal' => array('name' => 'SupplierProposal'),
  79. 'propal' => array('name' => 'Proposal'),
  80. 'commande' => array('name' => 'Order'),
  81. 'facture' => array('name' => 'Invoice'),
  82. 'facture_rec' => array('name' => 'RecurringInvoiceTemplate'),
  83. 'contrat' => array('name' => 'Contract'),
  84. 'fichinter' => array('name' => 'Fichinter'),
  85. 'facture_fourn' => array('name' => 'SupplierInvoice'),
  86. 'commande_fournisseur' => array('name' => 'SupplierOrder'),
  87. 'projet' => array('name' => 'Project'),
  88. 'expedition' => array('name' => 'Shipment'),
  89. 'prelevement_lignes' => array('name' => 'DirectDebitRecord'),
  90. );
  91. /**
  92. * @var array List of child tables. To know object to delete on cascade.
  93. * if name like with @ClassName:FilePathClass:ParentFkFieldName' it will call method deleteByParentField (with parentId as parameters) and FieldName to fetch and delete child object
  94. */
  95. protected $childtablesoncascade = array(
  96. 'societe_prices',
  97. 'product_fournisseur_price',
  98. 'product_customer_price_log',
  99. 'product_customer_price',
  100. '@Contact:/contact/class/contact.class.php:fk_soc',
  101. 'adherent',
  102. 'societe_account',
  103. 'societe_rib',
  104. 'societe_remise',
  105. 'societe_remise_except',
  106. 'societe_commerciaux',
  107. 'categorie',
  108. 'notify',
  109. 'notify_def',
  110. 'actioncomm',
  111. );
  112. /**
  113. * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
  114. */
  115. public $picto = 'company';
  116. /**
  117. * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  118. * @var int
  119. */
  120. public $ismultientitymanaged = 1;
  121. /**
  122. * @var int Does object support extrafields ? 0=No, 1=Yes
  123. */
  124. public $isextrafieldmanaged = 1;
  125. /**
  126. * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
  127. * @var integer
  128. */
  129. public $restrictiononfksoc = 1;
  130. /**
  131. * @var Societe To store a cloned copy of object before to edit it and keep track of old properties
  132. */
  133. public $oldcopy;
  134. /**
  135. * array of supplier categories
  136. * @var array
  137. */
  138. public $SupplierCategories = array();
  139. /**
  140. * prefixCustomerIsRequired
  141. * @var int
  142. */
  143. public $prefixCustomerIsRequired;
  144. /**
  145. * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
  146. * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
  147. * 'label' the translation key.
  148. * 'picto' is code of a picto to show before value in forms
  149. * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM)
  150. * 'position' is the sort order of field.
  151. * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
  152. * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
  153. * 'noteditable' says if field is not editable (1 or 0)
  154. * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
  155. * 'index' if we want an index in database.
  156. * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...).
  157. * 'searchall' is 1 if we want to search in this field when making a search from the quick search button.
  158. * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8).
  159. * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'maxwidth200', 'wordbreak', 'tdoverflowmax200'
  160. * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
  161. * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record
  162. * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code.
  163. * 'arrayofkeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel")
  164. * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1.
  165. * 'comment' is not used. You can store here any text of your choice. It is not used by application.
  166. *
  167. * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
  168. */
  169. /**
  170. * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
  171. */
  172. public $fields = array(
  173. 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
  174. 'parent' =>array('type'=>'integer', 'label'=>'Parent', 'enabled'=>1, 'visible'=>-1, 'position'=>20),
  175. 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25),
  176. 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>30),
  177. 'nom' =>array('type'=>'varchar(128)', 'label'=>'Nom', 'enabled'=>1, 'visible'=>-1, 'position'=>35, 'showoncombobox'=>1),
  178. 'name_alias' =>array('type'=>'varchar(128)', 'label'=>'Name alias', 'enabled'=>1, 'visible'=>-1, 'position'=>36, 'showoncombobox'=>2),
  179. 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>40, 'index'=>1),
  180. 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>45),
  181. 'code_client' =>array('type'=>'varchar(24)', 'label'=>'CustomerCode', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
  182. 'code_fournisseur' =>array('type'=>'varchar(24)', 'label'=>'SupplierCode', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
  183. 'code_compta' =>array('type'=>'varchar(24)', 'label'=>'CustomerAccountancyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
  184. 'code_compta_fournisseur' =>array('type'=>'varchar(24)', 'label'=>'SupplierAccountancyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>70),
  185. 'address' =>array('type'=>'varchar(255)', 'label'=>'Address', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
  186. 'zip' =>array('type'=>'varchar(25)', 'label'=>'Zip', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
  187. 'town' =>array('type'=>'varchar(50)', 'label'=>'Town', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
  188. 'fk_departement' =>array('type'=>'integer', 'label'=>'State', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
  189. 'fk_pays' =>array('type'=>'integer:Ccountry:core/class/ccountry.class.php', 'label'=>'Country', 'enabled'=>1, 'visible'=>-1, 'position'=>95),
  190. 'phone' =>array('type'=>'varchar(20)', 'label'=>'Phone', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
  191. 'fax' =>array('type'=>'varchar(20)', 'label'=>'Fax', 'enabled'=>1, 'visible'=>-1, 'position'=>105),
  192. 'url' =>array('type'=>'varchar(255)', 'label'=>'Url', 'enabled'=>1, 'visible'=>-1, 'position'=>110),
  193. 'email' =>array('type'=>'varchar(128)', 'label'=>'Email', 'enabled'=>1, 'visible'=>-1, 'position'=>115),
  194. 'socialnetworks' =>array('type'=>'text', 'label'=>'Socialnetworks', 'enabled'=>1, 'visible'=>-1, 'position'=>120),
  195. 'fk_effectif' =>array('type'=>'integer', 'label'=>'Workforce', 'enabled'=>1, 'visible'=>-1, 'position'=>170),
  196. 'fk_typent' =>array('type'=>'integer', 'label'=>'TypeOfCompany', 'enabled'=>1, 'visible'=>-1, 'position'=>175, 'csslist'=>'minwidth200'),
  197. 'fk_forme_juridique' =>array('type'=>'integer', 'label'=>'JuridicalStatus', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
  198. 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'Currency', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
  199. 'siren' =>array('type'=>'varchar(128)', 'label'=>'Idprof1', 'enabled'=>1, 'visible'=>-1, 'position'=>190),
  200. 'siret' =>array('type'=>'varchar(128)', 'label'=>'Idprof2', 'enabled'=>1, 'visible'=>-1, 'position'=>195),
  201. 'ape' =>array('type'=>'varchar(128)', 'label'=>'Idprof3', 'enabled'=>1, 'visible'=>-1, 'position'=>200),
  202. 'idprof4' =>array('type'=>'varchar(128)', 'label'=>'Idprof4', 'enabled'=>1, 'visible'=>-1, 'position'=>205),
  203. 'idprof5' =>array('type'=>'varchar(128)', 'label'=>'Idprof5', 'enabled'=>1, 'visible'=>-1, 'position'=>206),
  204. 'idprof6' =>array('type'=>'varchar(128)', 'label'=>'Idprof6', 'enabled'=>1, 'visible'=>-1, 'position'=>207),
  205. 'tva_intra' =>array('type'=>'varchar(20)', 'label'=>'Tva intra', 'enabled'=>1, 'visible'=>-1, 'position'=>210),
  206. 'capital' =>array('type'=>'double(24,8)', 'label'=>'Capital', 'enabled'=>1, 'visible'=>-1, 'position'=>215),
  207. 'fk_stcomm' =>array('type'=>'integer', 'label'=>'CommercialStatus', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>220),
  208. 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>225),
  209. 'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>230),
  210. 'prefix_comm' =>array('type'=>'varchar(5)', 'label'=>'Prefix comm', 'enabled'=>"getDolGlobalInt('SOCIETE_USEPREFIX')", 'visible'=>-1, 'position'=>235),
  211. 'client' =>array('type'=>'tinyint(4)', 'label'=>'Client', 'enabled'=>1, 'visible'=>-1, 'position'=>240),
  212. 'fournisseur' =>array('type'=>'tinyint(4)', 'label'=>'Fournisseur', 'enabled'=>1, 'visible'=>-1, 'position'=>245),
  213. 'supplier_account' =>array('type'=>'varchar(32)', 'label'=>'Supplier account', 'enabled'=>1, 'visible'=>-1, 'position'=>250),
  214. 'fk_prospectlevel' =>array('type'=>'varchar(12)', 'label'=>'ProspectLevel', 'enabled'=>1, 'visible'=>-1, 'position'=>255),
  215. 'customer_bad' =>array('type'=>'tinyint(4)', 'label'=>'Customer bad', 'enabled'=>1, 'visible'=>-1, 'position'=>260),
  216. 'customer_rate' =>array('type'=>'double', 'label'=>'Customer rate', 'enabled'=>1, 'visible'=>-1, 'position'=>265),
  217. 'supplier_rate' =>array('type'=>'double', 'label'=>'Supplier rate', 'enabled'=>1, 'visible'=>-1, 'position'=>270),
  218. 'fk_user_creat' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'position'=>275),
  219. 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>280),
  220. //'remise_client' =>array('type'=>'double', 'label'=>'CustomerDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>285, 'isameasure'=>1),
  221. //'remise_supplier' =>array('type'=>'double', 'label'=>'SupplierDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>290, 'isameasure'=>1),
  222. 'mode_reglement' =>array('type'=>'tinyint(4)', 'label'=>'Mode reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>295),
  223. 'cond_reglement' =>array('type'=>'tinyint(4)', 'label'=>'Cond reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>300),
  224. 'deposit_percent' =>array('type'=>'varchar(63)', 'label'=>'DepositPercent', 'enabled'=>1, 'visible'=>-1, 'position'=>301),
  225. 'mode_reglement_supplier' =>array('type'=>'integer', 'label'=>'Mode reglement supplier', 'enabled'=>1, 'visible'=>-1, 'position'=>305),
  226. 'cond_reglement_supplier' =>array('type'=>'integer', 'label'=>'Cond reglement supplier', 'enabled'=>1, 'visible'=>-1, 'position'=>308),
  227. 'outstanding_limit' =>array('type'=>'double(24,8)', 'label'=>'OutstandingBill', 'enabled'=>1, 'visible'=>-1, 'position'=>310, 'isameasure'=>1),
  228. 'order_min_amount' =>array('type'=>'double(24,8)', 'label'=>'Order min amount', 'enabled'=>'isModEnabled("commande") && !empty($conf->global->ORDER_MANAGE_MIN_AMOUNT)', 'visible'=>-1, 'position'=>315, 'isameasure'=>1),
  229. 'supplier_order_min_amount' =>array('type'=>'double(24,8)', 'label'=>'Supplier order min amount', 'enabled'=>'isModEnabled("commande") && !empty($conf->global->ORDER_MANAGE_MIN_AMOUNT)', 'visible'=>-1, 'position'=>320, 'isameasure'=>1),
  230. 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'Fk shipping method', 'enabled'=>1, 'visible'=>-1, 'position'=>330),
  231. 'tva_assuj' =>array('type'=>'tinyint(4)', 'label'=>'Tva assuj', 'enabled'=>1, 'visible'=>-1, 'position'=>335),
  232. 'localtax1_assuj' =>array('type'=>'tinyint(4)', 'label'=>'Localtax1 assuj', 'enabled'=>1, 'visible'=>-1, 'position'=>340),
  233. 'localtax1_value' =>array('type'=>'double(6,3)', 'label'=>'Localtax1 value', 'enabled'=>1, 'visible'=>-1, 'position'=>345),
  234. 'localtax2_assuj' =>array('type'=>'tinyint(4)', 'label'=>'Localtax2 assuj', 'enabled'=>1, 'visible'=>-1, 'position'=>350),
  235. 'localtax2_value' =>array('type'=>'double(6,3)', 'label'=>'Localtax2 value', 'enabled'=>1, 'visible'=>-1, 'position'=>355),
  236. 'vat_reverse_charge' =>array('type'=>'tinyint(4)', 'label'=>'Vat reverse charge', 'enabled'=>1, 'visible'=>-1, 'position'=>335),
  237. 'barcode' =>array('type'=>'varchar(255)', 'label'=>'Barcode', 'enabled'=>1, 'visible'=>-1, 'position'=>360),
  238. 'price_level' =>array('type'=>'integer', 'label'=>'Price level', 'enabled'=>'$conf->global->PRODUIT_MULTIPRICES || $conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES', 'visible'=>-1, 'position'=>365),
  239. 'default_lang' =>array('type'=>'varchar(6)', 'label'=>'Default lang', 'enabled'=>1, 'visible'=>-1, 'position'=>370),
  240. 'canvas' =>array('type'=>'varchar(32)', 'label'=>'Canvas', 'enabled'=>1, 'visible'=>-1, 'position'=>375),
  241. 'fk_barcode_type' =>array('type'=>'integer', 'label'=>'Fk barcode type', 'enabled'=>1, 'visible'=>-1, 'position'=>405),
  242. 'webservices_url' =>array('type'=>'varchar(255)', 'label'=>'Webservices url', 'enabled'=>1, 'visible'=>-1, 'position'=>410),
  243. 'webservices_key' =>array('type'=>'varchar(128)', 'label'=>'Webservices key', 'enabled'=>1, 'visible'=>-1, 'position'=>415),
  244. 'fk_incoterms' =>array('type'=>'integer', 'label'=>'Fk incoterms', 'enabled'=>1, 'visible'=>-1, 'position'=>425),
  245. 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'Location incoterms', 'enabled'=>1, 'visible'=>-1, 'position'=>430),
  246. 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>435),
  247. 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>270),
  248. 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>440),
  249. 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Multicurrency code', 'enabled'=>1, 'visible'=>-1, 'position'=>445),
  250. 'fk_account' =>array('type'=>'integer', 'label'=>'PaymentBankAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>450),
  251. 'fk_warehouse' =>array('type'=>'integer', 'label'=>'Warehouse', 'enabled'=>1, 'visible'=>-1, 'position'=>455),
  252. 'logo' =>array('type'=>'varchar(255)', 'label'=>'Logo', 'enabled'=>1, 'visible'=>-1, 'position'=>400),
  253. 'logo_squarred' =>array('type'=>'varchar(255)', 'label'=>'Logo squarred', 'enabled'=>1, 'visible'=>-1, 'position'=>401),
  254. 'status' =>array('type'=>'tinyint(4)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'position'=>500),
  255. 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000),
  256. );
  257. /**
  258. * @var int Entity
  259. */
  260. public $entity;
  261. /**
  262. * Thirdparty name
  263. * @var string
  264. * @deprecated Use $name instead
  265. * @see $name
  266. */
  267. public $nom;
  268. /**
  269. * @var string Thirdparty name
  270. */
  271. public $name;
  272. /**
  273. * Alias names (commercial, trademark or alias names)
  274. * @var string
  275. */
  276. public $name_alias;
  277. /**
  278. * @var int Physical thirdparty not a company
  279. */
  280. public $particulier;
  281. /**
  282. * Thirdparty status : 0=activity ceased, 1= in activity
  283. * @var int
  284. */
  285. public $status = 1;
  286. /**
  287. * Id of region
  288. * @var int
  289. */
  290. public $region_code;
  291. /**
  292. * @var string Region name
  293. */
  294. public $region;
  295. /**
  296. * @var int country_id
  297. */
  298. public $country_id;
  299. /**
  300. * @var string State code
  301. * @deprecated Use state_code instead
  302. * @see $state_code
  303. */
  304. public $departement_code;
  305. /**
  306. * @var string
  307. * @deprecated Use state instead
  308. * @see $state
  309. */
  310. public $departement;
  311. /**
  312. * @var string
  313. * @deprecated Use country instead
  314. * @see $country
  315. */
  316. public $pays;
  317. /**
  318. * Phone number
  319. * @var string
  320. */
  321. public $phone;
  322. /**
  323. * Fax number
  324. * @var string
  325. */
  326. public $fax;
  327. /**
  328. * Email
  329. * @var string
  330. */
  331. public $email;
  332. /**
  333. * No Email
  334. * @var int Set if company email found into unsubscribe of emailing list table
  335. */
  336. public $no_email;
  337. /**
  338. * Skype username
  339. * @var string
  340. * @deprecated
  341. */
  342. public $skype;
  343. /**
  344. * Twitter username
  345. * @var string
  346. * @deprecated
  347. */
  348. public $twitter;
  349. /**
  350. * Facebook username
  351. * @var string
  352. * @deprecated
  353. */
  354. public $facebook;
  355. /**
  356. * LinkedIn username
  357. * @var string
  358. * @deprecated
  359. */
  360. public $linkedin;
  361. /**
  362. * Webpage
  363. * @var string
  364. */
  365. public $url;
  366. /**
  367. * Barcode value
  368. * @var string
  369. */
  370. public $barcode;
  371. // 6 professional id (usage depends on country)
  372. /**
  373. * Professional ID 1 (Ex: Siren in France)
  374. * @var string
  375. */
  376. public $idprof1;
  377. /**
  378. * @var string Professional ID 1
  379. * @deprecated
  380. * @see $idprof1
  381. */
  382. public $siren;
  383. /**
  384. * Professional ID 2 (Ex: Siret in France)
  385. * @var string
  386. */
  387. public $idprof2;
  388. /**
  389. * @var string Professional ID 2
  390. * @deprecated
  391. * @see $idprof2
  392. */
  393. public $siret;
  394. /**
  395. * Professional ID 3 (Ex: Ape in France)
  396. * @var string
  397. */
  398. public $idprof3;
  399. /**
  400. * @var string Professional ID 3
  401. * @deprecated
  402. * @see $idprof3
  403. */
  404. public $ape;
  405. /**
  406. * Professional ID 4 (Ex: RCS in France)
  407. * @var string
  408. */
  409. public $idprof4;
  410. /**
  411. * Professional ID 5
  412. * @var string
  413. */
  414. public $idprof5;
  415. /**
  416. * Professional ID 6
  417. * @var string
  418. */
  419. public $idprof6;
  420. /**
  421. * Social object of the company
  422. * @var string
  423. */
  424. public $socialobject;
  425. /**
  426. * @var string Prefix comm
  427. */
  428. public $prefix_comm;
  429. /**
  430. * @var int Vat concerned
  431. */
  432. public $tva_assuj = 1;
  433. /**
  434. * Intracommunitary VAT ID
  435. * @var string
  436. */
  437. public $tva_intra;
  438. /**
  439. * @var int Vat reverse-charge concerned
  440. */
  441. public $vat_reverse_charge = 0;
  442. // Local taxes
  443. public $localtax1_assuj;
  444. public $localtax1_value;
  445. public $localtax2_assuj;
  446. public $localtax2_value;
  447. /**
  448. * @var string Manager
  449. */
  450. public $managers;
  451. /**
  452. * @var float Capital
  453. */
  454. public $capital;
  455. /**
  456. * @var int Type thirdparty
  457. */
  458. public $typent_id = 0;
  459. public $typent_code;
  460. public $effectif;
  461. public $effectif_id = 0;
  462. public $forme_juridique_code;
  463. public $forme_juridique = 0;
  464. public $remise_percent;
  465. public $remise_supplier_percent;
  466. public $mode_reglement_id;
  467. public $cond_reglement_id;
  468. public $deposit_percent;
  469. public $mode_reglement_supplier_id;
  470. public $cond_reglement_supplier_id;
  471. public $transport_mode_supplier_id;
  472. /**
  473. * @var int ID
  474. */
  475. public $fk_prospectlevel;
  476. /**
  477. * @var string second name
  478. */
  479. public $name_bis;
  480. //Log data
  481. /**
  482. * Date of last update
  483. * @var integer|string
  484. */
  485. public $date_modification;
  486. /**
  487. * User that made last update
  488. * @var User
  489. * @deprecated
  490. */
  491. public $user_modification;
  492. /**
  493. * Date of creation
  494. * @var integer|string
  495. */
  496. public $date_creation;
  497. /**
  498. * User that created the thirdparty
  499. * @var User
  500. * @deprecated
  501. */
  502. public $user_creation;
  503. /**
  504. * 0=no customer, 1=customer, 2=prospect, 3=customer and prospect
  505. * @var int
  506. */
  507. public $client = 0;
  508. /**
  509. * 0=no prospect, 1=prospect
  510. * @var int
  511. */
  512. public $prospect = 0;
  513. /**
  514. * 0=no supplier, 1=supplier
  515. * @var int
  516. */
  517. public $fournisseur;
  518. /**
  519. * Client code. E.g: CU2014-003
  520. * @var string
  521. */
  522. public $code_client;
  523. /**
  524. * Supplier code. E.g: SU2014-003
  525. * @var string
  526. */
  527. public $code_fournisseur;
  528. /**
  529. * Accounting code for client
  530. * @var string
  531. */
  532. public $code_compta_client;
  533. /**
  534. * Duplicate of code_compta_client (for backward compatibility)
  535. * @var string
  536. * @deprecated
  537. * @see $code_compta_client
  538. */
  539. public $code_compta;
  540. /**
  541. * Accounting code for customer
  542. * @var string
  543. */
  544. public $accountancy_code_customer;
  545. /**
  546. * Accounting code for supplier
  547. * @var string
  548. */
  549. public $code_compta_fournisseur;
  550. /**
  551. * Accounting code for supplier
  552. * @var string
  553. */
  554. public $accountancy_code_supplier;
  555. /**
  556. * Accounting code for product (for level 3 of suggestion of prouct accounting account)
  557. * @var string
  558. */
  559. public $code_compta_product;
  560. /**
  561. * @var string
  562. * @deprecated Note is split in public and private notes
  563. * @see $note_public, $note_private
  564. */
  565. public $note;
  566. /**
  567. * Private note
  568. * @var string
  569. */
  570. public $note_private;
  571. /**
  572. * Public note
  573. * @var string
  574. */
  575. public $note_public;
  576. /**
  577. * Status prospect id
  578. * @var int
  579. */
  580. public $stcomm_id;
  581. /**
  582. * Status prospect picto
  583. * @var string
  584. */
  585. public $stcomm_picto;
  586. /**
  587. * Status prospect label
  588. * @var int
  589. */
  590. public $status_prospect_label;
  591. /**
  592. * Assigned price level
  593. * @var int
  594. */
  595. public $price_level;
  596. /**
  597. * @var string outstanding limit
  598. */
  599. public $outstanding_limit;
  600. /**
  601. * @var string Min order amount
  602. */
  603. public $order_min_amount;
  604. /**
  605. * @var string Supplier min order amount
  606. */
  607. public $supplier_order_min_amount;
  608. /**
  609. * Id of sales representative to link (used for thirdparty creation). Not filled by a fetch, because we can have several sales representatives.
  610. * @var int
  611. */
  612. public $commercial_id;
  613. /**
  614. * Id of parent thirdparty (if one)
  615. * @var int
  616. */
  617. public $parent;
  618. /**
  619. * Default language code of thirdparty (en_US, ...)
  620. * @var string
  621. */
  622. public $default_lang;
  623. /**
  624. * @var string Ref
  625. */
  626. public $ref;
  627. /**
  628. * External user reference.
  629. * This is to allow external systems to store their id and make self-developed synchronizing functions easier to build.
  630. * @var string
  631. */
  632. public $ref_ext;
  633. /**
  634. * Import key.
  635. * Set when the thirdparty has been created through an import process. This is to relate those created thirdparties
  636. * to an import process
  637. * @var string
  638. */
  639. public $import_key;
  640. /**
  641. * Supplier WebServices URL
  642. * @var string
  643. */
  644. public $webservices_url;
  645. /**
  646. * Supplier WebServices Key
  647. * @var string
  648. */
  649. public $webservices_key;
  650. /**
  651. * @var string Logo
  652. */
  653. public $logo;
  654. /**
  655. * @var string logo small
  656. */
  657. public $logo_small;
  658. /**
  659. * @var string Logo mini
  660. */
  661. public $logo_mini;
  662. /**
  663. * @var string Logo squarred
  664. */
  665. public $logo_squarred;
  666. /**
  667. * @var string Logo squarred small
  668. */
  669. public $logo_squarred_small;
  670. /**
  671. * @var string Logo squarred mini
  672. */
  673. public $logo_squarred_mini;
  674. /**
  675. * @var string Accountancy account for sales
  676. */
  677. public $accountancy_code_sell;
  678. /**
  679. * @var string Accountancy account for bought
  680. */
  681. public $accountancy_code_buy;
  682. // Multicurrency
  683. /**
  684. * @var int ID
  685. */
  686. public $fk_multicurrency;
  687. // Warehouse
  688. /**
  689. * @var int ID
  690. */
  691. public $fk_warehouse;
  692. /**
  693. * @var string Multicurrency code
  694. */
  695. public $multicurrency_code;
  696. // Fields loaded by fetchPartnerships()
  697. public $partnerships = array();
  698. /**
  699. * @var Account|string Default BAN account
  700. */
  701. public $bank_account;
  702. const STATUS_CEASED = 0;
  703. const STATUS_INACTIVITY = 1;
  704. /**
  705. * Third party type is no customer
  706. */
  707. const NO_CUSTOMER = 0;
  708. /**
  709. * Third party type is a customer
  710. */
  711. const CUSTOMER = 1;
  712. /**
  713. * Third party type is a prospect
  714. */
  715. const PROSPECT = 2;
  716. /**
  717. * Third party type is a customer and a prospect
  718. */
  719. const CUSTOMER_AND_PROSPECT = 3;
  720. /**
  721. * Third party supplier flag is not supplier
  722. */
  723. const NO_SUPPLIER = 0;
  724. /**
  725. * Third party supplier flag is a supplier
  726. */
  727. const SUPPLIER = 1;
  728. /**
  729. * Constructor
  730. *
  731. * @param DoliDB $db Database handler
  732. */
  733. public function __construct($db)
  734. {
  735. global $conf;
  736. $this->db = $db;
  737. $this->client = 0;
  738. $this->prospect = 0;
  739. $this->fournisseur = 0;
  740. $this->typent_id = 0;
  741. $this->effectif_id = 0;
  742. $this->forme_juridique_code = 0;
  743. $this->tva_assuj = 1;
  744. $this->vat_reverse_charge = 0;
  745. $this->status = 1;
  746. if (getDolGlobalString('COMPANY_SHOW_ADDRESS_SELECTLIST')) {
  747. $this->fields['address']['showoncombobox'] = $conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST;
  748. $this->fields['zip']['showoncombobox'] = $conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST;
  749. $this->fields['town']['showoncombobox'] = $conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST;
  750. //$this->fields['fk_pays']['showoncombobox'] = $conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST;
  751. }
  752. }
  753. /**
  754. * Create third party in database.
  755. * $this->code_client = -1 and $this->code_fournisseur = -1 means automatic assignement.
  756. *
  757. * @param User $user Object of user that ask creation
  758. * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
  759. * @return int >=0 if OK, <0 if KO
  760. */
  761. public function create(User $user, $notrigger = 0)
  762. {
  763. global $langs, $conf, $mysoc;
  764. $error = 0;
  765. // Clean parameters
  766. if (empty($this->status)) {
  767. $this->status = 0;
  768. }
  769. $this->name = $this->name ? trim($this->name) : trim($this->nom);
  770. $this->setUpperOrLowerCase();
  771. $this->nom = $this->name; // For backward compatibility
  772. if (empty($this->client)) {
  773. $this->client = 0;
  774. }
  775. if (empty($this->fournisseur)) {
  776. $this->fournisseur = 0;
  777. }
  778. $this->import_key = trim($this->import_key);
  779. $this->accountancy_code_customer = trim($this->code_compta);
  780. $this->accountancy_code_supplier = trim($this->code_compta_fournisseur);
  781. $this->accountancy_code_buy = trim($this->accountancy_code_buy);
  782. $this->accountancy_code_sell = trim($this->accountancy_code_sell);
  783. if (!empty($this->multicurrency_code)) {
  784. $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
  785. }
  786. if (empty($this->fk_multicurrency)) {
  787. $this->multicurrency_code = '';
  788. $this->fk_multicurrency = 0;
  789. }
  790. dol_syslog(get_class($this)."::create ".$this->name);
  791. $now = dol_now();
  792. $this->db->begin();
  793. // For automatic creation during create action (not used by Dolibarr GUI, can be used by scripts)
  794. if ($this->code_client == -1 || $this->code_client === 'auto') {
  795. $this->get_codeclient($this, 0);
  796. }
  797. if ($this->code_fournisseur == -1 || $this->code_fournisseur === 'auto') {
  798. $this->get_codefournisseur($this, 1);
  799. }
  800. // Check more parameters (including mandatory setup
  801. // If error, this->errors[] is filled
  802. $result = $this->verify();
  803. if ($result >= 0) {
  804. $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
  805. $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe (";
  806. $sql .= "nom";
  807. $sql .= ", name_alias";
  808. $sql .= ", entity";
  809. $sql .= ", datec";
  810. $sql .= ", fk_user_creat";
  811. $sql .= ", fk_typent";
  812. $sql .= ", canvas";
  813. $sql .= ", status";
  814. $sql .= ", ref_ext";
  815. $sql .= ", fk_stcomm";
  816. $sql .= ", fk_incoterms";
  817. $sql .= ", location_incoterms";
  818. $sql .= ", import_key";
  819. $sql .= ", fk_multicurrency";
  820. $sql .= ", multicurrency_code";
  821. if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  822. $sql .= ", vat_reverse_charge";
  823. $sql .= ", accountancy_code_buy";
  824. $sql .= ", accountancy_code_sell";
  825. }
  826. $sql .= ") VALUES ('".$this->db->escape($this->name)."', '".$this->db->escape($this->name_alias)."', ".((int) $this->entity).", '".$this->db->idate($now)."'";
  827. $sql .= ", ".(!empty($user->id) ? ((int) $user->id) : "null");
  828. $sql .= ", ".(!empty($this->typent_id) ? ((int) $this->typent_id) : "null");
  829. $sql .= ", ".(!empty($this->canvas) ? "'".$this->db->escape($this->canvas)."'" : "null");
  830. $sql .= ", ".((int) $this->status);
  831. $sql .= ", ".(!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null");
  832. $sql .= ", 0";
  833. $sql .= ", ".(int) $this->fk_incoterms;
  834. $sql .= ", '".$this->db->escape($this->location_incoterms)."'";
  835. $sql .= ", ".(!empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null");
  836. $sql .= ", ".(int) $this->fk_multicurrency;
  837. $sql .= ", '".$this->db->escape($this->multicurrency_code)."'";
  838. if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  839. $sql .= ", ".(empty($this->vat_reverse_charge) ? '0' : '1');
  840. $sql .= ", '" . $this->db->escape($this->accountancy_code_buy) . "'";
  841. $sql .= ", '" . $this->db->escape($this->accountancy_code_sell) . "'";
  842. }
  843. $sql .= ")";
  844. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  845. $result = $this->db->query($sql);
  846. if ($result) {
  847. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."societe");
  848. $ret = $this->update($this->id, $user, 0, 1, 1, 'add');
  849. // update accountancy for this entity
  850. if (!$error && getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  851. $this->db->query("DELETE FROM ".MAIN_DB_PREFIX."societe_perentity WHERE fk_soc = ".((int) $this->id)." AND entity = ".((int) $conf->entity));
  852. $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_perentity (";
  853. $sql .= " fk_soc";
  854. $sql .= ", entity";
  855. $sql .= ", vat_reverse_charge";
  856. $sql .= ", accountancy_code_customer";
  857. $sql .= ", accountancy_code_supplier";
  858. $sql .= ", accountancy_code_buy";
  859. $sql .= ", accountancy_code_sell";
  860. $sql .= ") VALUES (";
  861. $sql .= $this->id;
  862. $sql .= ", ".((int) $conf->entity);
  863. $sql .= ", ".(empty($this->vat_reverse_charge) ? '0' : '1');
  864. $sql .= ", '".$this->db->escape($this->accountancy_code_customer)."'";
  865. $sql .= ", '".$this->db->escape($this->accountancy_code_supplier)."'";
  866. $sql .= ", '".$this->db->escape($this->accountancy_code_buy)."'";
  867. $sql .= ", '".$this->db->escape($this->accountancy_code_sell)."'";
  868. $sql .= ")";
  869. $result = $this->db->query($sql);
  870. if (!$result) {
  871. $error++;
  872. $this->error = 'ErrorFailedToUpdateAccountancyForEntity';
  873. }
  874. }
  875. // Ajout du commercial affecte
  876. if ($this->commercial_id != '' && $this->commercial_id != -1) {
  877. $this->add_commercial($user, $this->commercial_id);
  878. } elseif (!$user->hasRight('societe', 'client', 'voir')) {
  879. // si un commercial cree un client il lui est affecte automatiquement
  880. $this->add_commercial($user, $user->id);
  881. }
  882. if ($ret >= 0) {
  883. if (! $notrigger) {
  884. // Call trigger
  885. $result = $this->call_trigger('COMPANY_CREATE', $user);
  886. if ($result < 0) {
  887. $error++;
  888. }
  889. // End call triggers
  890. }
  891. } else {
  892. $error++;
  893. }
  894. if (!$error) {
  895. dol_syslog(get_class($this)."::Create success id=".$this->id);
  896. $this->db->commit();
  897. return $this->id;
  898. } else {
  899. dol_syslog(get_class($this)."::Create echec update ".$this->error.(empty($this->errors) ? '' : ' '.join(',', $this->errors)), LOG_ERR);
  900. $this->db->rollback();
  901. return -4;
  902. }
  903. } else {
  904. if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
  905. $this->error = $langs->trans("ErrorCompanyNameAlreadyExists", $this->name); // duplicate on a field (code or profid or ...)
  906. $result = -1;
  907. } else {
  908. $this->error = $this->db->lasterror();
  909. $result = -2;
  910. }
  911. $this->db->rollback();
  912. return $result;
  913. }
  914. } else {
  915. $this->db->rollback();
  916. dol_syslog(get_class($this)."::Create fails verify ".join(',', $this->errors), LOG_WARNING);
  917. return -3;
  918. }
  919. }
  920. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  921. /**
  922. * Create a contact/address from thirdparty
  923. *
  924. * @param User $user Object user
  925. * @param int $no_email 1=Do not send mailing, 0=Ok to recieve mailling
  926. * @param array $tags Array of tag to affect to contact
  927. * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
  928. * @return int Return integer <0 if KO, >0 if OK
  929. */
  930. public function create_individual(User $user, $no_email = 0, $tags = array(), $notrigger = 0)
  931. {
  932. global $conf;
  933. $error = 0;
  934. $this->db->begin();
  935. // phpcs:enable
  936. require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
  937. $contact = new Contact($this->db);
  938. $contact->name = $this->name_bis;
  939. $contact->firstname = $this->firstname;
  940. $contact->civility_id = $this->civility_id;
  941. $contact->socid = $this->id; // fk_soc
  942. $contact->statut = 1; // deprecated
  943. $contact->status = 1;
  944. $contact->priv = 0;
  945. $contact->country_id = $this->country_id;
  946. $contact->state_id = $this->state_id;
  947. $contact->address = $this->address;
  948. $contact->email = $this->email;
  949. $contact->zip = $this->zip;
  950. $contact->town = $this->town;
  951. $this->setUpperOrLowerCase();
  952. $contact->phone_pro = $this->phone;
  953. $contactId = $contact->create($user, $notrigger);
  954. if ($contactId < 0) {
  955. $error++;
  956. $this->error = $contact->error;
  957. $this->errors = $contact->errors;
  958. dol_syslog(get_class($this)."::create_individual ERROR:".$this->error, LOG_ERR);
  959. }
  960. if (empty($error) && is_array($tags) && !empty($tags)) {
  961. $result = $contact->setCategories($tags);
  962. if ($result < 0) {
  963. $error++;
  964. $this->error = $contact->error;
  965. $this->errors = array_merge($this->errors, $contact->errors);
  966. dol_syslog(get_class($this)."::create_individual Affect Tag ERROR:".$this->error, LOG_ERR);
  967. $contactId = $result;
  968. }
  969. }
  970. if (empty($error) && isModEnabled('mailing') && !empty($contact->email) && isset($no_email)) {
  971. $result = $contact->setNoEmail($no_email);
  972. if ($result < 0) {
  973. $this->error = $contact->error;
  974. $this->errors = array_merge($this->errors, $contact->errors);
  975. dol_syslog(get_class($this)."::create_individual set mailing status ERROR:".$this->error, LOG_ERR);
  976. $contactId = $result;
  977. }
  978. }
  979. if (empty($error)) {
  980. dol_syslog(get_class($this)."::create_individual success");
  981. $this->db->commit();
  982. } else {
  983. $this->db->rollback();
  984. }
  985. return $contactId;
  986. }
  987. /**
  988. * Check properties of third party are ok (like name, third party codes, ...)
  989. * Used before an add or update.
  990. *
  991. * @return int 0 if OK, <0 if KO
  992. */
  993. public function verify()
  994. {
  995. global $conf, $langs, $mysoc;
  996. $error = 0;
  997. $this->errors = array();
  998. $result = 0;
  999. $this->name = trim($this->name);
  1000. $this->nom = $this->name; // For backward compatibility
  1001. if (!$this->name) {
  1002. $this->errors[] = 'ErrorBadThirdPartyName';
  1003. $result = -2;
  1004. }
  1005. if ($this->client) {
  1006. $rescode = $this->check_codeclient();
  1007. if ($rescode != 0 && $rescode != -5) {
  1008. if ($rescode == -1) {
  1009. $this->errors[] = 'ErrorBadCustomerCodeSyntax';
  1010. } elseif ($rescode == -2) {
  1011. $this->errors[] = 'ErrorCustomerCodeRequired';
  1012. } elseif ($rescode == -3) {
  1013. $this->errors[] = 'ErrorCustomerCodeAlreadyUsed';
  1014. } elseif ($rescode == -4) {
  1015. $this->errors[] = 'ErrorPrefixRequired';
  1016. } else {
  1017. $this->errors[] = 'ErrorUnknownOnCustomerCodeCheck';
  1018. }
  1019. $result = -3;
  1020. }
  1021. }
  1022. if ($this->fournisseur) {
  1023. $rescode = $this->check_codefournisseur();
  1024. if ($rescode != 0 && $rescode != -5) {
  1025. if ($rescode == -1) {
  1026. $this->errors[] = 'ErrorBadSupplierCodeSyntax';
  1027. } elseif ($rescode == -2) {
  1028. $this->errors[] = 'ErrorSupplierCodeRequired';
  1029. } elseif ($rescode == -3) {
  1030. $this->errors[] = 'ErrorSupplierCodeAlreadyUsed';
  1031. } elseif ($rescode == -4) {
  1032. $this->errors[] = 'ErrorPrefixRequired';
  1033. } else {
  1034. $this->errors[] = 'ErrorUnknownOnSupplierCodeCheck';
  1035. }
  1036. $result = -3;
  1037. }
  1038. }
  1039. // Check for duplicate or mandatory fields defined into setup
  1040. $array_to_check = array('IDPROF1', 'IDPROF2', 'IDPROF3', 'IDPROF4', 'IDPROF5', 'IDPROF6', 'EMAIL', 'TVA_INTRA', 'ACCOUNTANCY_CODE_CUSTOMER', 'ACCOUNTANCY_CODE_SUPPLIER');
  1041. foreach ($array_to_check as $key) {
  1042. $keymin = strtolower($key);
  1043. if ($key == 'ACCOUNTANCY_CODE_CUSTOMER') {
  1044. $keymin = 'code_compta';
  1045. } elseif ($key == 'ACCOUNTANCY_CODE_SUPPLIER') {
  1046. $keymin = 'code_compta_fournisseur';
  1047. }
  1048. $i = (int) preg_replace('/[^0-9]/', '', $key);
  1049. $vallabel = $this->$keymin;
  1050. if ($i > 0) {
  1051. if ($this->isACompany()) {
  1052. // Check for mandatory prof id (but only if country is same than ours)
  1053. if ($mysoc->country_id > 0 && $this->country_id == $mysoc->country_id) {
  1054. $idprof_mandatory = 'SOCIETE_'.$key.'_MANDATORY';
  1055. if (!$vallabel && getDolGlobalString($idprof_mandatory)) {
  1056. $langs->load("errors");
  1057. $error++;
  1058. $this->errors[] = $langs->trans("ErrorProdIdIsMandatory", $langs->transcountry('ProfId'.$i, $this->country_code)).' ('.$langs->trans("ForbiddenBySetupRules").')';
  1059. }
  1060. }
  1061. }
  1062. // Check for unicity on profid
  1063. if (!$error && $vallabel && $this->id_prof_verifiable($i)) {
  1064. if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
  1065. $langs->load("errors");
  1066. $error++;
  1067. $this->errors[] = $langs->transcountry('ProfId'.$i, $this->country_code)." ".$langs->trans("ErrorProdIdAlreadyExist", $vallabel).' ('.$langs->trans("ForbiddenBySetupRules").')';
  1068. }
  1069. }
  1070. } else {
  1071. //var_dump($conf->global->SOCIETE_EMAIL_UNIQUE);
  1072. //var_dump($conf->global->SOCIETE_EMAIL_MANDATORY);
  1073. if ($key == 'EMAIL') {
  1074. // Check for mandatory
  1075. if (getDolGlobalString('SOCIETE_EMAIL_MANDATORY') && !isValidEMail($this->email)) {
  1076. $langs->load("errors");
  1077. $error++;
  1078. $this->errors[] = $langs->trans("ErrorBadEMail", $this->email).' ('.$langs->trans("ForbiddenBySetupRules").')';
  1079. }
  1080. // Check for unicity
  1081. if (!$error && $vallabel && getDolGlobalString('SOCIETE_EMAIL_UNIQUE')) {
  1082. if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
  1083. $langs->load("errors");
  1084. $error++;
  1085. $this->errors[] = $langs->trans('Email')." ".$langs->trans("ErrorProdIdAlreadyExist", $vallabel).' ('.$langs->trans("ForbiddenBySetupRules").')';
  1086. }
  1087. }
  1088. } elseif ($key == 'TVA_INTRA') {
  1089. // Check for unicity
  1090. if ($vallabel && getDolGlobalString('SOCIETE_VAT_INTRA_UNIQUE')) {
  1091. if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
  1092. $langs->load("errors");
  1093. $error++;
  1094. $this->errors[] = $langs->trans('VATIntra')." ".$langs->trans("ErrorProdIdAlreadyExist", $vallabel).' ('.$langs->trans("ForbiddenBySetupRules").')';
  1095. }
  1096. }
  1097. } elseif ($key == 'ACCOUNTANCY_CODE_CUSTOMER' && !empty($this->client)) {
  1098. // Check for unicity
  1099. if ($vallabel && getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_UNIQUE')) {
  1100. if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
  1101. $langs->loadLangs(array("errors", 'compta'));
  1102. $error++;
  1103. $this->errors[] = $langs->trans('CustomerAccountancyCodeShort') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
  1104. }
  1105. }
  1106. // Check for mandatory
  1107. if (getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_MANDATORY') && (!isset($vallabel) || trim($vallabel) === '')) {
  1108. $langs->loadLangs(array("errors", 'compta'));
  1109. $error++;
  1110. $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv('CustomerAccountancyCodeShort')) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
  1111. }
  1112. } elseif ($key == 'ACCOUNTANCY_CODE_SUPPLIER' && !empty($this->fournisseur)) {
  1113. // Check for unicity
  1114. if ($vallabel && getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_SUPPLIER_UNIQUE')) {
  1115. if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
  1116. $langs->loadLangs(array("errors", 'compta'));
  1117. $error++;
  1118. $this->errors[] = $langs->trans('SupplierAccountancyCodeShort') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
  1119. }
  1120. }
  1121. // Check for mandatory
  1122. if (getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_SUPPLIER_MANDATORY') && (!isset($vallabel) || trim($vallabel) === '')) {
  1123. $langs->loadLangs(array("errors", 'compta'));
  1124. $error++;
  1125. $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv('SupplierAccountancyCodeShort')) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
  1126. }
  1127. }
  1128. }
  1129. }
  1130. if ($error) {
  1131. $result = -4;
  1132. }
  1133. return $result;
  1134. }
  1135. /**
  1136. * Update parameters of third party
  1137. *
  1138. * @param int $id Id of company (deprecated, use 0 here and call update on an object loaded by a fetch)
  1139. * @param User $user User who requests the update
  1140. * @param int $call_trigger 0=no, 1=yes
  1141. * @param int $allowmodcodeclient Inclut modif code client et code compta
  1142. * @param int $allowmodcodefournisseur Inclut modif code fournisseur et code compta fournisseur
  1143. * @param string $action 'add' or 'update' or 'merge'
  1144. * @param int $nosyncmember Do not synchronize info of linked member
  1145. * @return int Return integer <0 if KO, >=0 if OK
  1146. */
  1147. public function update($id, $user = '', $call_trigger = 1, $allowmodcodeclient = 0, $allowmodcodefournisseur = 0, $action = 'update', $nosyncmember = 1)
  1148. {
  1149. global $langs, $conf, $hookmanager;
  1150. require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
  1151. if (empty($id)) {
  1152. $id = $this->id;
  1153. }
  1154. $error = 0;
  1155. dol_syslog(get_class($this)."::Update id=".$id." call_trigger=".$call_trigger." allowmodcodeclient=".$allowmodcodeclient." allowmodcodefournisseur=".$allowmodcodefournisseur);
  1156. $now = dol_now();
  1157. // Clean parameters
  1158. $this->id = $id;
  1159. $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
  1160. $this->name = $this->name ? trim($this->name) : trim($this->nom);
  1161. $this->nom = $this->name; // For backward compatibility
  1162. $this->name_alias = trim($this->name_alias);
  1163. $this->ref_ext = trim($this->ref_ext);
  1164. $this->address = $this->address ? trim($this->address) : trim($this->address);
  1165. $this->zip = $this->zip ? trim($this->zip) : trim($this->zip);
  1166. $this->town = $this->town ? trim($this->town) : trim($this->town);
  1167. $this->state_id = trim($this->state_id);
  1168. $this->country_id = ($this->country_id > 0) ? $this->country_id : 0;
  1169. $this->phone = trim($this->phone);
  1170. $this->phone = preg_replace("/\s/", "", $this->phone);
  1171. $this->phone = preg_replace("/\./", "", $this->phone);
  1172. $this->fax = trim($this->fax);
  1173. $this->fax = preg_replace("/\s/", "", $this->fax);
  1174. $this->fax = preg_replace("/\./", "", $this->fax);
  1175. $this->email = trim($this->email);
  1176. $this->url = $this->url ? clean_url($this->url, 0) : '';
  1177. $this->note_private = trim($this->note_private);
  1178. $this->note_public = trim($this->note_public);
  1179. $this->idprof1 = trim($this->idprof1);
  1180. $this->idprof2 = trim($this->idprof2);
  1181. $this->idprof3 = trim($this->idprof3);
  1182. $this->idprof4 = trim($this->idprof4);
  1183. $this->idprof5 = (!empty($this->idprof5) ? trim($this->idprof5) : '');
  1184. $this->idprof6 = (!empty($this->idprof6) ? trim($this->idprof6) : '');
  1185. $this->prefix_comm = trim($this->prefix_comm);
  1186. $this->outstanding_limit = price2num($this->outstanding_limit);
  1187. $this->order_min_amount = price2num($this->order_min_amount);
  1188. $this->supplier_order_min_amount = price2num($this->supplier_order_min_amount);
  1189. $this->tva_assuj = trim($this->tva_assuj);
  1190. $this->tva_intra = dol_sanitizeFileName($this->tva_intra, '');
  1191. $this->vat_reverse_charge = empty($this->vat_reverse_charge) ? '0' : '1';
  1192. if (empty($this->status)) {
  1193. $this->status = 0;
  1194. }
  1195. if (!empty($this->multicurrency_code)) {
  1196. $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
  1197. }
  1198. if (empty($this->fk_multicurrency)) {
  1199. $this->multicurrency_code = '';
  1200. $this->fk_multicurrency = 0;
  1201. }
  1202. // Local taxes
  1203. $this->localtax1_assuj = trim($this->localtax1_assuj);
  1204. $this->localtax2_assuj = trim($this->localtax2_assuj);
  1205. $this->localtax1_value = trim($this->localtax1_value);
  1206. $this->localtax2_value = trim($this->localtax2_value);
  1207. if ($this->capital != '') {
  1208. $this->capital = price2num(trim($this->capital));
  1209. }
  1210. if (!is_numeric($this->capital)) {
  1211. $this->capital = ''; // '' = undef
  1212. }
  1213. $this->effectif_id = trim($this->effectif_id);
  1214. $this->forme_juridique_code = trim($this->forme_juridique_code);
  1215. //Gencod
  1216. $this->barcode = trim($this->barcode);
  1217. // For automatic creation
  1218. if ($this->code_client == -1 || $this->code_client === 'auto') {
  1219. $this->get_codeclient($this, 0);
  1220. }
  1221. if ($this->code_fournisseur == -1 || $this->code_fournisseur === 'auto') {
  1222. $this->get_codefournisseur($this, 1);
  1223. }
  1224. $this->code_compta_client = trim(empty($this->code_compta) ? $this->code_compta_client : $this->code_compta);
  1225. $this->code_compta = $this->code_compta_client; // for backward compatibility
  1226. $this->code_compta_fournisseur = trim($this->code_compta_fournisseur);
  1227. // Check parameters. More tests are done later in the ->verify()
  1228. if (!is_numeric($this->client) && !is_numeric($this->fournisseur)) {
  1229. $langs->load("errors");
  1230. $this->error = $langs->trans("BadValueForParameterClientOrSupplier");
  1231. return -1;
  1232. }
  1233. $customer = false;
  1234. if (!empty($allowmodcodeclient) && !empty($this->client)) {
  1235. // If $allowmodcodeclient is set and value is not set, we generate it
  1236. if (empty($this->code_compta_client)) {
  1237. $ret = $this->get_codecompta('customer');
  1238. if ($ret < 0) {
  1239. return -1;
  1240. }
  1241. }
  1242. $customer = true;
  1243. }
  1244. $supplier = false;
  1245. if (!empty($allowmodcodefournisseur) && !empty($this->fournisseur)) {
  1246. // If $allowmodcodefournisseur is set and value is not set, we generate it
  1247. if (empty($this->code_compta_fournisseur)) {
  1248. $ret = $this->get_codecompta('supplier');
  1249. if ($ret < 0) {
  1250. return -1;
  1251. }
  1252. }
  1253. $supplier = true;
  1254. }
  1255. //Web services
  1256. $this->webservices_url = $this->webservices_url ? clean_url($this->webservices_url, 0) : '';
  1257. $this->webservices_key = trim($this->webservices_key);
  1258. $this->accountancy_code_buy = trim($this->accountancy_code_buy);
  1259. $this->accountancy_code_sell = trim($this->accountancy_code_sell);
  1260. //Incoterms
  1261. $this->fk_incoterms = (int) $this->fk_incoterms;
  1262. $this->location_incoterms = trim($this->location_incoterms);
  1263. $this->db->begin();
  1264. // Check name is required and codes are ok or unique.
  1265. // If error, this->errors[] is filled
  1266. $result = 0;
  1267. if ($action != 'add' && $action != 'merge') {
  1268. // We don't check when update called during a create because verify was already done.
  1269. // For a merge, we suppose source data is clean and a customer code of a deleted thirdparty must be accepted into a target thirdparty with empty code without duplicate error
  1270. $result = $this->verify();
  1271. // If there is only one error and error is ErrorBadCustomerCodeSyntax and we don't change customer code, we allow the update
  1272. // So we can update record that were using and old numbering rule.
  1273. if (is_array($this->errors)) {
  1274. if (in_array('ErrorBadCustomerCodeSyntax', $this->errors) && is_object($this->oldcopy) && $this->oldcopy->code_client == $this->code_client) {
  1275. if (($key = array_search('ErrorBadCustomerCodeSyntax', $this->errors)) !== false) {
  1276. unset($this->errors[$key]); // Remove error message
  1277. }
  1278. }
  1279. if (in_array('ErrorBadSupplierCodeSyntax', $this->errors) && is_object($this->oldcopy) && $this->oldcopy->code_fournisseur == $this->code_fournisseur) {
  1280. if (($key = array_search('ErrorBadSupplierCodeSyntax', $this->errors)) !== false) {
  1281. unset($this->errors[$key]); // Remove error message
  1282. }
  1283. }
  1284. if (empty($this->errors)) { // If there is no more error, we can make like if there is no error at all
  1285. $result = 0;
  1286. }
  1287. }
  1288. }
  1289. $this->setUpperOrLowerCase();
  1290. if ($result >= 0) {
  1291. dol_syslog(get_class($this)."::update verify ok or not done");
  1292. $sql = "UPDATE ".MAIN_DB_PREFIX."societe SET ";
  1293. $sql .= "entity = ".$this->db->escape($this->entity);
  1294. $sql .= ",nom = '".$this->db->escape($this->name)."'"; // Required
  1295. $sql .= ",name_alias = '".$this->db->escape($this->name_alias)."'";
  1296. $sql .= ",ref_ext = ".(!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null");
  1297. $sql .= ",address = '".$this->db->escape($this->address)."'";
  1298. $sql .= ",zip = ".(!empty($this->zip) ? "'".$this->db->escape($this->zip)."'" : "null");
  1299. $sql .= ",town = ".(!empty($this->town) ? "'".$this->db->escape($this->town)."'" : "null");
  1300. $sql .= ",fk_departement = ".((!empty($this->state_id) && $this->state_id > 0) ? ((int) $this->state_id) : 'null');
  1301. $sql .= ",fk_pays = ".((!empty($this->country_id) && $this->country_id > 0) ? ((int) $this->country_id) : 'null');
  1302. $sql .= ",phone = ".(!empty($this->phone) ? "'".$this->db->escape($this->phone)."'" : "null");
  1303. $sql .= ",fax = ".(!empty($this->fax) ? "'".$this->db->escape($this->fax)."'" : "null");
  1304. $sql .= ",email = ".(!empty($this->email) ? "'".$this->db->escape($this->email)."'" : "null");
  1305. $sql .= ",socialnetworks = '".$this->db->escape(json_encode($this->socialnetworks))."'";
  1306. $sql .= ",url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null");
  1307. $sql .= ",parent = ".($this->parent > 0 ? $this->parent : "null");
  1308. $sql .= ",note_private = ".(!empty($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null");
  1309. $sql .= ",note_public = ".(!empty($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : "null");
  1310. $sql .= ",siren = '".$this->db->escape($this->idprof1)."'";
  1311. $sql .= ",siret = '".$this->db->escape($this->idprof2)."'";
  1312. $sql .= ",ape = '".$this->db->escape($this->idprof3)."'";
  1313. $sql .= ",idprof4 = '".$this->db->escape($this->idprof4)."'";
  1314. $sql .= ",idprof5 = '".$this->db->escape($this->idprof5)."'";
  1315. $sql .= ",idprof6 = '".$this->db->escape($this->idprof6)."'";
  1316. $sql .= ",tva_assuj = ".($this->tva_assuj != '' ? "'".$this->db->escape($this->tva_assuj)."'" : "null");
  1317. $sql .= ",tva_intra = '".$this->db->escape($this->tva_intra)."'";
  1318. if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  1319. $sql .= ",vat_reverse_charge = " . ($this->vat_reverse_charge != '' ? "'" . $this->db->escape($this->vat_reverse_charge) . "'" : 0);
  1320. }
  1321. $sql .= ",status = ".((int) $this->status);
  1322. // Local taxes
  1323. $sql .= ",localtax1_assuj = ".($this->localtax1_assuj != '' ? "'".$this->db->escape($this->localtax1_assuj)."'" : "null");
  1324. $sql .= ",localtax2_assuj = ".($this->localtax2_assuj != '' ? "'".$this->db->escape($this->localtax2_assuj)."'" : "null");
  1325. if ($this->localtax1_assuj == 1) {
  1326. if ($this->localtax1_value != '') {
  1327. $sql .= ",localtax1_value =".$this->localtax1_value;
  1328. } else {
  1329. $sql .= ",localtax1_value =0.000";
  1330. }
  1331. } else {
  1332. $sql .= ",localtax1_value =0.000";
  1333. }
  1334. if ($this->localtax2_assuj == 1) {
  1335. if ($this->localtax2_value != '') {
  1336. $sql .= ",localtax2_value =".$this->localtax2_value;
  1337. } else {
  1338. $sql .= ",localtax2_value =0.000";
  1339. }
  1340. } else {
  1341. $sql .= ",localtax2_value =0.000";
  1342. }
  1343. $sql .= ",capital = ".($this->capital == '' ? "null" : $this->capital);
  1344. $sql .= ",prefix_comm = ".(!empty($this->prefix_comm) ? "'".$this->db->escape($this->prefix_comm)."'" : "null");
  1345. $sql .= ",fk_effectif = ".($this->effectif_id > 0 ? ((int) $this->effectif_id) : "null");
  1346. if (isset($this->stcomm_id)) {
  1347. $sql .= ",fk_stcomm=".(int) $this->stcomm_id;
  1348. }
  1349. if (isset($this->typent_id)) {
  1350. $sql .= ",fk_typent = ".($this->typent_id > 0 ? ((int) $this->typent_id) : "0");
  1351. }
  1352. $sql .= ",fk_forme_juridique = ".(!empty($this->forme_juridique_code) ? "'".$this->db->escape($this->forme_juridique_code)."'" : "null");
  1353. $sql .= ",mode_reglement = ".(!empty($this->mode_reglement_id) ? "'".$this->db->escape($this->mode_reglement_id)."'" : "null");
  1354. $sql .= ",cond_reglement = ".(!empty($this->cond_reglement_id) ? "'".$this->db->escape($this->cond_reglement_id)."'" : "null");
  1355. $sql .= ",deposit_percent = ".(!empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : "null");
  1356. $sql .= ",transport_mode = ".(!empty($this->transport_mode_id) ? "'".$this->db->escape($this->transport_mode_id)."'" : "null");
  1357. $sql .= ",mode_reglement_supplier = ".(!empty($this->mode_reglement_supplier_id) ? "'".$this->db->escape($this->mode_reglement_supplier_id)."'" : "null");
  1358. $sql .= ",cond_reglement_supplier = ".(!empty($this->cond_reglement_supplier_id) ? "'".$this->db->escape($this->cond_reglement_supplier_id)."'" : "null");
  1359. $sql .= ",transport_mode_supplier = ".(!empty($this->transport_mode_supplier_id) ? "'".$this->db->escape($this->transport_mode_supplier_id)."'" : "null");
  1360. $sql .= ",fk_shipping_method = ".(!empty($this->shipping_method_id) ? "'".$this->db->escape($this->shipping_method_id)."'" : "null");
  1361. $sql .= ",client = ".(!empty($this->client) ? $this->client : 0);
  1362. $sql .= ",fournisseur = ".(!empty($this->fournisseur) ? $this->fournisseur : 0);
  1363. $sql .= ",barcode = ".(!empty($this->barcode) ? "'".$this->db->escape($this->barcode)."'" : "null");
  1364. $sql .= ",default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null");
  1365. $sql .= ",logo = ".(!empty($this->logo) ? "'".$this->db->escape($this->logo)."'" : "null");
  1366. $sql .= ",logo_squarred = ".(!empty($this->logo_squarred) ? "'".$this->db->escape($this->logo_squarred)."'" : "null");
  1367. $sql .= ",outstanding_limit= ".($this->outstanding_limit != '' ? $this->outstanding_limit : 'null');
  1368. $sql .= ",order_min_amount= ".($this->order_min_amount != '' ? $this->order_min_amount : 'null');
  1369. $sql .= ",supplier_order_min_amount= ".($this->supplier_order_min_amount != '' ? $this->supplier_order_min_amount : 'null');
  1370. $sql .= ",fk_prospectlevel='".$this->db->escape($this->fk_prospectlevel)."'";
  1371. if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  1372. $sql .= ", accountancy_code_buy = '" . $this->db->escape($this->accountancy_code_buy) . "'";
  1373. $sql .= ", accountancy_code_sell= '" . $this->db->escape($this->accountancy_code_sell) . "'";
  1374. if ($customer) {
  1375. $sql .= ", code_compta = ".(!empty($this->code_compta_client) ? "'".$this->db->escape($this->code_compta_client)."'" : "null");
  1376. }
  1377. if ($supplier) {
  1378. $sql .= ", code_compta_fournisseur = ".(($this->code_compta_fournisseur != "") ? "'".$this->db->escape($this->code_compta_fournisseur)."'" : "null");
  1379. }
  1380. }
  1381. $sql .= ",webservices_url = ".(!empty($this->webservices_url) ? "'".$this->db->escape($this->webservices_url)."'" : "null");
  1382. $sql .= ",webservices_key = ".(!empty($this->webservices_key) ? "'".$this->db->escape($this->webservices_key)."'" : "null");
  1383. //Incoterms
  1384. $sql .= ", fk_incoterms = ".((int) $this->fk_incoterms);
  1385. $sql .= ", location_incoterms = ".(!empty($this->location_incoterms) ? "'".$this->db->escape($this->location_incoterms)."'" : "null");
  1386. if ($customer) {
  1387. $sql .= ", code_client = ".(!empty($this->code_client) ? "'".$this->db->escape($this->code_client)."'" : "null");
  1388. }
  1389. if ($supplier) {
  1390. $sql .= ", code_fournisseur = ".(!empty($this->code_fournisseur) ? "'".$this->db->escape($this->code_fournisseur)."'" : "null");
  1391. }
  1392. $sql .= ", fk_user_modif = ".($user->id > 0 ? $user->id : "null");
  1393. $sql .= ", fk_multicurrency = ".(int) $this->fk_multicurrency;
  1394. $sql .= ", multicurrency_code = '".$this->db->escape($this->multicurrency_code)."'";
  1395. $sql .= ", model_pdf = '".$this->db->escape($this->model_pdf)."'";
  1396. $sql .= " WHERE rowid = ".(int) $id;
  1397. $resql = $this->db->query($sql);
  1398. if ($resql) {
  1399. if (is_object($this->oldcopy)) { // If we have information on old values
  1400. if ($this->oldcopy->country_id != $this->country_id) {
  1401. unset($this->country_code);
  1402. unset($this->country);
  1403. }
  1404. if ($this->oldcopy->state_id != $this->state_id) {
  1405. unset($this->state_code);
  1406. unset($this->state);
  1407. }
  1408. } else {
  1409. unset($this->country_code); // We clean this, in the doubt, because it may have been changed after an update of country_id
  1410. unset($this->country);
  1411. unset($this->state_code);
  1412. unset($this->state);
  1413. }
  1414. $nbrowsaffected = $this->db->affected_rows($resql);
  1415. if (!$error && $nbrowsaffected) {
  1416. // Update information on linked member if it is an update
  1417. if (!$nosyncmember && isModEnabled('adherent')) {
  1418. require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
  1419. dol_syslog(get_class($this)."::update update linked member");
  1420. $lmember = new Adherent($this->db);
  1421. $result = $lmember->fetch(0, 0, $this->id);
  1422. if ($result > 0) {
  1423. $lmember->company = $this->name;
  1424. //$lmember->firstname=$this->firstname?$this->firstname:$lmember->firstname; // We keep firstname and lastname of member unchanged
  1425. //$lmember->lastname=$this->lastname?$this->lastname:$lmember->lastname; // We keep firstname and lastname of member unchanged
  1426. $lmember->address = $this->address;
  1427. $lmember->zip = $this->zip;
  1428. $lmember->town = $this->town;
  1429. $lmember->email = $this->email;
  1430. $lmember->socialnetworks = $this->socialnetworks;
  1431. $lmember->phone = $this->phone;
  1432. $lmember->state_id = $this->state_id;
  1433. $lmember->country_id = $this->country_id;
  1434. $lmember->default_lang = $this->default_lang;
  1435. $result = $lmember->update($user, 0, 1, 1, 1); // Use nosync to 1 to avoid cyclic updates
  1436. if ($result < 0) {
  1437. $this->error = $lmember->error;
  1438. $this->errors = array_merge($this->errors, $lmember->errors);
  1439. dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
  1440. $error++;
  1441. }
  1442. } elseif ($result < 0) {
  1443. $this->error = $lmember->error;
  1444. $error++;
  1445. }
  1446. }
  1447. }
  1448. $action = 'update';
  1449. // update accountancy for this entity
  1450. if (!$error && getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  1451. $this->db->query("DELETE FROM ".MAIN_DB_PREFIX."societe_perentity WHERE fk_soc = ".((int) $this->id)." AND entity = ".((int) $conf->entity));
  1452. $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_perentity (";
  1453. $sql .= " fk_soc";
  1454. $sql .= ", entity";
  1455. $sql .= ", vat_reverse_charge";
  1456. $sql .= ", accountancy_code_customer";
  1457. $sql .= ", accountancy_code_supplier";
  1458. $sql .= ", accountancy_code_buy";
  1459. $sql .= ", accountancy_code_sell";
  1460. $sql .= ") VALUES (";
  1461. $sql .= $this->id;
  1462. $sql .= ", ".$conf->entity;
  1463. $sql .= ", ".(empty($this->vat_reverse_charge) ? '0' : '1');
  1464. $sql .= ", '".$this->db->escape($this->code_compta_client)."'";
  1465. $sql .= ", '".$this->db->escape($this->code_compta_fournisseur)."'";
  1466. $sql .= ", '".$this->db->escape($this->accountancy_code_buy)."'";
  1467. $sql .= ", '".$this->db->escape($this->accountancy_code_sell)."'";
  1468. $sql .= ")";
  1469. $result = $this->db->query($sql);
  1470. if (!$result) {
  1471. $error++;
  1472. $this->error = 'ErrorFailedToUpdateAccountancyForEntity';
  1473. }
  1474. }
  1475. // Actions on extra fields
  1476. if (!$error) {
  1477. $result = $this->insertExtraFields();
  1478. if ($result < 0) {
  1479. $error++;
  1480. }
  1481. }
  1482. // Actions on extra languages
  1483. if (!$error && !getDolGlobalString('MAIN_EXTRALANGUAGES_DISABLED')) { // For avoid conflicts if trigger used
  1484. $result = $this->insertExtraLanguages();
  1485. if ($result < 0) {
  1486. $error++;
  1487. }
  1488. }
  1489. if (!$error && $call_trigger) {
  1490. // Call trigger
  1491. $result = $this->call_trigger('COMPANY_MODIFY', $user);
  1492. if ($result < 0) {
  1493. $error++;
  1494. }
  1495. // End call triggers
  1496. }
  1497. if (!$error) {
  1498. dol_syslog(get_class($this)."::Update success");
  1499. $this->db->commit();
  1500. return 1;
  1501. } else {
  1502. $this->db->rollback();
  1503. return -1;
  1504. }
  1505. } else {
  1506. if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
  1507. // Doublon
  1508. $this->error = $langs->trans("ErrorDuplicateField");
  1509. $result = -1;
  1510. } else {
  1511. $this->error = $this->db->lasterror();
  1512. $result = -2;
  1513. }
  1514. $this->db->rollback();
  1515. return $result;
  1516. }
  1517. } else {
  1518. $this->db->rollback();
  1519. dol_syslog(get_class($this)."::Update fails verify ".join(',', $this->errors), LOG_WARNING);
  1520. return -3;
  1521. }
  1522. }
  1523. /**
  1524. * Load a third party from database into memory
  1525. *
  1526. * @param int $rowid Id of third party to load
  1527. * @param string $ref Reference of third party, name (Warning, this can return several records)
  1528. * @param string $ref_ext External reference of third party (Warning, this information is a free field not provided by Dolibarr)
  1529. * @param string $barcode Barcode of third party to load
  1530. * @param string $idprof1 Prof id 1 of third party (Warning, this can return several records)
  1531. * @param string $idprof2 Prof id 2 of third party (Warning, this can return several records)
  1532. * @param string $idprof3 Prof id 3 of third party (Warning, this can return several records)
  1533. * @param string $idprof4 Prof id 4 of third party (Warning, this can return several records)
  1534. * @param string $idprof5 Prof id 5 of third party (Warning, this can return several records)
  1535. * @param string $idprof6 Prof id 6 of third party (Warning, this can return several records)
  1536. * @param string $email Email of third party (Warning, this can return several records)
  1537. * @param string $ref_alias Name_alias of third party (Warning, this can return several records)
  1538. * @return int >0 if OK, <0 if KO or if two records found for same ref or idprof, 0 if not found.
  1539. */
  1540. public function fetch($rowid, $ref = '', $ref_ext = '', $barcode = '', $idprof1 = '', $idprof2 = '', $idprof3 = '', $idprof4 = '', $idprof5 = '', $idprof6 = '', $email = '', $ref_alias = '')
  1541. {
  1542. global $langs;
  1543. global $conf;
  1544. if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($barcode) && empty($idprof1) && empty($idprof2) && empty($idprof3) && empty($idprof4) && empty($idprof5) && empty($idprof6) && empty($email)) {
  1545. return -1;
  1546. }
  1547. $sql = 'SELECT s.rowid, s.nom as name, s.name_alias, s.entity, s.ref_ext, s.address, s.datec as date_creation, s.prefix_comm';
  1548. $sql .= ', s.status, s.fk_warehouse';
  1549. $sql .= ', s.price_level';
  1550. $sql .= ', s.tms as date_modification, s.fk_user_creat, s.fk_user_modif';
  1551. $sql .= ', s.phone, s.fax, s.email';
  1552. $sql .= ', s.socialnetworks';
  1553. $sql .= ', s.url, s.zip, s.town, s.note_private, s.note_public, s.client, s.fournisseur';
  1554. $sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6';
  1555. $sql .= ', s.capital, s.tva_intra';
  1556. $sql .= ', s.fk_typent as typent_id';
  1557. $sql .= ', s.fk_effectif as effectif_id';
  1558. $sql .= ', s.fk_forme_juridique as forme_juridique_code';
  1559. $sql .= ', s.webservices_url, s.webservices_key, s.model_pdf, s.last_main_doc';
  1560. if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  1561. $sql .= ', s.code_compta, s.code_compta_fournisseur, s.accountancy_code_buy, s.accountancy_code_sell';
  1562. $sql .= ', s.vat_reverse_charge as soc_vat_reverse_charge';
  1563. } else {
  1564. $sql .= ', spe.accountancy_code_customer as code_compta, spe.accountancy_code_supplier as code_compta_fournisseur, spe.accountancy_code_buy, spe.accountancy_code_sell';
  1565. $sql .= ', spe.vat_reverse_charge as spe_vat_reverse_charge';
  1566. }
  1567. $sql .= ', s.code_client, s.code_fournisseur, s.parent, s.barcode';
  1568. $sql .= ', s.fk_departement as state_id, s.fk_pays as country_id, s.fk_stcomm, s.mode_reglement, s.cond_reglement, s.deposit_percent, s.transport_mode';
  1569. $sql .= ', s.fk_account, s.tva_assuj';
  1570. $sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.transport_mode_supplier';
  1571. $sql .= ', s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo, s.logo_squarred';
  1572. $sql .= ', s.fk_shipping_method';
  1573. $sql .= ', s.outstanding_limit, s.import_key, s.canvas, s.fk_incoterms, s.location_incoterms';
  1574. $sql .= ', s.order_min_amount, s.supplier_order_min_amount';
  1575. $sql .= ', s.fk_multicurrency, s.multicurrency_code';
  1576. $sql .= ', fj.libelle as forme_juridique';
  1577. $sql .= ', e.libelle as effectif';
  1578. $sql .= ', c.code as country_code, c.label as country';
  1579. $sql .= ', d.code_departement as state_code, d.nom as state';
  1580. $sql .= ', r.rowid as region_id, r.code_region as region_code';
  1581. $sql .= ', st.libelle as stcomm, st.picto as stcomm_picto';
  1582. $sql .= ', te.code as typent_code';
  1583. $sql .= ', i.libelle as label_incoterms';
  1584. if (!isModEnabled('multicompany')) {
  1585. $sql .= ', s.remise_client, s.remise_supplier';
  1586. } else {
  1587. $sql .= ', sr.remise_client, sr2.remise_supplier';
  1588. }
  1589. $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s';
  1590. if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  1591. $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = ".((int) $conf->entity);
  1592. }
  1593. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as e ON s.fk_effectif = e.id';
  1594. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid';
  1595. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcomm as st ON s.fk_stcomm = st.id';
  1596. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as fj ON s.fk_forme_juridique = fj.code';
  1597. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid';
  1598. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_regions as r ON d.fk_region = r.code_region ';
  1599. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as te ON s.fk_typent = te.id';
  1600. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON s.fk_incoterms = i.rowid';
  1601. // With default setup, llx_societe_remise is a history table in default setup and current value is in llx_societe.
  1602. // We use it for real value when multicompany is on. A better place would be into llx_societe_perentity.
  1603. if (isModEnabled('multicompany')) {
  1604. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_remise as sr ON sr.rowid = (SELECT MAX(rowid) FROM '.MAIN_DB_PREFIX.'societe_remise WHERE fk_soc = s.rowid AND entity IN ('.getEntity('discount').'))';
  1605. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_remise_supplier as sr2 ON sr2.rowid = (SELECT MAX(rowid) FROM '.MAIN_DB_PREFIX.'societe_remise_supplier WHERE fk_soc = s.rowid AND entity IN ('.getEntity('discount').'))';
  1606. }
  1607. $sql .= ' WHERE s.entity IN ('.getEntity($this->element).')';
  1608. if ($rowid) {
  1609. $sql .= ' AND s.rowid = '.((int) $rowid);
  1610. }
  1611. if ($ref) {
  1612. $sql .= " AND s.nom = '".$this->db->escape($ref)."'";
  1613. }
  1614. if ($ref_alias) {
  1615. $sql .= " AND s.name_alias = '".$this->db->escape($ref_alias)."'";
  1616. }
  1617. if ($ref_ext) {
  1618. $sql .= " AND s.ref_ext = '".$this->db->escape($ref_ext)."'";
  1619. }
  1620. if ($barcode) {
  1621. $sql .= " AND s.barcode = '".$this->db->escape($barcode)."'";
  1622. }
  1623. if ($idprof1) {
  1624. $sql .= " AND s.siren = '".$this->db->escape($idprof1)."'";
  1625. }
  1626. if ($idprof2) {
  1627. $sql .= " AND s.siret = '".$this->db->escape($idprof2)."'";
  1628. }
  1629. if ($idprof3) {
  1630. $sql .= " AND s.ape = '".$this->db->escape($idprof3)."'";
  1631. }
  1632. if ($idprof4) {
  1633. $sql .= " AND s.idprof4 = '".$this->db->escape($idprof4)."'";
  1634. }
  1635. if ($idprof5) {
  1636. $sql .= " AND s.idprof5 = '".$this->db->escape($idprof5)."'";
  1637. }
  1638. if ($idprof6) {
  1639. $sql .= " AND s.idprof6 = '".$this->db->escape($idprof6)."'";
  1640. }
  1641. if ($email) {
  1642. $sql .= " AND s.email = '".$this->db->escape($email)."'";
  1643. }
  1644. $resql = $this->db->query($sql);
  1645. if ($resql) {
  1646. $num = $this->db->num_rows($resql);
  1647. if ($num > 1) {
  1648. $this->error = 'Fetch found several records. Rename one of thirdparties to avoid duplicate.';
  1649. dol_syslog($this->error, LOG_ERR);
  1650. $result = -2;
  1651. } elseif ($num) { // $num = 1
  1652. $obj = $this->db->fetch_object($resql);
  1653. $this->id = $obj->rowid;
  1654. $this->entity = $obj->entity;
  1655. $this->canvas = $obj->canvas;
  1656. $this->ref = $obj->rowid;
  1657. $this->name = $obj->name;
  1658. $this->nom = $obj->name; // deprecated
  1659. $this->name_alias = $obj->name_alias;
  1660. $this->ref_ext = $obj->ref_ext;
  1661. $this->date_creation = $this->db->jdate($obj->date_creation);
  1662. $this->date_modification = $this->db->jdate($obj->date_modification);
  1663. $this->user_creation_id = $obj->fk_user_creat;
  1664. $this->user_modification_id = $obj->fk_user_modif;
  1665. $this->address = $obj->address;
  1666. $this->zip = $obj->zip;
  1667. $this->town = $obj->town;
  1668. $this->country_id = $obj->country_id;
  1669. $this->country_code = $obj->country_id ? $obj->country_code : '';
  1670. $this->country = $obj->country_id ? (($langs->transnoentities('Country'.$obj->country_code) != 'Country'.$obj->country_code) ? $langs->transnoentities('Country'.$obj->country_code) : $obj->country) : '';
  1671. $this->state_id = $obj->state_id;
  1672. $this->state_code = $obj->state_code;
  1673. $this->region_id = $obj->region_id;
  1674. $this->region_code = $obj->region_code;
  1675. $this->state = ($obj->state != '-' ? $obj->state : '');
  1676. $transcode = $langs->trans('StatusProspect'.$obj->fk_stcomm);
  1677. $label = ($transcode != 'StatusProspect'.$obj->fk_stcomm ? $transcode : $obj->stcomm);
  1678. $this->stcomm_id = $obj->fk_stcomm; // id status prospect
  1679. $this->status_prospect_label = $label; // label status prospect
  1680. $this->stcomm_picto = $obj->stcomm_picto; // picto statut commercial
  1681. $this->email = $obj->email;
  1682. $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : array());
  1683. $this->url = $obj->url;
  1684. $this->phone = $obj->phone;
  1685. $this->fax = $obj->fax;
  1686. $this->parent = $obj->parent;
  1687. $this->idprof1 = $obj->idprof1;
  1688. $this->idprof2 = $obj->idprof2;
  1689. $this->idprof3 = $obj->idprof3;
  1690. $this->idprof4 = $obj->idprof4;
  1691. $this->idprof5 = $obj->idprof5;
  1692. $this->idprof6 = $obj->idprof6;
  1693. $this->capital = $obj->capital;
  1694. $this->code_client = $obj->code_client;
  1695. $this->code_fournisseur = $obj->code_fournisseur;
  1696. $this->code_compta = $obj->code_compta; // For backward compatibility
  1697. $this->code_compta_client = $obj->code_compta;
  1698. $this->code_compta_fournisseur = $obj->code_compta_fournisseur;
  1699. $this->barcode = $obj->barcode;
  1700. $this->tva_assuj = $obj->tva_assuj;
  1701. $this->tva_intra = $obj->tva_intra;
  1702. if (!empty($obj->spe_vat_reverse_charge)) {
  1703. $this->vat_reverse_charge = $obj->spe_vat_reverse_charge;
  1704. } elseif (!empty($obj->soc_vat_reverse_charge)) {
  1705. $this->vat_reverse_charge = $obj->soc_vat_reverse_charge;
  1706. } else {
  1707. $this->vat_reverse_charge = 0;
  1708. }
  1709. $this->status = $obj->status;
  1710. // Local Taxes
  1711. $this->localtax1_assuj = $obj->localtax1_assuj;
  1712. $this->localtax2_assuj = $obj->localtax2_assuj;
  1713. $this->localtax1_value = $obj->localtax1_value;
  1714. $this->localtax2_value = $obj->localtax2_value;
  1715. $this->typent_id = $obj->typent_id;
  1716. $this->typent_code = $obj->typent_code;
  1717. $this->effectif_id = $obj->effectif_id;
  1718. $this->effectif = $obj->effectif_id ? $obj->effectif : '';
  1719. $this->forme_juridique_code = $obj->forme_juridique_code;
  1720. $this->forme_juridique = $obj->forme_juridique_code ? $obj->forme_juridique : '';
  1721. $this->fk_prospectlevel = $obj->fk_prospectlevel;
  1722. $this->prefix_comm = $obj->prefix_comm;
  1723. $this->remise_percent = $obj->remise_client ? price2num($obj->remise_client) : 0; // 0.000000 must be 0
  1724. $this->remise_supplier_percent = $obj->remise_supplier;
  1725. $this->mode_reglement_id = $obj->mode_reglement;
  1726. $this->cond_reglement_id = $obj->cond_reglement;
  1727. $this->deposit_percent = $obj->deposit_percent;
  1728. $this->transport_mode_id = $obj->transport_mode;
  1729. $this->mode_reglement_supplier_id = $obj->mode_reglement_supplier;
  1730. $this->cond_reglement_supplier_id = $obj->cond_reglement_supplier;
  1731. $this->transport_mode_supplier_id = $obj->transport_mode_supplier;
  1732. $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method : null;
  1733. $this->fk_account = $obj->fk_account;
  1734. $this->client = $obj->client;
  1735. $this->fournisseur = $obj->fournisseur;
  1736. $this->note = $obj->note_private; // TODO Deprecated for backward comtability
  1737. $this->note_private = $obj->note_private;
  1738. $this->note_public = $obj->note_public;
  1739. $this->model_pdf = $obj->model_pdf;
  1740. $this->default_lang = $obj->default_lang;
  1741. $this->logo = $obj->logo;
  1742. $this->logo_squarred = $obj->logo_squarred;
  1743. $this->webservices_url = $obj->webservices_url;
  1744. $this->webservices_key = $obj->webservices_key;
  1745. $this->accountancy_code_buy = $obj->accountancy_code_buy;
  1746. $this->accountancy_code_sell = $obj->accountancy_code_sell;
  1747. $this->outstanding_limit = $obj->outstanding_limit;
  1748. $this->order_min_amount = $obj->order_min_amount;
  1749. $this->supplier_order_min_amount = $obj->supplier_order_min_amount;
  1750. // multiprix
  1751. $this->price_level = $obj->price_level;
  1752. // warehouse
  1753. $this->fk_warehouse = $obj->fk_warehouse;
  1754. $this->import_key = $obj->import_key;
  1755. //Incoterms
  1756. $this->fk_incoterms = $obj->fk_incoterms;
  1757. $this->location_incoterms = $obj->location_incoterms;
  1758. $this->label_incoterms = $obj->label_incoterms;
  1759. // multicurrency
  1760. $this->fk_multicurrency = $obj->fk_multicurrency;
  1761. $this->multicurrency_code = $obj->multicurrency_code;
  1762. // pdf
  1763. $this->model_pdf = $obj->model_pdf;
  1764. $this->last_main_doc = $obj->last_main_doc;
  1765. $result = 1;
  1766. // fetch optionals attributes and labels
  1767. $this->fetch_optionals();
  1768. } else {
  1769. $result = 0;
  1770. }
  1771. $this->db->free($resql);
  1772. } else {
  1773. $this->error = $this->db->lasterror();
  1774. $this->errors[] = $this->db->lasterror();
  1775. $result = -3;
  1776. }
  1777. // Use first price level if level not defined for third party
  1778. if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) && empty($this->price_level)) {
  1779. $this->price_level = 1;
  1780. }
  1781. return $result;
  1782. }
  1783. /**
  1784. * Delete a third party from database and all its dependencies (contacts, rib...)
  1785. *
  1786. * @param int $id Id of third party to delete
  1787. * @param User|null $fuser User who ask to delete thirdparty
  1788. * @param int $call_trigger 0=No, 1=yes
  1789. * @return int Return integer <0 if KO, 0 if nothing done, >0 if OK
  1790. */
  1791. public function delete($id, User $fuser = null, $call_trigger = 1)
  1792. {
  1793. global $langs, $conf, $user;
  1794. if (empty($fuser)) {
  1795. $fuser = $user;
  1796. }
  1797. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  1798. $entity = isset($this->entity) ? $this->entity : $conf->entity;
  1799. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  1800. $error = 0;
  1801. // Test if child exists
  1802. $objectisused = $this->isObjectUsed($id);
  1803. if (empty($objectisused)) {
  1804. $this->db->begin();
  1805. // User is mandatory for trigger call
  1806. if (!$error && $call_trigger) {
  1807. // Call trigger
  1808. $result = $this->call_trigger('COMPANY_DELETE', $fuser);
  1809. if ($result < 0) {
  1810. $error++;
  1811. }
  1812. // End call triggers
  1813. }
  1814. if (!$error) {
  1815. require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
  1816. $static_cat = new Categorie($this->db);
  1817. $toute_categs = array();
  1818. // Fill $toute_categs array with an array of (type => array of ("Categorie" instance))
  1819. if ($this->client || $this->prospect) {
  1820. $toute_categs['customer'] = $static_cat->containing($this->id, Categorie::TYPE_CUSTOMER);
  1821. }
  1822. if ($this->fournisseur) {
  1823. $toute_categs['supplier'] = $static_cat->containing($this->id, Categorie::TYPE_SUPPLIER);
  1824. }
  1825. // Remove each "Categorie"
  1826. foreach ($toute_categs as $type => $categs_type) {
  1827. foreach ($categs_type as $cat) {
  1828. $cat->del_type($this, $type);
  1829. }
  1830. }
  1831. }
  1832. if (!$error) {
  1833. foreach ($this->childtablesoncascade as $tabletodelete) {
  1834. $deleteFromObject = explode(':', $tabletodelete);
  1835. if (count($deleteFromObject) >= 2) {
  1836. $className = str_replace('@', '', $deleteFromObject[0]);
  1837. $filepath = $deleteFromObject[1];
  1838. $columnName = $deleteFromObject[2];
  1839. if (dol_include_once($filepath)) {
  1840. $child_object = new $className($this->db);
  1841. $result = $child_object->deleteByParentField($id, $columnName);
  1842. if ($result < 0) {
  1843. $error++;
  1844. $this->errors[] = $child_object->error;
  1845. break;
  1846. }
  1847. } else {
  1848. $error++;
  1849. $this->errors[] = 'Cannot include child class file '.$filepath;
  1850. break;
  1851. }
  1852. } else {
  1853. $sql = "DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete;
  1854. $sql .= " WHERE fk_soc = ".((int) $id);
  1855. if (!$this->db->query($sql)) {
  1856. $error++;
  1857. $this->errors[] = $this->db->lasterror();
  1858. break;
  1859. }
  1860. }
  1861. }
  1862. }
  1863. // Removed extrafields
  1864. if (!$error) {
  1865. $result = $this->deleteExtraFields();
  1866. if ($result < 0) {
  1867. $error++;
  1868. dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR);
  1869. }
  1870. }
  1871. // Remove links to subsidiaries companies
  1872. if (!$error) {
  1873. $sql = "UPDATE ".MAIN_DB_PREFIX."societe";
  1874. $sql .= " SET parent = NULL";
  1875. $sql .= " WHERE parent = ".((int) $id);
  1876. if (!$this->db->query($sql)) {
  1877. $error++;
  1878. $this->errors[] = $this->db->lasterror();
  1879. }
  1880. }
  1881. // Remove third party
  1882. if (!$error) {
  1883. if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
  1884. $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_perentity";
  1885. $sql .= " WHERE fk_soc = ".((int) $id);
  1886. if (!$this->db->query($sql)) {
  1887. $error++;
  1888. $this->errors[] = $this->db->lasterror();
  1889. }
  1890. }
  1891. $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe";
  1892. $sql .= " WHERE rowid = ".((int) $id);
  1893. if (!$this->db->query($sql)) {
  1894. $error++;
  1895. $this->errors[] = $this->db->lasterror();
  1896. }
  1897. }
  1898. if (!$error) {
  1899. $this->db->commit();
  1900. // Delete directory
  1901. if (!empty($conf->societe->multidir_output[$entity])) {
  1902. $docdir = $conf->societe->multidir_output[$entity]."/".$id;
  1903. if (dol_is_dir($docdir)) {
  1904. dol_delete_dir_recursive($docdir);
  1905. }
  1906. }
  1907. return 1;
  1908. } else {
  1909. dol_syslog($this->error, LOG_ERR);
  1910. $this->db->rollback();
  1911. return -1;
  1912. }
  1913. } else {
  1914. dol_syslog("Can't remove thirdparty with id ".$id.". There is ".$objectisused." childs", LOG_WARNING);
  1915. }
  1916. return 0;
  1917. }
  1918. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  1919. /**
  1920. * Define third party as a customer
  1921. *
  1922. * @return int Return integer <0 if KO, >0 if OK
  1923. * @deprecated
  1924. * @see setAsCustomer()
  1925. */
  1926. public function set_as_client()
  1927. {
  1928. global $conf;
  1929. // phpcs:enable
  1930. dol_syslog(get_class($this)."::set_as_client is deprecated use setAsCustomer instead", LOG_NOTICE);
  1931. return $this->setAsCustomer();
  1932. }
  1933. /**
  1934. * Define third party as a customer
  1935. *
  1936. * @return int Return integer <0 if KO, >0 if OK
  1937. * @since dolibarr v19
  1938. */
  1939. public function setAsCustomer()
  1940. {
  1941. if ($this->id) {
  1942. $newclient = 1;
  1943. if (($this->client == 2 || $this->client == 3) && !getDolGlobalInt('SOCIETE_DISABLE_PROSPECTSCUSTOMERS')) {
  1944. $newclient = 3; //If prospect, we keep prospect tag
  1945. }
  1946. $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
  1947. $sql .= " SET client = ".((int) $newclient);
  1948. $sql .= " WHERE rowid = ".((int) $this->id);
  1949. $resql = $this->db->query($sql);
  1950. if ($resql) {
  1951. $this->client = $newclient;
  1952. return 1;
  1953. } else {
  1954. return -1;
  1955. }
  1956. }
  1957. return 0;
  1958. }
  1959. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  1960. /**
  1961. * Defines the company as a customer
  1962. *
  1963. * @param float $remise Value in % of the discount
  1964. * @param string $note Note/Reason for changing the discount
  1965. * @param User $user User who sets the discount
  1966. * @return int Return integer <0 if KO, >0 if OK
  1967. */
  1968. public function set_remise_client($remise, $note, User $user)
  1969. {
  1970. // phpcs:enable
  1971. global $conf, $langs;
  1972. // Parameter cleaning
  1973. $note = trim($note);
  1974. if (!$note) {
  1975. $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NoteReason"));
  1976. return -2;
  1977. }
  1978. dol_syslog(get_class($this)."::set_remise_client ".$remise.", ".$note.", ".$user->id);
  1979. if ($this->id) {
  1980. $this->db->begin();
  1981. $now = dol_now();
  1982. // Position current discount
  1983. $sql = "UPDATE ".MAIN_DB_PREFIX."societe ";
  1984. $sql .= " SET remise_client = '".$this->db->escape($remise)."'";
  1985. $sql .= " WHERE rowid = ".((int) $this->id);
  1986. $resql = $this->db->query($sql);
  1987. if (!$resql) {
  1988. $this->db->rollback();
  1989. $this->error = $this->db->error();
  1990. return -1;
  1991. }
  1992. // Writes trace in discount history
  1993. $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise";
  1994. $sql .= " (entity, datec, fk_soc, remise_client, note, fk_user_author)";
  1995. $sql .= " VALUES (".$conf->entity.", '".$this->db->idate($now)."', ".((int) $this->id).", '".$this->db->escape($remise)."',";
  1996. $sql .= " '".$this->db->escape($note)."',";
  1997. $sql .= " ".((int) $user->id);
  1998. $sql .= ")";
  1999. $resql = $this->db->query($sql);
  2000. if (!$resql) {
  2001. $this->db->rollback();
  2002. $this->error = $this->db->lasterror();
  2003. return -1;
  2004. }
  2005. $this->db->commit();
  2006. return 1;
  2007. }
  2008. return -1;
  2009. }
  2010. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2011. /**
  2012. * Defines the company as a customer
  2013. *
  2014. * @param float $remise Value in % of the discount
  2015. * @param string $note Note/Reason for changing the discount
  2016. * @param User $user User who sets the discount
  2017. * @return int Return integer <0 if KO, >0 if OK
  2018. */
  2019. public function set_remise_supplier($remise, $note, User $user)
  2020. {
  2021. // phpcs:enable
  2022. global $conf, $langs;
  2023. // Parameter cleaning
  2024. $note = trim($note);
  2025. if (!$note) {
  2026. $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NoteReason"));
  2027. return -2;
  2028. }
  2029. dol_syslog(get_class($this)."::set_remise_supplier ".$remise.", ".$note.", ".$user->id);
  2030. if ($this->id) {
  2031. $this->db->begin();
  2032. $now = dol_now();
  2033. // Position current discount
  2034. $sql = "UPDATE ".MAIN_DB_PREFIX."societe ";
  2035. $sql .= " SET remise_supplier = '".$this->db->escape($remise)."'";
  2036. $sql .= " WHERE rowid = ".((int) $this->id);
  2037. $resql = $this->db->query($sql);
  2038. if (!$resql) {
  2039. $this->db->rollback();
  2040. $this->error = $this->db->error();
  2041. return -1;
  2042. }
  2043. // Writes trace in discount history
  2044. $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_supplier";
  2045. $sql .= " (entity, datec, fk_soc, remise_supplier, note, fk_user_author)";
  2046. $sql .= " VALUES (".$conf->entity.", '".$this->db->idate($now)."', ".((int) $this->id).", '".$this->db->escape($remise)."',";
  2047. $sql .= " '".$this->db->escape($note)."',";
  2048. $sql .= " ".((int) $user->id);
  2049. $sql .= ")";
  2050. $resql = $this->db->query($sql);
  2051. if (!$resql) {
  2052. $this->db->rollback();
  2053. $this->error = $this->db->lasterror();
  2054. return -1;
  2055. }
  2056. $this->db->commit();
  2057. return 1;
  2058. }
  2059. return -1;
  2060. }
  2061. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2062. /**
  2063. * Add a discount for third party
  2064. *
  2065. * @param float $remise Amount of discount
  2066. * @param User $user User adding discount
  2067. * @param string $desc Reason of discount
  2068. * @param string $vatrate VAT rate (may contain the vat code too). Exemple: '1.23', '1.23 (ABC)', ...
  2069. * @param int $discount_type 0 => customer discount, 1 => supplier discount
  2070. * @param string $price_base_type Price base type 'HT' or 'TTC'
  2071. * @return int Return integer <0 if KO, id of discount record if OK
  2072. */
  2073. public function set_remise_except($remise, User $user, $desc, $vatrate = '', $discount_type = 0, $price_base_type = 'HT')
  2074. {
  2075. // phpcs:enable
  2076. global $langs;
  2077. // Clean parameters
  2078. $remise = price2num($remise);
  2079. $desc = trim($desc);
  2080. // Check parameters
  2081. if (!($remise > 0)) {
  2082. $this->error = $langs->trans("ErrorWrongValueForParameter", "1");
  2083. return -1;
  2084. }
  2085. if (!$desc) {
  2086. $this->error = $langs->trans("ErrorWrongValueForParameter", "3");
  2087. return -2;
  2088. }
  2089. if ($this->id > 0) {
  2090. // Clean vat code
  2091. $reg = array();
  2092. $vat_src_code = '';
  2093. if (preg_match('/\((.*)\)/', $vatrate, $reg)) {
  2094. $vat_src_code = $reg[1];
  2095. $vatrate = preg_replace('/\s*\(.*\)/', '', $vatrate); // Remove code into vatrate.
  2096. }
  2097. require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
  2098. $discount = new DiscountAbsolute($this->db);
  2099. $discount->fk_soc = $this->id;
  2100. $discount->discount_type = $discount_type;
  2101. if ($price_base_type == 'TTC') {
  2102. $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num($remise, 'MT');
  2103. $discount->amount_ht = $discount->multicurrency_amount_ht = price2num($remise / (1 + $vatrate / 100), 'MT');
  2104. $discount->amount_tva = $discount->multicurrency_amount_tva = price2num($discount->amount_ttc - $discount->amount_ht, 'MT');
  2105. } else {
  2106. $discount->amount_ht = $discount->multicurrency_amount_ht = price2num($remise, 'MT');
  2107. $discount->amount_tva = $discount->multicurrency_amount_tva = price2num($remise * $vatrate / 100, 'MT');
  2108. $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num($discount->amount_ht + $discount->amount_tva, 'MT');
  2109. }
  2110. $discount->tva_tx = price2num($vatrate);
  2111. $discount->vat_src_code = $vat_src_code;
  2112. $discount->description = $desc;
  2113. $result = $discount->create($user);
  2114. if ($result > 0) {
  2115. return $result;
  2116. } else {
  2117. $this->error = $discount->error;
  2118. return -3;
  2119. }
  2120. } else {
  2121. return 0;
  2122. }
  2123. }
  2124. /**
  2125. * Returns amount of included taxes of the current discounts/credits available from the company
  2126. *
  2127. * @param User $user Filter on a user author of discounts
  2128. * @param string $filter Other filter
  2129. * @param integer $maxvalue Filter on max value for discount
  2130. * @param int $discount_type 0 => customer discount, 1 => supplier discount
  2131. * @return int Return integer <0 if KO, Credit note amount otherwise
  2132. */
  2133. public function getAvailableDiscounts($user = '', $filter = '', $maxvalue = 0, $discount_type = 0)
  2134. {
  2135. require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
  2136. $discountstatic = new DiscountAbsolute($this->db);
  2137. $result = $discountstatic->getAvailableDiscounts($this, $user, $filter, $maxvalue, $discount_type);
  2138. if ($result >= 0) {
  2139. return $result;
  2140. } else {
  2141. $this->error = $discountstatic->error;
  2142. return -1;
  2143. }
  2144. }
  2145. /**
  2146. * Return array of sales representatives
  2147. *
  2148. * @param User $user Object user (not used)
  2149. * @param int $mode 0=Array with properties, 1=Array of id.
  2150. * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb'
  2151. * @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC';
  2152. * @return array|int Array of sales representatives of third party or <0 if KO
  2153. */
  2154. public function getSalesRepresentatives(User $user, $mode = 0, $sortfield = null, $sortorder = null)
  2155. {
  2156. global $conf;
  2157. $reparray = array();
  2158. $sql = "SELECT DISTINCT u.rowid, u.login, u.lastname, u.firstname, u.office_phone, u.job, u.email, u.statut as status, u.entity, u.photo, u.gender";
  2159. $sql .= ", u.office_fax, u.user_mobile, u.personal_mobile";
  2160. $sql .= " FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc, ".MAIN_DB_PREFIX."user as u";
  2161. if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
  2162. $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
  2163. $sql .= " WHERE ((ug.fk_user = sc.fk_user";
  2164. $sql .= " AND ug.entity = ".$conf->entity.")";
  2165. $sql .= " OR u.admin = 1)";
  2166. } else {
  2167. $sql .= " WHERE entity in (0, ".$conf->entity.")";
  2168. }
  2169. $sql .= " AND u.rowid = sc.fk_user AND sc.fk_soc = ".((int) $this->id);
  2170. if (empty($sortfield) && empty($sortorder)) {
  2171. $sortfield = 'u.lastname,u.firstname';
  2172. $sortorder = 'ASC,ASC';
  2173. }
  2174. $sql .= $this->db->order($sortfield, $sortorder);
  2175. $resql = $this->db->query($sql);
  2176. if ($resql) {
  2177. $num = $this->db->num_rows($resql);
  2178. $i = 0;
  2179. while ($i < $num) {
  2180. $obj = $this->db->fetch_object($resql);
  2181. if (empty($mode)) {
  2182. $reparray[$i]['id'] = $obj->rowid;
  2183. $reparray[$i]['lastname'] = $obj->lastname;
  2184. $reparray[$i]['firstname'] = $obj->firstname;
  2185. $reparray[$i]['email'] = $obj->email;
  2186. $reparray[$i]['phone'] = $obj->office_phone;
  2187. $reparray[$i]['office_phone'] = $obj->office_phone; // Pro phone
  2188. $reparray[$i]['office_fax'] = $obj->office_fax;
  2189. $reparray[$i]['user_mobile'] = $obj->user_mobile; // Pro mobile
  2190. $reparray[$i]['personal_mobile'] = $obj->personal_mobile; // Personal mobile
  2191. $reparray[$i]['job'] = $obj->job;
  2192. $reparray[$i]['statut'] = $obj->status; // deprecated
  2193. $reparray[$i]['status'] = $obj->status;
  2194. $reparray[$i]['entity'] = $obj->entity;
  2195. $reparray[$i]['login'] = $obj->login;
  2196. $reparray[$i]['photo'] = $obj->photo;
  2197. $reparray[$i]['gender'] = $obj->gender;
  2198. } else {
  2199. $reparray[] = $obj->rowid;
  2200. }
  2201. $i++;
  2202. }
  2203. return $reparray;
  2204. } else {
  2205. dol_print_error($this->db);
  2206. return -1;
  2207. }
  2208. }
  2209. /**
  2210. * Set the price level
  2211. *
  2212. * @param int $price_level Level of price
  2213. * @param User $user Use making change
  2214. * @return int Return integer <0 if KO, >0 if OK
  2215. */
  2216. public function setPriceLevel($price_level, User $user)
  2217. {
  2218. if ($this->id) {
  2219. $now = dol_now();
  2220. $sql = "UPDATE ".MAIN_DB_PREFIX."societe";
  2221. $sql .= " SET price_level = ".((int) $price_level);
  2222. $sql .= " WHERE rowid = ".((int) $this->id);
  2223. if (!$this->db->query($sql)) {
  2224. dol_print_error($this->db);
  2225. return -1;
  2226. }
  2227. $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_prices";
  2228. $sql .= " (datec, fk_soc, price_level, fk_user_author)";
  2229. $sql .= " VALUES ('".$this->db->idate($now)."', ".((int) $this->id).", ".((int) $price_level).", ".((int) $user->id).")";
  2230. if (!$this->db->query($sql)) {
  2231. dol_print_error($this->db);
  2232. return -1;
  2233. }
  2234. return 1;
  2235. }
  2236. return -1;
  2237. }
  2238. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2239. /**
  2240. * Add link to sales representative
  2241. *
  2242. * @param User $user Object user
  2243. * @param int $commid Id of user
  2244. * @return int Return integer <=0 if KO, >0 if OK
  2245. */
  2246. public function add_commercial(User $user, $commid)
  2247. {
  2248. // phpcs:enable
  2249. $error = 0;
  2250. if ($this->id > 0 && $commid > 0) {
  2251. $this->db->begin();
  2252. if (!$error) {
  2253. $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_commerciaux";
  2254. $sql .= " WHERE fk_soc = ".((int) $this->id)." AND fk_user = ".((int) $commid);
  2255. $resql = $this->db->query($sql);
  2256. if (!$resql) {
  2257. dol_syslog(get_class($this)."::add_commercial Error ".$this->db->lasterror());
  2258. $error++;
  2259. }
  2260. }
  2261. if (!$error) {
  2262. $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_commerciaux";
  2263. $sql .= " (fk_soc, fk_user)";
  2264. $sql .= " VALUES (".((int) $this->id).", ".((int) $commid).")";
  2265. $resql = $this->db->query($sql);
  2266. if (!$resql) {
  2267. dol_syslog(get_class($this)."::add_commercial Error ".$this->db->lasterror());
  2268. $error++;
  2269. }
  2270. }
  2271. if (!$error) {
  2272. $this->context = array('commercial_modified' => $commid);
  2273. $result = $this->call_trigger('COMPANY_LINK_SALE_REPRESENTATIVE', $user);
  2274. if ($result < 0) {
  2275. $error++;
  2276. }
  2277. }
  2278. if (!$error) {
  2279. $this->db->commit();
  2280. return 1;
  2281. } else {
  2282. $this->db->rollback();
  2283. return -1;
  2284. }
  2285. }
  2286. return 0;
  2287. }
  2288. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2289. /**
  2290. * Add link to sales representative
  2291. *
  2292. * @param User $user Object user
  2293. * @param int $commid Id of user
  2294. * @return void
  2295. */
  2296. public function del_commercial(User $user, $commid)
  2297. {
  2298. // phpcs:enable
  2299. $error = 0;
  2300. $this->context = array('commercial_modified'=>$commid);
  2301. $result = $this->call_trigger('COMPANY_UNLINK_SALE_REPRESENTATIVE', $user);
  2302. if ($result < 0) {
  2303. $error++;
  2304. }
  2305. if ($this->id > 0 && $commid > 0) {
  2306. $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_commerciaux ";
  2307. $sql .= " WHERE fk_soc = ".((int) $this->id)." AND fk_user = ".((int) $commid);
  2308. if (!$this->db->query($sql)) {
  2309. dol_syslog(get_class($this)."::del_commercial Erreur");
  2310. }
  2311. }
  2312. }
  2313. /**
  2314. * getTooltipContentArray
  2315. *
  2316. * @param array $params params to construct tooltip data
  2317. * @since v18
  2318. * @return array
  2319. */
  2320. public function getTooltipContentArray($params)
  2321. {
  2322. global $conf, $langs, $user;
  2323. $langs->loadLangs(['companies', 'commercial']);
  2324. $datas = array();
  2325. $option = $params['option'] ?? '';
  2326. $nofetch = !empty($params['nofetch']);
  2327. $noaliasinname = (empty($params['noaliasinname']) ? 0 : $params['noaliasinname']);
  2328. if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
  2329. return ['optimize' => $langs->trans("ShowCompany")];
  2330. }
  2331. if (!empty($this->logo) && class_exists('Form')) {
  2332. $photo = '<div class="photointooltip floatright">';
  2333. $photo .= Form::showphoto('societe', $this, 0, 40, 0, 'photoref', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip.
  2334. $photo .= '</div>';
  2335. $datas['photo'] = $photo;
  2336. } elseif (!empty($this->logo_squarred) && class_exists('Form')) {
  2337. /*$label.= '<div class="photointooltip">';
  2338. $label.= Form::showphoto('societe', $this, 0, 40, 0, 'photowithmargin', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip.
  2339. $label.= '</div><div style="clear: both;"></div>';*/
  2340. }
  2341. $datas['divopen'] = '<div class="centpercent">';
  2342. if ($option == 'customer' || $option == 'compta' || $option == 'category') {
  2343. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Customer").'</u>';
  2344. } elseif ($option == 'prospect' && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
  2345. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Prospect").'</u>';
  2346. } elseif ($option == 'supplier' || $option == 'category_supplier') {
  2347. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Supplier").'</u>';
  2348. } elseif ($option == 'agenda') {
  2349. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ThirdParty").'</u>';
  2350. } elseif ($option == 'project') {
  2351. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ThirdParty").'</u>';
  2352. } elseif ($option == 'margin') {
  2353. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ThirdParty").'</u>';
  2354. } elseif ($option == 'contact') {
  2355. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ThirdParty").'</u>';
  2356. } elseif ($option == 'ban') {
  2357. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ThirdParty").'</u>';
  2358. }
  2359. // By default
  2360. if (empty($datas['picto'])) {
  2361. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("ThirdParty").'</u>';
  2362. }
  2363. if (isset($this->status)) {
  2364. $datas['status'] = ' '.$this->getLibStatut(5);
  2365. }
  2366. if (isset($this->client) && isset($this->fournisseur)) {
  2367. $datas['type'] = ' &nbsp; ' . $this->getTypeUrl(1);
  2368. }
  2369. $datas['name'] = '<br><b>'.$langs->trans('Name').':</b> '.dol_escape_htmltag(dol_string_nohtmltag($this->name));
  2370. if (!empty($this->name_alias) && empty($noaliasinname)) {
  2371. $datas['namealias'] = ' ('.dol_escape_htmltag(dol_string_nohtmltag($this->name_alias)).')';
  2372. }
  2373. if (!empty($this->email)) {
  2374. $datas['email'] = '<br>'.img_picto('', 'email', 'class="pictofixedwidth"').$this->email;
  2375. }
  2376. if (!empty($this->url)) {
  2377. $datas['url'] = '<br>'.img_picto('', 'globe', 'class="pictofixedwidth"').$this->url;
  2378. }
  2379. if (!empty($this->phone) || !empty($this->fax)) {
  2380. $phonelist = array();
  2381. if ($this->phone) {
  2382. $phonelist[] = dol_print_phone($this->phone, $this->country_code, $this->id, 0, '', '&nbsp', 'phone');
  2383. }
  2384. if ($this->fax) {
  2385. $phonelist[] = dol_print_phone($this->fax, $this->country_code, $this->id, 0, '', '&nbsp', 'fax');
  2386. }
  2387. $datas['phonelist'] = '<br>'.implode('&nbsp;', $phonelist);
  2388. }
  2389. if (!empty($this->address)) {
  2390. $datas['address'] = '<br><b>'.$langs->trans("Address").':</b> '.dol_format_address($this, 1, ' ', $langs); // Address + country
  2391. } elseif (!empty($this->country_code)) {
  2392. $datas['address'] = '<br><b>'.$langs->trans('Country').':</b> '.$this->country_code;
  2393. }
  2394. if (!empty($this->tva_intra) || (getDolGlobalString('SOCIETE_SHOW_FIELD_IN_TOOLTIP') && strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'vatnumber') !== false)) {
  2395. $datas['vatintra'] = '<br><b>'.$langs->trans('VATIntra').':</b> '.dol_escape_htmltag($this->tva_intra);
  2396. }
  2397. if (getDolGlobalString('SOCIETE_SHOW_FIELD_IN_TOOLTIP')) {
  2398. if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid1') !== false && $langs->trans('ProfId1'.$this->country_code) != '-') {
  2399. $datas['profid1'] = '<br><b>'.$langs->trans('ProfId1'.$this->country_code).':</b> '.$this->idprof1;
  2400. }
  2401. if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid2') !== false && $langs->trans('ProfId2'.$this->country_code) != '-') {
  2402. $datas['profid2'] = '<br><b>'.$langs->trans('ProfId2'.$this->country_code).':</b> '.$this->idprof2;
  2403. }
  2404. if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid3') !== false && $langs->trans('ProfId3'.$this->country_code) != '-') {
  2405. $datas['profid3'] = '<br><b>'.$langs->trans('ProfId3'.$this->country_code).':</b> '.$this->idprof3;
  2406. }
  2407. if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid4') !== false && $langs->trans('ProfId4'.$this->country_code) != '-') {
  2408. $datas['profid4'] = '<br><b>'.$langs->trans('ProfId4'.$this->country_code).':</b> '.$this->idprof4;
  2409. }
  2410. if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid5') !== false && $langs->trans('ProfId5'.$this->country_code) != '-') {
  2411. $datas['profid5'] = '<br><b>'.$langs->trans('ProfId5'.$this->country_code).':</b> '.$this->idprof5;
  2412. }
  2413. if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid6') !== false && $langs->trans('ProfId6'.$this->country_code) != '-') {
  2414. $datas['profid6'] = '<br><b>'.$langs->trans('ProfId6'.$this->country_code).':</b> '.$this->idprof6;
  2415. }
  2416. }
  2417. $datas['separator'] = '<br>';
  2418. if (!empty($this->code_client) && ($this->client == 1 || $this->client == 3)) {
  2419. $datas['customercode'] = '<br><b>'.$langs->trans('CustomerCode').':</b> '.$this->code_client;
  2420. }
  2421. if (isModEnabled('accounting') && ($this->client == 1 || $this->client == 3)) {
  2422. $langs->load('compta');
  2423. $datas['accountancycustomercode'] = '<br><b>'.$langs->trans('CustomerAccountancyCode').':</b> '.($this->code_compta ? $this->code_compta : $this->code_compta_client);
  2424. }
  2425. // show categories for this record only in ajax to not overload lists
  2426. if (!$nofetch && isModEnabled('categorie') && $this->client) {
  2427. require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
  2428. $form = new Form($this->db);
  2429. $datas['categories_customer'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_CUSTOMER, 1, 1);
  2430. }
  2431. if (!empty($this->code_fournisseur) && $this->fournisseur) {
  2432. $datas['suppliercode'] = '<br><b>'.$langs->trans('SupplierCode').':</b> '.$this->code_fournisseur;
  2433. }
  2434. if (isModEnabled('accounting') && $this->fournisseur) {
  2435. $langs->load('compta');
  2436. $datas['accountancysuppliercode'] = '<br><b>'.$langs->trans('SupplierAccountancyCode').':</b> '.$this->code_compta_fournisseur;
  2437. }
  2438. // show categories for this record only in ajax to not overload lists
  2439. if (!$nofetch && isModEnabled('categorie') && $this->fournisseur) {
  2440. require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
  2441. $form = new Form($this->db);
  2442. $datas['categories_supplier'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_SUPPLIER, 1, 1);
  2443. }
  2444. $datas['divclose'] = '</div>';
  2445. return $datas;
  2446. }
  2447. /**
  2448. * Return a link on thirdparty (with picto)
  2449. *
  2450. * @param int $withpicto Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
  2451. * @param string $option Target of link ('', 'customer', 'prospect', 'supplier', 'project')
  2452. * @param int $maxlen Max length of name
  2453. * @param int $notooltip 1=Disable tooltip
  2454. * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
  2455. * @param int $noaliasinname 1=Do not add alias into the link ref
  2456. * @param string $target add attribute target
  2457. * @return string String with URL
  2458. */
  2459. public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target = '')
  2460. {
  2461. global $conf, $langs, $hookmanager;
  2462. if (!empty($conf->dol_no_mouse_hover)) {
  2463. $notooltip = 1; // Force disable tooltips
  2464. }
  2465. $name = $this->name ? $this->name : $this->nom;
  2466. if (getDolGlobalString('SOCIETE_ON_SEARCH_AND_LIST_GO_ON_CUSTOMER_OR_SUPPLIER_CARD')) {
  2467. if (empty($option) && $this->client > 0) {
  2468. $option = 'customer';
  2469. }
  2470. if (empty($option) && $this->fournisseur > 0) {
  2471. $option = 'supplier';
  2472. }
  2473. }
  2474. if (getDolGlobalString('SOCIETE_ADD_REF_IN_LIST') && (!empty($withpicto))) {
  2475. $code = '';
  2476. if (($this->client) && (!empty($this->code_client)) && (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1 || getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 2)) {
  2477. $code = $this->code_client.' - ';
  2478. }
  2479. if (($this->fournisseur) && (!empty($this->code_fournisseur)) && (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1 || getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 3)) {
  2480. $code .= $this->code_fournisseur.' - ';
  2481. }
  2482. if ($code) {
  2483. if (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1) {
  2484. $name = $code.' '.$name;
  2485. } else {
  2486. $name = $code;
  2487. }
  2488. }
  2489. }
  2490. if (!empty($this->name_alias) && empty($noaliasinname)) {
  2491. $name .= ' ('.$this->name_alias.')';
  2492. }
  2493. $result = '';
  2494. $params = [
  2495. 'id' => $this->id,
  2496. 'objecttype' => $this->element,
  2497. 'option' => $option,
  2498. 'nofetch' => 1,
  2499. ];
  2500. $classfortooltip = 'classfortooltip';
  2501. $dataparams = '';
  2502. if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
  2503. $classfortooltip = 'classforajaxtooltip';
  2504. $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
  2505. $label = '';
  2506. } else {
  2507. $label = implode($this->getTooltipContentArray($params));
  2508. }
  2509. $linkstart = '';
  2510. $linkend = '';
  2511. if ($option == 'customer' || $option == 'compta' || $option == 'category') {
  2512. $linkstart = '<a href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id;
  2513. } elseif ($option == 'prospect' && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
  2514. $linkstart = '<a href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id;
  2515. } elseif ($option == 'supplier' || $option == 'category_supplier') {
  2516. $linkstart = '<a href="'.DOL_URL_ROOT.'/fourn/card.php?socid='.$this->id;
  2517. } elseif ($option == 'agenda') {
  2518. $linkstart = '<a href="'.DOL_URL_ROOT.'/societe/agenda.php?socid='.$this->id;
  2519. } elseif ($option == 'project') {
  2520. $linkstart = '<a href="'.DOL_URL_ROOT.'/societe/project.php?socid='.$this->id;
  2521. } elseif ($option == 'margin') {
  2522. $linkstart = '<a href="'.DOL_URL_ROOT.'/margin/tabs/thirdpartyMargins.php?socid='.$this->id.'&type=1';
  2523. } elseif ($option == 'contact') {
  2524. $linkstart = '<a href="'.DOL_URL_ROOT.'/societe/contact.php?socid='.$this->id;
  2525. } elseif ($option == 'ban') {
  2526. $linkstart = '<a href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$this->id;
  2527. }
  2528. // By default
  2529. if (empty($linkstart)) {
  2530. $linkstart = '<a href="'.DOL_URL_ROOT.'/societe/card.php?socid='.$this->id;
  2531. }
  2532. // Add type of canvas
  2533. $linkstart .= (!empty($this->canvas) ? '&canvas='.$this->canvas : '');
  2534. // Add param to save lastsearch_values or not
  2535. $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
  2536. if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
  2537. $add_save_lastsearch_values = 1;
  2538. }
  2539. if ($add_save_lastsearch_values) {
  2540. $linkstart .= '&save_lastsearch_values=1';
  2541. }
  2542. $linkstart .= '"';
  2543. $linkclose = '';
  2544. if (empty($notooltip)) {
  2545. if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
  2546. $label = $langs->trans("ShowCompany");
  2547. $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
  2548. }
  2549. $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
  2550. $linkclose .= $dataparams.' class="'.$classfortooltip.' refurl valignmiddle"';
  2551. $target_value = array('_self', '_blank', '_parent', '_top');
  2552. if (in_array($target, $target_value)) {
  2553. $linkclose .= ' target="'.dol_escape_htmltag($target).'"';
  2554. }
  2555. } else {
  2556. $linkclose .= ' class="valignmiddle"';
  2557. }
  2558. $linkstart .= $linkclose.'>';
  2559. $linkend = '</a>';
  2560. global $user;
  2561. if (!$user->hasRight('societe', 'client', 'voir') && $user->socid > 0 && $this->id != $user->socid) {
  2562. $linkstart = '';
  2563. $linkend = '';
  2564. }
  2565. $result .= $linkstart;
  2566. if ($withpicto) {
  2567. $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (' class="'.(($withpicto != 2) ? 'paddingright' : '').'"'), 0, 0, $notooltip ? 0 : 1);
  2568. }
  2569. if ($withpicto != 2) {
  2570. $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name);
  2571. }
  2572. $result .= $linkend;
  2573. global $action;
  2574. $hookmanager->initHooks(array('thirdpartydao'));
  2575. $parameters = array(
  2576. 'id'=>$this->id,
  2577. 'getnomurl' => &$result,
  2578. 'withpicto '=> $withpicto,
  2579. 'option'=> $option,
  2580. 'maxlen'=> $maxlen,
  2581. 'notooltip'=> $notooltip,
  2582. 'save_lastsearch_value'=> $save_lastsearch_value
  2583. );
  2584. $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
  2585. if ($reshook > 0) {
  2586. $result = $hookmanager->resPrint;
  2587. } else {
  2588. $result .= $hookmanager->resPrint;
  2589. }
  2590. return $result;
  2591. }
  2592. /**
  2593. * Return link(s) on type of thirdparty (with picto)
  2594. *
  2595. * @param int $withpicto Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
  2596. * @param string $option ''=All
  2597. * @param int $notooltip 1=Disable tooltip
  2598. * @param string $tag Tag 'a' or 'span'
  2599. * @return string String with URL
  2600. */
  2601. public function getTypeUrl($withpicto = 0, $option = '', $notooltip = 0, $tag = 'a')
  2602. {
  2603. global $conf, $langs;
  2604. $s = '';
  2605. if (empty($option) || preg_match('/prospect/', $option)) {
  2606. if (($this->client == 2 || $this->client == 3) && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
  2607. $s .= '<'.$tag.' class="customer-back opacitymedium" title="'.$langs->trans("Prospect").'" href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id.'">'.dol_substr($langs->trans("Prospect"), 0, 1).'</'.$tag.'>';
  2608. }
  2609. }
  2610. if (empty($option) || preg_match('/customer/', $option)) {
  2611. if (($this->client == 1 || $this->client == 3) && !getDolGlobalString('SOCIETE_DISABLE_CUSTOMERS')) {
  2612. $s .= '<'.$tag.' class="customer-back" title="'.$langs->trans("Customer").'" href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id.'">'.dol_substr($langs->trans("Customer"), 0, 1).'</'.$tag.'>';
  2613. }
  2614. }
  2615. if (empty($option) || preg_match('/supplier/', $option)) {
  2616. if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && $this->fournisseur) {
  2617. $s .= '<'.$tag.' class="vendor-back" title="'.$langs->trans("Supplier").'" href="'.DOL_URL_ROOT.'/fourn/card.php?socid='.$this->id.'">'.dol_substr($langs->trans("Supplier"), 0, 1).'</'.$tag.'>';
  2618. }
  2619. }
  2620. return $s;
  2621. }
  2622. /**
  2623. * Return label of status (activity, closed)
  2624. *
  2625. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
  2626. * @return string Label of status
  2627. */
  2628. public function getLibStatut($mode = 0)
  2629. {
  2630. return $this->LibStatut($this->status, $mode);
  2631. }
  2632. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2633. /**
  2634. * Return the label of a given status
  2635. *
  2636. * @param int $status Status id
  2637. * @param int $mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto, 6=Long label + Picto
  2638. * @return string Status label
  2639. */
  2640. public function LibStatut($status, $mode = 0)
  2641. {
  2642. // phpcs:enable
  2643. global $langs;
  2644. $langs->load('companies');
  2645. $statusType = 'status4';
  2646. if ($status == 0) {
  2647. $statusType = 'status6';
  2648. }
  2649. if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
  2650. $this->labelStatus[0] = $langs->transnoentitiesnoconv("ActivityCeased");
  2651. $this->labelStatus[1] = $langs->transnoentitiesnoconv("InActivity");
  2652. $this->labelStatusShort[0] = $langs->transnoentitiesnoconv("ActivityCeased");
  2653. $this->labelStatusShort[1] = $langs->transnoentitiesnoconv("InActivity");
  2654. }
  2655. return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
  2656. }
  2657. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2658. /**
  2659. * Return list of contacts emails existing for third party
  2660. *
  2661. * @param int $addthirdparty 1=Add also a record for thirdparty email, 2=Same than 1 but add text ThirdParty in grey
  2662. * @return array Array of contacts emails
  2663. */
  2664. public function thirdparty_and_contact_email_array($addthirdparty = 0)
  2665. {
  2666. // phpcs:enable
  2667. global $langs;
  2668. $contact_emails = $this->contact_property_array('email', 1);
  2669. if ($this->email && $addthirdparty) {
  2670. if (empty($this->name)) {
  2671. $this->name = $this->nom;
  2672. }
  2673. $contact_emails['thirdparty'] = ($addthirdparty == 2 ? '<span class="opacitymedium">' : '').$langs->transnoentitiesnoconv("ThirdParty").($addthirdparty == 2 ? '</span>' : '').': '.dol_trunc($this->name, 16)." <".$this->email.">";
  2674. }
  2675. //var_dump($contact_emails)
  2676. return $contact_emails;
  2677. }
  2678. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2679. /**
  2680. * Return list of contacts mobile phone existing for third party
  2681. *
  2682. * @return array Array of contacts emails
  2683. */
  2684. public function thirdparty_and_contact_phone_array()
  2685. {
  2686. // phpcs:enable
  2687. global $langs;
  2688. $contact_phone = $this->contact_property_array('mobile');
  2689. if (!empty($this->phone)) { // If a phone of thirdparty is defined, we add it ot mobile of contacts
  2690. if (empty($this->name)) {
  2691. $this->name = $this->nom;
  2692. }
  2693. // TODO: Tester si tel non deja present dans tableau contact
  2694. $contact_phone['thirdparty'] = $langs->transnoentitiesnoconv("ThirdParty").': '.dol_trunc($this->name, 16)." <".$this->phone.">";
  2695. }
  2696. return $contact_phone;
  2697. }
  2698. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2699. /**
  2700. * Return list of contacts emails or mobile existing for third party
  2701. *
  2702. * @param string $mode 'email' or 'mobile'
  2703. * @param int $hidedisabled 1=Hide contact if disabled
  2704. * @return array Array of contacts emails or mobile. Example: array(id=>'Name <email>')
  2705. */
  2706. public function contact_property_array($mode = 'email', $hidedisabled = 0)
  2707. {
  2708. // phpcs:enable
  2709. global $langs;
  2710. $contact_property = array();
  2711. $sql = "SELECT rowid, email, statut as status, phone_mobile, lastname, poste, firstname";
  2712. $sql .= " FROM ".MAIN_DB_PREFIX."socpeople";
  2713. $sql .= " WHERE fk_soc = ".((int) $this->id);
  2714. $sql .= " ORDER BY lastname, firstname";
  2715. $resql = $this->db->query($sql);
  2716. if ($resql) {
  2717. $nump = $this->db->num_rows($resql);
  2718. if ($nump) {
  2719. $sepa = "(";
  2720. $sepb = ")";
  2721. if ($mode == 'email') {
  2722. //$sepa="&lt;"; $sepb="&gt;";
  2723. $sepa = "<";
  2724. $sepb = ">";
  2725. }
  2726. $i = 0;
  2727. while ($i < $nump) {
  2728. $obj = $this->db->fetch_object($resql);
  2729. if ($mode == 'email') {
  2730. $property = $obj->email;
  2731. } elseif ($mode == 'mobile') {
  2732. $property = $obj->phone_mobile;
  2733. } else {
  2734. $property = $obj->$mode;
  2735. }
  2736. // Show all contact. If hidedisabled is 1, showonly contacts with status = 1
  2737. if ($obj->status == 1 || empty($hidedisabled)) {
  2738. if (empty($property)) {
  2739. if ($mode == 'email') {
  2740. $property = $langs->transnoentitiesnoconv("NoEMail");
  2741. } elseif ($mode == 'mobile') {
  2742. $property = $langs->transnoentitiesnoconv("NoMobilePhone");
  2743. }
  2744. }
  2745. if (!empty($obj->poste)) {
  2746. $contact_property[$obj->rowid] = trim(dolGetFirstLastname($obj->firstname, $obj->lastname)).($obj->poste ? " - ".$obj->poste : "").(($mode != 'poste' && $property) ? " ".$sepa.$property.$sepb : '');
  2747. } else {
  2748. $contact_property[$obj->rowid] = trim(dolGetFirstLastname($obj->firstname, $obj->lastname)).(($mode != 'poste' && $property) ? " ".$sepa.$property.$sepb : '');
  2749. }
  2750. }
  2751. $i++;
  2752. }
  2753. }
  2754. } else {
  2755. dol_print_error($this->db);
  2756. }
  2757. return $contact_property;
  2758. }
  2759. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2760. /**
  2761. * Returns the contact list of this company
  2762. *
  2763. * @return array array of contacts
  2764. */
  2765. public function contact_array()
  2766. {
  2767. // phpcs:enable
  2768. $contacts = array();
  2769. $sql = "SELECT rowid, lastname, firstname FROM ".MAIN_DB_PREFIX."socpeople WHERE fk_soc = ".((int) $this->id);
  2770. $resql = $this->db->query($sql);
  2771. if ($resql) {
  2772. $nump = $this->db->num_rows($resql);
  2773. if ($nump) {
  2774. $i = 0;
  2775. while ($i < $nump) {
  2776. $obj = $this->db->fetch_object($resql);
  2777. $contacts[$obj->rowid] = dolGetFirstLastname($obj->firstname, $obj->lastname);
  2778. $i++;
  2779. }
  2780. }
  2781. } else {
  2782. dol_print_error($this->db);
  2783. }
  2784. return $contacts;
  2785. }
  2786. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2787. /**
  2788. * Returns the contact list of this company
  2789. *
  2790. * @return array $contacts array of contacts
  2791. */
  2792. public function contact_array_objects()
  2793. {
  2794. // phpcs:enable
  2795. require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
  2796. $contacts = array();
  2797. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."socpeople WHERE fk_soc = ".((int) $this->id);
  2798. $resql = $this->db->query($sql);
  2799. if ($resql) {
  2800. $nump = $this->db->num_rows($resql);
  2801. if ($nump) {
  2802. $i = 0;
  2803. while ($i < $nump) {
  2804. $obj = $this->db->fetch_object($resql);
  2805. $contact = new Contact($this->db);
  2806. $contact->fetch($obj->rowid);
  2807. $contacts[] = $contact;
  2808. $i++;
  2809. }
  2810. }
  2811. } else {
  2812. dol_print_error($this->db);
  2813. }
  2814. return $contacts;
  2815. }
  2816. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2817. /**
  2818. * Return property of contact from its id
  2819. *
  2820. * @param int $rowid id of contact
  2821. * @param string $mode 'email' or 'mobile'
  2822. * @return string Email of contact with format: "Full name <email>"
  2823. */
  2824. public function contact_get_property($rowid, $mode)
  2825. {
  2826. // phpcs:enable
  2827. $contact_property = '';
  2828. if (empty($rowid)) {
  2829. return '';
  2830. }
  2831. $sql = "SELECT rowid, email, phone_mobile, lastname, firstname";
  2832. $sql .= " FROM ".MAIN_DB_PREFIX."socpeople";
  2833. $sql .= " WHERE rowid = ".((int) $rowid);
  2834. $resql = $this->db->query($sql);
  2835. if ($resql) {
  2836. $nump = $this->db->num_rows($resql);
  2837. if ($nump) {
  2838. $obj = $this->db->fetch_object($resql);
  2839. if ($mode == 'email') {
  2840. $contact_property = dol_string_nospecial(dolGetFirstLastname($obj->firstname, $obj->lastname), ' ', array(","))." <".$obj->email.">";
  2841. } elseif ($mode == 'mobile') {
  2842. $contact_property = $obj->phone_mobile;
  2843. }
  2844. }
  2845. return $contact_property;
  2846. } else {
  2847. dol_print_error($this->db);
  2848. }
  2849. return '';
  2850. }
  2851. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2852. /**
  2853. * Return bank number property of thirdparty (label or rum)
  2854. *
  2855. * @param string $mode 'label' or 'rum' or 'format'
  2856. * @return string Bank label or RUM or '' if no bank account found
  2857. */
  2858. public function display_rib($mode = 'label')
  2859. {
  2860. // phpcs:enable
  2861. require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
  2862. $bac = new CompanyBankAccount($this->db);
  2863. $bac->fetch(0, $this->id);
  2864. if ($bac->id > 0) { // If a bank account has been found for company $this->id
  2865. if ($mode == 'label') {
  2866. return $bac->getRibLabel(true);
  2867. } elseif ($mode == 'rum') {
  2868. if (empty($bac->rum)) {
  2869. require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
  2870. $prelevement = new BonPrelevement($this->db);
  2871. $bac->fetch_thirdparty();
  2872. $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id);
  2873. }
  2874. return $bac->rum;
  2875. } elseif ($mode == 'format') {
  2876. return $bac->frstrecur;
  2877. } else {
  2878. return 'BadParameterToFunctionDisplayRib';
  2879. }
  2880. } else {
  2881. return '';
  2882. }
  2883. }
  2884. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2885. /**
  2886. * Return Array of RIB
  2887. *
  2888. * @return array|int 0 if KO, Array of CompanyBanckAccount if OK
  2889. */
  2890. public function get_all_rib()
  2891. {
  2892. // phpcs:enable
  2893. require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
  2894. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib WHERE type='ban' AND fk_soc = ".((int) $this->id);
  2895. $result = $this->db->query($sql);
  2896. if (!$result) {
  2897. $this->error++;
  2898. $this->errors[] = $this->db->lasterror;
  2899. return 0;
  2900. } else {
  2901. $num_rows = $this->db->num_rows($result);
  2902. $rib_array = array();
  2903. if ($num_rows) {
  2904. while ($obj = $this->db->fetch_object($result)) {
  2905. $rib = new CompanyBankAccount($this->db);
  2906. $rib->fetch($obj->rowid);
  2907. $rib_array[] = $rib;
  2908. }
  2909. }
  2910. return $rib_array;
  2911. }
  2912. }
  2913. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2914. /**
  2915. * Assigns a customer code from the code control module.
  2916. * Return value is stored into this->code_client
  2917. *
  2918. * @param Societe $objsoc Object thirdparty
  2919. * @param int $type Should be 0 to say customer
  2920. * @return void
  2921. */
  2922. public function get_codeclient($objsoc = 0, $type = 0)
  2923. {
  2924. // phpcs:enable
  2925. global $conf;
  2926. if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
  2927. $module = $conf->global->SOCIETE_CODECLIENT_ADDON;
  2928. $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
  2929. foreach ($dirsociete as $dirroot) {
  2930. $res = dol_include_once($dirroot.$module.'.php');
  2931. if ($res) {
  2932. break;
  2933. }
  2934. }
  2935. $mod = new $module();
  2936. $this->code_client = $mod->getNextValue($objsoc, $type);
  2937. $this->prefixCustomerIsRequired = $mod->prefixIsRequired;
  2938. dol_syslog(get_class($this)."::get_codeclient code_client=".$this->code_client." module=".$module);
  2939. }
  2940. }
  2941. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2942. /**
  2943. * Assigns a vendor code from the code control module.
  2944. * Return value is stored into this->code_fournisseur
  2945. *
  2946. * @param Societe $objsoc Object thirdparty
  2947. * @param int $type Should be 1 to say supplier
  2948. * @return void
  2949. */
  2950. public function get_codefournisseur($objsoc = 0, $type = 1)
  2951. {
  2952. // phpcs:enable
  2953. global $conf;
  2954. if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
  2955. $module = $conf->global->SOCIETE_CODECLIENT_ADDON;
  2956. $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
  2957. foreach ($dirsociete as $dirroot) {
  2958. $res = dol_include_once($dirroot.$module.'.php');
  2959. if ($res) {
  2960. break;
  2961. }
  2962. }
  2963. $mod = new $module();
  2964. $this->code_fournisseur = $mod->getNextValue($objsoc, $type);
  2965. dol_syslog(get_class($this)."::get_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$module);
  2966. }
  2967. }
  2968. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2969. /**
  2970. * Check if a client code is editable based on the parameters of the
  2971. * code control module.
  2972. *
  2973. * @return int 0=No, 1=Yes
  2974. */
  2975. public function codeclient_modifiable()
  2976. {
  2977. // phpcs:enable
  2978. global $conf;
  2979. if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
  2980. $module = $conf->global->SOCIETE_CODECLIENT_ADDON;
  2981. $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
  2982. foreach ($dirsociete as $dirroot) {
  2983. $res = dol_include_once($dirroot.$module.'.php');
  2984. if ($res) {
  2985. break;
  2986. }
  2987. }
  2988. $mod = new $module();
  2989. dol_syslog(get_class($this)."::codeclient_modifiable code_client=".$this->code_client." module=".$module);
  2990. if ($mod->code_modifiable_null && !$this->code_client) {
  2991. return 1;
  2992. }
  2993. if ($mod->code_modifiable_invalide && $this->check_codeclient() < 0) {
  2994. return 1;
  2995. }
  2996. if ($mod->code_modifiable) {
  2997. return 1; // A mettre en dernier
  2998. }
  2999. return 0;
  3000. } else {
  3001. return 0;
  3002. }
  3003. }
  3004. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3005. /**
  3006. * Check if a vendor code is editable in the code control module configuration
  3007. *
  3008. * @return int 0=No, 1=Yes
  3009. */
  3010. public function codefournisseur_modifiable()
  3011. {
  3012. // phpcs:enable
  3013. global $conf;
  3014. if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
  3015. $module = $conf->global->SOCIETE_CODECLIENT_ADDON;
  3016. $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
  3017. foreach ($dirsociete as $dirroot) {
  3018. $res = dol_include_once($dirroot.$module.'.php');
  3019. if ($res) {
  3020. break;
  3021. }
  3022. }
  3023. $mod = new $module();
  3024. dol_syslog(get_class($this)."::codefournisseur_modifiable code_founisseur=".$this->code_fournisseur." module=".$module);
  3025. if ($mod->code_modifiable_null && !$this->code_fournisseur) {
  3026. return 1;
  3027. }
  3028. if ($mod->code_modifiable_invalide && $this->check_codefournisseur() < 0) {
  3029. return 1;
  3030. }
  3031. if ($mod->code_modifiable) {
  3032. return 1; // A mettre en dernier
  3033. }
  3034. return 0;
  3035. } else {
  3036. return 0;
  3037. }
  3038. }
  3039. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3040. /**
  3041. * Check customer code
  3042. *
  3043. * @return int 0 if OK
  3044. * -1 ErrorBadCustomerCodeSyntax
  3045. * -2 ErrorCustomerCodeRequired
  3046. * -3 ErrorCustomerCodeAlreadyUsed
  3047. * -4 ErrorPrefixRequired
  3048. * -5 NotConfigured - Setup empty so any value may be ok or not
  3049. * -6 Other (see this->error)
  3050. */
  3051. public function check_codeclient()
  3052. {
  3053. // phpcs:enable
  3054. global $conf;
  3055. if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
  3056. $module = $conf->global->SOCIETE_CODECLIENT_ADDON;
  3057. $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
  3058. foreach ($dirsociete as $dirroot) {
  3059. $res = dol_include_once($dirroot.$module.'.php');
  3060. if ($res) {
  3061. break;
  3062. }
  3063. }
  3064. $mod = new $module();
  3065. dol_syslog(get_class($this)."::check_codeclient code_client=".$this->code_client." module=".$module);
  3066. $result = $mod->verif($this->db, $this->code_client, $this, 0);
  3067. if ($result) { // If error
  3068. $this->error = $mod->error;
  3069. $this->errors = $mod->errors;
  3070. }
  3071. return $result;
  3072. } else {
  3073. return 0;
  3074. }
  3075. }
  3076. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3077. /**
  3078. * Check supplier code
  3079. *
  3080. * @return int 0 if OK
  3081. * -1 ErrorBadCustomerCodeSyntax
  3082. * -2 ErrorCustomerCodeRequired
  3083. * -3 ErrorCustomerCodeAlreadyUsed
  3084. * -4 ErrorPrefixRequired
  3085. * -5 NotConfigured - Setup empty so any value may be ok or not
  3086. * -6 Other (see this->error)
  3087. */
  3088. public function check_codefournisseur()
  3089. {
  3090. // phpcs:enable
  3091. global $conf;
  3092. if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
  3093. $module = $conf->global->SOCIETE_CODECLIENT_ADDON;
  3094. $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
  3095. foreach ($dirsociete as $dirroot) {
  3096. $res = dol_include_once($dirroot.$module.'.php');
  3097. if ($res) {
  3098. break;
  3099. }
  3100. }
  3101. $mod = new $module();
  3102. dol_syslog(get_class($this)."::check_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$module);
  3103. $result = $mod->verif($this->db, $this->code_fournisseur, $this, 1);
  3104. if ($result) { // If error
  3105. $this->error = $mod->error;
  3106. $this->errors = $mod->errors;
  3107. }
  3108. return $result;
  3109. } else {
  3110. return 0;
  3111. }
  3112. }
  3113. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3114. /**
  3115. * Assigns a accounting code from the accounting code module.
  3116. * Computed value is stored into this->code_compta or this->code_compta_fournisseur according to $type.
  3117. * May be identical to the one entered or generated automatically. Currently, only the automatic generation is implemented.
  3118. *
  3119. * @param string $type Type of thirdparty ('customer' or 'supplier')
  3120. * @return int 0 if OK, <0 if $type is not valid
  3121. */
  3122. public function get_codecompta($type)
  3123. {
  3124. // phpcs:enable
  3125. global $conf;
  3126. if (getDolGlobalString('SOCIETE_CODECOMPTA_ADDON')) {
  3127. $module=$conf->global->SOCIETE_CODECOMPTA_ADDON;
  3128. $res = false;
  3129. $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
  3130. foreach ($dirsociete as $dirroot) {
  3131. $res = dol_include_once($dirroot.$module.'.php');
  3132. if ($res) {
  3133. break;
  3134. }
  3135. }
  3136. if ($res) {
  3137. $mod = new $module();
  3138. // Set code count in $mod->code
  3139. $result = $mod->get_code($this->db, $this, $type);
  3140. if ($type == 'customer') {
  3141. $this->code_compta_client = $mod->code;
  3142. $this->code_compta = $this->code_compta_client; // For backward compatibility
  3143. } elseif ($type == 'supplier') {
  3144. $this->code_compta_fournisseur = $mod->code;
  3145. }
  3146. return $result;
  3147. } else {
  3148. $this->error = 'ErrorAccountancyCodeNotDefined';
  3149. return -1;
  3150. }
  3151. } else {
  3152. if ($type == 'customer') {
  3153. $this->code_compta_client = '';
  3154. $this->code_compta = '';
  3155. } elseif ($type == 'supplier') {
  3156. $this->code_compta_fournisseur = '';
  3157. }
  3158. return 0;
  3159. }
  3160. }
  3161. /**
  3162. * Define parent company of current company
  3163. *
  3164. * @param int $id Id of thirdparty to set or '' to remove
  3165. * @return int Return integer <0 if KO, >0 if OK
  3166. */
  3167. public function setParent($id)
  3168. {
  3169. dol_syslog(get_class($this).'::setParent', LOG_DEBUG);
  3170. if ($this->id) {
  3171. // Check if the id we want to add as parent has not already one parent that is the current id we try to update
  3172. if ($id > 0) {
  3173. $sameparent = $this->validateFamilyTree($id, $this->id, 0);
  3174. if ($sameparent < 0) {
  3175. return -1;
  3176. }
  3177. if ($sameparent == 1) {
  3178. setEventMessages('ParentCompanyToAddIsAlreadyAChildOfModifiedCompany', null, 'warnings');
  3179. return -1;
  3180. }
  3181. }
  3182. $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe SET parent = '.($id > 0 ? $id : 'null').' WHERE rowid = '.((int) $this->id);
  3183. $resql = $this->db->query($sql);
  3184. if ($resql) {
  3185. $this->parent = $id;
  3186. return 1;
  3187. } else {
  3188. return -1;
  3189. }
  3190. }
  3191. return -1;
  3192. }
  3193. /**
  3194. * Check if a thirdparty $idchild is or not inside the parents (or grand parents) of another thirdparty id $idparent.
  3195. *
  3196. * @param int $idparent Id of thirdparty to check
  3197. * @param int $idchild Id of thirdparty to compare to
  3198. * @param int $counter Counter to protect against infinite loops
  3199. * @return int Return integer <0 if KO, 0 if OK or 1 if at some level a parent company was the child to compare to
  3200. */
  3201. public function validateFamilyTree($idparent, $idchild, $counter = 0)
  3202. {
  3203. if ($counter > 100) {
  3204. dol_syslog("Too high level of parent - child for company. May be an infinite loop ?", LOG_WARNING);
  3205. }
  3206. $sql = 'SELECT s.parent';
  3207. $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s';
  3208. $sql .= ' WHERE rowid = '.((int) $idparent);
  3209. $resql = $this->db->query($sql);
  3210. if ($resql) {
  3211. $obj = $this->db->fetch_object($resql);
  3212. if ($obj->parent == '') {
  3213. return 0;
  3214. } elseif ($obj->parent == $idchild) {
  3215. return 1;
  3216. } else {
  3217. $sameparent = $this->validateFamilyTree($obj->parent, $idchild, ($counter + 1));
  3218. }
  3219. return $sameparent;
  3220. } else {
  3221. return -1;
  3222. }
  3223. }
  3224. /**
  3225. * Get parents for company
  3226. *
  3227. * @param int $company_id ID of company to search parent
  3228. * @param array $parents List of companies ID found
  3229. * @return array
  3230. */
  3231. public function getParentsForCompany($company_id, $parents = array())
  3232. {
  3233. global $langs;
  3234. if ($company_id > 0) {
  3235. $sql = "SELECT parent FROM " . MAIN_DB_PREFIX . "societe WHERE rowid = ".((int) $company_id);
  3236. $resql = $this->db->query($sql);
  3237. if ($resql) {
  3238. if ($obj = $this->db->fetch_object($resql)) {
  3239. $parent = $obj->parent;
  3240. if ($parent > 0 && !in_array($parent, $parents)) {
  3241. $parents[] = $parent;
  3242. return $this->getParentsForCompany($parent, $parents);
  3243. } else {
  3244. return $parents;
  3245. }
  3246. }
  3247. $this->db->free($resql);
  3248. } else {
  3249. setEventMessage($langs->trans('GetCompanyParentsError', $this->db->lasterror()), 'errors');
  3250. }
  3251. }
  3252. // Return a default value when $company_id is not greater than 0
  3253. return array();
  3254. }
  3255. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3256. /**
  3257. * Returns if a profid sould be verified to be unique
  3258. *
  3259. * @param int $idprof 1,2,3,4,5,6 (Example: 1=siren, 2=siret, 3=naf, 4=rcs/rm, 5=eori, 6=idprof6)
  3260. * @return boolean true if the ID must be unique
  3261. */
  3262. public function id_prof_verifiable($idprof)
  3263. {
  3264. // phpcs:enable
  3265. global $conf;
  3266. switch ($idprof) {
  3267. case 1:
  3268. $ret = (!getDolGlobalString('SOCIETE_IDPROF1_UNIQUE') ? false : true);
  3269. break;
  3270. case 2:
  3271. $ret = (!getDolGlobalString('SOCIETE_IDPROF2_UNIQUE') ? false : true);
  3272. break;
  3273. case 3:
  3274. $ret = (!getDolGlobalString('SOCIETE_IDPROF3_UNIQUE') ? false : true);
  3275. break;
  3276. case 4:
  3277. $ret = (!getDolGlobalString('SOCIETE_IDPROF4_UNIQUE') ? false : true);
  3278. break;
  3279. case 5:
  3280. $ret = (!getDolGlobalString('SOCIETE_IDPROF5_UNIQUE') ? false : true);
  3281. break;
  3282. case 6:
  3283. $ret = (!getDolGlobalString('SOCIETE_IDPROF6_UNIQUE') ? false : true);
  3284. break;
  3285. default:
  3286. $ret = false;
  3287. }
  3288. return $ret;
  3289. }
  3290. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3291. /**
  3292. * Verify if a profid exists into database for others thirds
  3293. *
  3294. * @param string $idprof 'idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','email' (Example: idprof1=siren, idprof2=siret, idprof3=naf, idprof4=rcs/rm)
  3295. * @param string $value Value of profid
  3296. * @param int $socid Id of thirdparty to exclude (if update)
  3297. * @return boolean True if exists, False if not
  3298. */
  3299. public function id_prof_exists($idprof, $value, $socid = 0)
  3300. {
  3301. // phpcs:enable
  3302. $field = $idprof;
  3303. switch ($idprof) { // For backward compatibility
  3304. case '1':
  3305. case 'idprof1':
  3306. $field = "siren";
  3307. break;
  3308. case '2':
  3309. case 'idprof2':
  3310. $field = "siret";
  3311. break;
  3312. case '3':
  3313. case 'idprof3':
  3314. $field = "ape";
  3315. break;
  3316. case '4':
  3317. case 'idprof4':
  3318. $field = "idprof4";
  3319. break;
  3320. case '5':
  3321. $field = "idprof5";
  3322. break;
  3323. case '6':
  3324. $field = "idprof6";
  3325. break;
  3326. }
  3327. //Verify duplicate entries
  3328. $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."societe WHERE ".$field." = '".$this->db->escape($value)."' AND entity IN (".getEntity('societe').")";
  3329. if ($socid) {
  3330. $sql .= " AND rowid <> ".$socid;
  3331. }
  3332. $resql = $this->db->query($sql);
  3333. if ($resql) {
  3334. $obj = $this->db->fetch_object($resql);
  3335. $count = $obj->nb;
  3336. } else {
  3337. $count = 0;
  3338. print $this->db->error();
  3339. }
  3340. $this->db->free($resql);
  3341. if ($count > 0) {
  3342. return true;
  3343. } else {
  3344. return false;
  3345. }
  3346. }
  3347. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3348. /**
  3349. * Check the validity of a professional identifier according to the country of the company (siren, siret, ...)
  3350. *
  3351. * @param int $idprof 1,2,3,4 (Exemple: 1=siren,2=siret,3=naf,4=rcs/rm)
  3352. * @param Societe $soc Objet societe
  3353. * @return int Return integer <=0 if KO, >0 if OK
  3354. * TODO better to have this in a lib than into a business class
  3355. */
  3356. public function id_prof_check($idprof, $soc)
  3357. {
  3358. // phpcs:enable
  3359. global $conf;
  3360. $ok = 1;
  3361. if (getDolGlobalString('MAIN_DISABLEPROFIDRULES')) {
  3362. return 1;
  3363. }
  3364. // Check SIREN if country FR
  3365. if ($idprof == 1 && $soc->country_code == 'FR') {
  3366. $chaine = trim($this->idprof1);
  3367. $chaine = preg_replace('/(\s)/', '', $chaine);
  3368. if (!is_numeric($chaine)) {
  3369. return -1;
  3370. }
  3371. if (dol_strlen($chaine) != 9) {
  3372. return -1;
  3373. }
  3374. // on prend chaque chiffre un par un
  3375. // si son index (position dans la chaîne en commence à 0 au premier caractère) est impair
  3376. // on double sa valeur et si cette dernière est supérieure à 9, on lui retranche 9
  3377. // on ajoute cette valeur à la somme totale
  3378. $sum = 0;
  3379. for ($index = 0; $index < 9; $index++) {
  3380. $number = (int) $chaine[$index];
  3381. if (($index % 2) != 0) {
  3382. if (($number *= 2) > 9) {
  3383. $number -= 9;
  3384. }
  3385. }
  3386. $sum += $number;
  3387. }
  3388. // le numéro est valide si la somme des chiffres est multiple de 10
  3389. if (($sum % 10) != 0) {
  3390. return -1;
  3391. }
  3392. }
  3393. // Verifie SIRET si pays FR
  3394. if ($idprof == 2 && $soc->country_code == 'FR') {
  3395. $chaine = trim($this->idprof2);
  3396. $chaine = preg_replace('/(\s)/', '', $chaine);
  3397. if (!is_numeric($chaine)) {
  3398. return -1;
  3399. }
  3400. if (dol_strlen($chaine) != 14) {
  3401. return -1;
  3402. }
  3403. // on prend chaque chiffre un par un
  3404. // si son index (position dans la chaîne en commence à 0 au premier caractère) est pair
  3405. // on double sa valeur et si cette dernière est supérieure à 9, on lui retranche 9
  3406. // on ajoute cette valeur à la somme totale
  3407. $sum = 0;
  3408. for ($index = 0; $index < 14; $index++) {
  3409. $number = (int) $chaine[$index];
  3410. if (($index % 2) == 0) {
  3411. if (($number *= 2) > 9) {
  3412. $number -= 9;
  3413. }
  3414. }
  3415. $sum += $number;
  3416. }
  3417. // le numéro est valide si la somme des chiffres est multiple de 10
  3418. if (($sum % 10) != 0) {
  3419. return -1;
  3420. }
  3421. }
  3422. //Verify CIF/NIF/NIE if pays ES
  3423. //Returns: 1 if NIF ok, 2 if CIF ok, 3 if NIE ok, -1 if NIF bad, -2 if CIF bad, -3 if NIE bad, 0 if unexpected bad
  3424. if ($idprof == 1 && $soc->country_code == 'ES') {
  3425. $string = trim($this->idprof1);
  3426. $string = preg_replace('/(\s)/', '', $string);
  3427. $string = strtoupper($string);
  3428. //Check format
  3429. if (!preg_match('/((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)/', $string)) {
  3430. return 0;
  3431. }
  3432. $num = array();
  3433. for ($i = 0; $i < 9; $i++) {
  3434. $num[$i] = substr($string, $i, 1);
  3435. }
  3436. //Check NIF
  3437. if (preg_match('/(^[0-9]{8}[A-Z]{1}$)/', $string)) {
  3438. if ($num[8] == substr('TRWAGMYFPDXBNJZSQVHLCKE', substr($string, 0, 8) % 23, 1)) {
  3439. return 1;
  3440. } else {
  3441. return -1;
  3442. }
  3443. }
  3444. //algorithm checking type code CIF
  3445. $sum = $num[2] + $num[4] + $num[6];
  3446. for ($i = 1; $i < 8; $i += 2) {
  3447. $sum += intval(substr((2 * $num[$i]), 0, 1)) + intval(substr((2 * $num[$i]), 1, 1));
  3448. }
  3449. $n = 10 - substr($sum, strlen($sum) - 1, 1);
  3450. //Chek special NIF
  3451. if (preg_match('/^[KLM]{1}/', $string)) {
  3452. if ($num[8] == chr(64 + $n) || $num[8] == substr('TRWAGMYFPDXBNJZSQVHLCKE', substr($string, 1, 8) % 23, 1)) {
  3453. return 1;
  3454. } else {
  3455. return -1;
  3456. }
  3457. }
  3458. //Check CIF
  3459. if (preg_match('/^[ABCDEFGHJNPQRSUVW]{1}/', $string)) {
  3460. if ($num[8] == chr(64 + $n) || $num[8] == substr($n, strlen($n) - 1, 1)) {
  3461. return 2;
  3462. } else {
  3463. return -2;
  3464. }
  3465. }
  3466. //Check NIE T
  3467. if (preg_match('/^[T]{1}/', $string)) {
  3468. if ($num[8] == preg_match('/^[T]{1}[A-Z0-9]{8}$/', $string)) {
  3469. return 3;
  3470. } else {
  3471. return -3;
  3472. }
  3473. }
  3474. //Check NIE XYZ
  3475. if (preg_match('/^[XYZ]{1}/', $string)) {
  3476. if ($num[8] == substr('TRWAGMYFPDXBNJZSQVHLCKE', substr(str_replace(array('X', 'Y', 'Z'), array('0', '1', '2'), $string), 0, 8) % 23, 1)) {
  3477. return 3;
  3478. } else {
  3479. return -3;
  3480. }
  3481. }
  3482. //Can not be verified
  3483. return -4;
  3484. }
  3485. //Verify NIF if country is PT
  3486. //Returns: 1 if NIF ok, -1 if NIF bad, 0 if unexpected bad
  3487. if ($idprof == 1 && $soc->country_code == 'PT') {
  3488. $string = trim($this->idprof1);
  3489. $string = preg_replace('/(\s)/', '', $string);
  3490. //Check NIF
  3491. if (preg_match('/(^[0-9]{9}$)/', $string)) {
  3492. return 1;
  3493. } else {
  3494. return -1;
  3495. }
  3496. }
  3497. //Verify NIF if country is DZ
  3498. //Returns: 1 if NIF ok, -1 if NIF bad, 0 if unexpected bad
  3499. if ($idprof == 1 && $soc->country_code == 'DZ') {
  3500. $string = trim($this->idprof1);
  3501. $string = preg_replace('/(\s)/', '', $string);
  3502. //Check NIF
  3503. if (preg_match('/(^[0-9]{15}$)/', $string)) {
  3504. return 1;
  3505. } else {
  3506. return -1;
  3507. }
  3508. }
  3509. //Verify ID Prof 1 if country is BE (xxxx.xxx.xxx) (https://economie.fgov.be/fr/themes/entreprises/banque-carrefour-des/actualites/structure-du-numero)
  3510. //Returns: 1 if ok, -1 if bad, 0 if unexpected bad
  3511. if ($idprof == 1 && $soc->country_code == 'BE') {
  3512. $string = trim($this->idprof1);
  3513. $string = preg_replace('/(\s)/', '', $string);
  3514. //Check
  3515. if (preg_match('/(^[0-9]{4}\.[0-9]{3}\.[0-9]{3}$)/', $string)) {
  3516. return 1;
  3517. } else {
  3518. return -1;
  3519. }
  3520. }
  3521. return $ok;
  3522. }
  3523. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3524. /**
  3525. * Return an url to check online a professional id or empty string
  3526. *
  3527. * @param int $idprof 1,2,3,4 (Example: 1=siren,2=siret,3=naf,4=rcs/rm)
  3528. * @param Societe $thirdparty Object thirdparty
  3529. * @return string Url or empty string if no URL known
  3530. * TODO better in a lib than into business class
  3531. */
  3532. public function id_prof_url($idprof, $thirdparty)
  3533. {
  3534. // phpcs:enable
  3535. global $conf, $langs, $hookmanager;
  3536. $url = '';
  3537. $action = '';
  3538. $hookmanager->initHooks(array('idprofurl'));
  3539. $parameters = array('idprof'=>$idprof, 'company'=>$thirdparty);
  3540. $reshook = $hookmanager->executeHooks('getIdProfUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
  3541. if (empty($reshook)) {
  3542. if (getDolGlobalString('MAIN_DISABLEPROFIDRULES')) {
  3543. return '';
  3544. }
  3545. // TODO Move links to validate professional ID into a dictionary table "country" + "link"
  3546. $strippedIdProf1 = str_replace(' ', '', $thirdparty->idprof1);
  3547. if ($idprof == 1 && $thirdparty->country_code == 'FR') {
  3548. $url = 'https://annuaire-entreprises.data.gouv.fr/entreprise/'.$strippedIdProf1; // See also http://avis-situation-sirene.insee.fr/
  3549. }
  3550. if ($idprof == 1 && ($thirdparty->country_code == 'GB' || $thirdparty->country_code == 'UK')) {
  3551. $url = 'https://beta.companieshouse.gov.uk/company/'.$strippedIdProf1;
  3552. }
  3553. if ($idprof == 1 && $thirdparty->country_code == 'ES') {
  3554. $url = 'http://www.e-informa.es/servlet/app/portal/ENTP/screen/SProducto/prod/ETIQUETA_EMPRESA/nif/'.$strippedIdProf1;
  3555. }
  3556. if ($idprof == 1 && $thirdparty->country_code == 'IN') {
  3557. $url = 'http://www.tinxsys.com/TinxsysInternetWeb/dealerControllerServlet?tinNumber='.$strippedIdProf1.';&searchBy=TIN&backPage=searchByTin_Inter.jsp';
  3558. }
  3559. if ($idprof == 1 && $thirdparty->country_code == 'DZ') {
  3560. $url = 'http://nif.mfdgi.gov.dz/nif.asp?Nif='.$strippedIdProf1;
  3561. }
  3562. if ($idprof == 1 && $thirdparty->country_code == 'PT') {
  3563. $url = 'http://www.nif.pt/'.$strippedIdProf1;
  3564. }
  3565. if ($url) {
  3566. return '<a target="_blank" rel="noopener noreferrer" href="'.$url.'">'.$langs->trans("Check").'</a>';
  3567. }
  3568. } else {
  3569. return $hookmanager->resPrint;
  3570. }
  3571. return '';
  3572. }
  3573. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3574. /**
  3575. * Indicates if the company has projects
  3576. *
  3577. * @return bool true if the company has projects, false otherwise
  3578. */
  3579. public function has_projects()
  3580. {
  3581. // phpcs:enable
  3582. $sql = "SELECT COUNT(*) as numproj FROM ".MAIN_DB_PREFIX."projet WHERE fk_soc = ".((int) $this->id);
  3583. $resql = $this->db->query($sql);
  3584. if ($resql) {
  3585. $obj = $this->db->fetch_object($resql);
  3586. $count = $obj->numproj;
  3587. } else {
  3588. $count = 0;
  3589. print $this->db->error();
  3590. }
  3591. $this->db->free($resql);
  3592. return ($count > 0);
  3593. }
  3594. /**
  3595. * Load information for tab info
  3596. *
  3597. * @param int $id Id of thirdparty to load
  3598. * @return void
  3599. */
  3600. public function info($id)
  3601. {
  3602. $sql = "SELECT s.rowid, s.nom as name, s.datec, tms as datem,";
  3603. $sql .= " fk_user_creat, fk_user_modif";
  3604. $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
  3605. $sql .= " WHERE s.rowid = ".((int) $id);
  3606. $result = $this->db->query($sql);
  3607. if ($result) {
  3608. if ($this->db->num_rows($result)) {
  3609. $obj = $this->db->fetch_object($result);
  3610. $this->id = $obj->rowid;
  3611. $this->user_creation_id = $obj->fk_user_creat;
  3612. $this->user_modification_id = $obj->fk_user_modif;
  3613. $this->date_creation = $this->db->jdate($obj->datec);
  3614. $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
  3615. $this->ref = $obj->name;
  3616. }
  3617. $this->db->free($result);
  3618. } else {
  3619. dol_print_error($this->db);
  3620. }
  3621. }
  3622. /**
  3623. * Return if third party is a company (Business) or an end user (Consumer)
  3624. *
  3625. * @return boolean true=is a company, false=a and user
  3626. */
  3627. public function isACompany()
  3628. {
  3629. global $conf;
  3630. // Define if third party is treated as company (or not) when nature is unknown
  3631. $isacompany = !getDolGlobalString('MAIN_UNKNOWN_CUSTOMERS_ARE_COMPANIES') ? 0 : 1; // 0 by default
  3632. if (!empty($this->tva_intra)) {
  3633. $isacompany = 1;
  3634. } elseif (!empty($this->idprof1) || !empty($this->idprof2) || !empty($this->idprof3) || !empty($this->idprof4) || !empty($this->idprof5) || !empty($this->idprof6)) {
  3635. $isacompany = 1;
  3636. } elseif (!empty($this->typent_code) && $this->typent_code != 'TE_UNKNOWN') {
  3637. // TODO Add a field is_a_company into dictionary
  3638. if (preg_match('/^TE_PRIVATE/', $this->typent_code)) {
  3639. $isacompany = 0;
  3640. } else {
  3641. $isacompany = 1;
  3642. }
  3643. }
  3644. return $isacompany;
  3645. }
  3646. /**
  3647. * Return if a company is inside the EEC (European Economic Community)
  3648. *
  3649. * @return boolean true = country inside EEC, false = country outside EEC
  3650. */
  3651. public function isInEEC()
  3652. {
  3653. require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
  3654. return isInEEC($this);
  3655. }
  3656. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3657. /**
  3658. * Load the list of provider categories
  3659. *
  3660. * @return int 0 if success, <> 0 if error
  3661. */
  3662. public function LoadSupplierCateg()
  3663. {
  3664. // phpcs:enable
  3665. $this->SupplierCategories = array();
  3666. $sql = "SELECT rowid, label";
  3667. $sql .= " FROM ".MAIN_DB_PREFIX."categorie";
  3668. $sql .= " WHERE type = ".Categorie::TYPE_SUPPLIER;
  3669. $resql = $this->db->query($sql);
  3670. if ($resql) {
  3671. while ($obj = $this->db->fetch_object($resql)) {
  3672. $this->SupplierCategories[$obj->rowid] = $obj->label;
  3673. }
  3674. return 0;
  3675. } else {
  3676. return -1;
  3677. }
  3678. }
  3679. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3680. /**
  3681. * Insert link supplier - category
  3682. *
  3683. * @param int $categorie_id Id of category
  3684. * @return int 0 if success, <> 0 if error
  3685. */
  3686. public function AddFournisseurInCategory($categorie_id)
  3687. {
  3688. // phpcs:enable
  3689. if ($categorie_id > 0 && $this->id > 0) {
  3690. $sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_fournisseur (fk_categorie, fk_soc) ";
  3691. $sql .= " VALUES (".((int) $categorie_id).", ".((int) $this->id).")";
  3692. if ($resql = $this->db->query($sql)) {
  3693. return 0;
  3694. }
  3695. } else {
  3696. return 0;
  3697. }
  3698. return -1;
  3699. }
  3700. /**
  3701. * Return number of mass Emailing received by this contacts with its email
  3702. *
  3703. * @return int Number of EMailings
  3704. */
  3705. public function getNbOfEMailings()
  3706. {
  3707. $sql = "SELECT count(mc.email) as nb";
  3708. $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."mailing as m";
  3709. $sql .= " WHERE mc.fk_mailing=m.rowid AND mc.email = '".$this->db->escape($this->email)."' ";
  3710. $sql .= " AND m.entity IN (".getEntity($this->element).") AND mc.statut NOT IN (-1,0)"; // -1 error, 0 not sent, 1 sent with success
  3711. $resql = $this->db->query($sql);
  3712. if ($resql) {
  3713. $obj = $this->db->fetch_object($resql);
  3714. $nb = $obj->nb;
  3715. $this->db->free($resql);
  3716. return $nb;
  3717. } else {
  3718. $this->error = $this->db->error();
  3719. return -1;
  3720. }
  3721. }
  3722. /**
  3723. * Set "blacklist" mailing status
  3724. *
  3725. * @param int $no_email 1=Do not send mailing, 0=Ok to recieve mailling
  3726. * @return int Return integer <0 if KO, >0 if OK
  3727. */
  3728. public function setNoEmail($no_email)
  3729. {
  3730. $error = 0;
  3731. // Update mass emailing flag into table mailing_unsubscribe
  3732. if ($this->email) {
  3733. $this->db->begin();
  3734. if ($no_email) {
  3735. $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing', 0).") AND email = '".$this->db->escape($this->email)."'";
  3736. $resql = $this->db->query($sql);
  3737. if ($resql) {
  3738. $obj = $this->db->fetch_object($resql);
  3739. $noemail = $obj->nb;
  3740. if (empty($noemail)) {
  3741. $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_unsubscribe(email, entity, date_creat) VALUES ('".$this->db->escape($this->email)."', ".getEntity('mailing', 0).", '".$this->db->idate(dol_now())."')";
  3742. $resql = $this->db->query($sql);
  3743. if (!$resql) {
  3744. $error++;
  3745. $this->error = $this->db->lasterror();
  3746. $this->errors[] = $this->error;
  3747. }
  3748. }
  3749. } else {
  3750. $error++;
  3751. $this->error = $this->db->lasterror();
  3752. $this->errors[] = $this->error;
  3753. }
  3754. } else {
  3755. $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = '".$this->db->escape($this->email)."' AND entity IN (".getEntity('mailing', 0).")";
  3756. $resql = $this->db->query($sql);
  3757. if (!$resql) {
  3758. $error++;
  3759. $this->error = $this->db->lasterror();
  3760. $this->errors[] = $this->error;
  3761. }
  3762. }
  3763. if (empty($error)) {
  3764. $this->no_email = $no_email;
  3765. $this->db->commit();
  3766. return 1;
  3767. } else {
  3768. $this->db->rollback();
  3769. return $error * -1;
  3770. }
  3771. }
  3772. return 0;
  3773. }
  3774. /**
  3775. * get "blacklist" mailing status
  3776. * set no_email attribut to 1 or 0
  3777. *
  3778. * @return int Return integer <0 if KO, >0 if OK
  3779. */
  3780. public function getNoEmail()
  3781. {
  3782. if ($this->email) {
  3783. $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE entity IN (".getEntity('mailing').") AND email = '".$this->db->escape($this->email)."'";
  3784. $resql = $this->db->query($sql);
  3785. if ($resql) {
  3786. $obj = $this->db->fetch_object($resql);
  3787. $this->no_email = $obj->nb;
  3788. return 1;
  3789. } else {
  3790. $this->error = $this->db->lasterror();
  3791. $this->errors[] = $this->error;
  3792. return -1;
  3793. }
  3794. }
  3795. return 0;
  3796. }
  3797. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  3798. /**
  3799. * Create a third party into database from a member object
  3800. *
  3801. * @param Adherent $member Object member
  3802. * @param string $socname Name of third party to force
  3803. * @param string $socalias Alias name of third party to force
  3804. * @param string $customercode Customer code
  3805. * @return int Return integer <0 if KO, id of created account if OK
  3806. */
  3807. public function create_from_member(Adherent $member, $socname = '', $socalias = '', $customercode = '')
  3808. {
  3809. // phpcs:enable
  3810. global $conf, $user, $langs;
  3811. dol_syslog(get_class($this)."::create_from_member", LOG_DEBUG);
  3812. $fullname = $member->getFullName($langs);
  3813. if ($member->morphy == 'mor') {
  3814. if (empty($socname)) {
  3815. $socname = $member->company ? $member->company : $member->societe;
  3816. }
  3817. if (!empty($fullname) && empty($socalias)) {
  3818. $socalias = $fullname;
  3819. }
  3820. } elseif (empty($socname) && $member->morphy == 'phy') {
  3821. if (empty($socname)) {
  3822. $socname = $fullname;
  3823. }
  3824. if (!empty($member->company) && empty($socalias)) {
  3825. $socalias = $member->company;
  3826. }
  3827. }
  3828. $name = $socname;
  3829. $alias = $socalias ? $socalias : '';
  3830. // Positionne parametres
  3831. $this->nom = $name; // TODO deprecated
  3832. $this->name = $name;
  3833. $this->name_alias = $alias;
  3834. $this->address = $member->address;
  3835. $this->zip = $member->zip;
  3836. $this->town = $member->town;
  3837. $this->country_code = $member->country_code;
  3838. $this->country_id = $member->country_id;
  3839. $this->phone = $member->phone; // Prof phone
  3840. $this->email = $member->email;
  3841. $this->socialnetworks = $member->socialnetworks;
  3842. $this->entity = $member->entity;
  3843. $this->client = 1; // A member is a customer by default
  3844. $this->code_client = ($customercode ? $customercode : -1);
  3845. $this->code_fournisseur = -1;
  3846. $this->typent_code = ($member->morphy == 'phy' ? 'TE_PRIVATE' : 0);
  3847. $this->typent_id = $this->typent_code ? dol_getIdFromCode($this->db, $this->typent_code, 'c_typent', 'id', 'code') : 0;
  3848. $this->db->begin();
  3849. // Cree et positionne $this->id
  3850. $result = $this->create($user);
  3851. if ($result >= 0) {
  3852. // Auto-create contact on thirdparty creation
  3853. if (getDolGlobalString('THIRDPARTY_DEFAULT_CREATE_CONTACT')) {
  3854. // Fill fields needed by contact
  3855. $this->name_bis = $member->lastname;
  3856. $this->firstname = $member->firstname;
  3857. $this->civility_id = $member->civility_id;
  3858. dol_syslog("We ask to create a contact/address too", LOG_DEBUG);
  3859. $result = $this->create_individual($user);
  3860. if ($result < 0) {
  3861. setEventMessages($this->error, $this->errors, 'errors');
  3862. $this->db->rollback();
  3863. return -1;
  3864. }
  3865. }
  3866. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
  3867. $sql .= " SET fk_soc = ".((int) $this->id);
  3868. $sql .= " WHERE rowid = ".((int) $member->id);
  3869. $resql = $this->db->query($sql);
  3870. if ($resql) {
  3871. $this->db->commit();
  3872. return $this->id;
  3873. } else {
  3874. $this->error = $this->db->error();
  3875. $this->db->rollback();
  3876. return -1;
  3877. }
  3878. } else {
  3879. // $this->error deja positionne
  3880. dol_syslog(get_class($this)."::create_from_member - 2 - ".$this->error." - ".join(',', $this->errors), LOG_ERR);
  3881. $this->db->rollback();
  3882. return $result;
  3883. }
  3884. }
  3885. /**
  3886. * Set properties with value into $conf
  3887. *
  3888. * @param Conf $conf Conf object (possibility to use another entity)
  3889. * @return void
  3890. */
  3891. public function setMysoc(Conf $conf)
  3892. {
  3893. global $langs;
  3894. $this->id = 0;
  3895. $this->entity = $conf->entity;
  3896. $this->name = getDolGlobalString('MAIN_INFO_SOCIETE_NOM');
  3897. $this->nom = $this->name; // deprecated
  3898. $this->address = getDolGlobalString('MAIN_INFO_SOCIETE_ADDRESS');
  3899. $this->zip = getDolGlobalString('MAIN_INFO_SOCIETE_ZIP');
  3900. $this->town = getDolGlobalString('MAIN_INFO_SOCIETE_TOWN');
  3901. $this->region_code = getDolGlobalString('MAIN_INFO_SOCIETE_REGION');
  3902. $this->socialobject = getDolGlobalString('MAIN_INFO_SOCIETE_OBJECT');
  3903. $this->note_private = getDolGlobalString('MAIN_INFO_SOCIETE_NOTE');
  3904. // We define country_id, country_code and country
  3905. $country_id = $country_code = $country_label = '';
  3906. if (getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY')) {
  3907. $tmp = explode(':', $conf->global->MAIN_INFO_SOCIETE_COUNTRY);
  3908. $country_id = $tmp[0];
  3909. if (!empty($tmp[1])) { // If $conf->global->MAIN_INFO_SOCIETE_COUNTRY is "id:code:label"
  3910. $country_code = $tmp[1];
  3911. $country_label = $tmp[2];
  3912. } else {
  3913. // For backward compatibility
  3914. dol_syslog("Your country setup use an old syntax. Reedit it using setup area.", LOG_WARNING);
  3915. include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
  3916. $country_code = getCountry($country_id, 2, $this->db); // This need a SQL request, but it's the old feature that should not be used anymore
  3917. $country_label = getCountry($country_id, 0, $this->db); // This need a SQL request, but it's the old feature that should not be used anymore
  3918. }
  3919. }
  3920. $this->country_id = $country_id;
  3921. $this->country_code = $country_code;
  3922. $this->country = $country_label;
  3923. if (is_object($langs)) {
  3924. $this->country = ($langs->trans('Country'.$country_code) != 'Country'.$country_code) ? $langs->trans('Country'.$country_code) : $country_label;
  3925. }
  3926. //TODO This could be replicated for region but function `getRegion` didn't exist, so I didn't added it.
  3927. // We define state_id, state_code and state
  3928. $state_id = 0;
  3929. $state_code = $state_label = '';
  3930. if (getDolGlobalString('MAIN_INFO_SOCIETE_STATE')) {
  3931. $tmp = explode(':', $conf->global->MAIN_INFO_SOCIETE_STATE);
  3932. $state_id = $tmp[0];
  3933. if (!empty($tmp[1])) { // If $conf->global->MAIN_INFO_SOCIETE_STATE is "id:code:label"
  3934. $state_code = $tmp[1];
  3935. $state_label = $tmp[2];
  3936. } else { // For backward compatibility
  3937. dol_syslog("Your setup of State has an old syntax (entity=".$conf->entity."). Go in Home - Setup - Organization then Save should remove this error.", LOG_ERR);
  3938. include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
  3939. $state_code = getState($state_id, 2, $this->db); // This need a SQL request, but it's the old feature that should not be used anymore
  3940. $state_label = getState($state_id, 0, $this->db); // This need a SQL request, but it's the old feature that should not be used anymore
  3941. }
  3942. }
  3943. $this->state_id = $state_id;
  3944. $this->state_code = $state_code;
  3945. $this->state = $state_label;
  3946. if (is_object($langs)) {
  3947. $this->state = ($langs->trans('State'.$state_code) != 'State'.$state_code) ? $langs->trans('State'.$state_code) : $state_label;
  3948. }
  3949. $this->phone = getDolGlobalString('MAIN_INFO_SOCIETE_TEL');
  3950. $this->fax = getDolGlobalString('MAIN_INFO_SOCIETE_FAX');
  3951. $this->url = getDolGlobalString('MAIN_INFO_SOCIETE_WEB');
  3952. // Social networks
  3953. $facebook_url = getDolGlobalString('MAIN_INFO_SOCIETE_FACEBOOK_URL');
  3954. $twitter_url = getDolGlobalString('MAIN_INFO_SOCIETE_TWITTER_URL');
  3955. $linkedin_url = getDolGlobalString('MAIN_INFO_SOCIETE_LINKEDIN_URL');
  3956. $instagram_url = getDolGlobalString('MAIN_INFO_SOCIETE_INSTAGRAM_URL');
  3957. $youtube_url = getDolGlobalString('MAIN_INFO_SOCIETE_YOUTUBE_URL');
  3958. $github_url = getDolGlobalString('MAIN_INFO_SOCIETE_GITHUB_URL');
  3959. $this->socialnetworks = array();
  3960. if (!empty($facebook_url)) {
  3961. $this->socialnetworks['facebook'] = $facebook_url;
  3962. }
  3963. if (!empty($twitter_url)) {
  3964. $this->socialnetworks['twitter'] = $twitter_url;
  3965. }
  3966. if (!empty($linkedin_url)) {
  3967. $this->socialnetworks['linkedin'] = $linkedin_url;
  3968. }
  3969. if (!empty($instagram_url)) {
  3970. $this->socialnetworks['instagram'] = $instagram_url;
  3971. }
  3972. if (!empty($youtube_url)) {
  3973. $this->socialnetworks['youtube'] = $youtube_url;
  3974. }
  3975. if (!empty($github_url)) {
  3976. $this->socialnetworks['github'] = $github_url;
  3977. }
  3978. // Id prof generiques
  3979. $this->idprof1 = getDolGlobalString('MAIN_INFO_SIREN');
  3980. $this->idprof2 = getDolGlobalString('MAIN_INFO_SIRET');
  3981. $this->idprof3 = getDolGlobalString('MAIN_INFO_APE');
  3982. $this->idprof4 = getDolGlobalString('MAIN_INFO_RCS');
  3983. $this->idprof5 = getDolGlobalString('MAIN_INFO_PROFID5');
  3984. $this->idprof6 = getDolGlobalString('MAIN_INFO_PROFID6');
  3985. $this->tva_intra = getDolGlobalString('MAIN_INFO_TVAINTRA'); // VAT number, not necessarly INTRA.
  3986. $this->managers = getDolGlobalString('MAIN_INFO_SOCIETE_MANAGERS');
  3987. $this->capital = getDolGlobalString('MAIN_INFO_CAPITAL');
  3988. $this->forme_juridique_code = getDolGlobalString('MAIN_INFO_SOCIETE_FORME_JURIDIQUE');
  3989. $this->email = getDolGlobalString('MAIN_INFO_SOCIETE_MAIL');
  3990. $this->default_lang = getDolGlobalString('MAIN_LANG_DEFAULT', 'auto');
  3991. $this->logo =getDolGlobalString('MAIN_INFO_SOCIETE_LOGO');
  3992. $this->logo_small = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SMALL');
  3993. $this->logo_mini = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_MINI');
  3994. $this->logo_squarred = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED');
  3995. $this->logo_squarred_small = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED_SMALL');
  3996. $this->logo_squarred_mini = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED_MINI');
  3997. // Define if company use vat or not
  3998. $this->tva_assuj = $conf->global->FACTURE_TVAOPTION;
  3999. // Define if company use local taxes
  4000. $this->localtax1_assuj = ((isset($conf->global->FACTURE_LOCAL_TAX1_OPTION) && (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == '1' || getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on')) ? 1 : 0);
  4001. $this->localtax2_assuj = ((isset($conf->global->FACTURE_LOCAL_TAX2_OPTION) && (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == '1' || getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on')) ? 1 : 0);
  4002. }
  4003. /**
  4004. * Initialise an instance with random values.
  4005. * Used to build previews or test instances.
  4006. * id must be 0 if object instance is a specimen.
  4007. *
  4008. * @return int >0 if ok
  4009. */
  4010. public function initAsSpecimen()
  4011. {
  4012. $now = dol_now();
  4013. // Initialize parameters
  4014. $this->id = 0;
  4015. $this->entity = 1;
  4016. $this->name = 'THIRDPARTY SPECIMEN '.dol_print_date($now, 'dayhourlog');
  4017. $this->nom = $this->name; // For backward compatibility
  4018. $this->ref_ext = 'Ref ext';
  4019. $this->specimen = 1;
  4020. $this->address = '21 jump street';
  4021. $this->zip = '99999';
  4022. $this->town = 'MyTown';
  4023. $this->state_id = 1;
  4024. $this->state_code = 'AA';
  4025. $this->state = 'MyState';
  4026. $this->country_id = 1;
  4027. $this->country_code = 'FR';
  4028. $this->email = 'specimen@specimen.com';
  4029. $this->socialnetworks = array(
  4030. 'skype' => 'skypepseudo',
  4031. 'twitter' => 'twitterpseudo',
  4032. 'facebook' => 'facebookpseudo',
  4033. 'linkedin' => 'linkedinpseudo',
  4034. );
  4035. $this->url = 'http://www.specimen.com';
  4036. $this->phone = '0909090901';
  4037. $this->fax = '0909090909';
  4038. $this->code_client = 'CC-'.dol_print_date($now, 'dayhourlog');
  4039. $this->code_fournisseur = 'SC-'.dol_print_date($now, 'dayhourlog');
  4040. $this->capital = 10000;
  4041. $this->client = 1;
  4042. $this->prospect = 1;
  4043. $this->fournisseur = 1;
  4044. $this->tva_assuj = 1;
  4045. $this->tva_intra = 'EU1234567';
  4046. $this->note_public = 'This is a comment (public)';
  4047. $this->note_private = 'This is a comment (private)';
  4048. $this->idprof1 = 'idprof1';
  4049. $this->idprof2 = 'idprof2';
  4050. $this->idprof3 = 'idprof3';
  4051. $this->idprof4 = 'idprof4';
  4052. $this->idprof5 = 'idprof5';
  4053. $this->idprof6 = 'idprof6';
  4054. return 1;
  4055. }
  4056. /**
  4057. * Check if we must use localtax feature or not according to country (country of $mysoc in most cases).
  4058. *
  4059. * @param int $localTaxNum To get info for only localtax1 or localtax2
  4060. * @return boolean true or false
  4061. */
  4062. public function useLocalTax($localTaxNum = 0)
  4063. {
  4064. $sql = "SELECT t.localtax1, t.localtax2";
  4065. $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
  4066. $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$this->db->escape($this->country_code)."'";
  4067. $sql .= " AND t.active = 1";
  4068. $sql .= " AND t.entity IN (".getEntity('c_tva').")";
  4069. if (empty($localTaxNum)) {
  4070. $sql .= " AND (t.localtax1_type <> '0' OR t.localtax2_type <> '0')";
  4071. } elseif ($localTaxNum == 1) {
  4072. $sql .= " AND t.localtax1_type <> '0'";
  4073. } elseif ($localTaxNum == 2) {
  4074. $sql .= " AND t.localtax2_type <> '0'";
  4075. }
  4076. $resql = $this->db->query($sql);
  4077. if ($resql) {
  4078. return ($this->db->num_rows($resql) > 0);
  4079. } else {
  4080. return false;
  4081. }
  4082. }
  4083. /**
  4084. * Check if we must use NPR Vat (french stupid rule) or not according to country (country of $mysoc in most cases).
  4085. *
  4086. * @return boolean true or false
  4087. */
  4088. public function useNPR()
  4089. {
  4090. $sql = "SELECT t.rowid";
  4091. $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
  4092. $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$this->db->escape($this->country_code)."'";
  4093. $sql .= " AND t.active = 1 AND t.recuperableonly = 1";
  4094. $sql .= " AND t.entity IN (".getEntity('c_tva').")";
  4095. dol_syslog("useNPR", LOG_DEBUG);
  4096. $resql = $this->db->query($sql);
  4097. if ($resql) {
  4098. return ($this->db->num_rows($resql) > 0);
  4099. } else {
  4100. return false;
  4101. }
  4102. }
  4103. /**
  4104. * Check if we must use revenue stamps feature or not according to country (country of $mysocin most cases).
  4105. * Table c_revenuestamp contains the country and value of stamp per invoice.
  4106. *
  4107. * @return boolean true or false
  4108. */
  4109. public function useRevenueStamp()
  4110. {
  4111. $sql = "SELECT COUNT(*) as nb";
  4112. $sql .= " FROM ".MAIN_DB_PREFIX."c_revenuestamp as r, ".MAIN_DB_PREFIX."c_country as c";
  4113. $sql .= " WHERE r.fk_pays = c.rowid AND c.code = '".$this->db->escape($this->country_code)."'";
  4114. $sql .= " AND r.active = 1";
  4115. dol_syslog("useRevenueStamp", LOG_DEBUG);
  4116. $resql = $this->db->query($sql);
  4117. if ($resql) {
  4118. $obj = $this->db->fetch_object($resql);
  4119. return (($obj->nb > 0) ? true : false);
  4120. } else {
  4121. $this->error = $this->db->lasterror();
  4122. return false;
  4123. }
  4124. }
  4125. /**
  4126. * Return prostect level
  4127. *
  4128. * @return string Label of prospect status
  4129. */
  4130. public function getLibProspLevel()
  4131. {
  4132. return $this->LibProspLevel($this->fk_prospectlevel);
  4133. }
  4134. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  4135. /**
  4136. * Return label of prospect level
  4137. *
  4138. * @param int $fk_prospectlevel Prospect level
  4139. * @return string label of level
  4140. */
  4141. public function LibProspLevel($fk_prospectlevel)
  4142. {
  4143. // phpcs:enable
  4144. global $langs;
  4145. $lib = $langs->trans("ProspectLevel".$fk_prospectlevel);
  4146. // If lib not found in language file, we get label from cache/databse
  4147. if ($lib == $langs->trans("ProspectLevel".$fk_prospectlevel)) {
  4148. $lib = $langs->getLabelFromKey($this->db, $fk_prospectlevel, 'c_prospectlevel', 'code', 'label');
  4149. }
  4150. return $lib;
  4151. }
  4152. /**
  4153. * Return status of prospect
  4154. *
  4155. * @param int $mode 0=label long, 1=label short, 2=Picto + Label short, 3=Picto, 4=Picto + Label long
  4156. * @param string $label Label to use for status for added status
  4157. * @return string Label
  4158. */
  4159. public function getLibProspCommStatut($mode = 0, $label = '')
  4160. {
  4161. return $this->LibProspCommStatut($this->stcomm_id, $mode, $label, $this->stcomm_picto);
  4162. }
  4163. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  4164. /**
  4165. * Return label of a given status
  4166. *
  4167. * @param int|string $status Id or code for prospection status
  4168. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
  4169. * @param string $label Label to use for status for added status
  4170. * @param string $picto Name of image file to show ('filenew', ...)
  4171. * If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory.
  4172. * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img
  4173. * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img
  4174. * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1)
  4175. * @return string Label of prospection status
  4176. */
  4177. public function LibProspCommStatut($status, $mode = 0, $label = '', $picto = '')
  4178. {
  4179. // phpcs:enable
  4180. global $langs;
  4181. $langs->load('customers');
  4182. if ($mode == 2) {
  4183. if ($status == '-1' || $status == 'ST_NO') {
  4184. return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect-1");
  4185. } elseif ($status == '0' || $status == 'ST_NEVER') {
  4186. return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect0");
  4187. } elseif ($status == '1' || $status == 'ST_TODO') {
  4188. return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect1");
  4189. } elseif ($status == '2' || $status == 'ST_PEND') {
  4190. return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect2");
  4191. } elseif ($status == '3' || $status == 'ST_DONE') {
  4192. return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect3");
  4193. } else {
  4194. return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0, $picto, 'class="inline-block valignmiddle"').' '.(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label);
  4195. }
  4196. } elseif ($mode == 3) {
  4197. if ($status == '-1' || $status == 'ST_NO') {
  4198. return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"');
  4199. } elseif ($status == '0' || $status == 'ST_NEVER') {
  4200. return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"');
  4201. } elseif ($status == '1' || $status == 'ST_TODO') {
  4202. return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"');
  4203. } elseif ($status == '2' || $status == 'ST_PEND') {
  4204. return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"');
  4205. } elseif ($status == '3' || $status == 'ST_DONE') {
  4206. return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"');
  4207. } else {
  4208. return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0, $picto, 'class="inline-block valignmiddle"');
  4209. }
  4210. } elseif ($mode == 4) {
  4211. if ($status == '-1' || $status == 'ST_NO') {
  4212. return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect-1");
  4213. } elseif ($status == '0' || $status == 'ST_NEVER') {
  4214. return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect0");
  4215. } elseif ($status == '1' || $status == 'ST_TODO') {
  4216. return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect1");
  4217. } elseif ($status == '2' || $status == 'ST_PEND') {
  4218. return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect2");
  4219. } elseif ($status == '3' || $status == 'ST_DONE') {
  4220. return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"').' '.$langs->trans("StatusProspect3");
  4221. } else {
  4222. return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0, $picto, 'class="inline-block valignmiddle"').' '.(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label);
  4223. }
  4224. }
  4225. return "Error, mode/status not found";
  4226. }
  4227. /**
  4228. * Return amount of proposal not yet paid and total an dlist of all proposals
  4229. *
  4230. * @param string $mode 'customer' or 'supplier'
  4231. * @return array array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amunt including tax of all object paid or not)
  4232. */
  4233. public function getOutstandingProposals($mode = 'customer')
  4234. {
  4235. $table = 'propal';
  4236. if ($mode == 'supplier') {
  4237. $table = 'supplier_proposal';
  4238. }
  4239. $sql = "SELECT rowid, ref, total_ht, total_ttc, fk_statut as status FROM ".MAIN_DB_PREFIX.$table." as f";
  4240. $sql .= " WHERE fk_soc = ".((int) $this->id);
  4241. if ($mode == 'supplier') {
  4242. $sql .= " AND entity IN (".getEntity('supplier_proposal').")";
  4243. } else {
  4244. $sql .= " AND entity IN (".getEntity('propal').")";
  4245. }
  4246. dol_syslog("getOutstandingProposals for fk_soc = ".((int) $this->id), LOG_DEBUG);
  4247. $resql = $this->db->query($sql);
  4248. if ($resql) {
  4249. $outstandingOpened = 0;
  4250. $outstandingTotal = 0;
  4251. $outstandingTotalIncTax = 0;
  4252. $arrayofref = array();
  4253. while ($obj = $this->db->fetch_object($resql)) {
  4254. $arrayofref[$obj->rowid] = $obj->ref;
  4255. $outstandingTotal += $obj->total_ht;
  4256. $outstandingTotalIncTax += $obj->total_ttc;
  4257. if ($obj->status != 0) {
  4258. // Not a draft
  4259. $outstandingOpened += $obj->total_ttc;
  4260. }
  4261. }
  4262. return array('opened'=>$outstandingOpened, 'total_ht'=>$outstandingTotal, 'total_ttc'=>$outstandingTotalIncTax, 'refs'=>$arrayofref); // 'opened' is 'incl taxes'
  4263. } else {
  4264. return array();
  4265. }
  4266. }
  4267. /**
  4268. * Return amount of order not yet paid and total and list of all orders
  4269. *
  4270. * @param string $mode 'customer' or 'supplier'
  4271. * @return array array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amunt including tax of all object paid or not)
  4272. */
  4273. public function getOutstandingOrders($mode = 'customer')
  4274. {
  4275. $table = 'commande';
  4276. if ($mode == 'supplier') {
  4277. $table = 'commande_fournisseur';
  4278. }
  4279. $sql = "SELECT rowid, ref, total_ht, total_ttc, fk_statut as status FROM ".MAIN_DB_PREFIX.$table." as f";
  4280. $sql .= " WHERE fk_soc = ".((int) $this->id);
  4281. if ($mode == 'supplier') {
  4282. $sql .= " AND entity IN (".getEntity('supplier_order').")";
  4283. } else {
  4284. $sql .= " AND entity IN (".getEntity('commande').")";
  4285. }
  4286. dol_syslog("getOutstandingOrders", LOG_DEBUG);
  4287. $resql = $this->db->query($sql);
  4288. if ($resql) {
  4289. $outstandingOpened = 0;
  4290. $outstandingTotal = 0;
  4291. $outstandingTotalIncTax = 0;
  4292. $arrayofref = array();
  4293. while ($obj = $this->db->fetch_object($resql)) {
  4294. $arrayofref[$obj->rowid] = $obj->ref;
  4295. $outstandingTotal += $obj->total_ht;
  4296. $outstandingTotalIncTax += $obj->total_ttc;
  4297. if ($obj->status != 0) {
  4298. // Not a draft
  4299. $outstandingOpened += $obj->total_ttc;
  4300. }
  4301. }
  4302. return array('opened'=>$outstandingOpened, 'total_ht'=>$outstandingTotal, 'total_ttc'=>$outstandingTotalIncTax, 'refs'=>$arrayofref); // 'opened' is 'incl taxes'
  4303. } else {
  4304. return array();
  4305. }
  4306. }
  4307. /**
  4308. * Return amount of bill not yet paid and total of all invoices
  4309. *
  4310. * @param string $mode 'customer' or 'supplier'
  4311. * @param int $late 0 => all invoice, 1=> only late
  4312. * @return array array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amunt including tax of all object paid or not)
  4313. */
  4314. public function getOutstandingBills($mode = 'customer', $late = 0)
  4315. {
  4316. $table = 'facture';
  4317. if ($mode == 'supplier') {
  4318. $table = 'facture_fourn';
  4319. }
  4320. /* Accurate value of remain to pay is to sum remaintopay for each invoice
  4321. $paiement = $invoice->getSommePaiement();
  4322. $creditnotes=$invoice->getSumCreditNotesUsed();
  4323. $deposits=$invoice->getSumDepositsUsed();
  4324. $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
  4325. $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
  4326. */
  4327. $sql = "SELECT rowid, ref, total_ht, total_ttc, paye, type, fk_statut as status, close_code FROM ".MAIN_DB_PREFIX.$table." as f";
  4328. $sql .= " WHERE fk_soc = ".((int) $this->id);
  4329. if (!empty($late)) {
  4330. $sql .= " AND date_lim_reglement < '".$this->db->idate(dol_now())."'";
  4331. }
  4332. if ($mode == 'supplier') {
  4333. $sql .= " AND entity IN (".getEntity('facture_fourn').")";
  4334. } else {
  4335. $sql .= " AND entity IN (".getEntity('invoice').")";
  4336. }
  4337. dol_syslog("getOutstandingBills", LOG_DEBUG);
  4338. $resql = $this->db->query($sql);
  4339. if ($resql) {
  4340. $outstandingOpened = 0;
  4341. $outstandingTotal = 0;
  4342. $outstandingTotalIncTax = 0;
  4343. $arrayofref = array();
  4344. $arrayofrefopened = array();
  4345. if ($mode == 'supplier') {
  4346. require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
  4347. $tmpobject = new FactureFournisseur($this->db);
  4348. } else {
  4349. require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  4350. $tmpobject = new Facture($this->db);
  4351. }
  4352. while ($obj = $this->db->fetch_object($resql)) {
  4353. $arrayofref[$obj->rowid] = $obj->ref;
  4354. $tmpobject->id = $obj->rowid;
  4355. if ($obj->status != $tmpobject::STATUS_DRAFT // Not a draft
  4356. && !($obj->status == $tmpobject::STATUS_ABANDONED && $obj->close_code == 'replaced') // Not a replaced invoice
  4357. ) {
  4358. $outstandingTotal += $obj->total_ht;
  4359. $outstandingTotalIncTax += $obj->total_ttc;
  4360. }
  4361. $remaintopay = 0;
  4362. if ($obj->paye == 0
  4363. && $obj->status != $tmpobject::STATUS_DRAFT // Not a draft
  4364. && $obj->status != $tmpobject::STATUS_ABANDONED // Not abandonned
  4365. && $obj->status != $tmpobject::STATUS_CLOSED) { // Not classified as paid
  4366. //$sql .= " AND (status <> 3 OR close_code <> 'abandon')"; // Not abandonned for undefined reason
  4367. $paiement = $tmpobject->getSommePaiement();
  4368. $creditnotes = $tmpobject->getSumCreditNotesUsed();
  4369. $deposits = $tmpobject->getSumDepositsUsed();
  4370. $remaintopay = ($obj->total_ttc - $paiement - $creditnotes - $deposits);
  4371. $outstandingOpened += $remaintopay;
  4372. }
  4373. //if credit note is converted but not used
  4374. // TODO Do this also for customer ?
  4375. if ($mode == 'supplier' && $obj->type == FactureFournisseur::TYPE_CREDIT_NOTE && $tmpobject->isCreditNoteUsed()) {
  4376. $remainingcreditnote = $tmpobject->getSumFromThisCreditNotesNotUsed();
  4377. $remaintopay -= $remainingcreditnote;
  4378. $outstandingOpened -= $remainingcreditnote;
  4379. }
  4380. if ($remaintopay) {
  4381. $arrayofrefopened[$obj->rowid] = $obj->ref;
  4382. }
  4383. }
  4384. return array('opened'=>$outstandingOpened, 'total_ht'=>$outstandingTotal, 'total_ttc'=>$outstandingTotalIncTax, 'refs'=>$arrayofref, 'refsopened'=>$arrayofrefopened); // 'opened' is 'incl taxes'
  4385. } else {
  4386. dol_syslog("Sql error ".$this->db->lasterror, LOG_ERR);
  4387. return array();
  4388. }
  4389. }
  4390. /**
  4391. * Return label of status customer is prospect/customer
  4392. *
  4393. * @return string Label
  4394. * @see getTypeUrl()
  4395. */
  4396. public function getLibCustProspStatut()
  4397. {
  4398. return $this->LibCustProspStatut($this->client);
  4399. }
  4400. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  4401. /**
  4402. * Return the label of the customer/prospect status
  4403. *
  4404. * @param int $status Id of prospection status
  4405. * @return string Label of prospection status
  4406. */
  4407. public function LibCustProspStatut($status)
  4408. {
  4409. // phpcs:enable
  4410. global $langs;
  4411. $langs->load('companies');
  4412. if ($status == 0) {
  4413. return $langs->trans("NorProspectNorCustomer");
  4414. } elseif ($status == 1) {
  4415. return $langs->trans("Customer");
  4416. } elseif ($status == 2) {
  4417. return $langs->trans("Prospect");
  4418. } elseif ($status == 3) {
  4419. return $langs->trans("ProspectCustomer");
  4420. }
  4421. return '';
  4422. }
  4423. /**
  4424. * Create a document onto disk according to template module.
  4425. *
  4426. * @param string $modele Generator to use. Caller must set it to obj->model_pdf or GETPOST('model','alpha') for example.
  4427. * @param Translate $outputlangs objet lang a utiliser pour traduction
  4428. * @param int $hidedetails Hide details of lines
  4429. * @param int $hidedesc Hide description
  4430. * @param int $hideref Hide ref
  4431. * @param null|array $moreparams Array to provide more information
  4432. * @return int Return integer <0 if KO, >0 if OK
  4433. */
  4434. public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
  4435. {
  4436. global $conf, $user, $langs;
  4437. if (!empty($moreparams) && !empty($moreparams['use_companybankid'])) {
  4438. $modelpath = "core/modules/bank/doc/";
  4439. include_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
  4440. $companybankaccount = new CompanyBankAccount($this->db);
  4441. $result = $companybankaccount->fetch($moreparams['use_companybankid']);
  4442. if (!$result) {
  4443. dol_print_error($this->db, $companybankaccount->error, $companybankaccount->errors);
  4444. }
  4445. $result = $companybankaccount->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
  4446. $this->last_main_doc=$companybankaccount->last_main_doc;
  4447. } else {
  4448. // Positionne le modele sur le nom du modele a utiliser
  4449. if (!dol_strlen($modele)) {
  4450. if (getDolGlobalString('COMPANY_ADDON_PDF')) {
  4451. $modele = $conf->global->COMPANY_ADDON_PDF;
  4452. } else {
  4453. print $langs->trans("Error")." ".$langs->trans("Error_COMPANY_ADDON_PDF_NotDefined");
  4454. return 0;
  4455. }
  4456. }
  4457. if (!isset($this->bank_account)) {
  4458. require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
  4459. $bac = new CompanyBankAccount($this->db);
  4460. $result = $bac->fetch(0, $this->id);
  4461. if ($result > 0) {
  4462. $this->bank_account = $bac;
  4463. } else {
  4464. $this->bank_account = '';
  4465. }
  4466. }
  4467. $modelpath = "core/modules/societe/doc/";
  4468. $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
  4469. }
  4470. return $result;
  4471. }
  4472. /**
  4473. * Sets object to supplied categories.
  4474. *
  4475. * Deletes object from existing categories not supplied.
  4476. * Adds it to non existing supplied categories.
  4477. * Existing categories are left untouch.
  4478. *
  4479. * @param int[]|int $categories Category ID or array of Categories IDs
  4480. * @param string $type_categ Category type ('customer' or 'supplier')
  4481. * @return int Return integer <0 if KO, >0 if OK
  4482. */
  4483. public function setCategories($categories, $type_categ)
  4484. {
  4485. require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
  4486. // Decode type
  4487. if (!in_array($type_categ, array(Categorie::TYPE_CUSTOMER, Categorie::TYPE_SUPPLIER))) {
  4488. dol_syslog(__METHOD__.': Type '.$type_categ.'is an unknown company category type. Done nothing.', LOG_ERR);
  4489. return -1;
  4490. }
  4491. return parent::setCategoriesCommon($categories, $type_categ);
  4492. }
  4493. /**
  4494. * Sets sales representatives of the thirdparty
  4495. *
  4496. * @param int[]|int $salesrep User ID or array of user IDs
  4497. * @param bool $onlyAdd Only add (no delete before)
  4498. * @return int Return integer <0 if KO, >0 if OK
  4499. */
  4500. public function setSalesRep($salesrep, $onlyAdd = false)
  4501. {
  4502. global $user;
  4503. // Handle single user
  4504. if (!is_array($salesrep)) {
  4505. $salesrep = array($salesrep);
  4506. }
  4507. $to_del = array(); // Nothing to delete
  4508. $to_add = $salesrep;
  4509. if ($onlyAdd === false) {
  4510. // Get current users
  4511. $existing = $this->getSalesRepresentatives($user, 1);
  4512. // Diff
  4513. if (is_array($existing)) {
  4514. $to_del = array_diff($existing, $salesrep);
  4515. $to_add = array_diff($salesrep, $existing);
  4516. }
  4517. }
  4518. $error = 0;
  4519. // Process
  4520. foreach ($to_del as $del) {
  4521. $this->del_commercial($user, $del);
  4522. }
  4523. foreach ($to_add as $add) {
  4524. $result = $this->add_commercial($user, $add);
  4525. if ($result < 0) {
  4526. $error++;
  4527. break;
  4528. }
  4529. }
  4530. return $error ? -1 : 1;
  4531. }
  4532. /**
  4533. * Define third-party type of current company
  4534. *
  4535. * @param int $typent_id third party type rowid in llx_c_typent
  4536. * @return int Return integer <0 if KO, >0 if OK
  4537. */
  4538. public function setThirdpartyType($typent_id)
  4539. {
  4540. global $user;
  4541. dol_syslog(__METHOD__, LOG_DEBUG);
  4542. if ($this->id) {
  4543. $result = $this->setValueFrom('fk_typent', $typent_id, '', null, '', '', $user, 'COMPANY_MODIFY');
  4544. if ($result > 0) {
  4545. $this->typent_id = $typent_id;
  4546. $this->typent_code = dol_getIdFromCode($this->db, $this->typent_id, 'c_typent', 'id', 'code');
  4547. return 1;
  4548. } else {
  4549. return -1;
  4550. }
  4551. } else {
  4552. return -1;
  4553. }
  4554. }
  4555. /**
  4556. * Function used to replace a thirdparty id with another one.
  4557. * It must be used within a transaction to avoid trouble
  4558. *
  4559. * @param DoliDB $dbs Database handler, because function is static we name it $dbs not $db to avoid breaking coding test
  4560. * @param int $origin_id Old thirdparty id (will be removed)
  4561. * @param int $dest_id New thirdparty id
  4562. * @return bool True if success, False if error
  4563. */
  4564. public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
  4565. {
  4566. if ($origin_id == $dest_id) {
  4567. dol_syslog('Error: Try to merge a thirdparty into itself');
  4568. return false;
  4569. }
  4570. /**
  4571. * Thirdparty commercials cannot be the same in both thirdparties so we look for them and remove some to avoid duplicate.
  4572. * Because this function is meant to be executed within a transaction, we won't take care of begin/commit.
  4573. */
  4574. $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'societe_commerciaux ';
  4575. $sql .= ' WHERE fk_soc = '.(int) $dest_id.' AND fk_user IN ( ';
  4576. $sql .= ' SELECT fk_user ';
  4577. $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_commerciaux ';
  4578. $sql .= ' WHERE fk_soc = '.(int) $origin_id.') ';
  4579. $resql = $dbs->query($sql);
  4580. while ($obj = $dbs->fetch_object($resql)) {
  4581. $dbs->query('DELETE FROM '.MAIN_DB_PREFIX.'societe_commerciaux WHERE rowid = '.((int) $obj->rowid));
  4582. }
  4583. /**
  4584. * llx_societe_extrafields table must not be here because we don't care about the old thirdparty data
  4585. * Do not include llx_societe because it will be replaced later
  4586. */
  4587. $tables = array(
  4588. 'societe_commerciaux',
  4589. 'societe_prices',
  4590. 'societe_remise',
  4591. 'societe_remise_except',
  4592. 'societe_rib'
  4593. );
  4594. return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
  4595. }
  4596. /**
  4597. * Sets an accountancy code for a thirdparty.
  4598. * Also calls COMPANY_MODIFY trigger when modified
  4599. *
  4600. * @param string $type It can be only 'buy' or 'sell'
  4601. * @param string $value Accountancy code
  4602. * @return int Return integer <0 KO >0 OK
  4603. */
  4604. public function setAccountancyCode($type, $value)
  4605. {
  4606. global $user, $langs, $conf;
  4607. $this->db->begin();
  4608. $field = 'accountancy_code_sell';
  4609. if ($type == 'buy') {
  4610. $field = 'accountancy_code_buy';
  4611. } elseif ($type == 'sell') {
  4612. $field = 'accountancy_code_sell';
  4613. } else {
  4614. return -1;
  4615. }
  4616. $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ";
  4617. $sql .= $field." = '".$this->db->escape($value)."'";
  4618. $sql .= " WHERE rowid = ".((int) $this->id);
  4619. dol_syslog(get_class($this)."::".__FUNCTION__, LOG_DEBUG);
  4620. $resql = $this->db->query($sql);
  4621. if ($resql) {
  4622. // Call triggers
  4623. include_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
  4624. $interface = new Interfaces($this->db);
  4625. $result = $interface->run_triggers('COMPANY_MODIFY', $this, $user, $langs, $conf);
  4626. if ($result < 0) {
  4627. $this->errors = $interface->errors;
  4628. $this->db->rollback();
  4629. return -1;
  4630. }
  4631. // End call triggers
  4632. $this->$field = $value;
  4633. $this->db->commit();
  4634. return 1;
  4635. } else {
  4636. $this->error = $this->db->lasterror();
  4637. $this->db->rollback();
  4638. return -1;
  4639. }
  4640. }
  4641. /**
  4642. * Function to get partnerships array
  4643. *
  4644. * @param string $mode 'member' or 'thirdparty'
  4645. * @return int Return integer <0 if KO, >0 if OK
  4646. */
  4647. public function fetchPartnerships($mode)
  4648. {
  4649. global $langs;
  4650. require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php';
  4651. $this->partnerships[] = array();
  4652. return 1;
  4653. }
  4654. /**
  4655. * Return clicable link of object (with eventually picto)
  4656. *
  4657. * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
  4658. * @param array $arraydata Array of data
  4659. * @return string HTML Code for Kanban thumb.
  4660. */
  4661. public function getKanbanView($option = '', $arraydata = null)
  4662. {
  4663. $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
  4664. $return = '<div class="box-flex-item box-flex-grow-zero">';
  4665. $return .= '<div class="info-box info-box-sm">';
  4666. $return .= '<span class="info-box-icon bg-infobox-action">';
  4667. $return .= img_picto('', $this->picto);
  4668. $return .= '</span>';
  4669. $return .= '<div class="info-box-content">';
  4670. $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
  4671. if ($selected >= 0) {
  4672. $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
  4673. }
  4674. if (property_exists($this, 'code_client')) {
  4675. $return .= '<br><span class="info-box-label opacitymedium">'.$this->code_client.'</span>';
  4676. }
  4677. if (method_exists($this, 'getLibStatut')) {
  4678. $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
  4679. }
  4680. $return .= '</div>';
  4681. $return .= '</div>';
  4682. $return .= '</div>';
  4683. return $return;
  4684. }
  4685. /**
  4686. * Get array of all contacts for a society (stored in societe_contacts instead of element_contacts for all other objects)
  4687. *
  4688. * @param int $list 0:Return array contains all properties, 1:Return array contains just id
  4689. * @param string $code Filter on this code of contact type ('SHIPPING', 'BILLING', ...)
  4690. * @param string $element Filter on this element of default contact type ('facture', 'propal', 'commande' ...)
  4691. * @return array|int Array of contacts, -1 if error
  4692. *
  4693. */
  4694. public function getContacts($list = 0, $code = '', $element = '')
  4695. {
  4696. // phpcs:enable
  4697. global $langs;
  4698. $tab = array();
  4699. $sql = "SELECT sc.rowid, sc.fk_socpeople as id, sc.fk_c_type_contact"; // This field contains id of llx_socpeople or id of llx_user
  4700. $sql .= ", t.fk_soc as socid, t.statut as statuscontact";
  4701. $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email";
  4702. $sql .= ", tc.source, tc.element, tc.code, tc.libelle as type_label";
  4703. $sql .= " FROM ".$this->db->prefix()."c_type_contact tc";
  4704. $sql .= ", ".$this->db->prefix()."societe_contacts sc";
  4705. $sql .= " LEFT JOIN ".$this->db->prefix()."socpeople t on sc.fk_socpeople = t.rowid";
  4706. $sql .= " WHERE sc.fk_soc = ".((int) $this->id);
  4707. $sql .= " AND sc.fk_c_type_contact = tc.rowid";
  4708. if (!empty($element)) {
  4709. $sql .= " AND tc.element = '".$this->db->escape($element)."'";
  4710. }
  4711. if ($code) {
  4712. $sql .= " AND tc.code = '".$this->db->escape($code)."'";
  4713. }
  4714. $sql .= " AND sc.entity IN (".getEntity($this->element).")";
  4715. $sql .= " AND tc.source = 'external'";
  4716. $sql .= " AND tc.active=1";
  4717. $sql .= " ORDER BY t.lastname ASC";
  4718. dol_syslog(get_class($this)."::getContacts", LOG_DEBUG);
  4719. $resql = $this->db->query($sql);
  4720. if ($resql) {
  4721. $num = $this->db->num_rows($resql);
  4722. $i = 0;
  4723. while ($i < $num) {
  4724. $obj = $this->db->fetch_object($resql);
  4725. if (!$list) {
  4726. $transkey = "TypeContact_".$obj->element."_".$obj->source."_".$obj->code;
  4727. $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->type_label);
  4728. $tab[$i] = array(
  4729. 'source' => $obj->source,
  4730. 'socid' => $obj->socid,
  4731. 'id' => $obj->id,
  4732. 'nom' => $obj->lastname, // For backward compatibility
  4733. 'civility' => $obj->civility,
  4734. 'lastname' => $obj->lastname,
  4735. 'firstname' => $obj->firstname,
  4736. 'email'=>$obj->email,
  4737. 'login'=> (empty($obj->login) ? '' : $obj->login),
  4738. 'photo' => (empty($obj->photo) ? '' : $obj->photo),
  4739. 'statuscontact' => $obj->statuscontact,
  4740. 'rowid' => $obj->rowid,
  4741. 'code' => $obj->code,
  4742. 'element' => $obj->element,
  4743. 'libelle' => $libelle_type,
  4744. 'status' => $obj->statuslink,
  4745. 'fk_c_type_contact' => $obj->fk_c_type_contact
  4746. );
  4747. } else {
  4748. $tab[$i] = $obj->id;
  4749. }
  4750. $i++;
  4751. }
  4752. return $tab;
  4753. } else {
  4754. $this->error = $this->db->lasterror();
  4755. dol_print_error($this->db);
  4756. return -1;
  4757. }
  4758. }
  4759. /**
  4760. * Merge a company with another one, deleting the given company.
  4761. * The company given in parameter will be removed.
  4762. *
  4763. * @param int $soc_origin_id Company to merge the data from
  4764. * @return int -1 if error
  4765. */
  4766. public function mergeCompany($soc_origin_id)
  4767. {
  4768. global $langs, $hookmanager, $user, $action;
  4769. $error = 0;
  4770. $soc_origin = new Societe($this->db); // The thirdparty that we will delete
  4771. if (!$error && $soc_origin->fetch($soc_origin_id) < 1) {
  4772. $this->error = $langs->trans('ErrorRecordNotFound');
  4773. $error++;
  4774. }
  4775. if (!$error) {
  4776. $this->db->begin();
  4777. // Recopy some data
  4778. $this->client = $this->client | $soc_origin->client;
  4779. $this->fournisseur = $this->fournisseur | $soc_origin->fournisseur;
  4780. $listofproperties = array(
  4781. 'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'fax', 'email', 'socialnetworks', 'url', 'barcode',
  4782. 'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
  4783. 'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
  4784. 'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
  4785. 'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
  4786. 'model_pdf',
  4787. );
  4788. foreach ($listofproperties as $property) {
  4789. if (empty($this->$property)) {
  4790. $this->$property = $soc_origin->$property;
  4791. }
  4792. }
  4793. // Concat some data
  4794. $listofproperties = array(
  4795. 'note_public', 'note_private'
  4796. );
  4797. foreach ($listofproperties as $property) {
  4798. $this->$property = dol_concatdesc($this->$property, $soc_origin->$property);
  4799. }
  4800. // Merge extrafields
  4801. if (is_array($soc_origin->array_options)) {
  4802. foreach ($soc_origin->array_options as $key => $val) {
  4803. if (empty($this->array_options[$key])) {
  4804. $this->array_options[$key] = $val;
  4805. }
  4806. }
  4807. }
  4808. // If alias name is not defined on target thirdparty, we can store in it the old name of company.
  4809. if (empty($this->name_bis) && $this->name != $soc_origin->name) {
  4810. $this->name_bis = $this->name;
  4811. }
  4812. // Merge categories
  4813. $static_cat = new Categorie($this->db);
  4814. $custcats_ori = $static_cat->containing($soc_origin->id, 'customer', 'id');
  4815. $custcats = $static_cat->containing($this->id, 'customer', 'id');
  4816. $custcats = array_merge($custcats, $custcats_ori);
  4817. $this->setCategories($custcats, 'customer');
  4818. $suppcats_ori = $static_cat->containing($soc_origin->id, 'supplier', 'id');
  4819. $suppcats = $static_cat->containing($this->id, 'supplier', 'id');
  4820. $suppcats = array_merge($suppcats, $suppcats_ori);
  4821. $this->setCategories($suppcats, 'supplier');
  4822. // If thirdparty has a new code that is same than origin, we clean origin code to avoid duplicate key from database unique keys.
  4823. if ($soc_origin->code_client == $this->code_client
  4824. || $soc_origin->code_fournisseur == $this->code_fournisseur
  4825. || $soc_origin->barcode == $this->barcode) {
  4826. dol_syslog("We clean customer and supplier code so we will be able to make the update of target");
  4827. $soc_origin->code_client = '';
  4828. $soc_origin->code_fournisseur = '';
  4829. $soc_origin->barcode = '';
  4830. $soc_origin->update($soc_origin->id, $user, 0, 1, 1, 'merge');
  4831. }
  4832. // Update
  4833. $result = $this->update($this->id, $user, 0, 1, 1, 'merge');
  4834. if ($result < 0) {
  4835. $error++;
  4836. }
  4837. // Move links
  4838. if (!$error) {
  4839. $objects = array(
  4840. 'Adherent' => '/adherents/class/adherent.class.php',
  4841. 'Don' => array('file' => '/don/class/don.class.php', 'enabled' => isModEnabled('don')),
  4842. 'Societe' => '/societe/class/societe.class.php',
  4843. //'Categorie' => '/categories/class/categorie.class.php',
  4844. 'ActionComm' => '/comm/action/class/actioncomm.class.php',
  4845. 'Propal' => '/comm/propal/class/propal.class.php',
  4846. 'Commande' => '/commande/class/commande.class.php',
  4847. 'Facture' => '/compta/facture/class/facture.class.php',
  4848. 'FactureRec' => '/compta/facture/class/facture-rec.class.php',
  4849. 'LignePrelevement' => '/compta/prelevement/class/ligneprelevement.class.php',
  4850. 'Mo' => '/mrp/class/mo.class.php',
  4851. 'Contact' => '/contact/class/contact.class.php',
  4852. 'Contrat' => '/contrat/class/contrat.class.php',
  4853. 'Expedition' => '/expedition/class/expedition.class.php',
  4854. 'Fichinter' => '/fichinter/class/fichinter.class.php',
  4855. 'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php',
  4856. 'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php',
  4857. 'FactureFournisseurRec' => '/fourn/class/fournisseur.facture-rec.class.php',
  4858. 'Reception' => '/reception/class/reception.class.php',
  4859. 'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php',
  4860. 'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php',
  4861. 'Delivery' => '/delivery/class/delivery.class.php',
  4862. 'Product' => '/product/class/product.class.php',
  4863. 'Project' => '/projet/class/project.class.php',
  4864. 'Ticket' => array('file' => '/ticket/class/ticket.class.php', 'enabled' => isModEnabled('ticket')),
  4865. 'User' => '/user/class/user.class.php',
  4866. 'Account' => '/compta/bank/class/account.class.php',
  4867. 'ConferenceOrBoothAttendee' => '/eventorganization/class/conferenceorboothattendee.class.php'
  4868. );
  4869. //First, all core objects must update their tables
  4870. foreach ($objects as $object_name => $object_file) {
  4871. if (is_array($object_file)) {
  4872. if (empty($object_file['enabled'])) {
  4873. continue;
  4874. }
  4875. $object_file = $object_file['file'];
  4876. }
  4877. require_once DOL_DOCUMENT_ROOT.$object_file;
  4878. if (!$error && !$object_name::replaceThirdparty($this->db, $soc_origin->id, $this->id)) {
  4879. $error++;
  4880. $this->error = $this->db->lasterror();
  4881. break;
  4882. }
  4883. }
  4884. }
  4885. // External modules should update their ones too
  4886. if (!$error) {
  4887. $parameters = array('soc_origin' => $soc_origin->id, 'soc_dest' => $this->id);
  4888. $reshook = $hookmanager->executeHooks('replaceThirdparty', $parameters, $this, $action);
  4889. if ($reshook < 0) {
  4890. $this->error = $hookmanager->error;
  4891. $this->errors = $hookmanager->errors;
  4892. $error++;
  4893. }
  4894. }
  4895. if (!$error) {
  4896. $this->context = array('merge'=>1, 'mergefromid'=>$soc_origin->id, 'mergefromname'=>$soc_origin->name);
  4897. // Call trigger
  4898. $result = $this->call_trigger('COMPANY_MODIFY', $user);
  4899. if ($result < 0) {
  4900. $error++;
  4901. }
  4902. // End call triggers
  4903. }
  4904. if (!$error) {
  4905. // We finally remove the old thirdparty
  4906. if ($soc_origin->delete($soc_origin->id, $user) < 1) {
  4907. $this->error = $soc_origin->error;
  4908. $this->errors = $soc_origin->errors;
  4909. $error++;
  4910. }
  4911. }
  4912. if (!$error) {
  4913. $this->db->commit();
  4914. return 0;
  4915. } else {
  4916. $langs->load("errors");
  4917. $this->error = $langs->trans('ErrorsThirdpartyMerge');
  4918. $this->db->rollback();
  4919. return -1;
  4920. }
  4921. }
  4922. return -1;
  4923. }
  4924. }