card.php 171 KB

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