card.php 178 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221
  1. <?php
  2. /* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
  5. * Copyright (C) 2005 Marc Barilley <marc@ocebo.fr>
  6. * Copyright (C) 2005-2013 Regis Houssin <regis.houssin@inodbox.com>
  7. * Copyright (C) 2010-2019 Juanjo Menent <jmenent@2byte.es>
  8. * Copyright (C) 2013-2022 Philippe Grand <philippe.grand@atoo-net.com>
  9. * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
  10. * Copyright (C) 2014-2016 Marcos García <marcosgdf@gmail.com>
  11. * Copyright (C) 2016-2023 Alexandre Spangaro <aspangaro@open-dsi.fr>
  12. * Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr>
  13. * Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
  14. * Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
  15. * Copyright (C) 2023 Nick Fragoulis
  16. *
  17. * This program is free software; you can redistribute it and/or modify
  18. * it under the terms of the GNU General Public License as published by
  19. * the Free Software Foundation; either version 3 of the License, or
  20. * (at your option) any later version.
  21. *
  22. * This program is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU General Public License for more details.
  26. *
  27. * You should have received a copy of the GNU General Public License
  28. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  29. */
  30. /**
  31. * \file htdocs/fourn/facture/card.php
  32. * \ingroup facture, fournisseur
  33. * \brief Page for supplier invoice card (view, edit, validate)
  34. */
  35. // Load Dolibarr environment
  36. require '../../main.inc.php';
  37. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
  38. require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
  39. require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_invoice/modules_facturefournisseur.php';
  40. require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
  41. require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture-rec.class.php';
  42. require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
  43. require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
  44. require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
  45. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  46. require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  47. require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
  48. if (isModEnabled("product")) {
  49. require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
  50. require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
  51. }
  52. if (isModEnabled('project')) {
  53. require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
  54. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
  55. }
  56. if (isModEnabled('variants')) {
  57. require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
  58. }
  59. if (isModEnabled('accounting')) {
  60. require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
  61. }
  62. $langs->loadLangs(array('bills', 'compta', 'suppliers', 'companies', 'products', 'banks', 'admin'));
  63. if (isModEnabled('incoterm')) {
  64. $langs->load('incoterm');
  65. }
  66. $id = (GETPOST('facid', 'int') ? GETPOST('facid', 'int') : GETPOST('id', 'int'));
  67. $action = GETPOST('action', 'aZ09');
  68. $confirm = GETPOST("confirm");
  69. $ref = GETPOST('ref', 'alpha');
  70. $cancel = GETPOST('cancel', 'alpha');
  71. $backtopage = GETPOST('backtopage', 'alpha');
  72. $backtopageforcancel = '';
  73. $lineid = GETPOST('lineid', 'int');
  74. $projectid = GETPOST('projectid', 'int');
  75. $origin = GETPOST('origin', 'alpha');
  76. $originid = GETPOST('originid', 'int');
  77. $fac_recid = GETPOST('fac_rec', 'int');
  78. $rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1;
  79. // PDF
  80. $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
  81. $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
  82. $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
  83. // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
  84. $hookmanager->initHooks(array('invoicesuppliercard', 'globalcard'));
  85. $object = new FactureFournisseur($db);
  86. $extrafields = new ExtraFields($db);
  87. // fetch optionals attributes and labels
  88. $extrafields->fetch_name_optionals_label($object->table_element);
  89. // Load object
  90. if ($id > 0 || !empty($ref)) {
  91. $ret = $object->fetch($id, $ref);
  92. if ($ret < 0) {
  93. dol_print_error($db, $object->error);
  94. }
  95. $ret = $object->fetch_thirdparty();
  96. if ($ret < 0) {
  97. dol_print_error($db, $object->error);
  98. }
  99. }
  100. // Security check
  101. $socid = GETPOST('socid', 'int');
  102. if (!empty($user->socid)) {
  103. $socid = $user->socid;
  104. }
  105. $isdraft = (($object->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0);
  106. $result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture', 'fk_soc', 'rowid', $isdraft);
  107. // Common permissions
  108. $usercanread = ($user->hasRight("fournisseur", "facture", "lire") || $user->hasRight("supplier_invoice", "lire"));
  109. $usercancreate = ($user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"));
  110. $usercandelete = ($user->hasRight("fournisseur", "facture", "supprimer") || $user->hasRight("supplier_invoice", "supprimer"));
  111. $usercancreatecontract = $user->hasRight("contrat", "creer");
  112. // Advanced permissions
  113. $usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("fournisseur", "supplier_invoice_advance", "validate")));
  114. $usercansend = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight("fournisseur", "supplier_invoice_advance", "send"));
  115. // Permissions for includes
  116. $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
  117. $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
  118. $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php
  119. $permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
  120. $error = 0;
  121. /*
  122. * Actions
  123. */
  124. $parameters = array('socid'=>$socid);
  125. $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
  126. if ($reshook < 0) {
  127. setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
  128. }
  129. if (empty($reshook)) {
  130. $backurlforlist = DOL_URL_ROOT.'/fourn/facture/list.php';
  131. if (empty($backtopage) || ($cancel && empty($id))) {
  132. if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
  133. if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
  134. $backtopage = $backurlforlist;
  135. } else {
  136. $backtopage = DOL_URL_ROOT.'/fourn/facture/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
  137. }
  138. }
  139. }
  140. if ($cancel) {
  141. if (!empty($backtopageforcancel)) {
  142. header("Location: ".$backtopageforcancel);
  143. exit;
  144. } elseif (!empty($backtopage)) {
  145. header("Location: ".$backtopage);
  146. exit;
  147. }
  148. $action = '';
  149. }
  150. include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once
  151. include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
  152. include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once
  153. // Link invoice to order
  154. if (GETPOST('linkedOrder') && empty($cancel) && $id > 0) {
  155. $object->fetch($id);
  156. $object->fetch_thirdparty();
  157. $result = $object->add_object_linked('order_supplier', GETPOST('linkedOrder'));
  158. }
  159. // Action clone object
  160. if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) {
  161. $objectutil = dol_clone($object, 1); // To avoid to denaturate loaded object when setting some properties for clone. We use native clone to keep this->db valid.
  162. if (GETPOST('newsupplierref', 'alphanohtml')) {
  163. $objectutil->ref_supplier = GETPOST('newsupplierref', 'alphanohtml');
  164. }
  165. $objectutil->date = dol_mktime(12, 0, 0, GETPOST('newdatemonth', 'int'), GETPOST('newdateday', 'int'), GETPOST('newdateyear', 'int'));
  166. $result = $objectutil->createFromClone($user, $id);
  167. if ($result > 0) {
  168. header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
  169. exit;
  170. } else {
  171. $langs->load("errors");
  172. setEventMessages($objectutil->error, $objectutil->errors, 'errors');
  173. $action = '';
  174. }
  175. } elseif ($action == 'confirm_valid' && $confirm == 'yes' && $usercanvalidate) {
  176. $idwarehouse = GETPOST('idwarehouse');
  177. $object->fetch($id);
  178. $object->fetch_thirdparty();
  179. $qualified_for_stock_change = 0;
  180. if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
  181. $qualified_for_stock_change = $object->hasProductsOrServices(2);
  182. } else {
  183. $qualified_for_stock_change = $object->hasProductsOrServices(1);
  184. }
  185. // Check parameters
  186. if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
  187. $langs->load("stocks");
  188. if (!$idwarehouse || $idwarehouse == -1) {
  189. $error++;
  190. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
  191. $action = '';
  192. }
  193. }
  194. if (!$error) {
  195. $db->begin();
  196. $result = $object->validate($user, '', $idwarehouse);
  197. if ($result < 0) {
  198. $db->rollback();
  199. setEventMessages($object->error, $object->errors, 'errors');
  200. } else {
  201. $db->commit();
  202. // Define output language
  203. if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
  204. $outputlangs = $langs;
  205. $newlang = '';
  206. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  207. $newlang = GETPOST('lang_id', 'aZ09');
  208. }
  209. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
  210. $newlang = $object->thirdparty->default_lang;
  211. }
  212. if (!empty($newlang)) {
  213. $outputlangs = new Translate("", $conf);
  214. $outputlangs->setDefaultLang($newlang);
  215. }
  216. $model = $object->model_pdf;
  217. $ret = $object->fetch($id); // Reload to get new records
  218. $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  219. if ($result < 0) {
  220. dol_print_error($db, $result);
  221. }
  222. }
  223. }
  224. }
  225. } elseif ($action == 'confirm_delete' && $confirm == 'yes') {
  226. $object->fetch($id);
  227. $object->fetch_thirdparty();
  228. $isErasable = $object->is_erasable();
  229. if (($usercandelete && $isErasable > 0) || ($usercancreate && $isErasable == 1)) {
  230. $revertstock = GETPOST('revertstock');
  231. if ($revertstock) {
  232. $idwarehouse = GETPOST('idwarehouse');
  233. $qualified_for_stock_change = 0;
  234. if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
  235. $qualified_for_stock_change = $object->hasProductsOrServices(2);
  236. } else {
  237. $qualified_for_stock_change = $object->hasProductsOrServices(1);
  238. }
  239. // Check parameters
  240. if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
  241. $langs->load("stocks");
  242. if (!$idwarehouse || $idwarehouse == -1) {
  243. $error++;
  244. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
  245. $action = 'delete';
  246. } else {
  247. $result = $object->setDraft($user, $idwarehouse);
  248. if ($result < 0) {
  249. $error++;
  250. }
  251. }
  252. }
  253. }
  254. if (!$error) {
  255. $result = $object->delete($user);
  256. if ($result > 0) {
  257. header('Location: list.php?restore_lastsearch_values=1');
  258. exit;
  259. } else {
  260. setEventMessages($object->error, $object->errors, 'errors');
  261. }
  262. }
  263. }
  264. } elseif ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) {
  265. // Remove a product line
  266. $result = $object->deleteline($lineid);
  267. if ($result > 0) {
  268. // reorder lines
  269. $object->line_order(true);
  270. // Define output language
  271. /*$outputlangs = $langs;
  272. $newlang = '';
  273. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id','aZ09'))
  274. $newlang = GETPOST('lang_id','aZ09');
  275. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang))
  276. $newlang = $object->thirdparty->default_lang;
  277. if (!empty($newlang)) {
  278. $outputlangs = new Translate("", $conf);
  279. $outputlangs->setDefaultLang($newlang);
  280. }
  281. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  282. $ret = $object->fetch($object->id); // Reload to get new records
  283. $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  284. }*/
  285. header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
  286. exit;
  287. } else {
  288. setEventMessages($object->error, $object->errors, 'errors');
  289. /* Fix bug 1485 : Reset action to avoid asking again confirmation on failure */
  290. $action = '';
  291. }
  292. } elseif ($action == 'unlinkdiscount' && $usercancreate) {
  293. // Delete link of credit note to invoice
  294. $discount = new DiscountAbsolute($db);
  295. $result = $discount->fetch(GETPOSTINT("discountid"));
  296. $discount->unlink_invoice();
  297. } elseif ($action == 'confirm_paid' && $confirm == 'yes' && $usercancreate) {
  298. $object->fetch($id);
  299. $result = $object->setPaid($user);
  300. if ($result < 0) {
  301. setEventMessages($object->error, $object->errors, 'errors');
  302. }
  303. } elseif ($action == 'confirm_paid_partially' && $confirm == 'yes') {
  304. // Classif "paid partialy"
  305. $object->fetch($id);
  306. $close_code = GETPOST("close_code", 'restricthtml');
  307. $close_note = GETPOST("close_note", 'restricthtml');
  308. if ($close_code) {
  309. $result = $object->setPaid($user, $close_code, $close_note);
  310. if ($result < 0) {
  311. setEventMessages($object->error, $object->errors, 'errors');
  312. }
  313. } else {
  314. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), null, 'errors');
  315. }
  316. } elseif ($action == 'confirm_canceled' && $confirm == 'yes') {
  317. // Classify "abandoned"
  318. $object->fetch($id);
  319. $close_code = GETPOST("close_code", 'restricthtml');
  320. $close_note = GETPOST("close_note", 'restricthtml');
  321. if ($close_code) {
  322. $result = $object->setCanceled($user, $close_code, $close_note);
  323. if ($result < 0) {
  324. setEventMessages($object->error, $object->errors, 'errors');
  325. }
  326. } else {
  327. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), null, 'errors');
  328. }
  329. }
  330. // Set supplier ref
  331. if ($action == 'setref_supplier' && $usercancreate) {
  332. $object->ref_supplier = GETPOST('ref_supplier', 'alpha');
  333. if ($object->update($user) < 0) {
  334. setEventMessages($object->error, $object->errors, 'errors');
  335. } else {
  336. // Define output language
  337. $outputlangs = $langs;
  338. $newlang = '';
  339. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  340. $newlang = GETPOST('lang_id', 'aZ09');
  341. }
  342. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
  343. $newlang = $object->thirdparty->default_lang;
  344. }
  345. if (!empty($newlang)) {
  346. $outputlangs = new Translate("", $conf);
  347. $outputlangs->setDefaultLang($newlang);
  348. }
  349. if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
  350. $ret = $object->fetch($object->id); // Reload to get new records
  351. $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  352. }
  353. }
  354. }
  355. // payments conditions
  356. if ($action == 'setconditions' && $usercancreate) {
  357. $object->fetch($id);
  358. $object->cond_reglement_code = 0; // To clean property
  359. $object->cond_reglement_id = 0; // To clean property
  360. $error = 0;
  361. $db->begin();
  362. if (!$error) {
  363. $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
  364. if ($result < 0) {
  365. $error++;
  366. setEventMessages($object->error, $object->errors, 'errors');
  367. }
  368. }
  369. if (!$error) {
  370. $old_date_echeance = $object->date_echeance;
  371. $new_date_echeance = $object->calculate_date_lim_reglement();
  372. if ($new_date_echeance > $old_date_echeance) {
  373. $object->date_echeance = $new_date_echeance;
  374. }
  375. if ($object->date_echeance < $object->date) {
  376. $object->date_echeance = $object->date;
  377. }
  378. $result = $object->update($user);
  379. if ($result < 0) {
  380. $error++;
  381. setEventMessages($object->error, $object->errors, 'errors');
  382. }
  383. }
  384. if ($error) {
  385. $db->rollback();
  386. } else {
  387. $db->commit();
  388. }
  389. } elseif ($action == 'set_incoterms' && isModEnabled('incoterm')) {
  390. // Set incoterm
  391. $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha'));
  392. } elseif ($action == 'setmode' && $usercancreate) {
  393. // payment mode
  394. $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
  395. } elseif ($action == 'setmulticurrencycode' && $usercancreate) {
  396. // Multicurrency Code
  397. $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
  398. } elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
  399. // Multicurrency rate
  400. $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx', 'alpha')), GETPOST('calculation_mode', 'int'));
  401. } elseif ($action == 'setbankaccount' && $usercancreate) {
  402. // bank account
  403. $result = $object->setBankAccount(GETPOST('fk_account', 'int'));
  404. } elseif ($action == 'setvatreversecharge' && $usercancreate) {
  405. // vat reverse charge
  406. $vatreversecharge = GETPOST('vat_reverse_charge') == 'on' ? 1 : 0;
  407. $result = $object->setVATReverseCharge($vatreversecharge);
  408. }
  409. if ($action == 'settransportmode' && ($user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"))) {
  410. // transport mode
  411. $result = $object->setTransportMode(GETPOST('transport_mode_id', 'int'));
  412. } elseif ($action == 'setlabel' && $usercancreate) {
  413. // Set label
  414. $object->fetch($id);
  415. $object->label = GETPOST('label');
  416. $result = $object->update($user);
  417. if ($result < 0) {
  418. dol_print_error($db);
  419. }
  420. } elseif ($action == 'setdatef' && $usercancreate) {
  421. $newdate = dol_mktime(0, 0, 0, GETPOST('datefmonth', 'int'), GETPOST('datefday', 'int'), GETPOST('datefyear', 'int'), 'tzserver');
  422. if ($newdate > (dol_now('tzuserrel') + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
  423. if (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY')) {
  424. setEventMessages($langs->trans("WarningInvoiceDateInFuture"), null, 'warnings');
  425. } else {
  426. setEventMessages($langs->trans("WarningInvoiceDateTooFarInFuture"), null, 'warnings');
  427. }
  428. }
  429. $object->fetch($id);
  430. $object->date = $newdate;
  431. $date_echence_calc = $object->calculate_date_lim_reglement();
  432. if (!empty($object->date_echeance) && $object->date_echeance < $date_echence_calc) {
  433. $object->date_echeance = $date_echence_calc;
  434. }
  435. if ($object->date_echeance && $object->date_echeance < $object->date) {
  436. $object->date_echeance = $object->date;
  437. }
  438. $result = $object->update($user);
  439. if ($result < 0) {
  440. dol_print_error($db, $object->error);
  441. }
  442. } elseif ($action == 'setdate_lim_reglement' && $usercancreate) {
  443. $object->fetch($id);
  444. $object->date_echeance = dol_mktime(12, 0, 0, GETPOST('date_lim_reglementmonth', 'int'), GETPOST('date_lim_reglementday', 'int'), GETPOST('date_lim_reglementyear', 'int'));
  445. if (!empty($object->date_echeance) && $object->date_echeance < $object->date) {
  446. $object->date_echeance = $object->date;
  447. setEventMessages($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), null, 'warnings');
  448. }
  449. $result = $object->update($user);
  450. if ($result < 0) {
  451. dol_print_error($db, $object->error);
  452. }
  453. } elseif ($action == "setabsolutediscount" && $usercancreate) {
  454. $db->begin();
  455. // We use the credit to reduce amount of invoice
  456. if (GETPOST("remise_id", "int")) {
  457. $ret = $object->fetch($id);
  458. if ($ret > 0) {
  459. $result = $object->insert_discount(GETPOST("remise_id", "int"));
  460. if ($result < 0) {
  461. setEventMessages($object->error, $object->errors, 'errors');
  462. }
  463. } else {
  464. dol_print_error($db, $object->error);
  465. }
  466. }
  467. // We use the credit to reduce remain to pay
  468. if (GETPOST("remise_id_for_payment", "int")) {
  469. require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
  470. $discount = new DiscountAbsolute($db);
  471. $discount->fetch(GETPOST("remise_id_for_payment", "int"));
  472. //var_dump($object->getRemainToPay(0));
  473. //var_dump($discount->amount_ttc);exit;
  474. $remaintopay = $object->getRemainToPay(0);
  475. if (price2num($discount->amount_ttc) > price2num($remaintopay)) {
  476. // TODO Split the discount in 2 automatically
  477. $error++;
  478. setEventMessages($langs->trans("ErrorDiscountLargerThanRemainToPaySplitItBefore"), null, 'errors');
  479. }
  480. if (!$error) {
  481. $result = $discount->link_to_invoice(0, $id);
  482. if ($result < 0) {
  483. $error++;
  484. setEventMessages($discount->error, $discount->errors, 'errors');
  485. }
  486. }
  487. if (!$error) {
  488. $newremaintopay = $object->getRemainToPay(0);
  489. if ($newremaintopay == 0) {
  490. $object->setPaid($user);
  491. }
  492. }
  493. }
  494. if (!$error) {
  495. $db->commit();
  496. } else {
  497. $db->rollback();
  498. }
  499. if (empty($error) && !getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
  500. $outputlangs = $langs;
  501. $newlang = '';
  502. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  503. $newlang = GETPOST('lang_id', 'aZ09');
  504. }
  505. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
  506. $newlang = $object->thirdparty->default_lang;
  507. }
  508. if (!empty($newlang)) {
  509. $outputlangs = new Translate("", $conf);
  510. $outputlangs->setDefaultLang($newlang);
  511. }
  512. $ret = $object->fetch($id); // Reload to get new records
  513. $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  514. if ($result < 0) {
  515. setEventMessages($object->error, $object->errors, 'errors');
  516. }
  517. }
  518. } elseif ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $usercancreate) {
  519. // Convertir en reduc
  520. $object->fetch($id);
  521. $object->fetch_thirdparty();
  522. //$object->fetch_lines(); // Already done into fetch
  523. // Check if there is already a discount (protection to avoid duplicate creation when resubmit post)
  524. $discountcheck = new DiscountAbsolute($db);
  525. $result = $discountcheck->fetch(0, 0, $object->id);
  526. $canconvert = 0;
  527. if ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discountcheck->id)) {
  528. $canconvert = 1; // we can convert deposit into discount if deposit is paid (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc)
  529. }
  530. if (($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) {
  531. $canconvert = 1; // we can convert credit note into discount if credit note is not refunded completely and not already converted and amount of payment is 0 (see also the real condition used as the condition to show button converttoreduc)
  532. }
  533. if ($canconvert) {
  534. $db->begin();
  535. $amount_ht = $amount_tva = $amount_ttc = array();
  536. $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array();
  537. // Loop on each vat rate
  538. $i = 0;
  539. foreach ($object->lines as $line) {
  540. if ($line->product_type < 9 && $line->total_ht != 0) { // Remove lines with product_type greater than or equal to 9 and no need to create discount if amount is null
  541. $keyforvatrate = $line->tva_tx.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : '');
  542. $amount_ht[$keyforvatrate] += $line->total_ht;
  543. $amount_tva[$keyforvatrate] += $line->total_tva;
  544. $amount_ttc[$keyforvatrate] += $line->total_ttc;
  545. $multicurrency_amount_ht[$keyforvatrate] += $line->multicurrency_total_ht;
  546. $multicurrency_amount_tva[$keyforvatrate] += $line->multicurrency_total_tva;
  547. $multicurrency_amount_ttc[$keyforvatrate] += $line->multicurrency_total_ttc;
  548. $i++;
  549. }
  550. }
  551. // If some payments were already done, we change the amount to pay using same prorate
  552. if (getDolGlobalString('SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED') && $object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
  553. $alreadypaid = $object->getSommePaiement(); // This can be not 0 if we allow to create credit to reuse from credit notes partially refunded.
  554. if ($alreadypaid && abs($alreadypaid) < abs($object->total_ttc)) {
  555. $ratio = abs(($object->total_ttc - $alreadypaid) / $object->total_ttc);
  556. foreach ($amount_ht as $vatrate => $val) {
  557. $amount_ht[$vatrate] = price2num($amount_ht[$vatrate] * $ratio, 'MU');
  558. $amount_tva[$vatrate] = price2num($amount_tva[$vatrate] * $ratio, 'MU');
  559. $amount_ttc[$vatrate] = price2num($amount_ttc[$vatrate] * $ratio, 'MU');
  560. $multicurrency_amount_ht[$vatrate] = price2num($multicurrency_amount_ht[$vatrate] * $ratio, 'MU');
  561. $multicurrency_amount_tva[$vatrate] = price2num($multicurrency_amount_tva[$vatrate] * $ratio, 'MU');
  562. $multicurrency_amount_ttc[$vatrate] = price2num($multicurrency_amount_ttc[$vatrate] * $ratio, 'MU');
  563. }
  564. }
  565. }
  566. //var_dump($amount_ht);var_dump($amount_tva);var_dump($amount_ttc);exit;
  567. // Insert one discount by VAT rate category
  568. $discount = new DiscountAbsolute($db);
  569. if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
  570. $discount->description = '(CREDIT_NOTE)';
  571. } elseif ($object->type == FactureFournisseur::TYPE_DEPOSIT) {
  572. $discount->description = '(DEPOSIT)';
  573. } elseif ($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_SITUATION) {
  574. $discount->description = '(EXCESS PAID)';
  575. } else {
  576. setEventMessages($langs->trans('CantConvertToReducAnInvoiceOfThisType'), null, 'errors');
  577. }
  578. $discount->discount_type = 1; // Supplier discount
  579. $discount->fk_soc = $object->socid;
  580. $discount->fk_invoice_supplier_source = $object->id;
  581. $error = 0;
  582. if ($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_SITUATION) {
  583. // If we're on a standard invoice, we have to get excess paid to create a discount in TTC without VAT
  584. // Total payments
  585. $sql = 'SELECT SUM(pf.amount) as total_paiements';
  586. $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf, '.MAIN_DB_PREFIX.'paiementfourn as p';
  587. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN ('.getEntity('c_paiement').')';
  588. $sql .= ' WHERE pf.fk_facturefourn = '.((int) $object->id);
  589. $sql .= ' AND pf.fk_paiementfourn = p.rowid';
  590. $sql .= ' AND p.entity IN ('.getEntity('invoice').')';
  591. $resql = $db->query($sql);
  592. if (!$resql) {
  593. dol_print_error($db);
  594. }
  595. $res = $db->fetch_object($resql);
  596. $total_paiements = $res->total_paiements;
  597. // Total credit note and deposit
  598. $total_creditnote_and_deposit = 0;
  599. $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
  600. $sql .= " re.description, re.fk_invoice_supplier_source";
  601. $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
  602. $sql .= " WHERE fk_invoice_supplier = ".((int) $object->id);
  603. $resql = $db->query($sql);
  604. if (!empty($resql)) {
  605. while ($obj = $db->fetch_object($resql)) {
  606. $total_creditnote_and_deposit += $obj->amount_ttc;
  607. }
  608. } else {
  609. dol_print_error($db);
  610. }
  611. $discount->amount_ht = $discount->amount_ttc = $total_paiements + $total_creditnote_and_deposit - $object->total_ttc;
  612. $discount->amount_tva = 0;
  613. $discount->tva_tx = 0;
  614. $discount->vat_src_code = '';
  615. $result = $discount->create($user);
  616. if ($result < 0) {
  617. $error++;
  618. }
  619. }
  620. if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
  621. foreach ($amount_ht as $tva_tx => $xxx) {
  622. $discount->amount_ht = abs($amount_ht[$tva_tx]);
  623. $discount->amount_tva = abs($amount_tva[$tva_tx]);
  624. $discount->amount_ttc = abs($amount_ttc[$tva_tx]);
  625. $discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]);
  626. $discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]);
  627. $discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
  628. // Clean vat code
  629. $reg = array();
  630. $vat_src_code = '';
  631. if (preg_match('/\((.*)\)/', $tva_tx, $reg)) {
  632. $vat_src_code = $reg[1];
  633. $tva_tx = preg_replace('/\s*\(.*\)/', '', $tva_tx); // Remove code into vatrate.
  634. }
  635. $discount->tva_tx = abs($tva_tx);
  636. $discount->vat_src_code = $vat_src_code;
  637. $result = $discount->create($user);
  638. if ($result < 0) {
  639. $error++;
  640. break;
  641. }
  642. }
  643. }
  644. if (empty($error)) {
  645. if ($object->type != FactureFournisseur::TYPE_DEPOSIT) {
  646. // Classe facture
  647. $result = $object->setPaid($user);
  648. if ($result >= 0) {
  649. $db->commit();
  650. } else {
  651. setEventMessages($object->error, $object->errors, 'errors');
  652. $db->rollback();
  653. }
  654. } else {
  655. $db->commit();
  656. }
  657. } else {
  658. setEventMessages($discount->error, $discount->errors, 'errors');
  659. $db->rollback();
  660. }
  661. }
  662. } elseif ($action == 'confirm_delete_paiement' && $confirm == 'yes' && $usercancreate) {
  663. // Delete payment
  664. $object->fetch($id);
  665. if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0) {
  666. $paiementfourn = new PaiementFourn($db);
  667. $result = $paiementfourn->fetch(GETPOST('paiement_id'));
  668. if ($result > 0) {
  669. $result = $paiementfourn->delete();
  670. if ($result > 0) {
  671. header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
  672. exit;
  673. }
  674. }
  675. if ($result < 0) {
  676. setEventMessages($paiementfourn->error, $paiementfourn->errors, 'errors');
  677. }
  678. }
  679. } elseif ($action == 'add' && $usercancreate) {
  680. // Insert new invoice in database
  681. if ($socid > 0) {
  682. $object->socid = GETPOST('socid', 'int');
  683. }
  684. $selectedLines = GETPOST('toselect', 'array');
  685. $db->begin();
  686. $error = 0;
  687. // Fill array 'array_options' with data from add form
  688. $ret = $extrafields->setOptionalsFromPost(null, $object);
  689. if ($ret < 0) {
  690. $error++;
  691. }
  692. $dateinvoice = dol_mktime(0, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'), 'tzserver'); // If we enter the 02 january, we need to save the 02 january for server
  693. $datedue = dol_mktime(0, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'), 'tzserver');
  694. //var_dump($dateinvoice.' '.dol_print_date($dateinvoice, 'dayhour'));
  695. //var_dump(dol_now('tzuserrel').' '.dol_get_last_hour(dol_now('tzuserrel')).' '.dol_print_date(dol_now('tzuserrel'),'dayhour').' '.dol_print_date(dol_get_last_hour(dol_now('tzuserrel')), 'dayhour'));
  696. //var_dump($db->idate($dateinvoice));
  697. //exit;
  698. // Replacement invoice
  699. if (GETPOST('type', 'int') === '') {
  700. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
  701. $error++;
  702. }
  703. if (GETPOST('type') == FactureFournisseur::TYPE_REPLACEMENT) {
  704. if (empty($dateinvoice)) {
  705. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors');
  706. $action = 'create';
  707. $_GET['socid'] = $_POST['socid'];
  708. $error++;
  709. } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
  710. $error++;
  711. setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
  712. $action = 'create';
  713. }
  714. if (!(GETPOST('fac_replacement', 'int') > 0)) {
  715. $error++;
  716. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), null, 'errors');
  717. }
  718. if (!$error) {
  719. // This is a replacement invoice
  720. $result = $object->fetch(GETPOST('fac_replacement', 'int'));
  721. $object->fetch_thirdparty();
  722. $object->ref = GETPOST('ref', 'alphanohtml');
  723. $object->ref_supplier = GETPOST('ref_supplier', 'alpha');
  724. $object->socid = GETPOST('socid', 'int');
  725. $object->libelle = GETPOST('label', 'alphanohtml'); // deprecated
  726. $object->label = GETPOST('label', 'alphanohtml');
  727. $object->date = $dateinvoice;
  728. $object->date_echeance = $datedue;
  729. $object->note_public = GETPOST('note_public', 'restricthtml');
  730. $object->note_private = GETPOST('note_private', 'restricthtml');
  731. $object->cond_reglement_id = GETPOST('cond_reglement_id', 'int');
  732. $object->mode_reglement_id = GETPOST('mode_reglement_id', 'int');
  733. $object->fk_account = GETPOST('fk_account', 'int');
  734. $object->vat_reverse_charge = GETPOST('vat_reverse_charge') == 'on' ? 1 : 0;
  735. $object->fk_project = ($tmpproject > 0) ? $tmpproject : null;
  736. $object->fk_incoterms = GETPOST('incoterm_id', 'int');
  737. $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
  738. $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
  739. $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
  740. $object->transport_mode_id = GETPOST('transport_mode_id', 'int');
  741. // Proprietes particulieres a facture de remplacement
  742. $object->fk_facture_source = GETPOST('fac_replacement', 'int');
  743. $object->type = FactureFournisseur::TYPE_REPLACEMENT;
  744. $id = $object->createFromCurrent($user);
  745. if ($id <= 0) {
  746. $error++;
  747. setEventMessages($object->error, $object->errors, 'errors');
  748. }
  749. }
  750. }
  751. // Credit note invoice
  752. if (GETPOST('type') == FactureFournisseur::TYPE_CREDIT_NOTE) {
  753. $sourceinvoice = GETPOST('fac_avoir', 'int');
  754. if (!($sourceinvoice > 0) && !getDolGlobalString('INVOICE_CREDIT_NOTE_STANDALONE')) {
  755. $error++;
  756. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CorrectInvoice")), null, 'errors');
  757. }
  758. if (GETPOST('socid', 'int') < 1) {
  759. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors');
  760. $action = 'create';
  761. $error++;
  762. }
  763. if (empty($dateinvoice)) {
  764. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors');
  765. $action = 'create';
  766. $_GET['socid'] = $_POST['socid'];
  767. $error++;
  768. } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
  769. $error++;
  770. setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
  771. $action = 'create';
  772. }
  773. if (!GETPOST('ref_supplier')) {
  774. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('RefSupplierBill')), null, 'errors');
  775. $action = 'create';
  776. $_GET['socid'] = $_POST['socid'];
  777. $error++;
  778. }
  779. if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED') && empty(GETPOST("subtype"))) {
  780. $error++;
  781. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("InvoiceSubtype")), null, 'errors');
  782. $action = 'create';
  783. }
  784. if (!$error) {
  785. $tmpproject = GETPOST('projectid', 'int');
  786. // Creation facture
  787. $object->ref = GETPOST('ref', 'alphanohtml');
  788. $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
  789. $object->subtype = GETPOST('subtype', 'alphanohtml');
  790. $object->socid = GETPOST('socid', 'int');
  791. $object->libelle = GETPOST('label', 'alphanohtml');
  792. $object->label = GETPOST('label', 'alphanohtml');
  793. $object->date = $dateinvoice;
  794. $object->date_echeance = $datedue;
  795. $object->note_public = GETPOST('note_public', 'restricthtml');
  796. $object->note_private = GETPOST('note_private', 'restricthtml');
  797. $object->cond_reglement_id = GETPOST('cond_reglement_id');
  798. $object->mode_reglement_id = GETPOST('mode_reglement_id');
  799. $object->fk_account = GETPOST('fk_account', 'int');
  800. $object->vat_reverse_charge = GETPOST('vat_reverse_charge') == 'on' ? 1 : 0;
  801. $object->fk_project = ($tmpproject > 0) ? $tmpproject : null;
  802. $object->fk_incoterms = GETPOST('incoterm_id', 'int');
  803. $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
  804. $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
  805. $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
  806. $object->transport_mode_id = GETPOST('transport_mode_id', 'int');
  807. // Proprietes particulieres a facture avoir
  808. $object->fk_facture_source = $sourceinvoice > 0 ? $sourceinvoice : '';
  809. $object->type = FactureFournisseur::TYPE_CREDIT_NOTE;
  810. $id = $object->create($user);
  811. if ($id <= 0) {
  812. $error++;
  813. }
  814. if (GETPOST('invoiceAvoirWithLines', 'int') == 1 && $id > 0) {
  815. $facture_source = new FactureFournisseur($db); // fetch origin object
  816. if ($facture_source->fetch($object->fk_facture_source) > 0) {
  817. $fk_parent_line = 0;
  818. foreach ($facture_source->lines as $line) {
  819. // Reset fk_parent_line for no child products and special product
  820. if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
  821. $fk_parent_line = 0;
  822. }
  823. $line->fk_facture_fourn = $object->id;
  824. $line->fk_parent_line = $fk_parent_line;
  825. $line->subprice = -$line->subprice; // invert price for object
  826. $line->pa_ht = -$line->pa_ht;
  827. $line->total_ht = -$line->total_ht;
  828. $line->total_tva = -$line->total_tva;
  829. $line->total_ttc = -$line->total_ttc;
  830. $line->total_localtax1 = -$line->total_localtax1;
  831. $line->total_localtax2 = -$line->total_localtax2;
  832. $result = $line->insert();
  833. $object->lines[] = $line; // insert new line in current object
  834. // Defined the new fk_parent_line
  835. if ($result > 0 && $line->product_type == 9) {
  836. $fk_parent_line = $result;
  837. }
  838. }
  839. $object->update_price(1);
  840. }
  841. }
  842. if (GETPOST('invoiceAvoirWithPaymentRestAmount', 'int') == 1 && $id > 0) {
  843. $facture_source = new FactureFournisseur($db); // fetch origin object if not previously defined
  844. if ($facture_source->fetch($object->fk_facture_source) > 0) {
  845. $totalpaid = $facture_source->getSommePaiement();
  846. $totalcreditnotes = $facture_source->getSumCreditNotesUsed();
  847. $totaldeposits = $facture_source->getSumDepositsUsed();
  848. $remain_to_pay = abs($facture_source->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits);
  849. $desc = $langs->trans('invoiceAvoirLineWithPaymentRestAmount');
  850. $retAddLine = $object->addline($desc, $remain_to_pay, 0, 0, 0, 1, 0, 0, '', '', 0, '', 'TTC');
  851. if ($retAddLine < 0) {
  852. $error++;
  853. }
  854. }
  855. }
  856. }
  857. } elseif ($fac_recid > 0 && (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)) {
  858. // Standard invoice or Deposit invoice, created from a Predefined template invoice
  859. if (empty($dateinvoice)) {
  860. $error++;
  861. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
  862. $action = 'create';
  863. } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
  864. $error++;
  865. setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
  866. $action = 'create';
  867. }
  868. if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED') && empty(GETPOST("subtype"))) {
  869. $error++;
  870. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("InvoiceSubtype")), null, 'errors');
  871. $action = 'create';
  872. }
  873. if (!$error) {
  874. $object->socid = GETPOST('socid', 'int');
  875. $object->type = GETPOST('type', 'alphanohtml');
  876. $object->subtype = GETPOST('subtype', 'alphanohtml');
  877. $object->ref = GETPOST('ref', 'alphanohtml');
  878. $object->date = $dateinvoice;
  879. $object->note_public = trim(GETPOST('note_public', 'restricthtml'));
  880. $object->note_private = trim(GETPOST('note_private', 'restricthtml'));
  881. $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
  882. $object->model_pdf = GETPOST('model', 'alphanohtml');
  883. $object->fk_project = GETPOST('projectid', 'int');
  884. $object->cond_reglement_id = (GETPOST('type') == 3 ? 1 : GETPOST('cond_reglement_id'));
  885. $object->mode_reglement_id = GETPOST('mode_reglement_id', 'int');
  886. $object->fk_account = GETPOST('fk_account', 'int');
  887. $object->amount = price2num(GETPOST('amount'));
  888. //$object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU');
  889. //$object->remise_percent = price2num(GETPOST('remise_percent'), '', 2);
  890. $object->fk_incoterms = GETPOST('incoterm_id', 'int');
  891. $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
  892. $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
  893. $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
  894. // Source facture
  895. $object->fac_rec = $fac_recid;
  896. $fac_rec = new FactureFournisseurRec($db);
  897. $fac_rec->fetch($object->fac_rec);
  898. $fac_rec->fetch_lines();
  899. $object->lines = $fac_rec->lines;
  900. $id = $object->create($user); // This include recopy of links from recurring invoice and recurring invoice lines
  901. }
  902. } elseif ($fac_recid <= 0 && (GETPOST('type') == FactureFournisseur::TYPE_STANDARD || GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT)) {
  903. // Standard invoice or Deposit invoice, not from a Predefined template invoice
  904. if (GETPOST('socid', 'int') < 1) {
  905. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors');
  906. $action = 'create';
  907. $error++;
  908. }
  909. if (empty($dateinvoice)) {
  910. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('DateInvoice')), null, 'errors');
  911. $action = 'create';
  912. $_GET['socid'] = $_POST['socid'];
  913. $error++;
  914. } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (!getDolGlobalString('INVOICE_MAX_FUTURE_DELAY') ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) {
  915. $error++;
  916. setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors');
  917. $action = 'create';
  918. }
  919. if (!GETPOST('ref_supplier')) {
  920. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('RefSupplierBill')), null, 'errors');
  921. $action = 'create';
  922. $_GET['socid'] = $_POST['socid'];
  923. $error++;
  924. }
  925. if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED') && empty(GETPOST("subtype"))) {
  926. $error++;
  927. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("InvoiceSubtype")), null, 'errors');
  928. $action = 'create';
  929. }
  930. if (!$error) {
  931. $tmpproject = GETPOST('projectid', 'int');
  932. // Creation invoice
  933. $object->socid = GETPOST('socid', 'int');
  934. $object->type = GETPOST('type', 'alphanohtml');
  935. $object->subtype = GETPOST('subtype', 'alphanohtml');
  936. $object->ref = GETPOST('ref', 'alphanohtml');
  937. $object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
  938. $object->socid = GETPOST('socid', 'int');
  939. $object->libelle = GETPOST('label', 'alphanohtml'); // deprecated
  940. $object->label = GETPOST('label', 'alphanohtml');
  941. $object->date = $dateinvoice;
  942. $object->date_echeance = $datedue;
  943. $object->note_public = GETPOST('note_public', 'restricthtml');
  944. $object->note_private = GETPOST('note_private', 'restricthtml');
  945. $object->cond_reglement_id = GETPOST('cond_reglement_id');
  946. $object->mode_reglement_id = GETPOST('mode_reglement_id');
  947. $object->fk_account = GETPOST('fk_account', 'int');
  948. $object->vat_reverse_charge = GETPOST('vat_reverse_charge') == 'on' ? 1 : 0;
  949. $object->fk_project = ($tmpproject > 0) ? $tmpproject : null;
  950. $object->fk_incoterms = GETPOST('incoterm_id', 'int');
  951. $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
  952. $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
  953. $object->multicurrency_tx = GETPOST('originmulticurrency_tx', 'int');
  954. $object->transport_mode_id = GETPOST('transport_mode_id');
  955. // Auto calculation of date due if not filled by user
  956. if (empty($object->date_echeance)) {
  957. $object->date_echeance = $object->calculate_date_lim_reglement();
  958. }
  959. $object->fetch_thirdparty();
  960. // If creation from another object of another module
  961. if (!$error && GETPOST('origin', 'alpha') && GETPOST('originid')) {
  962. // Parse element/subelement (ex: project_task)
  963. $element = $subelement = GETPOST('origin', 'alpha');
  964. /*if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'),$regs))
  965. {
  966. $element = $regs[1];
  967. $subelement = $regs[2];
  968. }*/
  969. // For compatibility
  970. if ($element == 'order') {
  971. $element = $subelement = 'commande';
  972. }
  973. if ($element == 'propal') {
  974. $element = 'comm/propal';
  975. $subelement = 'propal';
  976. }
  977. if ($element == 'contract') {
  978. $element = $subelement = 'contrat';
  979. }
  980. if ($element == 'order_supplier') {
  981. $element = 'fourn';
  982. $subelement = 'fournisseur.commande';
  983. }
  984. if ($element == 'project') {
  985. $element = 'projet';
  986. }
  987. $object->origin = GETPOST('origin', 'alpha');
  988. $object->origin_id = GETPOST('originid', 'int');
  989. require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
  990. $classname = ucfirst($subelement);
  991. if ($classname == 'Fournisseur.commande') {
  992. $classname = 'CommandeFournisseur';
  993. }
  994. $objectsrc = new $classname($db);
  995. $objectsrc->fetch($originid);
  996. $objectsrc->fetch_thirdparty();
  997. if (!empty($object->origin) && !empty($object->origin_id)) {
  998. $object->linkedObjectsIds[$object->origin] = $object->origin_id;
  999. }
  1000. // Add also link with order if object is reception
  1001. if ($object->origin == 'reception') {
  1002. $objectsrc->fetchObjectLinked();
  1003. if (count($objectsrc->linkedObjectsIds['order_supplier']) > 0) {
  1004. foreach ($objectsrc->linkedObjectsIds['order_supplier'] as $key => $value) {
  1005. $object->linkedObjectsIds['order_supplier'] = $value;
  1006. }
  1007. }
  1008. }
  1009. $id = $object->create($user);
  1010. // Add lines
  1011. if ($id > 0) {
  1012. require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
  1013. $classname = ucfirst($subelement);
  1014. if ($classname == 'Fournisseur.commande') {
  1015. $classname = 'CommandeFournisseur';
  1016. }
  1017. $srcobject = new $classname($db);
  1018. $result = $srcobject->fetch(GETPOST('originid', 'int'));
  1019. // If deposit invoice - down payment with 1 line (fixed amount or percent)
  1020. $typeamount = GETPOST('typedeposit', 'alpha');
  1021. if (GETPOST('type') == FactureFournisseur::TYPE_DEPOSIT && in_array($typeamount, array('amount', 'variable'))) {
  1022. $valuedeposit = price2num(GETPOST('valuedeposit', 'alpha'), 'MU');
  1023. // Define the array $amountdeposit
  1024. $amountdeposit = array();
  1025. if (getDolGlobalString('MAIN_DEPOSIT_MULTI_TVA')) {
  1026. if ($typeamount == 'amount') {
  1027. $amount = $valuedeposit;
  1028. } else {
  1029. $amount = $srcobject->total_ttc * ($valuedeposit / 100);
  1030. }
  1031. $TTotalByTva = array();
  1032. foreach ($srcobject->lines as &$line) {
  1033. if (!empty($line->special_code)) {
  1034. continue;
  1035. }
  1036. $TTotalByTva[$line->tva_tx] += $line->total_ttc;
  1037. }
  1038. foreach ($TTotalByTva as $tva => &$total) {
  1039. $coef = $total / $srcobject->total_ttc; // Calc coef
  1040. $am = $amount * $coef;
  1041. $amount_ttc_diff += $am;
  1042. $amountdeposit[$tva] += $am / (1 + $tva / 100); // Convert into HT for the addline
  1043. }
  1044. } else {
  1045. if ($typeamount == 'amount') {
  1046. $amountdeposit[0] = $valuedeposit;
  1047. } elseif ($typeamount == 'variable') {
  1048. if ($result > 0) {
  1049. $totalamount = 0;
  1050. $lines = $srcobject->lines;
  1051. $numlines = count($lines);
  1052. for ($i = 0; $i < $numlines; $i++) {
  1053. $qualified = 1;
  1054. if (empty($lines[$i]->qty)) {
  1055. $qualified = 0; // We discard qty=0, it is an option
  1056. }
  1057. if (!empty($lines[$i]->special_code)) {
  1058. $qualified = 0; // We discard special_code (frais port, ecotaxe, option, ...)
  1059. }
  1060. if ($qualified) {
  1061. $totalamount += $lines[$i]->total_ht; // Fixme : is it not for the customer ? Shouldn't we take total_ttc ?
  1062. $tva_tx = $lines[$i]->tva_tx;
  1063. $amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $valuedeposit) / 100;
  1064. }
  1065. }
  1066. if ($totalamount == 0) {
  1067. $amountdeposit[0] = 0;
  1068. }
  1069. } else {
  1070. setEventMessages($srcobject->error, $srcobject->errors, 'errors');
  1071. $error++;
  1072. }
  1073. }
  1074. $amount_ttc_diff = $amountdeposit[0];
  1075. }
  1076. foreach ($amountdeposit as $tva => $amount) {
  1077. if (empty($amount)) {
  1078. continue;
  1079. }
  1080. $arraylist = array(
  1081. 'amount' => 'FixAmount',
  1082. 'variable' => 'VarAmount'
  1083. );
  1084. $descline = '(DEPOSIT)';
  1085. //$descline.= ' - '.$langs->trans($arraylist[$typeamount]);
  1086. if ($typeamount == 'amount') {
  1087. $descline .= ' ('.price($valuedeposit, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).')';
  1088. } elseif ($typeamount == 'variable') {
  1089. $descline .= ' ('.$valuedeposit.'%)';
  1090. }
  1091. $descline .= ' - '.$srcobject->ref;
  1092. $result = $object->addline(
  1093. $descline,
  1094. $amount, // subprice
  1095. $tva, // vat rate
  1096. 0, // localtax1_tx
  1097. 0, // localtax2_tx
  1098. 1, // quantity
  1099. (!getDolGlobalString('INVOICE_PRODUCTID_DEPOSIT') ? 0 : $conf->global->INVOICE_PRODUCTID_DEPOSIT), // fk_product
  1100. 0, // remise_percent
  1101. 0, // date_start
  1102. 0, // date_end
  1103. 0,
  1104. $lines[$i]->info_bits, // info_bits
  1105. 'HT',
  1106. 0, // product_type
  1107. 1,
  1108. 0,
  1109. 0,
  1110. null,
  1111. $object->origin,
  1112. 0,
  1113. '',
  1114. $lines[$i]->special_code,
  1115. 0,
  1116. 0
  1117. //,$langs->trans('Deposit') //Deprecated
  1118. );
  1119. }
  1120. $diff = $object->total_ttc - $amount_ttc_diff;
  1121. if (getDolGlobalString('MAIN_DEPOSIT_MULTI_TVA') && $diff != 0) {
  1122. $object->fetch_lines();
  1123. $subprice_diff = $object->lines[0]->subprice - $diff / (1 + $object->lines[0]->tva_tx / 100);
  1124. $object->updateline(
  1125. $object->lines[0]->id,
  1126. $object->lines[0]->desc,
  1127. $subprice_diff,
  1128. $object->lines[0]->tva_tx,
  1129. $object->lines[0]->localtax1_tx,
  1130. $object->lines[0]->localtax2_tx,
  1131. $object->lines[0]->qty,
  1132. $object->lines[0]->fk_product,
  1133. 'HT',
  1134. $object->lines[0]->info_bits,
  1135. $object->lines[0]->product_type,
  1136. $object->lines[0]->remise_percent,
  1137. 0,
  1138. $object->lines[0]->date_start,
  1139. $object->lines[0]->date_end,
  1140. 0,
  1141. 0,
  1142. 0,
  1143. '',
  1144. 100
  1145. );
  1146. }
  1147. } elseif ($result > 0) {
  1148. $lines = $srcobject->lines;
  1149. if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
  1150. $srcobject->fetch_lines();
  1151. $lines = $srcobject->lines;
  1152. }
  1153. $num = count($lines);
  1154. for ($i = 0; $i < $num; $i++) { // TODO handle subprice < 0
  1155. if (!in_array($lines[$i]->id, $selectedLines)) {
  1156. continue; // Skip unselected lines
  1157. }
  1158. $desc = ($lines[$i]->desc ? $lines[$i]->desc : $lines[$i]->libelle);
  1159. $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
  1160. // Extrafields
  1161. if (method_exists($lines[$i], 'fetch_optionals')) {
  1162. $lines[$i]->fetch_optionals();
  1163. }
  1164. // Dates
  1165. // TODO mutualiser
  1166. $date_start = $lines[$i]->date_debut_prevue;
  1167. if ($lines[$i]->date_debut_reel) {
  1168. $date_start = $lines[$i]->date_debut_reel;
  1169. }
  1170. if ($lines[$i]->date_start) {
  1171. $date_start = $lines[$i]->date_start;
  1172. }
  1173. $date_end = $lines[$i]->date_fin_prevue;
  1174. if ($lines[$i]->date_fin_reel) {
  1175. $date_end = $lines[$i]->date_fin_reel;
  1176. }
  1177. if ($lines[$i]->date_end) {
  1178. $date_end = $lines[$i]->date_end;
  1179. }
  1180. // FIXME Missing special_code into addline and updateline methods
  1181. $object->special_code = $lines[$i]->special_code;
  1182. // FIXME If currency different from main currency, take multicurrency price
  1183. if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
  1184. $pu = 0;
  1185. $pu_currency = $lines[$i]->multicurrency_subprice;
  1186. } else {
  1187. $pu = $lines[$i]->subprice;
  1188. $pu_currency = 0;
  1189. }
  1190. // FIXME Missing $lines[$i]->ref_supplier and $lines[$i]->label into addline and updateline methods. They are filled when coming from order for example.
  1191. $result = $object->addline(
  1192. $desc,
  1193. $pu,
  1194. $lines[$i]->tva_tx,
  1195. $lines[$i]->localtax1_tx,
  1196. $lines[$i]->localtax2_tx,
  1197. $lines[$i]->qty,
  1198. $lines[$i]->fk_product,
  1199. $lines[$i]->remise_percent,
  1200. $date_start,
  1201. $date_end,
  1202. 0,
  1203. $lines[$i]->info_bits,
  1204. 'HT',
  1205. $product_type,
  1206. $lines[$i]->rang,
  1207. 0,
  1208. $lines[$i]->array_options,
  1209. $lines[$i]->fk_unit,
  1210. $lines[$i]->id,
  1211. $pu_currency,
  1212. $lines[$i]->ref_supplier,
  1213. $lines[$i]->special_code
  1214. );
  1215. if ($result < 0) {
  1216. $error++;
  1217. break;
  1218. }
  1219. }
  1220. // Now reload line
  1221. $object->fetch_lines();
  1222. } else {
  1223. $error++;
  1224. }
  1225. } else {
  1226. $error++;
  1227. }
  1228. } elseif (!$error) {
  1229. $id = $object->create($user);
  1230. if ($id < 0) {
  1231. $error++;
  1232. }
  1233. }
  1234. }
  1235. }
  1236. if ($error) {
  1237. $langs->load("errors");
  1238. $db->rollback();
  1239. setEventMessages($object->error, $object->errors, 'errors');
  1240. $action = 'create';
  1241. $_GET['socid'] = $_POST['socid'];
  1242. } else {
  1243. $db->commit();
  1244. if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
  1245. $outputlangs = $langs;
  1246. $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1247. if ($result < 0) {
  1248. dol_print_error($db, $object->error, $object->errors);
  1249. exit;
  1250. }
  1251. }
  1252. header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
  1253. exit;
  1254. }
  1255. } elseif ($action == 'updateline' && $usercancreate) {
  1256. // Edit line
  1257. $db->begin();
  1258. if (! $object->fetch($id) > 0) {
  1259. dol_print_error($db);
  1260. }
  1261. $object->fetch_thirdparty();
  1262. $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
  1263. $tva_tx = str_replace('*', '', $tva_tx);
  1264. if (GETPOST('price_ht') != '' || GETPOST('multicurrency_subprice') != '') {
  1265. $up = price2num(GETPOST('price_ht'), '', 2);
  1266. $price_base_type = 'HT';
  1267. } else {
  1268. $up = price2num(GETPOST('price_ttc'), '', 2);
  1269. $price_base_type = 'TTC';
  1270. }
  1271. if (GETPOST('productid') > 0) {
  1272. $productsupplier = new ProductFournisseur($db);
  1273. if (getDolGlobalString('SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY')) {
  1274. if (GETPOST('productid') > 0 && $productsupplier->get_buyprice(0, price2num(GETPOST('qty')), GETPOST('productid', 'int'), 'restricthtml', GETPOST('socid', 'int')) < 0) {
  1275. setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings');
  1276. }
  1277. }
  1278. $prod = new Product($db);
  1279. $prod->fetch(GETPOST('productid'));
  1280. $label = $prod->description;
  1281. if (trim(GETPOST('product_desc', 'restricthtml')) != trim($label)) {
  1282. $label = GETPOST('product_desc', 'restricthtml');
  1283. }
  1284. $type = $prod->type;
  1285. } else {
  1286. $label = GETPOST('product_desc', 'restricthtml');
  1287. $type = GETPOST("type") ? GETPOST("type") : 0;
  1288. }
  1289. $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
  1290. $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
  1291. // Define info_bits
  1292. $info_bits = 0;
  1293. if (preg_match('/\*/', $tva_tx)) {
  1294. $info_bits |= 0x01;
  1295. }
  1296. // Define vat_rate
  1297. $tva_tx = str_replace('*', '', $tva_tx);
  1298. $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
  1299. $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
  1300. $remise_percent = price2num(GETPOST('remise_percent'), '', 2);
  1301. $pu_devise = price2num(GETPOST('multicurrency_subprice'), 'MU', 2);
  1302. // Extrafields Lines
  1303. $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
  1304. $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
  1305. // Unset extrafield POST Data
  1306. if (is_array($extralabelsline)) {
  1307. foreach ($extralabelsline as $key => $value) {
  1308. unset($_POST["options_".$key]);
  1309. }
  1310. }
  1311. $result = $object->updateline(
  1312. GETPOST('lineid', 'int'),
  1313. $label,
  1314. $up,
  1315. $tva_tx,
  1316. $localtax1_tx,
  1317. $localtax2_tx,
  1318. price2num(GETPOST('qty'), 'MS'),
  1319. GETPOST('productid', 'int'),
  1320. $price_base_type,
  1321. $info_bits,
  1322. $type,
  1323. $remise_percent,
  1324. 0,
  1325. $date_start,
  1326. $date_end,
  1327. $array_options,
  1328. GETPOST('units', 'alpha'),
  1329. $pu_devise,
  1330. GETPOST('fourn_ref', 'alpha')
  1331. );
  1332. if ($result >= 0) {
  1333. unset($_POST['label']);
  1334. unset($_POST['fourn_ref']);
  1335. unset($_POST['date_starthour']);
  1336. unset($_POST['date_startmin']);
  1337. unset($_POST['date_startsec']);
  1338. unset($_POST['date_startday']);
  1339. unset($_POST['date_startmonth']);
  1340. unset($_POST['date_startyear']);
  1341. unset($_POST['date_endhour']);
  1342. unset($_POST['date_endmin']);
  1343. unset($_POST['date_endsec']);
  1344. unset($_POST['date_endday']);
  1345. unset($_POST['date_endmonth']);
  1346. unset($_POST['date_endyear']);
  1347. unset($_POST['price_ttc']);
  1348. unset($_POST['price_ht']);
  1349. $db->commit();
  1350. } else {
  1351. $db->rollback();
  1352. setEventMessages($object->error, $object->errors, 'errors');
  1353. }
  1354. } elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha') && $usercancreate) {
  1355. // Define vat_rate
  1356. $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
  1357. $vat_rate = str_replace('*', '', $vat_rate);
  1358. $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
  1359. $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
  1360. foreach ($object->lines as $line) {
  1361. $result = $object->updateline($line->id, $line->desc, $line->subprice, $vat_rate, $localtax1_rate, $localtax2_rate, $line->qty, $line->fk_product, 'HT', $line->info_bits, $line->product_type, $line->remise_percent, 0, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice, $line->ref_supplier, $line->rang);
  1362. }
  1363. } elseif ($action == 'addline' && $usercancreate) {
  1364. // Add a product line
  1365. $db->begin();
  1366. $ret = $object->fetch($id);
  1367. if ($ret < 0) {
  1368. dol_print_error($db, $object->error);
  1369. exit;
  1370. }
  1371. $ret = $object->fetch_thirdparty();
  1372. $langs->load('errors');
  1373. $error = 0;
  1374. // Set if we used free entry or predefined product
  1375. $predef = '';
  1376. $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
  1377. $date_start = dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
  1378. $date_end = dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year'));
  1379. $prod_entry_mode = GETPOST('prod_entry_mode');
  1380. if ($prod_entry_mode == 'free') {
  1381. $idprod = 0;
  1382. } else {
  1383. $idprod = GETPOST('idprod', 'int');
  1384. }
  1385. $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)'
  1386. $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
  1387. $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
  1388. $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
  1389. $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
  1390. $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
  1391. $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
  1392. if (empty($remise_percent)) {
  1393. $remise_percent = 0;
  1394. }
  1395. // Extrafields
  1396. $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
  1397. $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
  1398. // Unset extrafield
  1399. if (is_array($extralabelsline)) {
  1400. // Get extra fields
  1401. foreach ($extralabelsline as $key => $value) {
  1402. unset($_POST["options_".$key]);
  1403. }
  1404. }
  1405. if ($prod_entry_mode == 'free' && GETPOST('price_ht') < 0 && $qty < 0) {
  1406. setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPrice'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
  1407. $error++;
  1408. }
  1409. if ($prod_entry_mode == 'free' && !GETPOST('idprodfournprice') && GETPOST('type') < 0) {
  1410. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
  1411. $error++;
  1412. }
  1413. if ($prod_entry_mode == 'free' && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''
  1414. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('UnitPrice')), null, 'errors');
  1415. $error++;
  1416. }
  1417. if ($prod_entry_mode == 'free' && !GETPOST('dp_desc')) {
  1418. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
  1419. $error++;
  1420. }
  1421. if (!GETPOST('qty', 'alpha')) { // 0 is NOT allowed for invoices
  1422. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
  1423. $error++;
  1424. }
  1425. if (!$error && isModEnabled('variants') && $prod_entry_mode != 'free') {
  1426. if ($combinations = GETPOST('combinations', 'array')) {
  1427. //Check if there is a product with the given combination
  1428. $prodcomb = new ProductCombination($db);
  1429. if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
  1430. $idprod = $res->fk_product_child;
  1431. } else {
  1432. setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
  1433. $error++;
  1434. }
  1435. }
  1436. }
  1437. if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
  1438. $productsupplier = new ProductFournisseur($db);
  1439. $idprod = 0;
  1440. if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') {
  1441. $idprod = -99; // Same behaviour than with combolist. When not select idprodfournprice is now -99 (to avoid conflict with next action that may return -1, -2, ...)
  1442. }
  1443. $reg = array();
  1444. if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) {
  1445. $idprod = $reg[1];
  1446. $res = $productsupplier->fetch($idprod); // Load product from its id
  1447. // Call to init some price properties of $productsupplier
  1448. // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
  1449. if (getDolGlobalString('SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER')) {
  1450. $fksoctosearch = 0;
  1451. $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
  1452. if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price
  1453. $productsupplier->ref_supplier = '';
  1454. }
  1455. } else {
  1456. $fksoctosearch = $object->thirdparty->id;
  1457. $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
  1458. }
  1459. } elseif (GETPOST('idprodfournprice', 'alpha') > 0) {
  1460. $qtytosearch = $qty; // Just to see if a price exists for the quantity. Not used to found vat.
  1461. //$qtytosearch=-1; // We force qty to -1 to be sure to find if a supplier price exist
  1462. $idprod = $productsupplier->get_buyprice(GETPOST('idprodfournprice', 'alpha'), $qtytosearch);
  1463. $res = $productsupplier->fetch($idprod);
  1464. }
  1465. if ($idprod > 0) {
  1466. $label = $productsupplier->label;
  1467. // Define output language
  1468. if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
  1469. $outputlangs = $langs;
  1470. $newlang = '';
  1471. if (empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  1472. $newlang = GETPOST('lang_id', 'aZ09');
  1473. }
  1474. if (empty($newlang)) {
  1475. $newlang = $object->thirdparty->default_lang;
  1476. }
  1477. if (!empty($newlang)) {
  1478. $outputlangs = new Translate("", $conf);
  1479. $outputlangs->setDefaultLang($newlang);
  1480. }
  1481. $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description;
  1482. } else {
  1483. $desc = $productsupplier->description;
  1484. }
  1485. // if we use supplier description of the products
  1486. if (!empty($productsupplier->desc_supplier) && getDolGlobalString('PRODUIT_FOURN_TEXTS')) {
  1487. $desc = $productsupplier->desc_supplier;
  1488. }
  1489. //If text set in desc is the same as product descpription (as now it's preloaded) whe add it only one time
  1490. if (trim($product_desc) == trim($desc) && getDolGlobalString('PRODUIT_AUTOFILL_DESC')) {
  1491. $product_desc = '';
  1492. }
  1493. if (!empty($product_desc) && getDolGlobalString('MAIN_NO_CONCAT_DESCRIPTION')) {
  1494. $desc = $product_desc;
  1495. }
  1496. if (!empty($product_desc) && trim($product_desc) != trim($desc)) {
  1497. $desc = dol_concatdesc($desc, $product_desc, '', getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION'));
  1498. }
  1499. $ref_supplier = $productsupplier->ref_supplier;
  1500. // Get vat rate
  1501. if (!GETPOSTISSET('tva_tx')) { // If vat rate not provided from the form (the form has the priority)
  1502. $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha'));
  1503. $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha'));
  1504. }
  1505. if (empty($tva_tx)) {
  1506. $tva_npr = 0;
  1507. }
  1508. $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
  1509. $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
  1510. $type = $productsupplier->type;
  1511. if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
  1512. $price_base_type = 'HT';
  1513. $pu = price2num($price_ht, 'MU');
  1514. $pu_devise = price2num($price_ht_devise, 'CU');
  1515. } elseif (GETPOST('price_ttc') != '' || GETPOST('multicurrency_price_ttc') != '') {
  1516. $price_base_type = 'TTC';
  1517. $pu = price2num($price_ttc, 'MU');
  1518. $pu_devise = price2num($price_ttc_devise, 'CU');
  1519. } else {
  1520. $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT');
  1521. if (empty($object->multicurrency_code) || ($productsupplier->fourn_multicurrency_code != $object->multicurrency_code)) { // If object is in a different currency and price not in this currency
  1522. $pu = $productsupplier->fourn_pu;
  1523. $pu_devise = 0;
  1524. } else {
  1525. $pu = $productsupplier->fourn_pu;
  1526. $pu_devise = $productsupplier->fourn_multicurrency_unitprice;
  1527. }
  1528. }
  1529. $ref_supplier = $productsupplier->ref_supplier;
  1530. $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha'));
  1531. $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha'));
  1532. if (empty($tva_tx)) {
  1533. $tva_npr = 0;
  1534. }
  1535. $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
  1536. $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
  1537. if (empty($pu)) {
  1538. $pu = 0; // If pu is '' or null, we force to have a numeric value
  1539. }
  1540. $result = $object->addline(
  1541. $desc,
  1542. $pu,
  1543. $tva_tx,
  1544. $localtax1_tx,
  1545. $localtax2_tx,
  1546. $qty,
  1547. $idprod,
  1548. $remise_percent,
  1549. $date_start,
  1550. $date_end,
  1551. 0,
  1552. $tva_npr,
  1553. $price_base_type,
  1554. $type,
  1555. min($rank, count($object->lines) + 1),
  1556. 0,
  1557. $array_options,
  1558. $productsupplier->fk_unit,
  1559. 0,
  1560. $pu_devise,
  1561. GETPOST('fourn_ref', 'alpha'),
  1562. ''
  1563. );
  1564. }
  1565. if ($idprod == -99 || $idprod == 0) {
  1566. // Product not selected
  1567. $error++;
  1568. $langs->load("errors");
  1569. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
  1570. }
  1571. if ($idprod == -1) {
  1572. // Quantity too low
  1573. $error++;
  1574. $langs->load("errors");
  1575. setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors');
  1576. }
  1577. } elseif (empty($error)) { // $price_ht is already set
  1578. $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
  1579. $tva_tx = str_replace('*', '', $tva_tx);
  1580. $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
  1581. $desc = $product_desc;
  1582. $type = GETPOST('type');
  1583. $ref_supplier = GETPOST('fourn_ref', 'alpha');
  1584. $fk_unit = GETPOST('units', 'alpha');
  1585. if (!preg_match('/\((.*)\)/', $tva_tx)) {
  1586. $tva_tx = price2num($tva_tx); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1'
  1587. }
  1588. // Local Taxes
  1589. $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
  1590. $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
  1591. if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
  1592. $pu_ht = price2num($price_ht, 'MU'); // $pu_ht must be rounded according to settings
  1593. } else {
  1594. $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
  1595. $pu_ht = price2num($pu_ttc / (1 + ($tva_tx / 100)), 'MU'); // $pu_ht must be rounded according to settings
  1596. }
  1597. $price_base_type = 'HT';
  1598. $pu_devise = price2num($price_ht_devise, 'CU');
  1599. $result = $object->addline($product_desc, $pu_ht, $tva_tx, $localtax1_tx, $localtax2_tx, $qty, 0, $remise_percent, $date_start, $date_end, 0, $tva_npr, $price_base_type, $type, -1, 0, $array_options, $fk_unit, 0, $pu_devise, $ref_supplier);
  1600. }
  1601. //print "xx".$tva_tx; exit;
  1602. if (!$error && $result > 0) {
  1603. $db->commit();
  1604. // Define output language
  1605. if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
  1606. $outputlangs = $langs;
  1607. $newlang = '';
  1608. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  1609. $newlang = GETPOST('lang_id', 'aZ09');
  1610. }
  1611. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
  1612. $newlang = $object->thirdparty->default_lang;
  1613. }
  1614. if (!empty($newlang)) {
  1615. $outputlangs = new Translate("", $conf);
  1616. $outputlangs->setDefaultLang($newlang);
  1617. }
  1618. $model = $object->model_pdf;
  1619. $ret = $object->fetch($id); // Reload to get new records
  1620. $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1621. if ($result < 0) {
  1622. dol_print_error($db, $result);
  1623. }
  1624. }
  1625. unset($_POST ['prod_entry_mode']);
  1626. unset($_POST['qty']);
  1627. unset($_POST['type']);
  1628. unset($_POST['remise_percent']);
  1629. unset($_POST['pu']);
  1630. unset($_POST['price_ht']);
  1631. unset($_POST['multicurrency_price_ht']);
  1632. unset($_POST['price_ttc']);
  1633. unset($_POST['fourn_ref']);
  1634. unset($_POST['tva_tx']);
  1635. unset($_POST['label']);
  1636. unset($localtax1_tx);
  1637. unset($localtax2_tx);
  1638. unset($_POST['np_marginRate']);
  1639. unset($_POST['np_markRate']);
  1640. unset($_POST['dp_desc']);
  1641. unset($_POST['idprodfournprice']);
  1642. unset($_POST['units']);
  1643. unset($_POST['date_starthour']);
  1644. unset($_POST['date_startmin']);
  1645. unset($_POST['date_startsec']);
  1646. unset($_POST['date_startday']);
  1647. unset($_POST['date_startmonth']);
  1648. unset($_POST['date_startyear']);
  1649. unset($_POST['date_endhour']);
  1650. unset($_POST['date_endmin']);
  1651. unset($_POST['date_endsec']);
  1652. unset($_POST['date_endday']);
  1653. unset($_POST['date_endmonth']);
  1654. unset($_POST['date_endyear']);
  1655. } else {
  1656. $db->rollback();
  1657. setEventMessages($object->error, $object->errors, 'errors');
  1658. }
  1659. $action = '';
  1660. } elseif ($action == 'classin' && $usercancreate) {
  1661. $object->fetch($id);
  1662. $result = $object->setProject($projectid);
  1663. } elseif ($action == 'confirm_edit' && $confirm == 'yes' && $usercancreate) {
  1664. // Set invoice to draft status
  1665. $object->fetch($id);
  1666. $totalpaid = $object->getSommePaiement();
  1667. $resteapayer = $object->total_ttc - $totalpaid;
  1668. // We check that lines of invoices are exported in accountancy
  1669. $ventilExportCompta = $object->getVentilExportCompta();
  1670. if (!$ventilExportCompta) {
  1671. // On verifie si aucun paiement n'a ete effectue
  1672. if ($resteapayer == price2num($object->total_ttc, 'MT', 1) && $object->statut == FactureFournisseur::STATUS_VALIDATED) {
  1673. $idwarehouse = GETPOST('idwarehouse');
  1674. $object->fetch_thirdparty();
  1675. $qualified_for_stock_change = 0;
  1676. if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
  1677. $qualified_for_stock_change = $object->hasProductsOrServices(2);
  1678. } else {
  1679. $qualified_for_stock_change = $object->hasProductsOrServices(1);
  1680. }
  1681. // Check parameters
  1682. if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
  1683. $langs->load("stocks");
  1684. if (!$idwarehouse || $idwarehouse == -1) {
  1685. $error++;
  1686. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
  1687. $action = '';
  1688. }
  1689. }
  1690. $object->setDraft($user, $idwarehouse);
  1691. // Define output language
  1692. if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
  1693. $outputlangs = $langs;
  1694. $newlang = '';
  1695. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  1696. $newlang = GETPOST('lang_id', 'aZ09');
  1697. }
  1698. if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
  1699. $newlang = $object->thirdparty->default_lang;
  1700. }
  1701. if (!empty($newlang)) {
  1702. $outputlangs = new Translate("", $conf);
  1703. $outputlangs->setDefaultLang($newlang);
  1704. }
  1705. $model = $object->model_pdf;
  1706. $ret = $object->fetch($id); // Reload to get new records
  1707. $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1708. if ($result < 0) {
  1709. dol_print_error($db, $result);
  1710. }
  1711. }
  1712. $action = '';
  1713. }
  1714. }
  1715. } elseif ($action == 'reopen' && $usercancreate) {
  1716. // Set invoice to validated/unpaid status
  1717. $result = $object->fetch($id);
  1718. if ($object->statut == FactureFournisseur::STATUS_CLOSED
  1719. || ($object->statut == FactureFournisseur::STATUS_ABANDONED && $object->close_code != 'replaced')) {
  1720. $result = $object->setUnpaid($user);
  1721. if ($result > 0) {
  1722. header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
  1723. exit;
  1724. } else {
  1725. setEventMessages($object->error, $object->errors, 'errors');
  1726. }
  1727. }
  1728. }
  1729. // Actions when printing a doc from card
  1730. include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
  1731. // Actions to send emails
  1732. $triggersendname = 'BILL_SUPPLIER_SENTBYMAIL';
  1733. $paramname = 'id';
  1734. $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO';
  1735. $trackid = 'sinv'.$object->id;
  1736. include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
  1737. // Actions to build doc
  1738. $upload_dir = $conf->fournisseur->facture->dir_output;
  1739. $permissiontoadd = $usercancreate;
  1740. include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
  1741. // Make calculation according to calculationrule
  1742. if ($action == 'calculate') {
  1743. $calculationrule = GETPOST('calculationrule');
  1744. $object->fetch($id);
  1745. $object->fetch_thirdparty();
  1746. $result = $object->update_price(0, (($calculationrule == 'totalofround') ? '0' : '1'), 0, $object->thirdparty);
  1747. if ($result <= 0) {
  1748. dol_print_error($db, $result);
  1749. exit;
  1750. }
  1751. }
  1752. if ($action == 'update_extras') {
  1753. $object->oldcopy = dol_clone($object, 2);
  1754. // Fill array 'array_options' with data from add form
  1755. $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
  1756. if ($ret < 0) {
  1757. $error++;
  1758. }
  1759. if (!$error) {
  1760. // Actions on extra fields
  1761. if (!$error) {
  1762. $result = $object->insertExtraFields('BILL_SUPPLIER_MODIFY');
  1763. if ($result < 0) {
  1764. $error++;
  1765. }
  1766. }
  1767. }
  1768. if ($error) {
  1769. $action = 'edit_extras';
  1770. }
  1771. }
  1772. if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB') && $usercancreate) {
  1773. if ($action == 'addcontact') {
  1774. $result = $object->fetch($id);
  1775. if ($result > 0 && $id > 0) {
  1776. $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
  1777. $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
  1778. $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
  1779. }
  1780. if ($result >= 0) {
  1781. header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
  1782. exit;
  1783. } else {
  1784. if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
  1785. $langs->load("errors");
  1786. setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
  1787. } else {
  1788. setEventMessages($object->error, $object->errors, 'errors');
  1789. }
  1790. }
  1791. } elseif ($action == 'swapstatut') {
  1792. // bascule du statut d'un contact
  1793. if ($object->fetch($id)) {
  1794. $result = $object->swapContactStatus(GETPOST('ligne', 'int'));
  1795. } else {
  1796. dol_print_error($db);
  1797. }
  1798. } elseif ($action == 'deletecontact') {
  1799. // Efface un contact
  1800. $object->fetch($id);
  1801. $result = $object->delete_contact(GETPOST("lineid", 'int'));
  1802. if ($result >= 0) {
  1803. header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
  1804. exit;
  1805. } else {
  1806. dol_print_error($db);
  1807. }
  1808. }
  1809. }
  1810. }
  1811. /*
  1812. * View
  1813. */
  1814. $form = new Form($db);
  1815. $formfile = new FormFile($db);
  1816. $bankaccountstatic = new Account($db);
  1817. $paymentstatic = new PaiementFourn($db);
  1818. if (isModEnabled('project')) {
  1819. $formproject = new FormProjets($db);
  1820. }
  1821. $now = dol_now();
  1822. $title = $object->ref." - ".$langs->trans('Card');
  1823. if ($action == 'create') {
  1824. $title = $langs->trans("NewSupplierInvoice");
  1825. }
  1826. $help_url = 'EN:Module_Suppliers_Invoices|FR:Module_Fournisseurs_Factures|ES:Módulo_Facturas_de_proveedores|DE:Modul_Lieferantenrechnungen';
  1827. llxHeader('', $title, $help_url);
  1828. // Mode creation
  1829. if ($action == 'create') {
  1830. $facturestatic = new FactureFournisseur($db);
  1831. print load_fiche_titre($langs->trans('NewSupplierInvoice'), '', 'supplier_invoice');
  1832. dol_htmloutput_events();
  1833. $currency_code = $conf->currency;
  1834. $societe = '';
  1835. if (GETPOST('socid', 'int') > 0) {
  1836. $societe = new Societe($db);
  1837. $societe->fetch(GETPOST('socid', 'int'));
  1838. if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) {
  1839. $currency_code = $societe->multicurrency_code;
  1840. }
  1841. }
  1842. if (!empty($origin) && !empty($originid)) {
  1843. // Parse element/subelement (ex: project_task)
  1844. $element = $subelement = $origin;
  1845. if ($element == 'project') {
  1846. $projectid = $originid;
  1847. $element = 'projet';
  1848. }
  1849. // For compatibility
  1850. if ($element == 'order') {
  1851. $element = $subelement = 'commande';
  1852. }
  1853. if ($element == 'propal') {
  1854. $element = 'comm/propal';
  1855. $subelement = 'propal';
  1856. }
  1857. if ($element == 'contract') {
  1858. $element = $subelement = 'contrat';
  1859. }
  1860. if ($element == 'order_supplier') {
  1861. $element = 'fourn';
  1862. $subelement = 'fournisseur.commande';
  1863. }
  1864. require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php';
  1865. $classname = ucfirst($subelement);
  1866. if ($classname == 'Fournisseur.commande') {
  1867. $classname = 'CommandeFournisseur';
  1868. }
  1869. $objectsrc = new $classname($db);
  1870. $objectsrc->fetch($originid);
  1871. $objectsrc->fetch_thirdparty();
  1872. $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
  1873. //$ref_client = (!empty($objectsrc->ref_client)?$object->ref_client:'');
  1874. $soc = $objectsrc->thirdparty;
  1875. $cond_reglement_id = 0;
  1876. $mode_reglement_id = 0;
  1877. $fk_account = 0;
  1878. //$remise_percent = 0;
  1879. //$remise_absolue = 0;
  1880. $transport_mode_id = 0;
  1881. // set from object source
  1882. if (!empty($objectsrc->cond_reglement_id)) {
  1883. $cond_reglement_id = $objectsrc->cond_reglement_id;
  1884. }
  1885. if (!empty($objectsrc->mode_reglement_id)) {
  1886. $mode_reglement_id = $objectsrc->mode_reglement_id;
  1887. }
  1888. if (!empty($objectsrc->fk_account)) {
  1889. $fk_account = $objectsrc->fk_account;
  1890. }
  1891. if (!empty($objectsrc->transport_mode_id)) {
  1892. $transport_mode_id = $objectsrc->transport_mode_id;
  1893. }
  1894. if (empty($cond_reglement_id)
  1895. || empty($mode_reglement_id)
  1896. || empty($fk_account)
  1897. || empty($transport_mode_id)
  1898. ) {
  1899. if ($origin == 'reception') {
  1900. // try to get from source of reception (supplier order)
  1901. if (!isset($objectsrc->supplier_order)) {
  1902. $objectsrc->fetch_origin();
  1903. }
  1904. if (!empty($objectsrc->commandeFournisseur)) {
  1905. $supplierOrder = $objectsrc->commandeFournisseur;
  1906. if (empty($cond_reglement_id) && !empty($supplierOrder->cond_reglement_id)) {
  1907. $cond_reglement_id = $supplierOrder->cond_reglement_id;
  1908. }
  1909. if (empty($mode_reglement_id) && !empty($supplierOrder->mode_reglement_id)) {
  1910. $mode_reglement_id = $supplierOrder->mode_reglement_id;
  1911. }
  1912. if (empty($fk_account) && !empty($supplierOrder->fk_account)) {
  1913. $fk_account = $supplierOrder->fk_account;
  1914. }
  1915. if (empty($transport_mode_id) && !empty($supplierOrder->transport_mode_id)) {
  1916. $transport_mode_id = $supplierOrder->transport_mode_id;
  1917. }
  1918. }
  1919. }
  1920. // try to get from third-party of source object
  1921. if (!empty($soc)) {
  1922. if (empty($cond_reglement_id) && !empty($soc->cond_reglement_supplier_id)) {
  1923. $cond_reglement_id = $soc->cond_reglement_supplier_id;
  1924. }
  1925. if (empty($mode_reglement_id) && !empty($soc->mode_reglement_supplier_id)) {
  1926. $mode_reglement_id = $soc->mode_reglement_supplier_id;
  1927. }
  1928. if (empty($fk_account) && !empty($soc->fk_account)) {
  1929. $fk_account = $soc->fk_account;
  1930. }
  1931. if (empty($transport_mode_id) && !empty($soc->transport_mode_id)) {
  1932. $transport_mode_id = $soc->transport_mode_id;
  1933. }
  1934. }
  1935. }
  1936. if (isModEnabled("multicurrency")) {
  1937. if (!empty($objectsrc->multicurrency_code)) {
  1938. $currency_code = $objectsrc->multicurrency_code;
  1939. }
  1940. if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
  1941. $currency_tx = $objectsrc->multicurrency_tx;
  1942. }
  1943. }
  1944. $datetmp = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
  1945. $dateinvoice = ($datetmp == '' ? (!getDolGlobalString('MAIN_AUTOFILL_DATE') ? -1 : '') : $datetmp);
  1946. $datetmp = dol_mktime(12, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'));
  1947. $datedue = ($datetmp == '' ? -1 : $datetmp);
  1948. // Replicate extrafields
  1949. $objectsrc->fetch_optionals();
  1950. $object->array_options = $objectsrc->array_options;
  1951. } else {
  1952. $cond_reglement_id = !empty($societe->cond_reglement_supplier_id) ? $societe->cond_reglement_supplier_id : 0;
  1953. $mode_reglement_id = !empty($societe->mode_reglement_supplier_id) ? $societe->mode_reglement_supplier_id : 0;
  1954. $vat_reverse_charge = (empty($societe) ? '' : $societe->vat_reverse_charge);
  1955. $transport_mode_id = !empty($societe->transport_mode_supplier_id) ? $societe->transport_mode_supplier_id : 0;
  1956. $fk_account = !empty($societe->fk_account) ? $societe->fk_account : 0;
  1957. $datetmp = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
  1958. $dateinvoice = ($datetmp == '' ? (getDolGlobalInt('MAIN_AUTOFILL_DATE') ? '' : -1) : $datetmp);
  1959. $datetmp = dol_mktime(12, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'));
  1960. $datedue = ($datetmp == '' ? -1 : $datetmp);
  1961. if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) {
  1962. $currency_code = $soc->multicurrency_code;
  1963. }
  1964. }
  1965. // when payment condition is empty (means not override by payment condition form a other object, like third-party), try to use default value
  1966. if (empty($cond_reglement_id)) {
  1967. $cond_reglement_id = GETPOST("cond_reglement_id");
  1968. }
  1969. // when payment mode is empty (means not override by payment condition form a other object, like third-party), try to use default value
  1970. if (empty($mode_reglement_id)) {
  1971. $mode_reglement_id = GETPOST("mode_reglement_id");
  1972. }
  1973. // If form was posted (but error returned), we must reuse the value posted in priority (standard Dolibarr behaviour)
  1974. if (!GETPOST('changecompany')) {
  1975. if (GETPOSTISSET('cond_reglement_id')) {
  1976. $cond_reglement_id = GETPOST('cond_reglement_id', 'int');
  1977. }
  1978. if (GETPOSTISSET('mode_reglement_id')) {
  1979. $mode_reglement_id = GETPOST('mode_reglement_id', 'int');
  1980. }
  1981. if (GETPOSTISSET('cond_reglement_id')) {
  1982. $fk_account = GETPOST('fk_account', 'int');
  1983. }
  1984. }
  1985. $note_public = $object->getDefaultCreateValueFor('note_public', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && getDolGlobalString('FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM')) ? $objectsrc->note_public : null));
  1986. $note_private = $object->getDefaultCreateValueFor('note_private', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && getDolGlobalString('FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM')) ? $objectsrc->note_private : null));
  1987. if ($origin == 'contrat') {
  1988. $langs->load("admin");
  1989. $text = $langs->trans("ToCreateARecurringInvoice");
  1990. $text .= ' '.$langs->trans("ToCreateARecurringInvoiceGene", $langs->transnoentitiesnoconv("MenuFinancial"), $langs->transnoentitiesnoconv("SupplierBills"), $langs->transnoentitiesnoconv("ListOfTemplates"));
  1991. if (!getDolGlobalString('INVOICE_DISABLE_AUTOMATIC_RECURRING_INVOICE')) {
  1992. $text .= ' '.$langs->trans("ToCreateARecurringInvoiceGeneAuto", $langs->transnoentitiesnoconv('Module2300Name'));
  1993. }
  1994. print info_admin($text, 0, 0, 0, 'opacitymedium').'<br>';
  1995. }
  1996. print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="post">';
  1997. print '<input type="hidden" name="token" value="'.newToken().'">';
  1998. print '<input type="hidden" name="action" value="add">';
  1999. print '<input type="hidden" name="changecompany" value="0">'; // will be set to 1 by javascript so we know post is done after a company change
  2000. if (!empty($societe->id) && $societe->id > 0) {
  2001. print '<input type="hidden" name="socid" value="'.$societe->id.'">'."\n";
  2002. }
  2003. print '<input type="hidden" name="origin" value="'.$origin.'">';
  2004. print '<input type="hidden" name="originid" value="'.$originid.'">';
  2005. if (!empty($currency_tx)) {
  2006. print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
  2007. }
  2008. print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
  2009. print dol_get_fiche_head();
  2010. // Call Hook tabContentCreateSupplierInvoice
  2011. $parameters = array();
  2012. // Note that $action and $object may be modified by hook
  2013. $reshook = $hookmanager->executeHooks('tabContentCreateSupplierInvoice', $parameters, $object, $action);
  2014. if (empty($reshook)) {
  2015. print '<table class="border centpercent">';
  2016. // Ref
  2017. print '<tr><td class="titlefieldcreate">'.$langs->trans('Ref').'</td><td>'.$langs->trans('Draft').'</td></tr>';
  2018. $exampletemplateinvoice = new FactureFournisseurRec($db);
  2019. $invoice_predefined = new FactureFournisseurRec($db);
  2020. if (empty($origin) && empty($originid) && $fac_recid > 0) {
  2021. $invoice_predefined->fetch($fac_recid);
  2022. }
  2023. // Third party
  2024. print '<tr><td class="fieldrequired">'.$langs->trans('Supplier').'</td>';
  2025. print '<td>';
  2026. if (!empty($societe->id) && $societe->id > 0 && ($fac_recid <= 0 || !empty($invoice_predefined->frequency))) {
  2027. $absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1);
  2028. print $societe->getNomUrl(1, 'supplier');
  2029. print '<input type="hidden" name="socid" value="'.$societe->id.'">';
  2030. } else {
  2031. $filter = '((s.fournisseur:=:1) AND (s.status:=:1))';
  2032. print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(empty($societe->id) ? 0 : $societe->id, 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 widthcentpercentminusxx maxwidth500');
  2033. // reload page to retrieve supplier informations
  2034. if (!getDolGlobalString('RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED')) {
  2035. print '<script type="text/javascript">
  2036. $(document).ready(function() {
  2037. $("#socid").change(function() {
  2038. console.log("We have changed the company - Reload page");
  2039. // reload page
  2040. $("input[name=action]").val("create");
  2041. $("input[name=changecompany]").val("1");
  2042. $("form[name=add]").submit();
  2043. });
  2044. });
  2045. </script>';
  2046. }
  2047. if ($fac_recid <= 0) {
  2048. print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&client=0&fournisseur=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span></a>';
  2049. }
  2050. }
  2051. print '</td></tr>';
  2052. // Overwrite some values if creation of invoice is from a predefined invoice
  2053. if (empty($origin) && empty($originid) && $fac_recid > 0) {
  2054. $invoice_predefined->fetch($fac_recid);
  2055. $dateinvoice = $invoice_predefined->date_when; // To use next gen date by default later
  2056. if (empty($projectid)) {
  2057. $projectid = $invoice_predefined->fk_project;
  2058. }
  2059. $cond_reglement_id = $invoice_predefined->cond_reglement_id;
  2060. $mode_reglement_id = $invoice_predefined->mode_reglement_id;
  2061. $fk_account = $invoice_predefined->fk_account;
  2062. $note_public = $invoice_predefined->note_public;
  2063. $note_private = $invoice_predefined->note_private;
  2064. if (!empty($invoice_predefined->multicurrency_code)) {
  2065. $currency_code = $invoice_predefined->multicurrency_code;
  2066. }
  2067. if (!empty($invoice_predefined->multicurrency_tx)) {
  2068. $currency_tx = $invoice_predefined->multicurrency_tx;
  2069. }
  2070. $sql = 'SELECT r.rowid, r.titre as title, r.total_ttc';
  2071. $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn_rec as r';
  2072. $sql .= ' WHERE r.fk_soc = '. (int) $invoice_predefined->socid;
  2073. $resql = $db->query($sql);
  2074. if ($resql) {
  2075. $num = $db->num_rows($resql);
  2076. $i = 0;
  2077. if ($num > 0) {
  2078. print '<tr><td>'.$langs->trans('CreateFromRepeatableInvoice').'</td><td>';
  2079. //print '<input type="hidden" name="fac_rec" id="fac_rec" value="'.$fac_recid.'">';
  2080. print '<select class="flat" id="fac_rec" name="fac_rec">'; // We may want to change the template to use
  2081. print '<option value="0" selected></option>';
  2082. while ($i < $num) {
  2083. $objp = $db->fetch_object($resql);
  2084. print '<option value="'.$objp->rowid.'"';
  2085. if ($fac_recid == $objp->rowid) {
  2086. print ' selected';
  2087. $exampletemplateinvoice->fetch($fac_recid);
  2088. }
  2089. print '>'.$objp->title.' ('.price($objp->total_ttc).' '.$langs->trans("TTC").')</option>';
  2090. $i++;
  2091. }
  2092. print '</select>';
  2093. // Option to reload page to retrieve customer informations. Note, this clear other input
  2094. if (!getDolGlobalString('RELOAD_PAGE_ON_TEMPLATE_CHANGE_DISABLED')) {
  2095. print '<script type="text/javascript">
  2096. $(document).ready(function() {
  2097. $("#fac_rec").change(function() {
  2098. console.log("We have changed the template invoice - Reload page");
  2099. // reload page
  2100. $("input[name=action]").val("create");
  2101. $("form[name=add]").submit();
  2102. });
  2103. });
  2104. </script>';
  2105. }
  2106. print '</td></tr>';
  2107. }
  2108. $db->free($resql);
  2109. } else {
  2110. dol_print_error($db);
  2111. }
  2112. }
  2113. // Ref supplier
  2114. print '<tr><td class="fieldrequired">'.$langs->trans('RefSupplierBill').'</td><td><input name="ref_supplier" value="'.(GETPOSTISSET('ref_supplier') ? GETPOST('ref_supplier') : (!empty($objectsrc->ref_supplier) ? $objectsrc->ref_supplier : '')).'" type="text"';
  2115. if (!empty($societe->id) && $societe->id > 0) {
  2116. print ' autofocus';
  2117. }
  2118. print '></td>';
  2119. print '</tr>';
  2120. print '<tr><td class="tdtop fieldrequired">'.$langs->trans('Type').'</td><td>';
  2121. print '<div class="tagtable">'."\n";
  2122. // Standard invoice
  2123. print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
  2124. $tmp = '<input type="radio" id="radio_standard" name="type" value="0"'.(GETPOST('type', 'int') ? '' : 'checked').'> ';
  2125. $desc = $form->textwithpicto($tmp.'<label for="radio_standard">'.$langs->trans("InvoiceStandardAsk").'</label>', $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3);
  2126. print $desc;
  2127. print '</div></div>';
  2128. if (empty($origin) || ($origin == 'order_supplier' && !empty($originid))) {
  2129. // Deposit - Down payment
  2130. if (!getDolGlobalString('INVOICE_DISABLE_DEPOSIT')) {
  2131. print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
  2132. $tmp='<input type="radio" id="radio_deposit" name="type" value="3"' . (GETPOST('type') == 3 ? ' checked' : '') . '> ';
  2133. print '<script type="text/javascript">
  2134. jQuery(document).ready(function() {
  2135. jQuery("#typestandardinvoice, #valuestandardinvoice").click(function() {
  2136. jQuery("#radio_standard").prop("checked", true);
  2137. });
  2138. jQuery("#typedeposit, #valuedeposit").click(function() {
  2139. jQuery("#radio_deposit").prop("checked", true);
  2140. });
  2141. jQuery("#typedeposit").change(function() {
  2142. console.log("We change type of down payment");
  2143. jQuery("#radio_deposit").prop("checked", true);
  2144. setRadioForTypeOfInvoice();
  2145. });
  2146. jQuery("#radio_standard, #radio_deposit, #radio_replacement, #radio_template").change(function() {
  2147. setRadioForTypeOfInvoice();
  2148. });
  2149. function setRadioForTypeOfInvoice() {
  2150. console.log("Change radio");
  2151. if (jQuery("#radio_deposit").prop("checked") && (jQuery("#typedeposit").val() == \'amount\' || jQuery("#typedeposit").val() == \'variable\')) {
  2152. jQuery(".checkforselect").prop("disabled", true);
  2153. jQuery(".checkforselect").prop("checked", false);
  2154. } else {
  2155. jQuery(".checkforselect").prop("disabled", false);
  2156. jQuery(".checkforselect").prop("checked", true);
  2157. }
  2158. }
  2159. });
  2160. </script>';
  2161. $tmp = $tmp.'<label for="radio_deposit" >'.$langs->trans("InvoiceDeposit").'</label>';
  2162. $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
  2163. print '<table class="nobordernopadding"><tr>';
  2164. print '<td>';
  2165. print $desc;
  2166. print '</td>';
  2167. if ($origin == 'order_supplier') {
  2168. print '<td class="nowrap" style="padding-left: 15px">';
  2169. $arraylist = array(
  2170. 'amount' => $langs->transnoentitiesnoconv('FixAmount', $langs->transnoentitiesnoconv('Deposit')),
  2171. 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')),
  2172. 'variablealllines' => $langs->transnoentitiesnoconv('VarAmountAllLines')
  2173. );
  2174. print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit', 'aZ09'), 0, 0, 0, '', 1);
  2175. print '</td>';
  2176. print '<td class="nowrap" style="padding-left: 5px">';
  2177. print '<span class="opacitymedium paddingleft">'.$langs->trans("AmountOrPercent").'</span><input type="text" id="valuedeposit" name="valuedeposit" class="width75 right" value="' . GETPOST('valuedeposit', 'int') . '"/>';
  2178. print '</td>';
  2179. }
  2180. print '</tr></table>';
  2181. print '</div></div>';
  2182. }
  2183. }
  2184. /* Not yet supported for supplier
  2185. if ($societe->id > 0)
  2186. {
  2187. // Replacement
  2188. if (empty($conf->global->INVOICE_DISABLE_REPLACEMENT))
  2189. {
  2190. // Type invoice
  2191. $facids = $facturestatic->list_replacable_supplier_invoices($societe->id);
  2192. if ($facids < 0) {
  2193. dol_print_error($db, $facturestatic->error, $facturestatic->errors);
  2194. exit();
  2195. }
  2196. $options = "";
  2197. foreach ($facids as $facparam)
  2198. {
  2199. $options .= '<option value="' . $facparam ['id'] . '"';
  2200. if ($facparam ['id'] == GETPOST('fac_replacement') {
  2201. $options .= ' selected';
  2202. }
  2203. $options .= '>' . $facparam ['ref'];
  2204. $options .= ' (' . $facturestatic->LibStatut(0, $facparam ['status']) . ')';
  2205. $options .= '</option>';
  2206. }
  2207. print '<!-- replacement line -->';
  2208. print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
  2209. $tmp='<input type="radio" name="type" id="radio_replacement" value="1"' . (GETPOST('type') == 1 ? ' checked' : '');
  2210. if (! $options) $tmp.=' disabled';
  2211. $tmp.='> ';
  2212. print '<script type="text/javascript">
  2213. jQuery(document).ready(function() {
  2214. jQuery("#fac_replacement").change(function() {
  2215. jQuery("#radio_replacement").prop("checked", true);
  2216. });
  2217. });
  2218. </script>';
  2219. $text = $tmp.$langs->trans("InvoiceReplacementAsk") . ' ';
  2220. $text .= '<select class="flat" name="fac_replacement" id="fac_replacement"';
  2221. if (! $options)
  2222. $text .= ' disabled';
  2223. $text .= '>';
  2224. if ($options) {
  2225. $text .= '<option value="-1">&nbsp;</option>';
  2226. $text .= $options;
  2227. } else {
  2228. $text .= '<option value="-1">' . $langs->trans("NoReplacableInvoice") . '</option>';
  2229. }
  2230. $text .= '</select>';
  2231. $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
  2232. print $desc;
  2233. print '</div></div>';
  2234. }
  2235. }
  2236. else
  2237. {
  2238. print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
  2239. $tmp='<input type="radio" name="type" id="radio_replacement" value="0" disabled> ';
  2240. $text = $tmp.$langs->trans("InvoiceReplacement") . ' ';
  2241. $text.= '('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").') ';
  2242. $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
  2243. print $desc;
  2244. print '</div></div>';
  2245. }
  2246. */
  2247. if (empty($origin)) {
  2248. if (!empty($societe->id) && $societe->id > 0) {
  2249. // Credit note
  2250. if (!getDolGlobalString('INVOICE_DISABLE_CREDIT_NOTE')) {
  2251. // Show link for credit note
  2252. $facids = $facturestatic->list_qualified_avoir_supplier_invoices($societe->id);
  2253. if ($facids < 0) {
  2254. dol_print_error($db, $facturestatic->error, $facturestatic->errors);
  2255. exit;
  2256. }
  2257. $optionsav = "";
  2258. $newinvoice_static = new FactureFournisseur($db);
  2259. foreach ($facids as $key => $valarray) {
  2260. $newinvoice_static->id = $key;
  2261. $newinvoice_static->ref = $valarray ['ref'];
  2262. $newinvoice_static->statut = $valarray ['status'];
  2263. $newinvoice_static->type = $valarray ['type'];
  2264. $newinvoice_static->paye = $valarray ['paye'];
  2265. $optionsav .= '<option value="'.$key.'"';
  2266. if ($key == GETPOST('fac_avoir', 'int')) {
  2267. $optionsav .= ' selected';
  2268. }
  2269. $optionsav .= '>';
  2270. $optionsav .= $newinvoice_static->ref;
  2271. $optionsav .= ' ('.$newinvoice_static->getLibStatut(1, $valarray ['paymentornot']).')';
  2272. $optionsav .= '</option>';
  2273. }
  2274. print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
  2275. $tmp = '<input type="radio" id="radio_creditnote" name="type" value="2"'.(GETPOST('type') == 2 ? ' checked' : '');
  2276. if (!$optionsav && !getDolGlobalString('INVOICE_CREDIT_NOTE_STANDALONE')) {
  2277. $tmp .= ' disabled';
  2278. }
  2279. $tmp .= '> ';
  2280. // Show credit note options only if we checked credit note
  2281. print '<script type="text/javascript">
  2282. jQuery(document).ready(function() {
  2283. if (! jQuery("#radio_creditnote").is(":checked"))
  2284. {
  2285. jQuery("#credit_note_options").hide();
  2286. }
  2287. jQuery("#radio_creditnote").click(function() {
  2288. jQuery("#credit_note_options").show();
  2289. });
  2290. jQuery("#radio_standard, #radio_replacement, #radio_deposit").click(function() {
  2291. jQuery("#credit_note_options").hide();
  2292. });
  2293. });
  2294. </script>';
  2295. $text = $tmp.'<label for="radio_creditnote">'.$langs->transnoentities("InvoiceAvoirAsk").'</label> ';
  2296. // $text.='<input type="text" value="">';
  2297. $text .= '<select class="flat valignmiddle" name="fac_avoir" id="fac_avoir"';
  2298. if (!$optionsav) {
  2299. $text .= ' disabled';
  2300. }
  2301. $text .= '>';
  2302. if ($optionsav) {
  2303. $text .= '<option value="-1"></option>';
  2304. $text .= $optionsav;
  2305. } else {
  2306. $text .= '<option value="-1">'.$langs->trans("NoInvoiceToCorrect").'</option>';
  2307. }
  2308. $text .= '</select>';
  2309. $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
  2310. print $desc;
  2311. print '<div id="credit_note_options" class="clearboth">';
  2312. print '&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithPaymentRestAmount\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithLines', 'int') > 0 ? 'checked' : '').' /> ';
  2313. print '<label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
  2314. print '<br>&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithLines\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int') > 0 ? 'checked' : '').' /> ';
  2315. print '<label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
  2316. print '</div>';
  2317. print '</div></div>';
  2318. }
  2319. } else {
  2320. print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
  2321. if (!getDolGlobalString('INVOICE_CREDIT_NOTE_STANDALONE')) {
  2322. $tmp = '<input type="radio" name="type" id="radio_creditnote" value="0" disabled> ';
  2323. } else {
  2324. $tmp='<input type="radio" name="type" id="radio_creditnote" value="2"> ';
  2325. }
  2326. $text = $tmp.$langs->trans("InvoiceAvoir").' ';
  2327. $text .= '<span class="opacitymedium">('.$langs->trans("YouMustCreateInvoiceFromSupplierThird").')</span> ';
  2328. $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
  2329. print $desc;
  2330. print '</div></div>'."\n";
  2331. }
  2332. }
  2333. print '</div>';
  2334. print '</td></tr>';
  2335. // Invoice Subtype
  2336. if (getDolGlobalInt('INVOICE_SUBTYPE_ENABLED')) {
  2337. print '<tr><td class="fieldrequired">'.$langs->trans('InvoiceSubtype').'</td><td colspan="2">';
  2338. print $form->getSelectInvoiceSubtype(GETPOST('subtype'), 'subtype', 1, 0, '');
  2339. print '</td></tr>';
  2340. }
  2341. if (!empty($societe->id) && $societe->id > 0) {
  2342. // Discounts for third party
  2343. print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
  2344. $thirdparty = $societe;
  2345. $discount_type = 1;
  2346. $backtopage = urlencode($_SERVER["PHP_SELF"].'?socid='.$societe->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid'));
  2347. include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
  2348. print '</td></tr>';
  2349. }
  2350. // Label
  2351. print '<tr><td>'.$langs->trans('Label').'</td><td><input class="minwidth200" name="label" value="'.dol_escape_htmltag(GETPOST('label')).'" type="text"></td></tr>';
  2352. // Date invoice
  2353. print '<tr><td class="fieldrequired">'.$langs->trans('DateInvoice').'</td><td>';
  2354. print img_picto('', 'action', 'class="pictofixedwidth"');
  2355. print $form->selectDate($dateinvoice, '', '', '', '', "add", 1, 1);
  2356. print '</td></tr>';
  2357. // Payment term
  2358. print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
  2359. print img_picto('', 'payment', 'class="pictofixedwidth"');
  2360. print $form->getSelectConditionsPaiements($cond_reglement_id, 'cond_reglement_id', -1, 1);
  2361. print '</td></tr>';
  2362. // Due date
  2363. print '<tr><td>'.$langs->trans('DateMaxPayment').'</td><td>';
  2364. print img_picto('', 'action', 'class="pictofixedwidth"');
  2365. print $form->selectDate($datedue, 'ech', '', '', '', "add", 1, 1);
  2366. print '</td></tr>';
  2367. // Payment mode
  2368. print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
  2369. print img_picto('', 'bank', 'class="pictofixedwidth"');
  2370. $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id', 'DBIT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx');
  2371. print '</td></tr>';
  2372. // Bank Account
  2373. if (isModEnabled("banque")) {
  2374. print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
  2375. // when bank account is empty (means not override by payment mode form a other object, like third-party), try to use default value
  2376. print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes($fk_account, 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
  2377. print '</td></tr>';
  2378. }
  2379. // Project
  2380. if (isModEnabled('project')) {
  2381. $formproject = new FormProjets($db);
  2382. $langs->load('projects');
  2383. print '<tr><td>'.$langs->trans('Project').'</td><td>';
  2384. print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects((!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
  2385. print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.(!empty($soc->id) ? $soc->id : 0).'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.(!empty($soc->id) ? $soc->id : 0).($fac_recid > 0 ? '&fac_rec='.$fac_recid : '')).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
  2386. print '</td></tr>';
  2387. }
  2388. // Incoterms
  2389. if (isModEnabled('incoterm')) {
  2390. print '<tr>';
  2391. print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), !empty($objectsrc->label_incoterms) ? $objectsrc->label_incoterms : '', 1).'</label></td>';
  2392. print '<td colspan="3" class="maxwidthonsmartphone">';
  2393. print img_picto('', 'incoterm', 'class="pictofixedwidth"');
  2394. print $form->select_incoterms(GETPOSTISSET('incoterm_id') ? GETPOST('incoterm_id', 'alphanohtml') : (!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : ''), GETPOSTISSET('location_incoterms') ? GETPOST('location_incoterms', 'alphanohtml') : (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : ''));
  2395. print '</td></tr>';
  2396. }
  2397. // Vat reverse-charge by default
  2398. if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
  2399. require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
  2400. print '<tr><td>' . $langs->trans('VATReverseCharge') . '</td><td>';
  2401. // Try to propose to use VAT reverse charge even if the VAT reverse charge is not activated in the supplier card, if this corresponds to the context of use, the activation is proposed
  2402. if ($vat_reverse_charge == 1 || $societe->vat_reverse_charge == 1 || ($societe->country_code != 'FR' && isInEEC($societe) && !empty($societe->tva_intra))) {
  2403. $vat_reverse_charge = 1;
  2404. } else {
  2405. $vat_reverse_charge = 0;
  2406. }
  2407. print '<input type="checkbox" name="vat_reverse_charge"'. (!empty($vat_reverse_charge) ? ' checked ' : '') . '>';
  2408. print '</td></tr>';
  2409. }
  2410. // Multicurrency
  2411. if (isModEnabled("multicurrency")) {
  2412. print '<tr>';
  2413. print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
  2414. print '<td class="maxwidthonsmartphone">';
  2415. print img_picto('', 'currency', 'class="pictofixedwidth"');
  2416. $used_currency_code = $currency_code;
  2417. if (!GETPOST('changecompany')) {
  2418. $used_currency_code = GETPOSTISSET('multicurrency_code') ? GETPOST('multicurrency_code', 'alpha') : $currency_code;
  2419. }
  2420. print $form->selectMultiCurrency($used_currency_code, 'multicurrency_code');
  2421. print '</td></tr>';
  2422. }
  2423. // Help of substitution key
  2424. $htmltext = '';
  2425. if ($fac_recid > 0) {
  2426. $dateexample = $dateinvoice;
  2427. if (empty($dateexample)) {
  2428. $dateexample = dol_now();
  2429. }
  2430. $substitutionarray = array(
  2431. '__TOTAL_HT__' => $langs->trans("AmountHT").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ht).')',
  2432. '__TOTAL_TTC__' => $langs->trans("AmountTTC").' ('.$langs->trans("Example").': '.price($exampletemplateinvoice->total_ttc).')',
  2433. '__INVOICE_PREVIOUS_MONTH__' => $langs->trans("PreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%m').')',
  2434. '__INVOICE_MONTH__' => $langs->trans("MonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%m').')',
  2435. '__INVOICE_NEXT_MONTH__' => $langs->trans("NextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%m').')',
  2436. '__INVOICE_PREVIOUS_MONTH_TEXT__' => $langs->trans("TextPreviousMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'm'), '%B').')',
  2437. '__INVOICE_MONTH_TEXT__' => $langs->trans("TextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%B').')',
  2438. '__INVOICE_NEXT_MONTH_TEXT__' => $langs->trans("TextNextMonthOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'm'), '%B').')',
  2439. '__INVOICE_PREVIOUS_YEAR__' => $langs->trans("PreviousYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, -1, 'y'), '%Y').')',
  2440. '__INVOICE_YEAR__' => $langs->trans("YearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date($dateexample, '%Y').')',
  2441. '__INVOICE_NEXT_YEAR__' => $langs->trans("NextYearOfInvoice").' ('.$langs->trans("Example").': '.dol_print_date(dol_time_plus_duree($dateexample, 1, 'y'), '%Y').')'
  2442. );
  2443. $htmltext = '<i>'.$langs->trans("FollowingConstantsWillBeSubstituted").':<br>';
  2444. foreach ($substitutionarray as $key => $val) {
  2445. $htmltext .= $key.' = '.$langs->trans($val).'<br>';
  2446. }
  2447. $htmltext .= '</i>';
  2448. }
  2449. // Intracomm report
  2450. if (isModEnabled('intracommreport')) {
  2451. $langs->loadLangs(array("intracommreport"));
  2452. print '<!-- If module intracomm on -->'."\n";
  2453. print '<tr><td>'.$langs->trans('IntracommReportTransportMode').'</td><td>';
  2454. $form->selectTransportMode(GETPOSTISSET('transport_mode_id') ? GETPOST('transport_mode_id') : $transport_mode_id, 'transport_mode_id');
  2455. print '</td></tr>';
  2456. }
  2457. if (empty($reshook)) {
  2458. print $object->showOptionals($extrafields, 'create');
  2459. }
  2460. // Public note
  2461. print '<tr><td>'.$langs->trans('NotePublic').'</td>';
  2462. print '<td>';
  2463. $doleditor = new DolEditor('note_public', (GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : $note_public), '', 80, 'dolibarr_notes', 'In', 0, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
  2464. print $doleditor->Create(1);
  2465. print '</td>';
  2466. // print '<td><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
  2467. print '</tr>';
  2468. // Private note
  2469. print '<tr><td>'.$langs->trans('NotePrivate').'</td>';
  2470. print '<td>';
  2471. $doleditor = new DolEditor('note_private', (GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : $note_private), '', 80, 'dolibarr_notes', 'In', 0, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
  2472. print $doleditor->Create(1);
  2473. print '</td>';
  2474. // print '<td><textarea name="note" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
  2475. print '</tr>';
  2476. if (!empty($objectsrc) && is_object($objectsrc)) {
  2477. print "\n<!-- ".$classname." info -->";
  2478. print "\n";
  2479. print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
  2480. print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
  2481. print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
  2482. print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
  2483. print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
  2484. $txt = $langs->trans($classname);
  2485. if ($classname == 'CommandeFournisseur') {
  2486. $langs->load('orders');
  2487. $txt = $langs->trans("SupplierOrder");
  2488. }
  2489. print '<tr><td>'.$txt.'</td><td>'.$objectsrc->getNomUrl(1);
  2490. // We check if Origin document (id and type is known) has already at least one invoice attached to it
  2491. $objectsrc->fetchObjectLinked($originid, $origin, '', 'invoice_supplier');
  2492. $invoice_supplier = $objectsrc->linkedObjects['invoice_supplier'];
  2493. // count function need a array as argument (Note: the array must implement Countable too)
  2494. if (is_array($invoice_supplier)) {
  2495. $cntinvoice = count($invoice_supplier);
  2496. if ($cntinvoice >= 1) {
  2497. setEventMessages('WarningBillExist', null, 'warnings');
  2498. echo ' ('.$langs->trans('LatestRelatedBill').end($invoice_supplier)->getNomUrl(1).')';
  2499. }
  2500. }
  2501. print '</td></tr>';
  2502. print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
  2503. print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
  2504. if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { //Localtax1
  2505. print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
  2506. }
  2507. if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { //Localtax2
  2508. print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
  2509. }
  2510. print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
  2511. if (isModEnabled("multicurrency")) {
  2512. print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht).'</td></tr>';
  2513. print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva)."</td></tr>";
  2514. print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc)."</td></tr>";
  2515. }
  2516. }
  2517. // Other options
  2518. $parameters = array();
  2519. $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
  2520. print $hookmanager->resPrint;
  2521. print "</table>\n";
  2522. }
  2523. print dol_get_fiche_end();
  2524. print $form->buttonsSaveCancel("CreateDraft");
  2525. // Show origin lines
  2526. if (!empty($objectsrc) && is_object($objectsrc)) {
  2527. print '<br>';
  2528. $title = $langs->trans('ProductsAndServices');
  2529. print load_fiche_titre($title);
  2530. print '<div class="div-table-responsive-no-min">';
  2531. print '<table class="noborder centpercent">';
  2532. $objectsrc->printOriginLinesList('', $selectedLines);
  2533. print '</table>';
  2534. print '</div>';
  2535. }
  2536. print "</form>\n";
  2537. } else {
  2538. if ($id > 0 || !empty($ref)) {
  2539. //
  2540. // View or edit mode
  2541. //
  2542. $now = dol_now();
  2543. $productstatic = new Product($db);
  2544. $result = $object->fetch($id, $ref);
  2545. if ($result <= 0) {
  2546. $langs->load("errors");
  2547. print $langs->trans("ErrorRecordNotFound");
  2548. llxFooter();
  2549. $db->close();
  2550. exit;
  2551. }
  2552. $result = $object->fetch_thirdparty();
  2553. if ($result < 0) {
  2554. dol_print_error($db, $object->error, $object->errors);
  2555. exit;
  2556. }
  2557. $societe = $object->thirdparty;
  2558. $totalpaid = $object->getSommePaiement();
  2559. $totalcreditnotes = $object->getSumCreditNotesUsed();
  2560. $totaldeposits = $object->getSumDepositsUsed();
  2561. // print "totalpaid=".$totalpaid." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits."
  2562. // selleruserrevenuestamp=".$selleruserevenustamp;
  2563. // We can also use bcadd to avoid pb with floating points
  2564. // For example print 239.2 - 229.3 - 9.9; does not return 0.
  2565. // $resteapayer=bcadd($object->total_ttc,$totalpaid,$conf->global->MAIN_MAX_DECIMALS_TOT);
  2566. // $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
  2567. $resteapayer = price2num($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT');
  2568. // Multicurrency
  2569. $multicurrency_resteapayer = 0;
  2570. if (isModEnabled("multicurrency")) {
  2571. $multicurrency_totalpaid = $object->getSommePaiement(1);
  2572. $multicurrency_totalcreditnotes = $object->getSumCreditNotesUsed(1);
  2573. $multicurrency_totaldeposits = $object->getSumDepositsUsed(1);
  2574. $multicurrency_resteapayer = price2num($object->multicurrency_total_ttc - $multicurrency_totalpaid - $multicurrency_totalcreditnotes - $multicurrency_totaldeposits, 'MT');
  2575. // Code to fix case of corrupted data
  2576. // TODO We should not need this. Also data comes from not reliable value of $object->multicurrency_total_ttc that may be wrong if it was
  2577. // calculated by summing lines that were in a currency for some of them and into another for others (lines from discount/down payment into another currency for example)
  2578. if ($resteapayer == 0 && $multicurrency_resteapayer != 0 && $object->multicurrency_code != $conf->currency) {
  2579. $resteapayer = price2num($multicurrency_resteapayer / $object->multicurrency_tx, 'MT');
  2580. }
  2581. }
  2582. if ($object->paye) {
  2583. $resteapayer = 0;
  2584. }
  2585. $resteapayeraffiche = $resteapayer;
  2586. if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { // Never use this
  2587. $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
  2588. $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
  2589. } else {
  2590. $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
  2591. $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
  2592. }
  2593. $absolute_discount = $societe->getAvailableDiscounts('', $filterabsolutediscount, 0, 1);
  2594. $absolute_creditnote = $societe->getAvailableDiscounts('', $filtercreditnote, 0, 1);
  2595. $absolute_discount = price2num($absolute_discount, 'MT');
  2596. $absolute_creditnote = price2num($absolute_creditnote, 'MT');
  2597. /*
  2598. * View card
  2599. */
  2600. $objectidnext = $object->getIdReplacingInvoice();
  2601. $head = facturefourn_prepare_head($object);
  2602. $titre = $langs->trans('SupplierInvoice');
  2603. print dol_get_fiche_head($head, 'card', $titre, -1, 'supplier_invoice', 0, '', '', 0, '', 1);
  2604. $formconfirm = '';
  2605. // Confirmation de la conversion de l'avoir en reduc
  2606. if ($action == 'converttoreduc') {
  2607. $type_fac = '';
  2608. if ($object->type == FactureFournisseur::TYPE_STANDARD) {
  2609. $type_fac = 'ExcessPaid';
  2610. } elseif ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
  2611. $type_fac = 'CreditNote';
  2612. } elseif ($object->type == FactureFournisseur::TYPE_DEPOSIT) {
  2613. $type_fac = 'Deposit';
  2614. }
  2615. $text = $langs->trans('ConfirmConvertToReducSupplier', strtolower($langs->transnoentities($type_fac)));
  2616. $text .= '<br>'.$langs->trans('ConfirmConvertToReducSupplier2');
  2617. $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?facid='.$object->id, $langs->trans('ConvertToReduc'), $text, 'confirm_converttoreduc', '', "yes", 2);
  2618. }
  2619. // Clone confirmation
  2620. if ($action == 'clone') {
  2621. // Create an array for form
  2622. $formquestion = array(
  2623. array('type' => 'text', 'name' => 'newsupplierref', 'label' => $langs->trans("RefSupplierBill"), 'value' => $langs->trans("CopyOf").' '.$object->ref_supplier),
  2624. array('type' => 'date', 'name' => 'newdate', 'label' => $langs->trans("Date"), 'value' => dol_now())
  2625. );
  2626. // Ask confirmation to clone
  2627. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneInvoice', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 250);
  2628. }
  2629. // Confirmation of validation
  2630. if ($action == 'valid') {
  2631. // We check if number is temporary number
  2632. if (preg_match('/^[\(]?PROV/i', $object->ref) || empty($object->ref)) {
  2633. // empty should not happened, but when it occurs, the test save life
  2634. $numref = $object->getNextNumRef($societe);
  2635. } else {
  2636. $numref = $object->ref;
  2637. }
  2638. if ($numref < 0) {
  2639. setEventMessages($object->error, $object->errors, 'errors');
  2640. $action = '';
  2641. } else {
  2642. $text = $langs->trans('ConfirmValidateBill', $numref);
  2643. /*if (isModEnabled('notification'))
  2644. {
  2645. require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php';
  2646. $notify=new Notify($db);
  2647. $text.='<br>';
  2648. $text.=$notify->confirmMessage('BILL_SUPPLIER_VALIDATE',$object->socid, $object);
  2649. }*/
  2650. $formquestion = array();
  2651. $qualified_for_stock_change = 0;
  2652. if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
  2653. $qualified_for_stock_change = $object->hasProductsOrServices(2);
  2654. } else {
  2655. $qualified_for_stock_change = $object->hasProductsOrServices(1);
  2656. }
  2657. if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
  2658. $langs->load("stocks");
  2659. require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
  2660. $formproduct = new FormProduct($db);
  2661. $warehouse = new Entrepot($db);
  2662. $warehouse_array = $warehouse->list_array();
  2663. if (count($warehouse_array) == 1) {
  2664. $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockDecrease", current($warehouse_array)) : $langs->trans("WarehouseForStockIncrease", current($warehouse_array));
  2665. $value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
  2666. } else {
  2667. $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockDecrease") : $langs->trans("SelectWarehouseForStockIncrease");
  2668. $value = $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
  2669. }
  2670. $formquestion = array(
  2671. array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $value)
  2672. );
  2673. }
  2674. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, 1, 1);
  2675. }
  2676. }
  2677. // Confirmation edit (back to draft)
  2678. if ($action == 'edit') {
  2679. $formquestion = array();
  2680. $qualified_for_stock_change = 0;
  2681. if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
  2682. $qualified_for_stock_change = $object->hasProductsOrServices(2);
  2683. } else {
  2684. $qualified_for_stock_change = $object->hasProductsOrServices(1);
  2685. }
  2686. if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
  2687. $langs->load("stocks");
  2688. require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
  2689. $formproduct = new FormProduct($db);
  2690. $warehouse = new Entrepot($db);
  2691. $warehouse_array = $warehouse->list_array();
  2692. if (count($warehouse_array) == 1) {
  2693. $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockIncrease", current($warehouse_array)) : $langs->trans("WarehouseForStockDecrease", current($warehouse_array));
  2694. $value = '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
  2695. } else {
  2696. $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
  2697. $value = $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
  2698. }
  2699. $formquestion = array(
  2700. array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $value)
  2701. );
  2702. }
  2703. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('UnvalidateBill'), $langs->trans('ConfirmUnvalidateBill', $object->ref), 'confirm_edit', $formquestion, 1, 1);
  2704. }
  2705. // Confirmation set paid
  2706. if ($action == 'paid' && ($resteapayer <= 0 || (getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') && $resteapayer == $object->total_ttc))) {
  2707. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', 0, 1);
  2708. }
  2709. if ($action == 'paid' && $resteapayer > 0 && (!getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') || $resteapayer != $object->total_ttc)) {
  2710. $close = array();
  2711. // Code
  2712. $i = 0;
  2713. $close[$i]['code'] = 'discount_vat'; // escompte
  2714. $i++;
  2715. $close[$i]['code'] = 'badsupplier';
  2716. $i++;
  2717. $close[$i]['code'] = 'other';
  2718. $i++;
  2719. // Help
  2720. $i = 0;
  2721. $close[$i]['label'] = $langs->trans("HelpEscompte").'<br><br>'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc");
  2722. $i++;
  2723. $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadSupplierDesc");
  2724. $i++;
  2725. $close[$i]['label'] = $langs->trans("Other");
  2726. $i++;
  2727. // Text
  2728. $i = 0;
  2729. $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscount", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1);
  2730. $i++;
  2731. $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1);
  2732. $i++;
  2733. $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("Other"), $close[$i]['label'], 1);
  2734. $i++;
  2735. // arrayreasons[code]=reason
  2736. foreach ($close as $key => $val) {
  2737. $arrayreasons[$close[$key]['code']] = $close[$key]['reason'];
  2738. }
  2739. // Create a form table
  2740. $formquestion = array('text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'morecss' => 'minwidth300'));
  2741. // Incomplete payment. We ask if the reason is discount or other
  2742. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes", 1, 310);
  2743. }
  2744. // Confirmation of the abandoned classification
  2745. if ($action == 'canceled') {
  2746. // Code
  2747. $close[1]['code'] = 'badsupplier';
  2748. $close[2]['code'] = 'abandon';
  2749. // Help
  2750. $close[1]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadSupplierDesc");
  2751. $close[2]['label'] = $langs->trans("ConfirmClassifyAbandonReasonOtherDesc");
  2752. // Text
  2753. $close[1]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadSupplier", $object->ref), $close[1]['label'], 1);
  2754. $close[2]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyAbandonReasonOther"), $close[2]['label'], 1);
  2755. // arrayreasons
  2756. $arrayreasons[$close[1]['code']] = $close[1]['reason'];
  2757. $arrayreasons[$close[2]['code']] = $close[2]['reason'];
  2758. // Create a form table
  2759. $formquestion = array('text' => $langs->trans("ConfirmCancelBillQuestion"), array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'morecss' => 'minwidth300'));
  2760. $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('CancelBill'), $langs->trans('ConfirmCancelBill', $object->ref), 'confirm_canceled', $formquestion, "yes", 1, 250);
  2761. }
  2762. // Confirmation de la suppression de la facture fournisseur
  2763. if ($action == 'delete') {
  2764. $formquestion = array();
  2765. $qualified_for_stock_change = 0;
  2766. if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
  2767. $qualified_for_stock_change = $object->hasProductsOrServices(2);
  2768. } else {
  2769. $qualified_for_stock_change = $object->hasProductsOrServices(1);
  2770. }
  2771. if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_BILL') && $qualified_for_stock_change) {
  2772. $langs->load("stocks");
  2773. require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
  2774. $formproduct = new FormProduct($db);
  2775. $warehouse = new Entrepot($db);
  2776. $warehouse_array = $warehouse->list_array();
  2777. $selectwarehouse = '<span class="questionrevertstock hidden">';
  2778. if (count($warehouse_array) == 1) {
  2779. $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("WarehouseForStockIncrease", current($warehouse_array)) : $langs->trans("WarehouseForStockDecrease", current($warehouse_array));
  2780. $selectwarehouse .= '<input type="hidden" id="idwarehouse" name="idwarehouse" value="'.key($warehouse_array).'">';
  2781. } else {
  2782. $label = $object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("SelectWarehouseForStockIncrease") : $langs->trans("SelectWarehouseForStockDecrease");
  2783. $selectwarehouse .= $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1);
  2784. }
  2785. $selectwarehouse .= '</span>';
  2786. $selectyesno = array(0 => $langs->trans('No'), 1 => $langs->trans('Yes'));
  2787. print '<script type="text/javascript">
  2788. $(document).ready(function() {
  2789. $("#revertstock").change(function() {
  2790. if(this.value > 0) {
  2791. $(".questionrevertstock").removeClass("hidden");
  2792. } else {
  2793. $(".questionrevertstock").addClass("hidden");
  2794. }
  2795. });
  2796. });
  2797. </script>';
  2798. $formquestion = array(
  2799. array('type' => 'select', 'name' => 'revertstock', 'label' => $langs->trans("RevertProductsToStock"), 'select_show_empty' => 0, 'values' => $selectyesno),
  2800. array('type' => 'other', 'name' => 'idwarehouse', 'label' => $label, 'value' => $selectwarehouse, 'tdclass' => 'questionrevertstock hidden')
  2801. );
  2802. }
  2803. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBill'), $langs->trans('ConfirmDeleteBill'), 'confirm_delete', $formquestion, 1, 1);
  2804. }
  2805. if ($action == 'deletepayment') {
  2806. $payment_id = GETPOST('paiement_id');
  2807. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&paiement_id='.$payment_id, $langs->trans('DeletePayment'), $langs->trans('ConfirmDeletePayment'), 'confirm_delete_paiement', '', 0, 1);
  2808. }
  2809. // Confirmation to delete line
  2810. if ($action == 'ask_deleteline') {
  2811. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
  2812. }
  2813. if (!$formconfirm) {
  2814. $parameters = array('formConfirm' => $formconfirm, 'lineid'=>$lineid);
  2815. $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
  2816. if (empty($reshook)) {
  2817. $formconfirm .= $hookmanager->resPrint;
  2818. } elseif ($reshook > 0) {
  2819. $formconfirm = $hookmanager->resPrint;
  2820. }
  2821. }
  2822. // Print form confirm
  2823. print $formconfirm;
  2824. // Supplier invoice card
  2825. $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/facture/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
  2826. $morehtmlref = '<div class="refidno">';
  2827. // Ref supplier
  2828. $morehtmlref .= $form->editfieldkey("RefSupplierBill", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', 0, 1);
  2829. $morehtmlref .= $form->editfieldval("RefSupplierBill", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string', '', null, null, '', 1);
  2830. // Thirdparty
  2831. $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'supplier');
  2832. if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
  2833. $morehtmlref .= ' <div class="inline-block valignmiddle">(<a class="valignmiddle" href="'.DOL_URL_ROOT.'/fourn/facture/list.php?socid='.((int) $object->thirdparty->id).'&search_company='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherBills").'</a>)</div>';
  2834. }
  2835. // Project
  2836. if (isModEnabled('project')) {
  2837. $langs->load("projects");
  2838. $morehtmlref .= '<br>';
  2839. if ($permissiontoadd) {
  2840. $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
  2841. if ($action != 'classify') {
  2842. $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.((int) $object->id).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
  2843. }
  2844. $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
  2845. } else {
  2846. if (!empty($object->fk_project)) {
  2847. $proj = new Project($db);
  2848. $proj->fetch($object->fk_project);
  2849. $morehtmlref .= $proj->getNomUrl(1);
  2850. if ($proj->title) {
  2851. $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
  2852. }
  2853. }
  2854. }
  2855. }
  2856. $morehtmlref .= '</div>';
  2857. $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
  2858. dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
  2859. // Call Hook tabContentViewSupplierInvoice
  2860. $parameters = array();
  2861. // Note that $action and $object may be modified by hook
  2862. $reshook = $hookmanager->executeHooks('tabContentViewSupplierInvoice', $parameters, $object, $action);
  2863. if (empty($reshook)) {
  2864. print '<div class="fichecenter">';
  2865. print '<div class="fichehalfleft">';
  2866. print '<div class="underbanner clearboth"></div>';
  2867. print '<table class="border tableforfield centpercent">';
  2868. // Type
  2869. print '<tr><td class="titlefield">'.$langs->trans('Type').'</td><td>';
  2870. print '<span class="badgeneutral">';
  2871. print $object->getLibType();
  2872. print '</span>';
  2873. if ($object->subtype > 0) {
  2874. print ' '.$object->getSubtypeLabel('facture_fourn');
  2875. }
  2876. if ($object->type == FactureFournisseur::TYPE_REPLACEMENT) {
  2877. $facreplaced = new FactureFournisseur($db);
  2878. $facreplaced->fetch($object->fk_facture_source);
  2879. print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)).'</span>';
  2880. }
  2881. if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
  2882. if ($object->fk_facture_source > 0) {
  2883. $facusing = new FactureFournisseur($db);
  2884. $facusing->fetch($object->fk_facture_source);
  2885. print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).'</span>';
  2886. } else {
  2887. $langs->load("errors");
  2888. print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("WarningCorrectedInvoiceNotFound").'</span>';
  2889. }
  2890. }
  2891. $facidavoir = $object->getListIdAvoirFromInvoice();
  2892. if (count($facidavoir) > 0) {
  2893. $invoicecredits = array();
  2894. foreach ($facidavoir as $id) {
  2895. $facavoir = new FactureFournisseur($db);
  2896. $facavoir->fetch($id);
  2897. $invoicecredits[] = $facavoir->getNomUrl(1);
  2898. }
  2899. print ' <span class="opacitymediumbycolor paddingleft">'.$langs->transnoentities("InvoiceHasAvoir") . (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits);
  2900. print '</span>';
  2901. }
  2902. if (isset($objectidnext) && $objectidnext > 0) {
  2903. $facthatreplace = new FactureFournisseur($db);
  2904. $facthatreplace->fetch($objectidnext);
  2905. print ' <span class="opacitymediumbycolor paddingleft">'.str_replace('{s1}', $facthatreplace->getNomUrl(1), $langs->transnoentities("ReplacedByInvoice", '{s1}')).'</span>';
  2906. }
  2907. if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
  2908. $discount = new DiscountAbsolute($db);
  2909. $result = $discount->fetch(0, 0, $object->id);
  2910. if ($result > 0) {
  2911. print ' <span class="opacitymediumbycolor paddingleft">';
  2912. $s = $langs->trans("CreditNoteConvertedIntoDiscount", '{s1}', '{s2}');
  2913. $s = str_replace('{s1}', $object->getLibType(1), $s);
  2914. $s = str_replace('{s2}', $discount->getNomUrl(1, 'discount'), $s);
  2915. print $s;
  2916. print '</span><br>';
  2917. }
  2918. }
  2919. if ($object->fk_fac_rec_source > 0) {
  2920. $tmptemplate = new FactureFournisseurRec($db);
  2921. $result = $tmptemplate->fetch($object->fk_fac_rec_source);
  2922. if ($result > 0) {
  2923. print ' <span class="opacitymediumbycolor paddingleft">';
  2924. $link = '<a href="'.DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$tmptemplate->id.'">'.dol_escape_htmltag($tmptemplate->title).'</a>';
  2925. $s = $langs->transnoentities("GeneratedFromSupplierTemplate", $link);
  2926. print $s;
  2927. print '</span>';
  2928. }
  2929. }
  2930. print '</td></tr>';
  2931. // Relative and absolute discounts
  2932. print '<!-- Discounts -->'."\n";
  2933. print '<tr><td>'.$langs->trans('DiscountStillRemaining');
  2934. print '</td><td>';
  2935. $thirdparty = $societe;
  2936. $discount_type = 1;
  2937. include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
  2938. print '</td></tr>';
  2939. // Label
  2940. print '<tr>';
  2941. print '<td>'.$form->editfieldkey("Label", 'label', $object->label, $object, $usercancreate).'</td>';
  2942. print '<td>'.$form->editfieldval("Label", 'label', $object->label, $object, $usercancreate).'</td>';
  2943. print '</tr>';
  2944. //$form_permission = ($object->statut < FactureFournisseur::STATUS_CLOSED) && $usercancreate && ($object->getSommePaiement() <= 0);
  2945. $form_permission = ($object->statut < FactureFournisseur::STATUS_CLOSED) && $usercancreate;
  2946. // Date
  2947. print '<tr><td>';
  2948. print $form->editfieldkey("DateInvoice", 'datef', $object->date, $object, $form_permission, 'datepicker');
  2949. print '</td><td colspan="3">';
  2950. print $form->editfieldval("Date", 'datef', $object->date, $object, $form_permission, 'datepicker');
  2951. print '</td>';
  2952. // Default terms of the settlement
  2953. $langs->load('bills');
  2954. print '<tr><td class="nowrap">';
  2955. print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
  2956. print $langs->trans('PaymentConditions');
  2957. print '<td>';
  2958. if ($action != 'editconditions' && $form_permission) {
  2959. print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editconditions&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetConditions'), 1).'</a></td>';
  2960. }
  2961. print '</tr></table>';
  2962. print '</td><td>';
  2963. if ($action == 'editconditions') {
  2964. $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
  2965. } else {
  2966. $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none');
  2967. }
  2968. print "</td>";
  2969. print '</tr>';
  2970. // Due date
  2971. print '<tr><td>';
  2972. print $form->editfieldkey("DateMaxPayment", 'date_lim_reglement', $object->date_echeance, $object, $form_permission, 'datepicker');
  2973. print '</td><td>';
  2974. print $form->editfieldval("DateMaxPayment", 'date_lim_reglement', $object->date_echeance, $object, $form_permission, 'datepicker');
  2975. if ($action != 'editdate_lim_reglement' && $object->hasDelay()) {
  2976. print img_warning($langs->trans('Late'));
  2977. }
  2978. print '</td>';
  2979. // Mode of payment
  2980. $langs->load('bills');
  2981. print '<tr><td class="nowrap">';
  2982. print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
  2983. print $langs->trans('PaymentMode');
  2984. print '</td>';
  2985. if ($action != 'editmode' && $form_permission) {
  2986. print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
  2987. }
  2988. print '</tr></table>';
  2989. print '</td><td>';
  2990. if ($action == 'editmode') {
  2991. $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
  2992. } else {
  2993. $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'none');
  2994. }
  2995. print '</td></tr>';
  2996. // Multicurrency
  2997. if (isModEnabled("multicurrency")) {
  2998. // Multicurrency code
  2999. print '<tr>';
  3000. print '<td>';
  3001. print '<table class="nobordernopadding" width="100%"><tr><td>';
  3002. print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0);
  3003. print '</td>';
  3004. if ($action != 'editmulticurrencycode' && $object->statut == $object::STATUS_DRAFT) {
  3005. print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmulticurrencycode&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).'</a></td>';
  3006. }
  3007. print '</tr></table>';
  3008. print '</td><td>';
  3009. if ($action == 'editmulticurrencycode') {
  3010. $form->form_multicurrency_code($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_code, 'multicurrency_code');
  3011. } else {
  3012. $form->form_multicurrency_code($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_code, 'none');
  3013. }
  3014. print '</td></tr>';
  3015. // Multicurrency rate
  3016. if ($object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
  3017. print '<tr>';
  3018. print '<td>';
  3019. print '<table class="nobordernopadding centpercent"><tr><td>';
  3020. print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0);
  3021. print '</td>';
  3022. if ($action != 'editmulticurrencyrate' && $object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
  3023. print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmulticurrencyrate&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).'</a></td>';
  3024. }
  3025. print '</tr></table>';
  3026. print '</td><td>';
  3027. if ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') {
  3028. if ($action == 'actualizemulticurrencyrate') {
  3029. list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
  3030. }
  3031. $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code);
  3032. } else {
  3033. $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
  3034. if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
  3035. print '<div class="inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; ';
  3036. print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=actualizemulticurrencyrate">'.$langs->trans("ActualizeCurrency").'</a>';
  3037. print '</div>';
  3038. }
  3039. }
  3040. print '</td></tr>';
  3041. }
  3042. }
  3043. // Bank Account
  3044. if (isModEnabled("banque")) {
  3045. print '<tr><td class="nowrap">';
  3046. print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
  3047. print $langs->trans('BankAccount');
  3048. print '<td>';
  3049. if ($action != 'editbankaccount' && $usercancreate) {
  3050. print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
  3051. }
  3052. print '</tr></table>';
  3053. print '</td><td>';
  3054. if ($action == 'editbankaccount') {
  3055. $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
  3056. } else {
  3057. $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
  3058. }
  3059. print "</td>";
  3060. print '</tr>';
  3061. }
  3062. // Vat reverse-charge by default
  3063. if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
  3064. print '<tr><td class="nowrap">';
  3065. print '<table width="100%" class="nobordernopadding"><tr><td class="nowrap">';
  3066. print $langs->trans('VATReverseCharge');
  3067. print '<td>';
  3068. if ($action != 'editvatreversecharge' && $usercancreate) {
  3069. print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editvatreversecharge&amp;id='.$object->id.'">'.img_edit($langs->trans('SetVATReverseCharge'), 1).'</a></td>';
  3070. }
  3071. print '</tr></table>';
  3072. print '</td><td>';
  3073. if ($action == 'editvatreversecharge') {
  3074. print '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
  3075. print '<input type="hidden" name="action" value="setvatreversecharge">';
  3076. print '<input type="hidden" name="token" value="'.newToken().'">';
  3077. print '<input type="checkbox" name="vat_reverse_charge"' . ($object->vat_reverse_charge == '1' ? ' checked ' : '') . '>';
  3078. print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
  3079. print '</form>';
  3080. } else {
  3081. print '<input type="checkbox" name="vat_reverse_charge"'. ($object->vat_reverse_charge == '1' ? ' checked ' : '') . ' disabled>';
  3082. }
  3083. print '</td></tr>';
  3084. }
  3085. // Incoterms
  3086. if (isModEnabled('incoterm')) {
  3087. print '<tr><td>';
  3088. print '<table width="100%" class="nobordernopadding"><tr><td>';
  3089. print $langs->trans('IncotermLabel');
  3090. print '<td><td class="right">';
  3091. if ($usercancreate) {
  3092. print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
  3093. } else {
  3094. print '&nbsp;';
  3095. }
  3096. print '</td></tr></table>';
  3097. print '</td>';
  3098. print '<td>';
  3099. if ($action != 'editincoterm') {
  3100. print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
  3101. } else {
  3102. print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
  3103. }
  3104. print '</td></tr>';
  3105. }
  3106. // Intracomm report
  3107. if (isModEnabled('intracommreport')) {
  3108. $langs->loadLangs(array("intracommreport"));
  3109. print '<!-- If module intracomm on -->'."\n";
  3110. print '<tr><td>';
  3111. print '<table class="nobordernopadding centpercent"><tr><td>';
  3112. print $langs->trans('IntracommReportTransportMode');
  3113. print '</td>';
  3114. if ($action != 'edittransportmode' && ($user->hasRight("fournisseur", "facture", "creer") || $user->hasRight("supplier_invoice", "creer"))) {
  3115. print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edittransportmode&token='.newToken().'&id='.$object->id.'">'.img_edit().'</a></td>';
  3116. }
  3117. print '</tr></table>';
  3118. print '</td>';
  3119. print '<td>';
  3120. if ($action == 'edittransportmode') {
  3121. $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?id='.$object->id, $object->transport_mode_id, 'transport_mode_id', 1, 1);
  3122. } else {
  3123. $form->formSelectTransportMode($_SERVER['PHP_SELF'].'?id='.$object->id, $object->transport_mode_id, 'none');
  3124. }
  3125. print '</td></tr>';
  3126. }
  3127. // Other attributes
  3128. $cols = 2;
  3129. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
  3130. print '</table>';
  3131. print '</div>';
  3132. print '<div class="fichehalfright">';
  3133. print '<div class="underbanner clearboth"></div>';
  3134. print '<table class="border tableforfield centpercent">';
  3135. print '<tr>';
  3136. print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
  3137. print '<td class="nowrap amountcard right">' . price($object->total_ht, '', $langs, 0, -1, -1, $conf->currency) . '</td>';
  3138. if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
  3139. print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
  3140. }
  3141. print '</tr>';
  3142. print '<tr>';
  3143. print '<td>' . $langs->trans('AmountVAT') . '</td>';
  3144. print '<td class="nowrap amountcard right">';
  3145. if (GETPOST('calculationrule')) {
  3146. $calculationrule = GETPOST('calculationrule', 'alpha');
  3147. } else {
  3148. $calculationrule = (!getDolGlobalString('MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND') ? 'totalofround' : 'roundoftotal');
  3149. }
  3150. if ($calculationrule == 'totalofround') {
  3151. $calculationrulenum = 1;
  3152. } else {
  3153. $calculationrulenum = 2;
  3154. }
  3155. // Show link for "recalculate"
  3156. if ($object->getVentilExportCompta() == 0) {
  3157. $s = '<span class="hideonsmartphone opacitymedium">' . $langs->trans("ReCalculate") . ' </span>';
  3158. $s .= '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=calculate&calculationrule=totalofround">' . $langs->trans("Mode1") . '</a>';
  3159. $s .= ' / ';
  3160. $s .= '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=calculate&calculationrule=roundoftotal">' . $langs->trans("Mode2") . '</a>';
  3161. print '<div class="inline-block">';
  3162. print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc", $calculationrulenum) . '<br>' . $langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('', 'help'), '', 3, '', 0, 'recalculate');
  3163. print '&nbsp; &nbsp; &nbsp; &nbsp;';
  3164. print '</div>';
  3165. }
  3166. print price($object->total_tva, 1, $langs, 0, -1, -1, $conf->currency);
  3167. print '</td>';
  3168. if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
  3169. print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
  3170. }
  3171. print '</tr>';
  3172. if ($societe->localtax1_assuj == "1") { //Localtax1
  3173. print '<tr>';
  3174. print '<td>' . $langs->transcountry("AmountLT1", $societe->country_code) . '</td>';
  3175. print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 1, $langs, 0, -1, -1, $conf->currency) . '</td>';
  3176. print '</tr>';
  3177. }
  3178. if ($societe->localtax2_assuj == "1") { //Localtax2
  3179. print '<tr>';
  3180. print '<td>' . $langs->transcountry("AmountLT2", $societe->country_code) . '</td>';
  3181. print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 1, $langs, 0, -1, -1, $conf->currency) . '</td>';
  3182. print '</tr>';
  3183. }
  3184. print '<tr>';
  3185. print '<td>' . $langs->trans('AmountTTC') . '</td>';
  3186. print '<td class="nowrap amountcard right">' . price($object->total_ttc, '', $langs, 0, -1, -1, $conf->currency) . '</td>';
  3187. if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
  3188. print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ttc, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
  3189. }
  3190. print '</tr>';
  3191. print '</table>';
  3192. // List of payments
  3193. $totalpaid = 0;
  3194. $sign = 1;
  3195. if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
  3196. $sign = - 1;
  3197. }
  3198. $nbrows = 9;
  3199. $nbcols = 3;
  3200. if (isModEnabled('project')) {
  3201. $nbrows++;
  3202. }
  3203. if (isModEnabled("banque")) {
  3204. $nbrows++;
  3205. $nbcols++;
  3206. }
  3207. if (isModEnabled('incoterm')) {
  3208. $nbrows++;
  3209. }
  3210. if (isModEnabled("multicurrency")) {
  3211. $nbrows += 5;
  3212. }
  3213. // Local taxes
  3214. if ($societe->localtax1_assuj == "1") {
  3215. $nbrows++;
  3216. }
  3217. if ($societe->localtax2_assuj == "1") {
  3218. $nbrows++;
  3219. }
  3220. $sql = 'SELECT p.datep as dp, p.ref, p.num_paiement as num_payment, p.rowid, p.fk_bank,';
  3221. $sql .= ' c.id as payment_type, c.code as payment_code,';
  3222. $sql .= ' pf.amount,';
  3223. $sql .= ' ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal';
  3224. $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn as p';
  3225. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
  3226. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
  3227. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id';
  3228. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_paiementfourn = p.rowid';
  3229. $sql .= ' WHERE pf.fk_facturefourn = '.((int) $object->id);
  3230. $sql .= ' ORDER BY p.datep, p.tms';
  3231. $result = $db->query($sql);
  3232. if ($result) {
  3233. $num = $db->num_rows($result);
  3234. $i = 0;
  3235. print '<div class="div-table-responsive-no-min">';
  3236. print '<table class="noborder paymenttable centpercent">';
  3237. print '<tr class="liste_titre">';
  3238. print '<td class="liste_titre">'.($object->type == FactureFournisseur::TYPE_CREDIT_NOTE ? $langs->trans("PaymentsBack") : $langs->trans('Payments')).'</td>';
  3239. print '<td>'.$langs->trans('Date').'</td>';
  3240. print '<td>'.$langs->trans('Type').'</td>';
  3241. if (isModEnabled("banque")) {
  3242. print '<td class="right">'.$langs->trans('BankAccount').'</td>';
  3243. }
  3244. print '<td class="right">'.$langs->trans('Amount').'</td>';
  3245. print '<td width="18">&nbsp;</td>';
  3246. print '</tr>';
  3247. if ($num > 0) {
  3248. while ($i < $num) {
  3249. $objp = $db->fetch_object($result);
  3250. $paymentstatic->id = $objp->rowid;
  3251. $paymentstatic->datepaye = $db->jdate($objp->dp);
  3252. $paymentstatic->ref = ($objp->ref ? $objp->ref : $objp->rowid);
  3253. $paymentstatic->num_payment = $objp->num_payment;
  3254. $paymentstatic->paiementcode = $objp->payment_code;
  3255. $paymentstatic->type_code = $objp->payment_code;
  3256. $paymentstatic->type_label = $objp->payment_type;
  3257. print '<tr class="oddeven">';
  3258. print '<td class="nowraponall">';
  3259. print $paymentstatic->getNomUrl(1);
  3260. print '</td>';
  3261. print '<td>'.dol_print_date($db->jdate($objp->dp), 'day').'</td>';
  3262. $s = $form->form_modes_reglement(null, $objp->payment_type, 'none', '', 1, 0, '', 1).' '.$objp->num_payment;
  3263. print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($s).'">';
  3264. print $s;
  3265. print '</td>';
  3266. if (isModEnabled("banque")) {
  3267. $bankaccountstatic->id = $objp->baid;
  3268. $bankaccountstatic->ref = $objp->baref;
  3269. $bankaccountstatic->label = $objp->baref;
  3270. $bankaccountstatic->number = $objp->banumber;
  3271. if (isModEnabled('accounting')) {
  3272. $bankaccountstatic->account_number = $objp->account_number;
  3273. $accountingjournal = new AccountingJournal($db);
  3274. $accountingjournal->fetch($objp->fk_accountancy_journal);
  3275. $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
  3276. }
  3277. print '<td class="right">';
  3278. if ($objp->baid > 0) {
  3279. print $bankaccountstatic->getNomUrl(1, 'transactions');
  3280. }
  3281. print '</td>';
  3282. }
  3283. print '<td class="right">'.price($sign * $objp->amount).'</td>';
  3284. print '<td class="center">';
  3285. if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && $user->socid == 0) {
  3286. print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deletepayment&token='.newToken().'&paiement_id='.$objp->rowid.'">';
  3287. print img_delete();
  3288. print '</a>';
  3289. }
  3290. print '</td>';
  3291. print '</tr>';
  3292. $totalpaid += $objp->amount;
  3293. $i++;
  3294. }
  3295. } else {
  3296. print '<tr class="oddeven"><td colspan="'.$nbcols.'"><span class="opacitymedium">'.$langs->trans("None").'</span></td><td></td><td></td></tr>';
  3297. }
  3298. /*
  3299. if ($object->paye == 0)
  3300. {
  3301. print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('AlreadyPaid').' :</td><td class="right">'.price($totalpaid).'</td><td></td></tr>';
  3302. print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("Billed").' :</td><td class="right">'.price($object->total_ttc).'</td><td></td></tr>';
  3303. $resteapayer = $object->total_ttc - $totalpaid;
  3304. print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('RemainderToPay').' :</td>';
  3305. print '<td class="right'.($resteapayer?' amountremaintopay':'').'">'.price($resteapayer).'</td><td></td></tr>';
  3306. }
  3307. */
  3308. $db->free($result);
  3309. } else {
  3310. dol_print_error($db);
  3311. }
  3312. if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE) {
  3313. // Total already paid
  3314. print '<tr><td colspan="'.$nbcols.'" class="right">';
  3315. print '<span class="opacitymedium">';
  3316. if ($object->type != FactureFournisseur::TYPE_DEPOSIT) {
  3317. print $langs->trans('AlreadyPaidNoCreditNotesNoDeposits');
  3318. } else {
  3319. print $langs->trans('AlreadyPaid');
  3320. }
  3321. print '</span>';
  3322. print '</td><td class="right"'.(($totalpaid > 0) ? ' class="amountalreadypaid"' : '').'>'.price($totalpaid).'</td><td>&nbsp;</td></tr>';
  3323. //$resteapayer = $object->total_ttc - $totalpaid;
  3324. $resteapayeraffiche = $resteapayer;
  3325. $cssforamountpaymentcomplete = 'amountpaymentcomplete';
  3326. // Loop on each credit note or deposit amount applied
  3327. $creditnoteamount = 0;
  3328. $depositamount = 0;
  3329. $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,";
  3330. $sql .= " re.description, re.fk_invoice_supplier_source";
  3331. $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re";
  3332. $sql .= " WHERE fk_invoice_supplier = ".((int) $object->id);
  3333. $resql = $db->query($sql);
  3334. if ($resql) {
  3335. $num = $db->num_rows($resql);
  3336. $i = 0;
  3337. $invoice = new FactureFournisseur($db);
  3338. while ($i < $num) {
  3339. $obj = $db->fetch_object($resql);
  3340. $invoice->fetch($obj->fk_invoice_supplier_source);
  3341. print '<tr><td colspan="'.$nbcols.'" class="right">';
  3342. if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
  3343. print $langs->trans("CreditNote").' ';
  3344. }
  3345. if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
  3346. print $langs->trans("Deposit").' ';
  3347. }
  3348. print $invoice->getNomUrl(0);
  3349. print ' :</td>';
  3350. print '<td class="right">'.price($obj->amount_ttc).'</td>';
  3351. print '<td class="right">';
  3352. print '<a href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=unlinkdiscount&discountid='.$obj->rowid.'">';
  3353. print img_picto($langs->transnoentitiesnoconv("RemoveDiscount"), 'unlink');
  3354. print '</a>';
  3355. print '</td></tr>';
  3356. $i++;
  3357. if ($invoice->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
  3358. $creditnoteamount += $obj->amount_ttc;
  3359. }
  3360. if ($invoice->type == FactureFournisseur::TYPE_DEPOSIT) {
  3361. $depositamount += $obj->amount_ttc;
  3362. }
  3363. }
  3364. } else {
  3365. dol_print_error($db);
  3366. }
  3367. // Paye partiellement 'escompte'
  3368. if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'discount_vat') {
  3369. print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
  3370. print '<span class="opacitymedium">';
  3371. print $form->textwithpicto($langs->trans("Discount"), $langs->trans("HelpEscompte"), - 1);
  3372. print '</span>';
  3373. print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
  3374. $resteapayeraffiche = 0;
  3375. $cssforamountpaymentcomplete = 'amountpaymentneutral';
  3376. }
  3377. // Paye partiellement ou Abandon 'badsupplier'
  3378. if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'badsupplier') {
  3379. print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
  3380. print '<span class="opacitymedium">';
  3381. print $form->textwithpicto($langs->trans("Abandoned"), $langs->trans("HelpAbandonBadCustomer"), - 1);
  3382. print '</span>';
  3383. print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
  3384. // $resteapayeraffiche=0;
  3385. $cssforamountpaymentcomplete = 'amountpaymentneutral';
  3386. }
  3387. // Paye partiellement ou Abandon 'product_returned'
  3388. if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'product_returned') {
  3389. print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
  3390. print '<span class="opacitymedium">';
  3391. print $form->textwithpicto($langs->trans("ProductReturned"), $langs->trans("HelpAbandonProductReturned"), - 1);
  3392. print '</span>';
  3393. print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
  3394. $resteapayeraffiche = 0;
  3395. $cssforamountpaymentcomplete = 'amountpaymentneutral';
  3396. }
  3397. // Paye partiellement ou Abandon 'abandon'
  3398. if (($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED) && $object->close_code == 'abandon') {
  3399. print '<tr><td colspan="'.$nbcols.'" class="right nowrap">';
  3400. $text = $langs->trans("HelpAbandonOther");
  3401. if ($object->close_note) {
  3402. $text .= '<br><br><b>'.$langs->trans("Reason").'</b>:'.$object->close_note;
  3403. }
  3404. print '<span class="opacitymedium">';
  3405. print $form->textwithpicto($langs->trans("Abandoned"), $text, - 1);
  3406. print '</span>';
  3407. print '</td><td class="right">'.price($object->total_ttc - $creditnoteamount - $depositamount - $totalpaid).'</td><td>&nbsp;</td></tr>';
  3408. $resteapayeraffiche = 0;
  3409. $cssforamountpaymentcomplete = 'amountpaymentneutral';
  3410. }
  3411. // Billed
  3412. print '<tr><td colspan="'.$nbcols.'" class="right">';
  3413. print '<span class="opacitymedium">';
  3414. print $langs->trans("Billed");
  3415. print '</span>';
  3416. print '</td><td class="right">'.price($object->total_ttc).'</td><td>&nbsp;</td></tr>';
  3417. // Remainder to pay
  3418. print '<tr><td colspan="'.$nbcols.'" class="right">';
  3419. print '<span class="opacitymedium">';
  3420. print $langs->trans('RemainderToPay');
  3421. if ($resteapayeraffiche < 0) {
  3422. print ' ('.$langs->trans('NegativeIfExcessPaid').')';
  3423. }
  3424. print '</span>';
  3425. print '</td>';
  3426. print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($resteapayeraffiche).'</td><td>&nbsp;</td></tr>';
  3427. // Remainder to pay Multicurrency
  3428. if (isModEnabled('multicurrency') && $object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
  3429. print '<tr><td colspan="'.$nbcols.'" class="right">';
  3430. print '<span class="opacitymedium">';
  3431. print $langs->trans('RemainderToPayMulticurrency');
  3432. if ($resteapayeraffiche < 0) {
  3433. print ' ('.$langs->trans('NegativeIfExcessPaid').')';
  3434. }
  3435. print '</span>';
  3436. print '</td>';
  3437. print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.(!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency).' '.price(price2num($multicurrency_resteapayer, 'MT')).'</td><td>&nbsp;</td></tr>';
  3438. }
  3439. } else { // Credit note
  3440. $cssforamountpaymentcomplete = 'amountpaymentneutral';
  3441. // Total already paid back
  3442. print '<tr><td colspan="'.$nbcols.'" class="right">';
  3443. print $langs->trans('AlreadyPaidBack');
  3444. print ' :</td><td class="right">'.price($sign * $totalpaid).'</td><td>&nbsp;</td></tr>';
  3445. // Billed
  3446. print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("Billed").' :</td><td class="right">'.price($sign * $object->total_ttc).'</td><td>&nbsp;</td></tr>';
  3447. // Remainder to pay back
  3448. print '<tr><td colspan="'.$nbcols.'" class="right">';
  3449. print '<span class="opacitymedium">';
  3450. print $langs->trans('RemainderToPayBack');
  3451. if ($resteapayeraffiche > 0) {
  3452. print ' ('.$langs->trans('NegativeIfExcessRefunded').')';
  3453. }
  3454. print '</td>';
  3455. print '</span>';
  3456. print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($sign * $resteapayeraffiche).'</td><td>&nbsp;</td></tr>';
  3457. // Remainder to pay back Multicurrency
  3458. if (isModEnabled('multicurrency') && $object->multicurrency_code != $conf->currency || $object->multicurrency_tx != 1) {
  3459. print '<tr><td colspan="'.$nbcols.'" class="right">';
  3460. print '<span class="opacitymedium">';
  3461. print $langs->trans('RemainderToPayBackMulticurrency');
  3462. if ($resteapayeraffiche> 0) {
  3463. print ' ('.$langs->trans('NegativeIfExcessRefunded').')';
  3464. }
  3465. print '</span>';
  3466. print '</td>';
  3467. print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.(!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency).' '.price(price2num($sign * $object->multicurrency_tx * $resteapayeraffiche, 'MT')).'</td><td>&nbsp;</td></tr>';
  3468. }
  3469. // Sold credit note
  3470. // print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans('TotalTTC').' :</td>';
  3471. // print '<td class="right" style="border: 1px solid;" bgcolor="#f0f0f0"><b>'.price($sign *
  3472. // $object->total_ttc).'</b></td><td>&nbsp;</td></tr>';
  3473. }
  3474. print '</table>';
  3475. print '</div>';
  3476. print '</div>';
  3477. print '</div>';
  3478. print '<div class="clearboth"></div><br>';
  3479. if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
  3480. $blocname = 'contacts';
  3481. $title = $langs->trans('ContactsAddresses');
  3482. include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
  3483. }
  3484. if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
  3485. $colwidth = 20;
  3486. $blocname = 'notes';
  3487. $title = $langs->trans('Notes');
  3488. include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
  3489. }
  3490. /*
  3491. * Lines
  3492. */
  3493. print '<form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">';
  3494. print '<input type="hidden" name="token" value="'.newToken().'">';
  3495. print '<input type="hidden" name="action" value="'.(($action != 'editline') ? 'addline' : 'updateline').'">';
  3496. print '<input type="hidden" name="mode" value="">';
  3497. print '<input type="hidden" name="page_y" value="">';
  3498. print '<input type="hidden" name="id" value="'.$object->id.'">';
  3499. print '<input type="hidden" name="socid" value="'.$societe->id.'">';
  3500. print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
  3501. if (!empty($conf->use_javascript_ajax) && $object->statut == FactureFournisseur::STATUS_DRAFT) {
  3502. include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
  3503. }
  3504. print '<div class="div-table-responsive-no-min">';
  3505. print '<table id="tablelines" class="noborder noshadow centpercent">';
  3506. global $forceall, $senderissupplier, $dateSelector, $inputalsopricewithtax;
  3507. $forceall = 1;
  3508. $dateSelector = 0;
  3509. $inputalsopricewithtax = 1;
  3510. $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty and disable autofill qty with minimum.
  3511. //if (!empty($conf->global->SUPPLIER_INVOICE_WITH_NOPRICEDEFINED)) $senderissupplier=2;
  3512. if (getDolGlobalString('SUPPLIER_INVOICE_WITH_PREDEFINED_PRICES_ONLY')) {
  3513. $senderissupplier = 1;
  3514. }
  3515. // Show object lines (result may vary according to hidden option MAIN_NO_INPUT_PRICE_WITH_TAX)
  3516. if (!empty($object->lines)) {
  3517. $object->printObjectLines($action, $societe, $mysoc, $lineid, 1);
  3518. }
  3519. $num = count($object->lines);
  3520. // Form to add new line
  3521. if ($object->statut == FactureFournisseur::STATUS_DRAFT && $usercancreate) {
  3522. if ($action != 'editline') {
  3523. // Add free products/services
  3524. $parameters = array();
  3525. $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
  3526. if ($reshook < 0) {
  3527. setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
  3528. }
  3529. if (empty($reshook)) {
  3530. $object->formAddObjectLine(1, $societe, $mysoc);
  3531. }
  3532. }
  3533. }
  3534. print '</table>';
  3535. print '</div>';
  3536. print '</form>';
  3537. }
  3538. print dol_get_fiche_end();
  3539. if ($action != 'presend') {
  3540. /*
  3541. * Buttons actions
  3542. */
  3543. print '<div class="tabsAction">';
  3544. $parameters = array();
  3545. $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
  3546. // modified by hook
  3547. if (empty($reshook)) {
  3548. // Modify a validated invoice with no payments
  3549. if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $action != 'confirm_edit' && $object->getSommePaiement() == 0 && $usercancreate) {
  3550. // We check if lines of invoice are not already transfered into accountancy
  3551. $ventilExportCompta = $object->getVentilExportCompta(); // Should be 0 since the sum of payments are zero. But we keep the protection.
  3552. if ($ventilExportCompta == 0) {
  3553. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans('Modify').'</a>';
  3554. } else {
  3555. print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseDispatchedInBookkeeping").'">'.$langs->trans('Modify').'</span>';
  3556. }
  3557. }
  3558. $discount = new DiscountAbsolute($db);
  3559. $result = $discount->fetch(0, 0, $object->id);
  3560. // Reopen a standard paid invoice
  3561. if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT
  3562. || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && empty($discount->id))
  3563. || ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discount->id)))
  3564. && ($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED)) { // A paid invoice (partially or completely)
  3565. if (!$objectidnext && $object->close_code != 'replaced' && $usercancreate) { // Not replaced by another invoice
  3566. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans('ReOpen').'</a>';
  3567. } else {
  3568. if ($usercancreate) {
  3569. print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseReplacedInvoice").'">'.$langs->trans('ReOpen').'</span>';
  3570. } elseif (!getDolGlobalString('MAIN_BUTTON_HIDE_UNAUTHORIZED')) {
  3571. print '<span class="butActionRefused classfortooltip">'.$langs->trans('ReOpen').'</span>';
  3572. }
  3573. }
  3574. }
  3575. // Validate
  3576. if ($action != 'confirm_edit' && $object->statut == FactureFournisseur::STATUS_DRAFT) {
  3577. if (count($object->lines)) {
  3578. if ($usercanvalidate) {
  3579. print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=valid"';
  3580. print '>'.$langs->trans('Validate').'</a>';
  3581. } else {
  3582. print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'"';
  3583. print '>'.$langs->trans('Validate').'</a>';
  3584. }
  3585. }
  3586. }
  3587. // Send by mail
  3588. if (empty($user->socid)) {
  3589. if (($object->statut == FactureFournisseur::STATUS_VALIDATED || $object->statut == FactureFournisseur::STATUS_CLOSED)) {
  3590. if ($usercansend) {
  3591. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendMail').'</a>';
  3592. } else {
  3593. print '<span class="butActionRefused classfortooltip">'.$langs->trans('SendMail').'</span>';
  3594. }
  3595. }
  3596. }
  3597. // Create payment
  3598. if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0) {
  3599. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.DOL_URL_ROOT.'/fourn/facture/paiement.php?facid='.$object->id.'&amp;action=create'.($object->fk_account > 0 ? '&amp;accountid='.$object->fk_account : '').'">'.$langs->trans('DoPayment').'</a>'; // must use facid because id is for payment id not invoice
  3600. }
  3601. // Reverse back money or convert to reduction
  3602. if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) {
  3603. // For credit note only
  3604. if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0) {
  3605. if ($resteapayer == 0) {
  3606. print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPaymentBack').'</span>';
  3607. } else {
  3608. print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/paiement.php?facid='.$object->id.'&amp;action=create&amp;accountid='.$object->fk_account.'">'.$langs->trans('DoPaymentBack').'</a>';
  3609. }
  3610. }
  3611. // For standard invoice with excess paid
  3612. if ($object->type == FactureFournisseur::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits) < 0 && $usercancreate && empty($discount->id)) {
  3613. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertExcessPaidToReduc').'</a>';
  3614. }
  3615. // For credit note
  3616. if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate
  3617. && (getDolGlobalString('SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED') || $object->getSommePaiement() == 0)
  3618. ) {
  3619. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc" title="'.dol_escape_htmltag($langs->trans("ConfirmConvertToReducSupplier2")).'">'.$langs->trans('ConvertToReduc').'</a>';
  3620. }
  3621. // For deposit invoice
  3622. if ($object->type == FactureFournisseur::TYPE_DEPOSIT && $usercancreate && $object->statut > 0 && empty($discount->id)) {
  3623. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&amp;action=converttoreduc">'.$langs->trans('ConvertToReduc').'</a>';
  3624. }
  3625. }
  3626. // Classify paid
  3627. if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && (
  3628. ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->type != FactureFournisseur::TYPE_DEPOSIT && ($resteapayer <= 0 || (getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') && $object->total_ttc == $resteapayer))) ||
  3629. ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $resteapayer >= 0) ||
  3630. ($object->type == FactureFournisseur::TYPE_DEPOSIT && $object->total_ttc > 0 && ($resteapayer == 0 || (getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') && $object->total_ttc == $resteapayer)))
  3631. )
  3632. ) {
  3633. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaid').'</a>';
  3634. }
  3635. // Classify 'closed not completely paid' (possible if validated and not yet filed paid)
  3636. if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && $resteapayer > 0 && (!getDolGlobalString('SUPPLIER_INVOICE_CAN_SET_PAID_EVEN_IF_PARTIALLY_PAID') || $object->total_ttc != $resteapayer)) {
  3637. if ($totalpaid > 0 || $totalcreditnotes > 0) {
  3638. // If one payment or one credit note was linked to this invoice
  3639. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=paid">'.$langs->trans('ClassifyPaidPartially').'</a>';
  3640. } else {
  3641. if (!getDolGlobalString('INVOICE_CAN_NEVER_BE_CANCELED')) {
  3642. print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=canceled">'.$langs->trans('ClassifyCanceled').'</a>';
  3643. }
  3644. }
  3645. }
  3646. // Create event
  3647. /*if (isModEnabled('agenda') && !empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a "workflow" action so should appears somewhere else on page.
  3648. {
  3649. print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/comm/action/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '">' . $langs->trans("AddAction") . '</a></div>';
  3650. }*/
  3651. // Create a credit note
  3652. if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->statut > 0 && $usercancreate) {
  3653. if (!$objectidnext) {
  3654. print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?socid='.$object->socid.'&amp;fac_avoir='.$object->id.'&amp;action=create&amp;type=2'.($object->fk_project > 0 ? '&amp;projectid='.$object->fk_project : '').'">'.$langs->trans("CreateCreditNote").'</a>';
  3655. }
  3656. }
  3657. // Clone
  3658. if ($action != 'edit' && $usercancreate) {
  3659. print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=clone&amp;socid='.$object->socid.'">'.$langs->trans('ToClone').'</a>';
  3660. }
  3661. // Clone as predefined / Create template
  3662. if (($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_DEPOSIT) && $object->statut == 0 && $usercancreate) {
  3663. if (!$objectidnext && count($object->lines) > 0) {
  3664. print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card-rec.php?facid='.$object->id.'&amp;action=create">'.$langs->trans("ChangeIntoRepeatableInvoice").'</a>';
  3665. }
  3666. }
  3667. // Delete
  3668. $isErasable = $object->is_erasable();
  3669. if ($action != 'confirm_edit' && ($usercandelete || ($usercancreate && $isErasable == 1))) { // isErasable = 1 means draft with temporary ref (draft can always be deleted with no need of permissions)
  3670. $enableDelete = false;
  3671. $htmltooltip = '';
  3672. $params = (empty($conf->use_javascript_ajax) ? array() : array('attr' => array('class' => 'reposition')));
  3673. //var_dump($isErasable); var_dump($params);
  3674. if ($isErasable == -4) {
  3675. $htmltooltip = $langs->trans("DisabledBecausePayments");
  3676. } elseif ($isErasable == -3) { // Should never happen with supplier invoice
  3677. $htmltooltip = $langs->trans("DisabledBecauseNotLastSituationInvoice");
  3678. } elseif ($isErasable == -2) { // Should never happen with supplier invoice
  3679. $htmltooltip = $langs->trans("DisabledBecauseNotLastInvoice");
  3680. } elseif ($isErasable == -1) {
  3681. $htmltooltip = $langs->trans("DisabledBecauseDispatchedInBookkeeping");
  3682. } elseif ($isErasable <= 0) { // Any other cases
  3683. $htmltooltip = $langs->trans("DisabledBecauseNotErasable");
  3684. } else {
  3685. $enableDelete = true;
  3686. $htmltooltip = '';
  3687. }
  3688. print dolGetButtonAction($htmltooltip, $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), $object->id, $enableDelete, $params);
  3689. }
  3690. print '</div>';
  3691. if ($action != 'confirm_edit') {
  3692. print '<div class="fichecenter"><div class="fichehalfleft">';
  3693. /*
  3694. * Generated documents
  3695. */
  3696. $ref = dol_sanitizeFileName($object->ref);
  3697. $subdir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$ref;
  3698. $filedir = $conf->fournisseur->facture->dir_output.'/'.$subdir;
  3699. $urlsource = $_SERVER['PHP_SELF'].'?id='.$object->id;
  3700. $genallowed = $usercanread;
  3701. $delallowed = $usercancreate;
  3702. $modelpdf = (!empty($object->model_pdf) ? $object->model_pdf : (!getDolGlobalString('INVOICE_SUPPLIER_ADDON_PDF') ? '' : $conf->global->INVOICE_SUPPLIER_ADDON_PDF));
  3703. print $formfile->showdocuments('facture_fournisseur', $subdir, $filedir, $urlsource, $genallowed, $delallowed, $modelpdf, 1, 0, 0, 40, 0, '', '', '', $societe->default_lang);
  3704. $somethingshown = $formfile->numoffiles;
  3705. // Show links to link elements
  3706. $linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice_supplier'));
  3707. $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
  3708. print '</div><div class="fichehalfright">';
  3709. // List of actions on element
  3710. include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
  3711. $formactions = new FormActions($db);
  3712. $somethingshown = $formactions->showactions($object, 'invoice_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : ''));
  3713. print '</div></div>';
  3714. }
  3715. }
  3716. }
  3717. // Select mail models is same action as presend
  3718. if (GETPOST('modelselected')) {
  3719. $action = 'presend';
  3720. }
  3721. // Presend form
  3722. $modelmail = 'invoice_supplier_send';
  3723. $defaulttopic = 'SendBillRef';
  3724. $diroutput = $conf->fournisseur->facture->dir_output;
  3725. $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO';
  3726. $trackid = 'sinv'.$object->id;
  3727. include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
  3728. }
  3729. }
  3730. // End of page
  3731. llxFooter();
  3732. $db->close();