From d428f79d46157ca3e474e860f4e262902339d109 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Wed, 15 May 2019 12:26:39 +0200 Subject: [PATCH 001/434] NEW: new line template: hidden conf to fill service dates from the last service line --- htdocs/core/tpl/objectline_create.tpl.php | 47 +++++++++++++++++++++++ htdocs/langs/en_US/products.lang | 1 + 2 files changed, 48 insertions(+) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 4a4febe65d3..b76a2f55219 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -464,6 +464,27 @@ if ((! empty($conf->service->enabled) || ($object->element == 'contrat')) && $da global->MAIN_FILL_SERVICE_DATES_FROM_LAST_SERVICE_LINE) && ! empty($object->lines)) + { + for($i = count($object->lines) - 1; $i >= 0; $i--) + { + $lastline = $object->lines[$i]; + + if($lastline->product_type == Product::TYPE_SERVICE && (! empty($lastline->date_start) || ! empty($lastline->date_end))) + { + $date_start_prefill = $lastline->date_start; + $date_end_prefill = $lastline->date_end; + + $prefillDates = true; + break; + } + } + } + + if (! empty($object->element) && $object->element == 'contrat') { print $langs->trans("DateStartPlanned").' '; @@ -478,7 +499,33 @@ if ((! empty($conf->service->enabled) || ($object->element == 'contrat')) && $da echo ' '.$langs->trans('to').' '; print $form->selectDate($date_end, 'date_end', empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1, empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1, 1, "addproduct", 1, 0); }; + + if($prefillDates) + { + echo ' ' . $langs->trans('FillWithLastServiceDates') . ''; + } + print ''; + } + } +} else { + print '
Not Allowed
'.$langs->trans('Back').'
'; +} + + +print ""; + +// End of page +htmlPrintOnlinePaymentFooter($mysoc, $langs, 0, $suffix, $object); + +llxFooter('', 'public'); + +$db->close(); diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php new file mode 100644 index 00000000000..b4d13747d3f --- /dev/null +++ b/htdocs/public/recruitment/view.php @@ -0,0 +1,319 @@ + + * Copyright (C) 2018 Frédéric France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/public/recruitment/view.php + * \ingroup recruitment + * \brief Public file to show on job + */ + +if (!defined('NOCSRFCHECK')) { + define('NOCSRFCHECK', '1'); +} +// Do not check anti CSRF attack test +if (!defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); +} +// If there is no need to load and show top and left menu +if (!defined("NOLOGIN")) { + define("NOLOGIN", '1'); +} +// If this page is public (can be called outside logged session) + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("companies", "other", "recruitment")); + +// Get parameters +$cancel = GETPOST('cancel', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$email = GETPOST('email', 'alpha'); + +$ref = GETPOST('ref', 'alpha'); + +if (GETPOST('btn_view')) { + unset($_SESSION['email_customer']); +} +if (isset($_SESSION['email_customer'])) { + $email = $_SESSION['email_customer']; +} + +$object = new RecruitmentJobPosition($db); + + +/* + * Actions + */ + +if ($cancel) +{ + if (!empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + $action = 'view'; +} + +if ($action == "view" || $action == "presend" || $action == "close" || $action == "confirm_public_close" || $action == "add_message") { + $error = 0; + $display_ticket = false; + if (!strlen($ref)) { + $error++; + array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref"))); + $action = ''; + } + if (!strlen($email)) { + $error++; + array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Email"))); + $action = ''; + } else { + if (!isValidEmail($email)) { + $error++; + array_push($object->errors, $langs->trans("ErrorEmailInvalid")); + $action = ''; + } + } + + if (!$error) { + $ret = $object->fetch('', $ref); + } + + /* + if (!$error && $action == "add_message" && $display_ticket && GETPOSTISSET('btn_add_message')) + { + // TODO Add message... + $ret = $object->dao->newMessage($user, $action, 0, 1); + + + + + if (!$error) + { + $action = 'view'; + } + } + */ + + if ($error || $errors) { + setEventMessages($object->error, $object->errors, 'errors'); + if ($action == "add_message") + { + $action = 'presend'; + } else { + $action = ''; + } + } +} +//var_dump($action); +//$object->doActions($action); + +// Actions to send emails (for ticket, we need to manage the addfile and removefile only) +$triggersendname = 'CANDIDATURE_SENTBYMAIL'; +$paramname = 'id'; +$autocopy = 'MAIN_MAIL_AUTOCOPY_CANDIDATURE_TO'; // used to know the automatic BCC to add +$trackid = 'can'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + + + +/* + * View + */ + +$form = new Form($db); + +if (!$conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE) { + print '
'.$langs->trans('PublicInterfaceForbidden').'
'; + $db->close(); + exit(); +} + +$arrayofjs = array(); +$arrayofcss = array('/ticket/css/styles.css.php'); + +llxHeaderRecruitment($langs->trans("Jobs"), "", 0, 0, $arrayofjs, $arrayofcss); + +print '
'; + +if ($action == "view" || $action == "presend" || $action == "close" || $action == "confirm_public_close") { + if ($display_ticket) + { + // Confirmation close + if ($action == 'close') { + print $form->formconfirm($_SERVER["PHP_SELF"]."?track_id=".$track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1); + } + + print '
'; + + print ''; + + // Ref + print ''; + + // Tracking ID + print ''; + + // Subject + print ''; + + // Statut + print ''; + + // Type + print ''; + + // Category + print ''; + + // Severity + print ''; + + // Creation date + print ''; + + // Author + print ''; + + // Read date + if (!empty($object->dao->date_read)) { + print ''; + } + + // Close date + if (!empty($object->dao->date_close)) { + print ''; + } + + // User assigned + print ''; + + // Progression + print ''; + + print '
'.$langs->trans("Ref").''; + print $object->dao->ref; + print '
'.$langs->trans("TicketTrackId").''; + print $object->dao->track_id; + print '
'.$langs->trans("Subject").''; + print $object->dao->subject; + print '
'.$langs->trans("Status").''; + print $object->dao->getLibStatut(2); + print '
'.$langs->trans("Type").''; + print $object->dao->type_label; + print '
'.$langs->trans("Category").''; + print $object->dao->category_label; + print '
'.$langs->trans("Severity").''; + print $object->dao->severity_label; + print '
'.$langs->trans("DateCreation").''; + print dol_print_date($object->dao->datec, 'dayhour'); + print '
'.$langs->trans("Author").''; + if ($object->dao->fk_user_create > 0) { + $langs->load("users"); + $fuser = new User($db); + $fuser->fetch($object->dao->fk_user_create); + print $fuser->getFullName($langs); + } else { + print dol_escape_htmltag($object->dao->origin_email); + } + + print '
'.$langs->trans("TicketReadOn").''; + print dol_print_date($object->dao->date_read, 'dayhour'); + print '
'.$langs->trans("TicketCloseOn").''; + print dol_print_date($object->dao->date_close, 'dayhour'); + print '
'.$langs->trans("AssignedTo").''; + if ($object->dao->fk_user_assign > 0) { + $fuser = new User($db); + $fuser->fetch($object->dao->fk_user_assign); + print $fuser->getFullName($langs, 1); + } + print '
'.$langs->trans("Progression").''; + print ($object->dao->progress > 0 ? $object->dao->progress : '0').'%'; + print '
'; + + print '
'; + + print '
'; + + if ($action == 'presend') { + print load_fiche_titre($langs->trans('AddMessage'), '', 'messages@ticket'); + + /*$formticket = new FormTicket($db); + + $formticket->action = "add_message"; + $formticket->track_id = $object->dao->track_id; + $formticket->id = $object->dao->id; + + $formticket->param = array('track_id' => $object->dao->track_id, 'fk_user_create' => '-1', 'returnurl' => DOL_URL_ROOT.'/public/ticket/view.php'); + + $formticket->withfile = 2; + $formticket->withcancel = 1; + + $formticket->showMessageForm('100%'); + */ + print 'TODO Show message form'; + } + + if ($action != 'presend') { + print '
'; + print ''; + print ''; + print ''; + print ''; + //print ''; + print "
\n"; + + print '
'; + + // List ticket + print ''; + + if ($object->dao->fk_statut < Ticket::STATUS_CLOSED) { + // New message + print ''; + + // Close ticket + if ($object->dao->fk_statut >= Ticket::STATUS_NOT_READ && $object->dao->fk_statut < Ticket::STATUS_CLOSED) { + print ''; + } + } + + print '
'; + } + + // Message list + print load_fiche_titre($langs->trans('JobMessagesList'), '', 'object_conversation'); + //$object->viewTicketMessages(false, true, $object->dao); + } else { + print ''; + } +} + +print "
"; + +// End of page +htmlPrintOnlinePaymentFooter($mysoc, $langs, 0, $suffix, $object); + +llxFooter('', 'public'); + +$db->close(); diff --git a/htdocs/public/ticket/img/bg_ticket.png b/htdocs/public/ticket/img/bg_ticket.png deleted file mode 100644 index c5fd05c662a721015116ec7cc87e4acf3276721d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9235 zcmXw9cTkhh(}#r6LP8G#0tqM(ng#`=6MFQE5SkR}h*G2~T}r5eKq81BA`*&5lqy|% z7g34`2vP%zi1c3HIKO%SdFEzzZ*O;R?{4?APa@vP0KzK3N=HWrxr);@rK6)iPaE$u zGt$0#{?FOy=*~@C)zvZ&rvE$T`UK%RaklX+5!@;AkxM(4!&b*Ph#9s|eGXZL9TQwZ zwX+x4(-KzV6>i0JaB2IFq5RHUUAp=ztnk;~S+4p?zVVCPXSvUs-!7Lntlrb`Nqbt{ zTy}VU=bIRBa<$(DXtz|FRI;2nTe5{OrWaL-J|o)saz35Yv5gg3jJW5L?8Mflx6kp( zm$TvF8Cb)YV^s_2A1rK;A9i!*2iyfd<##^U01ByNieW{LjiisYQStT)t38TE7oz04 zF*R)`l=w~I9u+<0O#36Rge!S~GUv=!xh~0a$#&~f=ChEyV=G(N9&E&H@R~b{2Y%A* zhM(&ghg>ED9Oh=za%YmREXRIbKW9Fxu#!7{71NCg?D51CkbVLx8OJJK!PE>t4tYN?@RMwgw9PKH@I4r1LcrX z<$%mQPk-??c*j!Gf8_uv43eqlXy;QEN!^!sIS(-7sCg#Q4(}L8&R{{yzPzDN7S;P2 zTMIS-JnL-wM_2yIbW;O@8u6=tC%&;Fl6)SW|Gl_$H~p^Rv78Fke?$w^+(o`H{dKYL zU92FUop+!4`S(~sZinR0>zw9!!dD!{?yL#6CzTNS+j!qMiE(?@Semo*W)XH?v_#^h ztrJ=H+jgHeI^Qi@Vlu?KqCatLvhHdXwhLrJI_PcRsiE_O}oNbpBT#IYW$FWBjE z~0E;%)D7KpIzYRd@JK z7Zp!%*SLFGBfOUzFI0ybc`C_5rdJa3(J67B?*0uYrC}y6`L=a>7_Pe>gddeB%zbNh zm-v-`i6AlpVxqE)=)AI9-e7?0XU0b8sb29t?0F0S`89NZzb&ZsjGqxe+uzu|qb?mjUsbdt@c~|caM7!x6gOt%+;t4H|Is?mRE3KAQZwQ_@Z=&=Fax4)1bodft z3nlQVhioNBba}^=39e`F^K32Dz59v9WBD&n-P=_*wuep}f1`foSzR7*I)aZL(DgI_ z5DJvoh=k$fI^an`0Ewkiz5;53eQcw%eW!}to3$N)M0azH?hF0&5y9{3a3!dVZLHP^ za4ZkHnf9hbVTsepjtE91>^aVEvx5tjTym0Bn3Z$*wBSMy5AdQ{2TGV|8x3}4<^Uyy zbvXDu5>wN)M`)3<(`L@+%z}!gJxk>j8S%+%oj%5^$;{3Gk zHGN558#BThf5j|Pkm<|F%aqnR1{m&5`x0?1uhDh9DKQ3-iDj`QUR+ly?eZIES9N03 zcfs7yw%{H+v}cKt6L2Z#-tF+KgAu9Vk=F~-KL~ou-a#@koAx@9|F#i!Z3+;y`K~86 z8nVKOcJdDv407S>cH&Wq4?Z7ekle0h*gh33sEl^<##*#3X8i#Md92=^%m;DN>GOKW z)7@X%K01bgGdNz(!Vpm!6)(U~AxyKd2LLf(weEG^QMh;fR7q_xioYAg5w#O&*(FIl zXrO-(6XpwN3{{noQH6G>?=x;f6?A1KIrRCe>P}&}SNR4r(JjvK=6Wfk2P2vDXZ*EJ zcb$JF1ax@q^Czi$BnU_`i{f2sN~}>Cq0TFoypu?2C`k{5ag((`969D(ByO-HqP|FG zzx|>_cZL<>Q5|8cHsjFG$gkOaog*I^T?$Hz8|vN{J}eV5mSGm#K1h)g|H1z{IuiIg z@8#Xq!#SQt`Yu4V_GbzvnewK+=K(Q4;h7c6T5B!VgSmI|z}&(d7Hdk>C|24&q&zyg zDj%M1`23UX#(5rok64?JV-Sjn$D47Nw-sh{n>SI`^vGBn3dL?9FRysBEAGpbdBqtr zfB#v8fTC2$)Lr{4?eYtGgLuIaoEF?7QNUwWxmpRA_W9X6w;nRR$Ea|+xyd*3EGa6r zc>HgFIn?|CvuACHx>xF0w+6D_hAkKaBE&j>4d*8?{J5@I~`N~(4gXa3wo6}?4`wTe=%?>3$1xCXD!kTS}) zNp*Rc8gm5pw?h$D&?5_EGj-kVa8Cnh>F5;kO-LbetUN zzP@sZvqlHB>d7iLJ-hi+3A2_5Lre{Scn>nIWG!Je6A5Z5HRr*W5k3ojI}r-3;&`}I zRtC;iJItTh(F%2NH0GtUV7p%Tr0oxb&Q&YI)X5OidC+sjryhi($oNTM27SwLDcWK zqj;%BzXD&}6|AYD(*Y;iP&n>M|5VDJ0DP&%Zb~QDXsh!)EAW1PZ6g8#l6Q1&)YR$7 zddP^LeVbI^9gblPivQjR_(;SoKRUq2mVV*e@qNGqlAliwj);%d&6D5Y{k&c+b};CcOneaA9!5kTvI;KJuHP zi#!uAXZoWi!R|G(s6Xve%T{Hm#_N8m#3rrrA1mM){NXd&6))Kp=8R#?L(a!69_ob3@zJ7tH@{TMipQRv%Op@(cy5x4#tMRMO);MVM@qH{*LzNeMF#6)D7qR zoxkvxzudQdZ?`VYlkWg*GBTi@hFI+?z@ONv4K-E;>d0u*E2kXVV2HFFc->q_q+t;7 z@o!;Zk26}ATjxh`sFOW7Jk=g1U$U?Ed~M*fP8r9aJq%j+(a;n?Qu)r7ra+s170@5g zU3%efH5=7~!lJywp#{-&v;?|k8#|4F9_5i_+KT1WTBIg7%e3O>1;6 zF!Fx~V_ksXx@g_UJD%_t8yX|AXP&1DY}B(n@kZho&e6>Z{6nKEtkfDqAlm`ML=c{L zgRxq;63>|eH#@G6mt#!9b6UUSi&33#WQ@CI6yo#Un;=imdi9(l@nd`dY$Vn)Npk>W zPssMYVdxQhP97`r%#mQ;e6$$}jaw+qdJ(pxHWCYD74~UWqVs6qq9mJm%`n6*Y;CUW z+(i8a#w{3Zr+jCu5r`lpWu+Lwbmqre>=JrX+ez?K-z^YNbfzq6Lh-83P}V502i_saZ9#}^VU(I*jU-z^HJ%;xAo&ZSCl}&` zGh{z~0glUq)cV$94`n_}ATKd$Q@VOZ4MeYC>4`-cl5h+_03*I$_m~og!Msw41Q zkRjPzk$WB&{KJHp&bNlwNG6d(Cb0veX7l0JZ&SgJoexTV%W+AQ@p$ zZjYd*c!{Ae#(V{y&46BN(O)b?lkB4a8akPxJrb^YjTz3zpJx$hhAXrTLQzDh9PTfZ z&?YxM-k=StY`ZPv0$#|Anlk0k|DZ*$eAi^5hah8~=a~$Aqq&UgffeX{`gDsRFTS%^ z1}FfU=Rw~mJqY*!Wew)bU}&=bA_4!{$ja+*ID{m=|z51MMRDg(ru0`-;) zTmt+#whPnV@5xa*+z4EPHvRh{+4Z{g#{^dS33Vp=oUzSKE0j7!xdx%GHom@0j$(^v z6t0E%;|XPhl4Oa&2oP_t({oYFDG>rUt`_#=Ev?umv$ zXUGQ8?G&bF=}L)l_4PU`iI8NqdKKjbj&uC;DzgLdo2$1%kFt3SXv?ZVX4FZ_`2$-~ zwadxFHYkm=OZk^haExHDTPK8*OaKl4M{*ept)f3=Qy@bx@`ilzYJ+f` zaB=9LBr$Az=?U*~E$4|JuMDNgp0X+Lrh!a1*juD4NiLJ2Rh*}E3g==H3BR^GX$9pD z3v=NgGT`3e<@Kz@UhL=nwgRjGQ2D9eV``-gDKHvwlVBw575gX;_O5ldbt^EQ^;Shg zk5g6XW5zRD46=2zQb3Q?SPP+60OcC9*(N8#eg1{<%eh_;@8!Wp=IccVn!r-)Q9Xoh zI`i35QDO+R8V~*%99a7^QY+OC7VKb!YGPFmY`!BnpNVI=q*U2k@4H2AM2zlWl1KHR zeb0#*0HQJ%KZU^|6o$KlO>OcZ@Nf*5{)P`Ib{mtqWII}0w}KK_k3V%_5Bba;_e3+@ ztr;_x%mx7N;k^}NFdTY+kSTtHTo7|dkjjKltlSTJJXXgpRi0t+r-j#iwpo;TaHSHT zsIe|XlG0K6-Z)Eq1{#KvTr^gN8X?u%j0v!M1e-apwdJTu zKCRThq)1IG)C)T0z*h+bd2Wv)k9SHJUMd-8MTI(4ymTiP_AQX-h!h@B~2P3Pnhm8J9g2u#_ z5H61bu_a`1Qw1ev-6MJI$bvZlF1X)vY6YksO4k?#C>*;B)I6@sxs(=z$X<0vod|gp zu$|g3C=A4J)+ElU_y8AQOm*H#BTOu<Zl6gCYuG@h`nD}jE z40QkF>kYn5xUae}&S4DvEly#p9Dkh{VG4}za zcGulb_OP^(&G8Tw8w&GZ0?}Bm_mW?$wNS!gQUzUB-(vzC_#crk_02mIfxmr7IzHE6 zxR+Yc>pM!MF9r~EeTBNon1Ghap@x@heyEd+3xjvkK*QR-#gpCJb;Z&_g zGZcZ7aC}w(*?Iym+mlR<4(2ynSE8jHh`u5f(mq`%HuVM74<(f1(Myn^Mq~h)iv6m3 z2=}EHtcdbV!`QR3*k4d8I)PBdlkw&^lKz`g9~GNTr>uziOpxdDUty-1gijzm>1y~N zb%cr)U{_YWM58kJuecF`?rOy%J>i85d&DS@{Xg~6cqHsXP9NJzUg}g;bC9)02?3P@3x5&J<7!QQRT7^Jo|*_v>u3BT z+~-&rm!p}YNOFnfT3fu_&3wyt_c7OmW}jp1+LkfIfkC+@oW|Jfg`ZzLGN|4+HvRcRAeUz7z0)Q~ zg8WzS*LDKk9#(VB#D(xPH_#2~5bG7iiOXASAaLOkci5aH6Wl0kG#YVa+Gv@E*);J1Bm#ToBfhJ3Oe{#P+^LF5ug!!j|>#*#6RA< zTGC8c^jp#C_lKWgjA$ESg#Z1}Y%`I^`iw%$f0Wytss#K=E=<-ag-FRX{oacIxSKPp zM3#T-Jr@0g{N~gVyC!5ur#$+Q1`mBU?qtFb`#k(5Ky@CWc{z?2d2L-+Uut@6bN5!T z+t|avg&*Bh^ELonWL8m$3eGtVq_6e_2*ajJB@<>u#Dp zxkf0wFkMLI>&L%K$ZyW(^S@*pHT$SG_QK#odrAW0i2sEd$F)0oj2ZNaQ-xiQFTyhi8eK(S*X`Cqehi?+UZNyRK?#{d zM(+x^aP<0@a6GfUVMGNm`3@;y(7^wjX5aj?s($wBeIGQ#UUkF)EeVQR;fUIFdY9zE z6n@_Fq`>1{HVu(uE%OCFK5|dv8@eaiKZ#Nn2Ix))AG-Hn$aH!<2$&E_FMq zv_X|X;ub1m`zGLc85f z<`SOJ0U&+{R(ma-t6!zLo!EMhJ%;rbMp4A63MP=p(KvPLT7y*qvVN3issFYcgl`>y z^8~M)^ge-e{i%8%X?|_r)i-jsK4$$g&$`f!|F9@^rno{jgNB=^oeqEWd2Y3q`h~bxE~EJRT9me&nTRa2H*2$N`>%EsY45Bg^`SbCb)3Z@CO8si@^HO9%?xXsD~l< zz3ejW`nk433%<$LtyF@|de&>FDlV9oNIm(%Cm(`5+!}qpHcS8q5fh%gEWh3;XaZDl zdDC%f0`X>3yW^JFW2jJ7$F^&r_^1trTYS-~nnzkFf0i(&X_{z{b#1%%Vcv7WX8D}* z5^`}}p@A{=WhlLr3DZEkTlk1h;2WVxpu1IX`o4HEEngMJOXmm#pT44az9BB;MVcpE z2M#Fndc+9}fAbTwkJC0KI>B(>;#*p1U5QX0TsZlL6+r=5wqYgi&i)R&7=3Pc~^kigR&M3mj0+%+I zw-{QQs3rV&@ght84rbzCMQ;?Ny{*v@%7OF5icvZYZR70*D}o1JpM)2hI!JRo{4jf| zUsuRHT0xC6`6ZZ}bx3~i&uu~#XDncp=hizAuL;q*j_X6lu#c0W_Vx7e!reWh2j)#@ z^SE~%*Lzyatm3Ji#0N@>4C%O~v&7PJ9Gt^a)(EN-2+O-8X#bYgCy!QX<-a&7P-!F- zE6P|JuMpl=(DhBCe(p3Nc}RKxjo6^Pk`X-lMR0y9b^_6-`j)Ni3L8J#(Ovb(fS*me zWAg=Q(Myvfxzb=*7NT~kD^$~K1?lSh;Mr3z z`6snrhMra2x3xq*h#l`#W0&LB$fPNOuhoI_5^}m?Q4`d0u$X+ z?3va+$Q{mFu7NZk&3 zUNhNUb=~Dh_K#$sNb+7saQfxZIzq zz9ZBep?Pe24JkROc?dc|To`+w1y5J8WpB~utW(jLECiXd_a}(1tH<}CNJgF3sWUDJ z4-qvJ?K29Din#dIT1k#kp-u&+&6!0MhT%3?i-6>Z4-zdzp@o+*DzSSZ%n+*y8Z$k6 zT)A3-pMGcc7~e}RPL|z48Im*CHDfGi2oiXXt?-O*_~>2on#jAax@Wk3VQGVw)i0i< zn$yvuT;pab+~7ibD+av<&*Wq@i7|HHUNxUn;>wVwM`tRF?Ve*(3E^ViLz#BEe^}x$ z4Qv(N1S(!_^QyntX0LY|e$h59`ldq}as%1Ic=u)9fC9P8pM{6KJS##kZn9G?^c2gv ziQbka6|bxDkSCVdbLCT^q5W9SP+C&4tKJ4KL}Wy3&oD)*T}>%y>26gN4`z0;0)t!5CW8}7^GkMB1$q~;XX!!JfTFBur> z7QNr8MHP3hmBW+BVB69bP}D%smg%2&tQ-MIUsoIU)De;Mp%`m^%57(2ZUEGq*I z-3Vq)s*t1@2BECUf$iz|{-*I)(#+$>tI2%itT3(@otJ36kD!sn@D!HYkmE=e)djE~U+UB`#HR z>cbS+%mf&c&zXMB+5mhWTvUK(5BbUTw`st$%#+uP89e)x2C z9k~TlsR*Zj!S~>OGbj!8Rndx$|7$X6Ts%3u3R{U^ru9Qiy4B($oW_bk zY2k6Id^;pLN>BYRuWTQ-(s6=o3zhD%RbJ%94Z}U`G9EP(Nxx=B4K6aKx#*RhoZzK5 z7{L$S_2U1$(lEQ%i%qhn$10hi%9t`JNSt(kg*3d3p4q=wMnYOJB7rsLE9 zwFK4ugqB698KJfbxmVx*_fK8`hF2LqY6vx}FdF`6U9>xo@WVyn^fx^~ct%YFO-0>X0ve@>6HDmZfzpz6WIb@;}9PzY(i@SM`U7AAJ7E z!W&>;&KPXHxDF5>FS`xHdAZEVGw{{?Y2W>6W*a4P!)(!oaBHrL-@DtnSKd?3yZiPH zRT!@OM3&I)B;bJpYJd$p>fF3fZqar(N5w_;n7%9zb}iASF_ZmY--~k3d}Qj^fWVphC%Bsa@!;8QRZ2bXWC^bW61zqyG Date: Sun, 26 Jul 2020 22:04:19 +0200 Subject: [PATCH 051/434] Removed not used files --- htdocs/public/ticket/img/bg_ticket.png | Bin 9235 -> 0 bytes htdocs/public/ticket/img/index.html | 1 - 2 files changed, 1 deletion(-) delete mode 100644 htdocs/public/ticket/img/bg_ticket.png delete mode 100644 htdocs/public/ticket/img/index.html diff --git a/htdocs/public/ticket/img/bg_ticket.png b/htdocs/public/ticket/img/bg_ticket.png deleted file mode 100644 index c5fd05c662a721015116ec7cc87e4acf3276721d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9235 zcmXw9cTkhh(}#r6LP8G#0tqM(ng#`=6MFQE5SkR}h*G2~T}r5eKq81BA`*&5lqy|% z7g34`2vP%zi1c3HIKO%SdFEzzZ*O;R?{4?APa@vP0KzK3N=HWrxr);@rK6)iPaE$u zGt$0#{?FOy=*~@C)zvZ&rvE$T`UK%RaklX+5!@;AkxM(4!&b*Ph#9s|eGXZL9TQwZ zwX+x4(-KzV6>i0JaB2IFq5RHUUAp=ztnk;~S+4p?zVVCPXSvUs-!7Lntlrb`Nqbt{ zTy}VU=bIRBa<$(DXtz|FRI;2nTe5{OrWaL-J|o)saz35Yv5gg3jJW5L?8Mflx6kp( zm$TvF8Cb)YV^s_2A1rK;A9i!*2iyfd<##^U01ByNieW{LjiisYQStT)t38TE7oz04 zF*R)`l=w~I9u+<0O#36Rge!S~GUv=!xh~0a$#&~f=ChEyV=G(N9&E&H@R~b{2Y%A* zhM(&ghg>ED9Oh=za%YmREXRIbKW9Fxu#!7{71NCg?D51CkbVLx8OJJK!PE>t4tYN?@RMwgw9PKH@I4r1LcrX z<$%mQPk-??c*j!Gf8_uv43eqlXy;QEN!^!sIS(-7sCg#Q4(}L8&R{{yzPzDN7S;P2 zTMIS-JnL-wM_2yIbW;O@8u6=tC%&;Fl6)SW|Gl_$H~p^Rv78Fke?$w^+(o`H{dKYL zU92FUop+!4`S(~sZinR0>zw9!!dD!{?yL#6CzTNS+j!qMiE(?@Semo*W)XH?v_#^h ztrJ=H+jgHeI^Qi@Vlu?KqCatLvhHdXwhLrJI_PcRsiE_O}oNbpBT#IYW$FWBjE z~0E;%)D7KpIzYRd@JK z7Zp!%*SLFGBfOUzFI0ybc`C_5rdJa3(J67B?*0uYrC}y6`L=a>7_Pe>gddeB%zbNh zm-v-`i6AlpVxqE)=)AI9-e7?0XU0b8sb29t?0F0S`89NZzb&ZsjGqxe+uzu|qb?mjUsbdt@c~|caM7!x6gOt%+;t4H|Is?mRE3KAQZwQ_@Z=&=Fax4)1bodft z3nlQVhioNBba}^=39e`F^K32Dz59v9WBD&n-P=_*wuep}f1`foSzR7*I)aZL(DgI_ z5DJvoh=k$fI^an`0Ewkiz5;53eQcw%eW!}to3$N)M0azH?hF0&5y9{3a3!dVZLHP^ za4ZkHnf9hbVTsepjtE91>^aVEvx5tjTym0Bn3Z$*wBSMy5AdQ{2TGV|8x3}4<^Uyy zbvXDu5>wN)M`)3<(`L@+%z}!gJxk>j8S%+%oj%5^$;{3Gk zHGN558#BThf5j|Pkm<|F%aqnR1{m&5`x0?1uhDh9DKQ3-iDj`QUR+ly?eZIES9N03 zcfs7yw%{H+v}cKt6L2Z#-tF+KgAu9Vk=F~-KL~ou-a#@koAx@9|F#i!Z3+;y`K~86 z8nVKOcJdDv407S>cH&Wq4?Z7ekle0h*gh33sEl^<##*#3X8i#Md92=^%m;DN>GOKW z)7@X%K01bgGdNz(!Vpm!6)(U~AxyKd2LLf(weEG^QMh;fR7q_xioYAg5w#O&*(FIl zXrO-(6XpwN3{{noQH6G>?=x;f6?A1KIrRCe>P}&}SNR4r(JjvK=6Wfk2P2vDXZ*EJ zcb$JF1ax@q^Czi$BnU_`i{f2sN~}>Cq0TFoypu?2C`k{5ag((`969D(ByO-HqP|FG zzx|>_cZL<>Q5|8cHsjFG$gkOaog*I^T?$Hz8|vN{J}eV5mSGm#K1h)g|H1z{IuiIg z@8#Xq!#SQt`Yu4V_GbzvnewK+=K(Q4;h7c6T5B!VgSmI|z}&(d7Hdk>C|24&q&zyg zDj%M1`23UX#(5rok64?JV-Sjn$D47Nw-sh{n>SI`^vGBn3dL?9FRysBEAGpbdBqtr zfB#v8fTC2$)Lr{4?eYtGgLuIaoEF?7QNUwWxmpRA_W9X6w;nRR$Ea|+xyd*3EGa6r zc>HgFIn?|CvuACHx>xF0w+6D_hAkKaBE&j>4d*8?{J5@I~`N~(4gXa3wo6}?4`wTe=%?>3$1xCXD!kTS}) zNp*Rc8gm5pw?h$D&?5_EGj-kVa8Cnh>F5;kO-LbetUN zzP@sZvqlHB>d7iLJ-hi+3A2_5Lre{Scn>nIWG!Je6A5Z5HRr*W5k3ojI}r-3;&`}I zRtC;iJItTh(F%2NH0GtUV7p%Tr0oxb&Q&YI)X5OidC+sjryhi($oNTM27SwLDcWK zqj;%BzXD&}6|AYD(*Y;iP&n>M|5VDJ0DP&%Zb~QDXsh!)EAW1PZ6g8#l6Q1&)YR$7 zddP^LeVbI^9gblPivQjR_(;SoKRUq2mVV*e@qNGqlAliwj);%d&6D5Y{k&c+b};CcOneaA9!5kTvI;KJuHP zi#!uAXZoWi!R|G(s6Xve%T{Hm#_N8m#3rrrA1mM){NXd&6))Kp=8R#?L(a!69_ob3@zJ7tH@{TMipQRv%Op@(cy5x4#tMRMO);MVM@qH{*LzNeMF#6)D7qR zoxkvxzudQdZ?`VYlkWg*GBTi@hFI+?z@ONv4K-E;>d0u*E2kXVV2HFFc->q_q+t;7 z@o!;Zk26}ATjxh`sFOW7Jk=g1U$U?Ed~M*fP8r9aJq%j+(a;n?Qu)r7ra+s170@5g zU3%efH5=7~!lJywp#{-&v;?|k8#|4F9_5i_+KT1WTBIg7%e3O>1;6 zF!Fx~V_ksXx@g_UJD%_t8yX|AXP&1DY}B(n@kZho&e6>Z{6nKEtkfDqAlm`ML=c{L zgRxq;63>|eH#@G6mt#!9b6UUSi&33#WQ@CI6yo#Un;=imdi9(l@nd`dY$Vn)Npk>W zPssMYVdxQhP97`r%#mQ;e6$$}jaw+qdJ(pxHWCYD74~UWqVs6qq9mJm%`n6*Y;CUW z+(i8a#w{3Zr+jCu5r`lpWu+Lwbmqre>=JrX+ez?K-z^YNbfzq6Lh-83P}V502i_saZ9#}^VU(I*jU-z^HJ%;xAo&ZSCl}&` zGh{z~0glUq)cV$94`n_}ATKd$Q@VOZ4MeYC>4`-cl5h+_03*I$_m~og!Msw41Q zkRjPzk$WB&{KJHp&bNlwNG6d(Cb0veX7l0JZ&SgJoexTV%W+AQ@p$ zZjYd*c!{Ae#(V{y&46BN(O)b?lkB4a8akPxJrb^YjTz3zpJx$hhAXrTLQzDh9PTfZ z&?YxM-k=StY`ZPv0$#|Anlk0k|DZ*$eAi^5hah8~=a~$Aqq&UgffeX{`gDsRFTS%^ z1}FfU=Rw~mJqY*!Wew)bU}&=bA_4!{$ja+*ID{m=|z51MMRDg(ru0`-;) zTmt+#whPnV@5xa*+z4EPHvRh{+4Z{g#{^dS33Vp=oUzSKE0j7!xdx%GHom@0j$(^v z6t0E%;|XPhl4Oa&2oP_t({oYFDG>rUt`_#=Ev?umv$ zXUGQ8?G&bF=}L)l_4PU`iI8NqdKKjbj&uC;DzgLdo2$1%kFt3SXv?ZVX4FZ_`2$-~ zwadxFHYkm=OZk^haExHDTPK8*OaKl4M{*ept)f3=Qy@bx@`ilzYJ+f` zaB=9LBr$Az=?U*~E$4|JuMDNgp0X+Lrh!a1*juD4NiLJ2Rh*}E3g==H3BR^GX$9pD z3v=NgGT`3e<@Kz@UhL=nwgRjGQ2D9eV``-gDKHvwlVBw575gX;_O5ldbt^EQ^;Shg zk5g6XW5zRD46=2zQb3Q?SPP+60OcC9*(N8#eg1{<%eh_;@8!Wp=IccVn!r-)Q9Xoh zI`i35QDO+R8V~*%99a7^QY+OC7VKb!YGPFmY`!BnpNVI=q*U2k@4H2AM2zlWl1KHR zeb0#*0HQJ%KZU^|6o$KlO>OcZ@Nf*5{)P`Ib{mtqWII}0w}KK_k3V%_5Bba;_e3+@ ztr;_x%mx7N;k^}NFdTY+kSTtHTo7|dkjjKltlSTJJXXgpRi0t+r-j#iwpo;TaHSHT zsIe|XlG0K6-Z)Eq1{#KvTr^gN8X?u%j0v!M1e-apwdJTu zKCRThq)1IG)C)T0z*h+bd2Wv)k9SHJUMd-8MTI(4ymTiP_AQX-h!h@B~2P3Pnhm8J9g2u#_ z5H61bu_a`1Qw1ev-6MJI$bvZlF1X)vY6YksO4k?#C>*;B)I6@sxs(=z$X<0vod|gp zu$|g3C=A4J)+ElU_y8AQOm*H#BTOu<Zl6gCYuG@h`nD}jE z40QkF>kYn5xUae}&S4DvEly#p9Dkh{VG4}za zcGulb_OP^(&G8Tw8w&GZ0?}Bm_mW?$wNS!gQUzUB-(vzC_#crk_02mIfxmr7IzHE6 zxR+Yc>pM!MF9r~EeTBNon1Ghap@x@heyEd+3xjvkK*QR-#gpCJb;Z&_g zGZcZ7aC}w(*?Iym+mlR<4(2ynSE8jHh`u5f(mq`%HuVM74<(f1(Myn^Mq~h)iv6m3 z2=}EHtcdbV!`QR3*k4d8I)PBdlkw&^lKz`g9~GNTr>uziOpxdDUty-1gijzm>1y~N zb%cr)U{_YWM58kJuecF`?rOy%J>i85d&DS@{Xg~6cqHsXP9NJzUg}g;bC9)02?3P@3x5&J<7!QQRT7^Jo|*_v>u3BT z+~-&rm!p}YNOFnfT3fu_&3wyt_c7OmW}jp1+LkfIfkC+@oW|Jfg`ZzLGN|4+HvRcRAeUz7z0)Q~ zg8WzS*LDKk9#(VB#D(xPH_#2~5bG7iiOXASAaLOkci5aH6Wl0kG#YVa+Gv@E*);J1Bm#ToBfhJ3Oe{#P+^LF5ug!!j|>#*#6RA< zTGC8c^jp#C_lKWgjA$ESg#Z1}Y%`I^`iw%$f0Wytss#K=E=<-ag-FRX{oacIxSKPp zM3#T-Jr@0g{N~gVyC!5ur#$+Q1`mBU?qtFb`#k(5Ky@CWc{z?2d2L-+Uut@6bN5!T z+t|avg&*Bh^ELonWL8m$3eGtVq_6e_2*ajJB@<>u#Dp zxkf0wFkMLI>&L%K$ZyW(^S@*pHT$SG_QK#odrAW0i2sEd$F)0oj2ZNaQ-xiQFTyhi8eK(S*X`Cqehi?+UZNyRK?#{d zM(+x^aP<0@a6GfUVMGNm`3@;y(7^wjX5aj?s($wBeIGQ#UUkF)EeVQR;fUIFdY9zE z6n@_Fq`>1{HVu(uE%OCFK5|dv8@eaiKZ#Nn2Ix))AG-Hn$aH!<2$&E_FMq zv_X|X;ub1m`zGLc85f z<`SOJ0U&+{R(ma-t6!zLo!EMhJ%;rbMp4A63MP=p(KvPLT7y*qvVN3issFYcgl`>y z^8~M)^ge-e{i%8%X?|_r)i-jsK4$$g&$`f!|F9@^rno{jgNB=^oeqEWd2Y3q`h~bxE~EJRT9me&nTRa2H*2$N`>%EsY45Bg^`SbCb)3Z@CO8si@^HO9%?xXsD~l< zz3ejW`nk433%<$LtyF@|de&>FDlV9oNIm(%Cm(`5+!}qpHcS8q5fh%gEWh3;XaZDl zdDC%f0`X>3yW^JFW2jJ7$F^&r_^1trTYS-~nnzkFf0i(&X_{z{b#1%%Vcv7WX8D}* z5^`}}p@A{=WhlLr3DZEkTlk1h;2WVxpu1IX`o4HEEngMJOXmm#pT44az9BB;MVcpE z2M#Fndc+9}fAbTwkJC0KI>B(>;#*p1U5QX0TsZlL6+r=5wqYgi&i)R&7=3Pc~^kigR&M3mj0+%+I zw-{QQs3rV&@ght84rbzCMQ;?Ny{*v@%7OF5icvZYZR70*D}o1JpM)2hI!JRo{4jf| zUsuRHT0xC6`6ZZ}bx3~i&uu~#XDncp=hizAuL;q*j_X6lu#c0W_Vx7e!reWh2j)#@ z^SE~%*Lzyatm3Ji#0N@>4C%O~v&7PJ9Gt^a)(EN-2+O-8X#bYgCy!QX<-a&7P-!F- zE6P|JuMpl=(DhBCe(p3Nc}RKxjo6^Pk`X-lMR0y9b^_6-`j)Ni3L8J#(Ovb(fS*me zWAg=Q(Myvfxzb=*7NT~kD^$~K1?lSh;Mr3z z`6snrhMra2x3xq*h#l`#W0&LB$fPNOuhoI_5^}m?Q4`d0u$X+ z?3va+$Q{mFu7NZk&3 zUNhNUb=~Dh_K#$sNb+7saQfxZIzq zz9ZBep?Pe24JkROc?dc|To`+w1y5J8WpB~utW(jLECiXd_a}(1tH<}CNJgF3sWUDJ z4-qvJ?K29Din#dIT1k#kp-u&+&6!0MhT%3?i-6>Z4-zdzp@o+*DzSSZ%n+*y8Z$k6 zT)A3-pMGcc7~e}RPL|z48Im*CHDfGi2oiXXt?-O*_~>2on#jAax@Wk3VQGVw)i0i< zn$yvuT;pab+~7ibD+av<&*Wq@i7|HHUNxUn;>wVwM`tRF?Ve*(3E^ViLz#BEe^}x$ z4Qv(N1S(!_^QyntX0LY|e$h59`ldq}as%1Ic=u)9fC9P8pM{6KJS##kZn9G?^c2gv ziQbka6|bxDkSCVdbLCT^q5W9SP+C&4tKJ4KL}Wy3&oD)*T}>%y>26gN4`z0;0)t!5CW8}7^GkMB1$q~;XX!!JfTFBur> z7QNr8MHP3hmBW+BVB69bP}D%smg%2&tQ-MIUsoIU)De;Mp%`m^%57(2ZUEGq*I z-3Vq)s*t1@2BECUf$iz|{-*I)(#+$>tI2%itT3(@otJ36kD!sn@D!HYkmE=e)djE~U+UB`#HR z>cbS+%mf&c&zXMB+5mhWTvUK(5BbUTw`st$%#+uP89e)x2C z9k~TlsR*Zj!S~>OGbj!8Rndx$|7$X6Ts%3u3R{U^ru9Qiy4B($oW_bk zY2k6Id^;pLN>BYRuWTQ-(s6=o3zhD%RbJ%94Z}U`G9EP(Nxx=B4K6aKx#*RhoZzK5 z7{L$S_2U1$(lEQ%i%qhn$10hi%9t`JNSt(kg*3d3p4q=wMnYOJB7rsLE9 zwFK4ugqB698KJfbxmVx*_fK8`hF2LqY6vx}FdF`6U9>xo@WVyn^fx^~ct%YFO-0>X0ve@>6HDmZfzpz6WIb@;}9PzY(i@SM`U7AAJ7E z!W&>;&KPXHxDF5>FS`xHdAZEVGw{{?Y2W>6W*a4P!)(!oaBHrL-@DtnSKd?3yZiPH zRT!@OM3&I)B;bJpYJd$p>fF3fZqar(N5w_;n7%9zb}iASF_ZmY--~k3d}Qj^fWVphC%Bsa@!;8QRZ2bXWC^bW61zqyG Date: Mon, 27 Jul 2020 02:25:09 +0200 Subject: [PATCH 052/434] FIX Setup of clicktodial hang on smartphone --- htdocs/admin/clicktodial.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php index 4c386aa7792..b92d3d316f7 100644 --- a/htdocs/admin/clicktodial.php +++ b/htdocs/admin/clicktodial.php @@ -60,6 +60,8 @@ if ($action == 'setvalue' && $user->admin) * View */ +$form = new Form($db); + $user->fetch_clicktodial(); $wikihelp = 'EN:Module_ClickToDial_En|FR:Module_ClickToDial|ES:Módulo_ClickTodial_Es'; From 8cd4636de7ee5e59f117bb43a5f00beb8b787fa1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Jul 2020 02:27:27 +0200 Subject: [PATCH 053/434] Fix responsive --- htdocs/admin/clicktodial.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php index b92d3d316f7..5fa7b78ca8b 100644 --- a/htdocs/admin/clicktodial.php +++ b/htdocs/admin/clicktodial.php @@ -77,6 +77,7 @@ print '
'; print ''; print ''; +print '
'; print ''; print ''; print ''; @@ -109,6 +110,7 @@ print $langs->trans("Example").':
http://myphoneserver/mypage?login=__LOGIN__ print ''; print '
'.$langs->trans("Name").'
'; +print '
'; print '

'; From 0011e092482e24eebf0d316e8062d7bfc82ee27b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Jul 2020 02:25:09 +0200 Subject: [PATCH 054/434] FIX Setup of clicktodial hang on smartphone --- htdocs/admin/clicktodial.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php index 8d22e01b436..f6033934077 100644 --- a/htdocs/admin/clicktodial.php +++ b/htdocs/admin/clicktodial.php @@ -62,6 +62,8 @@ if ($action == 'setvalue' && $user->admin) * View */ +$form = new Form($db); + $user->fetch_clicktodial(); $wikihelp = 'EN:Module_ClickToDial_En|FR:Module_ClickToDial|ES:Módulo_ClickTodial_Es'; From 9798bb1b30b92b18ff05495983538533d94b91b3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Jul 2020 02:27:27 +0200 Subject: [PATCH 055/434] Fix responsive --- htdocs/admin/clicktodial.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php index f6033934077..13efb42af1a 100644 --- a/htdocs/admin/clicktodial.php +++ b/htdocs/admin/clicktodial.php @@ -79,6 +79,7 @@ print ''; print ''; print ''; +print '
'; print ''; print ''; print ''; @@ -111,6 +112,7 @@ print $langs->trans("Example").':
http://myphoneserver/mypage?login=__LOGIN__ print ''; print '
'.$langs->trans("Name").'
'; +print '
'; print '

'; From 19b550009b3dd9710d6795acc8c0229641967e1e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Jul 2020 02:38:31 +0200 Subject: [PATCH 056/434] Trans --- htdocs/langs/en_US/admin.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 5887f6cde4a..c99c436915d 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1687,7 +1687,7 @@ AGENDA_SHOW_LINKED_OBJECT=Show linked object into agenda view ##### Clicktodial ##### ClickToDialSetup=Click To Dial module setup ClickToDialUrlDesc=Url called when a click on phone picto is done. In URL, you can use tags
__PHONETO__ that will be replaced with the phone number of person to call
__PHONEFROM__ that will be replaced with phone number of calling person (yours)
__LOGIN__ that will be replaced with clicktodial login (defined on user card)
__PASS__ that will be replaced with clicktodial password (defined on user card). -ClickToDialDesc=This module makea phone numbers clickable links. A click on the icon will make your phone call the number. This can be used to call a call-center system from Dolibarr that can call the phone number on a SIP system for example. +ClickToDialDesc=This module change phone numbers, when using a desktop computer, into clickable links. A click will call the number. This can be used to start the phone call when using a soft phone on your desktop or when using a CTI system based on SIP protocol for example. Note: When using a smartphone, phone numbers are always clickable. ClickToDialUseTelLink=Use just a link "tel:" on phone numbers ClickToDialUseTelLinkDesc=Use this method if your users have a softphone or a software interface installed on the same computer as the browser, and called when you click on a link in your browser that starts with "tel:". If you need a full server solution (no need of local software installation), you must set this to "No" and fill next field. ##### Point Of Sale (CashDesk) ##### From fd6477c054e06c13ad614364ea689664f5f2da39 Mon Sep 17 00:00:00 2001 From: abb Date: Mon, 27 Jul 2020 10:52:42 +0100 Subject: [PATCH 057/434] fetch product model_pdf field --- htdocs/product/class/product.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 5de1ee5ad99..d617d98b500 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2033,7 +2033,7 @@ class Product extends CommonObject $sql .= " accountancy_code_buy, accountancy_code_buy_intra, accountancy_code_buy_export,"; $sql .= " accountancy_code_sell, accountancy_code_sell_intra, accountancy_code_sell_export, stock, pmp,"; $sql .= " datec, tms, import_key, entity, desiredstock, tobatch, fk_unit,"; - $sql .= " fk_price_expression, price_autogen"; + $sql .= " fk_price_expression, price_autogen,model_pdf"; $sql .= " FROM ".MAIN_DB_PREFIX."product"; if ($id) { $sql .= " WHERE rowid = ".(int) $id; @@ -2134,6 +2134,7 @@ class Product extends CommonObject $this->fk_price_expression = $obj->fk_price_expression; $this->fk_unit = $obj->fk_unit; $this->price_autogen = $obj->price_autogen; + $this->model_pdf = $obj->model_pdf; $this->db->free($resql); From 988e9e581701c5d3667736b00e5465ce17e8d8b2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Jul 2020 13:52:19 +0200 Subject: [PATCH 058/434] Update to jquery 3.5.1 --- COPYRIGHT | 2 +- dev/dolibarr_changes.txt | 3 +- htdocs/includes/jquery/js/jquery.js | 1238 ++++++++++++++--------- htdocs/includes/jquery/js/jquery.min.js | 4 +- 4 files changed, 760 insertions(+), 487 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index 2964c915ec1..251ad7f2fe4 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -39,7 +39,7 @@ TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes JS libraries: Ace 1.4.8 BSD Yes JS library to get code syntaxique coloration in a textarea. ChartJS 2.9.3 MIT License Yes JS library for graph -jQuery 3.4.1 MIT License Yes JS library +jQuery 3.5.1 MIT License Yes JS library jQuery UI 1.12.1 GPL and MIT License Yes JS library plugin UI jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect. Warning: 4.0.6+ create troubles without patching css jQuery blockUI 2.70.0 GPL and MIT License Yes JS library plugin blockUI (to use ajax popups) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 79f927160ee..cc5524ab048 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -167,6 +167,7 @@ In htdocs/includes/tecnickcom/tcpdf/tcpdf.php TCPDI: ------ Add fpdf_tpl.php 1.2 + Add tcpdi.php Add tcpdi_parser.php and replace: @@ -205,8 +206,6 @@ with - - JCROP: ------ * Remove analytics tag into file index.html diff --git a/htdocs/includes/jquery/js/jquery.js b/htdocs/includes/jquery/js/jquery.js index 5b16efa11d4..f2fa5e85896 100644 --- a/htdocs/includes/jquery/js/jquery.js +++ b/htdocs/includes/jquery/js/jquery.js @@ -1,5 +1,5 @@ /*! - * jQuery JavaScript Library v3.4.1 + * jQuery JavaScript Library v3.5.1 * https://jquery.com/ * * Includes Sizzle.js @@ -9,7 +9,7 @@ * Released under the MIT license * https://jquery.org/license * - * Date: 2019-05-01T21:04Z + * Date: 2020-05-04T22:49Z */ ( function( global, factory ) { @@ -47,13 +47,16 @@ var arr = []; -var document = window.document; - var getProto = Object.getPrototypeOf; var slice = arr.slice; -var concat = arr.concat; +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + var push = arr.push; @@ -86,6 +89,8 @@ var isWindow = function isWindow( obj ) { }; +var document = window.document; + var preservedScriptAttributes = { @@ -142,7 +147,7 @@ function toType( obj ) { var - version = "3.4.1", + version = "3.5.1", // Define a local copy of jQuery jQuery = function( selector, context ) { @@ -150,11 +155,7 @@ var // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); - }, - - // Support: Android <=4.0 only - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + }; jQuery.fn = jQuery.prototype = { @@ -220,6 +221,18 @@ jQuery.fn = jQuery.prototype = { return this.eq( -1 ); }, + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); @@ -353,9 +366,10 @@ jQuery.extend( { return true; }, - // Evaluates a script in a global context - globalEval: function( code, options ) { - DOMEval( code, { nonce: options && options.nonce } ); + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); }, each: function( obj, callback ) { @@ -379,13 +393,6 @@ jQuery.extend( { return obj; }, - // Support: Android <=4.0 only - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; @@ -472,7 +479,7 @@ jQuery.extend( { } // Flatten any nested arrays - return concat.apply( [], ret ); + return flat( ret ); }, // A global GUID counter for objects @@ -489,7 +496,7 @@ if ( typeof Symbol === "function" ) { // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( i, name ) { +function( _i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); @@ -511,17 +518,16 @@ function isArrayLike( obj ) { } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.3.4 + * Sizzle CSS Selector Engine v2.3.5 * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://js.foundation/ * - * Date: 2019-04-08 + * Date: 2020-03-14 */ -(function( window ) { - +( function( window ) { var i, support, Expr, @@ -561,59 +567,70 @@ var i, }, // Instance methods - hasOwn = ({}).hasOwnProperty, + hasOwn = ( {} ).hasOwnProperty, arr = [], pop = arr.pop, - push_native = arr.push, + pushNative = arr.push, push = arr.push, slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function( list, elem ) { var i = 0, len = list.length; for ( ; i < len; i++ ) { - if ( list[i] === elem ) { + if ( list[ i ] === elem ) { return i; } } return -1; }, - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), rdescend = new RegExp( whitespace + "|>" ), rpseudo = new RegExp( pseudos ), @@ -625,14 +642,16 @@ var i, "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, rhtml = /HTML$/i, @@ -648,18 +667,21 @@ var i, // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair high < 0 ? - // BMP codepoint String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }, @@ -675,7 +697,8 @@ var i, } // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; } // Other potentially-special ASCII characters get backslash-escaped @@ -700,18 +723,20 @@ var i, // Optimize for push.apply( _, NodeList ) try { push.apply( - (arr = slice.call( preferredDoc.childNodes )), + ( arr = slice.call( preferredDoc.childNodes ) ), preferredDoc.childNodes ); + // Support: Android<4.0 // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { push = { apply: arr.length ? // Leverage slice if possible function( target, els ) { - push_native.apply( target, slice.call(els) ); + pushNative.apply( target, slice.call( els ) ); } : // Support: IE<9 @@ -719,8 +744,9 @@ try { function( target, els ) { var j = target.length, i = 0; + // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} + while ( ( target[ j++ ] = els[ i++ ] ) ) {} target.length = j - 1; } }; @@ -744,24 +770,21 @@ function Sizzle( selector, context, results, seed ) { // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } + setDocument( context ); context = context || document; if ( documentIsHTML ) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { // ID selector - if ( (m = match[1]) ) { + if ( ( m = match[ 1 ] ) ) { // Document context if ( nodeType === 9 ) { - if ( (elem = context.getElementById( m )) ) { + if ( ( elem = context.getElementById( m ) ) ) { // Support: IE, Opera, Webkit // TODO: identify versions @@ -780,7 +803,7 @@ function Sizzle( selector, context, results, seed ) { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID - if ( newContext && (elem = newContext.getElementById( m )) && + if ( newContext && ( elem = newContext.getElementById( m ) ) && contains( context, elem ) && elem.id === m ) { @@ -790,12 +813,12 @@ function Sizzle( selector, context, results, seed ) { } // Type selector - } else if ( match[2] ) { + } else if ( match[ 2 ] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class selector - } else if ( (m = match[3]) && support.getElementsByClassName && + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); @@ -806,11 +829,11 @@ function Sizzle( selector, context, results, seed ) { // Take advantage of querySelectorAll if ( support.qsa && !nonnativeSelectorCache[ selector + " " ] && - (!rbuggyQSA || !rbuggyQSA.test( selector )) && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && // Support: IE 8 only // Exclude object elements - (nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) { + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { newSelector = selector; newContext = context; @@ -819,27 +842,36 @@ function Sizzle( selector, context, results, seed ) { // descendant combinators, which is not what we want. // In such cases, we work around the behavior by prefixing every selector in the // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. // Thanks to Andrew Dupont for this technique. - if ( nodeType === 1 && rdescend.test( selector ) ) { + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { - // Capture the context ID, setting it first if necessary - if ( (nid = context.getAttribute( "id" )) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", (nid = expando) ); + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } } // Prefix every selector in the list groups = tokenize( selector ); i = groups.length; while ( i-- ) { - groups[i] = "#" + nid + " " + toSelector( groups[i] ); + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); } newSelector = groups.join( "," ); - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; } try { @@ -872,12 +904,14 @@ function createCache() { var keys = []; function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries delete cache[ keys.shift() ]; } - return (cache[ key + " " ] = value); + return ( cache[ key + " " ] = value ); } return cache; } @@ -896,17 +930,19 @@ function markFunction( fn ) { * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { - var el = document.createElement("fieldset"); + var el = document.createElement( "fieldset" ); try { return !!fn( el ); - } catch (e) { + } catch ( e ) { return false; } finally { + // Remove from its parent by default if ( el.parentNode ) { el.parentNode.removeChild( el ); } + // release memory in IE el = null; } @@ -918,11 +954,11 @@ function assert( fn ) { * @param {Function} handler The method that will be applied */ function addHandle( attrs, handler ) { - var arr = attrs.split("|"), + var arr = attrs.split( "|" ), i = arr.length; while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; + Expr.attrHandle[ arr[ i ] ] = handler; } } @@ -944,7 +980,7 @@ function siblingCheck( a, b ) { // Check if b follows a if ( cur ) { - while ( (cur = cur.nextSibling) ) { + while ( ( cur = cur.nextSibling ) ) { if ( cur === b ) { return -1; } @@ -972,7 +1008,7 @@ function createInputPseudo( type ) { function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; + return ( name === "input" || name === "button" ) && elem.type === type; }; } @@ -1015,7 +1051,7 @@ function createDisabledPseudo( disabled ) { // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && - inDisabledFieldset( elem ) === disabled; + inDisabledFieldset( elem ) === disabled; } return elem.disabled === disabled; @@ -1037,21 +1073,21 @@ function createDisabledPseudo( disabled ) { * @param {Function} fn */ function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { + return markFunction( function( argument ) { argument = +argument; - return markFunction(function( seed, matches ) { + return markFunction( function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); } } - }); - }); + } ); + } ); } /** @@ -1073,7 +1109,7 @@ support = Sizzle.support = {}; */ isXML = Sizzle.isXML = function( elem ) { var namespace = elem.namespaceURI, - docElem = (elem.ownerDocument || elem).documentElement; + docElem = ( elem.ownerDocument || elem ).documentElement; // Support: IE <=8 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes @@ -1091,7 +1127,11 @@ setDocument = Sizzle.setDocument = function( node ) { doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } @@ -1100,10 +1140,14 @@ setDocument = Sizzle.setDocument = function( node ) { docElem = document.documentElement; documentIsHTML = !isXML( document ); - // Support: IE 9-11, Edge + // Support: IE 9 - 11+, Edge 12 - 18+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - if ( preferredDoc !== document && - (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { // Support: IE 11, Edge if ( subWindow.addEventListener ) { @@ -1115,25 +1159,36 @@ setDocument = Sizzle.setDocument = function( node ) { } } + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) - support.attributes = assert(function( el ) { + support.attributes = assert( function( el ) { el.className = "i"; - return !el.getAttribute("className"); - }); + return !el.getAttribute( "className" ); + } ); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( el ) { - el.appendChild( document.createComment("") ); - return !el.getElementsByTagName("*").length; - }); + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); // Support: IE<9 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); @@ -1142,38 +1197,38 @@ setDocument = Sizzle.setDocument = function( node ) { // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test - support.getById = assert(function( el ) { + support.getById = assert( function( el ) { docElem.appendChild( el ).id = expando; return !document.getElementsByName || !document.getElementsByName( expando ).length; - }); + } ); // ID filter and find if ( support.getById ) { - Expr.filter["ID"] = function( id ) { + Expr.filter[ "ID" ] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { - return elem.getAttribute("id") === attrId; + return elem.getAttribute( "id" ) === attrId; }; }; - Expr.find["ID"] = function( id, context ) { + Expr.find[ "ID" ] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var elem = context.getElementById( id ); return elem ? [ elem ] : []; } }; } else { - Expr.filter["ID"] = function( id ) { + Expr.filter[ "ID" ] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode("id"); + elem.getAttributeNode( "id" ); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut - Expr.find["ID"] = function( id, context ) { + Expr.find[ "ID" ] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var node, i, elems, elem = context.getElementById( id ); @@ -1181,7 +1236,7 @@ setDocument = Sizzle.setDocument = function( node ) { if ( elem ) { // Verify the id attribute - node = elem.getAttributeNode("id"); + node = elem.getAttributeNode( "id" ); if ( node && node.value === id ) { return [ elem ]; } @@ -1189,8 +1244,8 @@ setDocument = Sizzle.setDocument = function( node ) { // Fall back on getElementsByName elems = context.getElementsByName( id ); i = 0; - while ( (elem = elems[i++]) ) { - node = elem.getAttributeNode("id"); + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); if ( node && node.value === id ) { return [ elem ]; } @@ -1203,7 +1258,7 @@ setDocument = Sizzle.setDocument = function( node ) { } // Tag - Expr.find["TAG"] = support.getElementsByTagName ? + Expr.find[ "TAG" ] = support.getElementsByTagName ? function( tag, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( tag ); @@ -1218,12 +1273,13 @@ setDocument = Sizzle.setDocument = function( node ) { var elem, tmp = [], i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { - while ( (elem = results[i++]) ) { + while ( ( elem = results[ i++ ] ) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } @@ -1235,7 +1291,7 @@ setDocument = Sizzle.setDocument = function( node ) { }; // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } @@ -1256,10 +1312,14 @@ setDocument = Sizzle.setDocument = function( node ) { // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; - if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + // Build QSA regex // Regex strategy adopted from Diego Perini - assert(function( el ) { + assert( function( el ) { + + var input; + // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, @@ -1273,78 +1333,98 @@ setDocument = Sizzle.setDocument = function( node ) { // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll("[msallowcapture^='']").length ) { + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // Support: IE8 // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll("[selected]").length ) { + if ( !el.querySelectorAll( "[selected]" ).length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push("~="); + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push(".#.+[+~]"); + rbuggyQSA.push( ".#.+[+~]" ); } - }); - assert(function( el ) { + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { el.innerHTML = "" + ""; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement("input"); + var input = document.createElement( "input" ); input.setAttribute( "type", "hidden" ); el.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll("[name=d]").length ) { + if ( el.querySelectorAll( "[name=d]" ).length ) { rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests - if ( el.querySelectorAll(":enabled").length !== 2 ) { + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll(":disabled").length !== 2 ) { + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } + // Support: Opera 10 - 11 only // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); } - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { - assert(function( el ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( el, "*" ); @@ -1353,11 +1433,11 @@ setDocument = Sizzle.setDocument = function( node ) { // Gecko does not error, returns false instead matches.call( el, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); - }); + } ); } - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); /* Contains ---------------------------------------------------------------------- */ @@ -1374,11 +1454,11 @@ setDocument = Sizzle.setDocument = function( node ) { adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); + ) ); } : function( a, b ) { if ( b ) { - while ( (b = b.parentNode) ) { + while ( ( b = b.parentNode ) ) { if ( b === a ) { return true; } @@ -1407,7 +1487,11 @@ setDocument = Sizzle.setDocument = function( node ) { } // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected @@ -1415,13 +1499,24 @@ setDocument = Sizzle.setDocument = function( node ) { // Disconnected nodes if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { // Choose the first element that is related to our preferred document - if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { return -1; } - if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { return 1; } @@ -1434,6 +1529,7 @@ setDocument = Sizzle.setDocument = function( node ) { return compare & 4 ? -1 : 1; } : function( a, b ) { + // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; @@ -1449,8 +1545,14 @@ setDocument = Sizzle.setDocument = function( node ) { // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { - return a === document ? -1 : - b === document ? 1 : + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ aup ? -1 : bup ? 1 : sortInput ? @@ -1464,26 +1566,32 @@ setDocument = Sizzle.setDocument = function( node ) { // Otherwise we need full lists of their ancestors for comparison cur = a; - while ( (cur = cur.parentNode) ) { + while ( ( cur = cur.parentNode ) ) { ap.unshift( cur ); } cur = b; - while ( (cur = cur.parentNode) ) { + while ( ( cur = cur.parentNode ) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { + while ( ap[ i ] === bp[ i ] ) { i++; } return i ? + // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : + siblingCheck( ap[ i ], bp[ i ] ) : // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ 0; }; @@ -1495,10 +1603,7 @@ Sizzle.matches = function( expr, elements ) { }; Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } + setDocument( elem ); if ( support.matchesSelector && documentIsHTML && !nonnativeSelectorCache[ expr + " " ] && @@ -1510,12 +1615,13 @@ Sizzle.matchesSelector = function( elem, expr ) { // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { return ret; } - } catch (e) { + } catch ( e ) { nonnativeSelectorCache( expr, true ); } } @@ -1524,20 +1630,31 @@ Sizzle.matchesSelector = function( elem, expr ) { }; Sizzle.contains = function( context, elem ) { + // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { + // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { setDocument( elem ); } var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? fn( elem, name, !documentIsHTML ) : @@ -1547,13 +1664,13 @@ Sizzle.attr = function( elem, name ) { val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? + ( val = elem.getAttributeNode( name ) ) && val.specified ? val.value : null; }; Sizzle.escape = function( sel ) { - return (sel + "").replace( rcssescape, fcssescape ); + return ( sel + "" ).replace( rcssescape, fcssescape ); }; Sizzle.error = function( msg ) { @@ -1576,7 +1693,7 @@ Sizzle.uniqueSort = function( results ) { results.sort( sortOrder ); if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { + while ( ( elem = results[ i++ ] ) ) { if ( elem === results[ i ] ) { j = duplicates.push( i ); } @@ -1604,17 +1721,21 @@ getText = Sizzle.getText = function( elem ) { nodeType = elem.nodeType; if ( !nodeType ) { + // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { + while ( ( node = elem[ i++ ] ) ) { + // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { + // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); @@ -1623,6 +1744,7 @@ getText = Sizzle.getText = function( elem ) { } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } + // Do not include comment or processing instruction nodes return ret; @@ -1650,19 +1772,21 @@ Expr = Sizzle.selectors = { preFilter: { "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) @@ -1673,22 +1797,25 @@ Expr = Sizzle.selectors = { 7 sign of y-component 8 y of y-component */ - match[1] = match[1].toLowerCase(); + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { - if ( match[1].slice( 0, 3 ) === "nth" ) { // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); } return match; @@ -1696,26 +1823,28 @@ Expr = Sizzle.selectors = { "PSEUDO": function( match ) { var excess, - unquoted = !match[6] && match[2]; + unquoted = !match[ 6 ] && match[ 2 ]; - if ( matchExpr["CHILD"].test( match[0] ) ) { + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { return null; } // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && + ( excess = tokenize( unquoted, true ) ) && + // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) @@ -1728,7 +1857,9 @@ Expr = Sizzle.selectors = { "TAG": function( nodeNameSelector ) { var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); return nodeNameSelector === "*" ? - function() { return true; } : + function() { + return true; + } : function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; @@ -1738,10 +1869,16 @@ Expr = Sizzle.selectors = { var pattern = classCache[ className + " " ]; return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); - }); + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); }, "ATTR": function( name, operator, check ) { @@ -1757,6 +1894,8 @@ Expr = Sizzle.selectors = { result += ""; + /* eslint-disable max-len */ + return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : @@ -1765,10 +1904,12 @@ Expr = Sizzle.selectors = { operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; + /* eslint-enable max-len */ + }; }, - "CHILD": function( type, what, argument, first, last ) { + "CHILD": function( type, what, _argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; @@ -1780,7 +1921,7 @@ Expr = Sizzle.selectors = { return !!elem.parentNode; } : - function( elem, context, xml ) { + function( elem, _context, xml ) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, @@ -1794,7 +1935,7 @@ Expr = Sizzle.selectors = { if ( simple ) { while ( dir ) { node = elem; - while ( (node = node[ dir ]) ) { + while ( ( node = node[ dir ] ) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { @@ -1802,6 +1943,7 @@ Expr = Sizzle.selectors = { return false; } } + // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } @@ -1817,22 +1959,22 @@ Expr = Sizzle.selectors = { // ...in a gzip-friendly way node = parent; - outerCache = node[ expando ] || (node[ expando ] = {}); + outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); + ( outerCache[ node.uniqueID ] = {} ); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; - while ( (node = ++nodeIndex && node && node[ dir ] || + while ( ( node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { + ( diff = nodeIndex = 0 ) || start.pop() ) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { @@ -1842,16 +1984,18 @@ Expr = Sizzle.selectors = { } } else { + // Use previously-cached element index if available if ( useCache ) { + // ...in a gzip-friendly way node = elem; - outerCache = node[ expando ] || (node[ expando ] = {}); + outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); + ( outerCache[ node.uniqueID ] = {} ); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; @@ -1861,9 +2005,10 @@ Expr = Sizzle.selectors = { // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : @@ -1872,12 +2017,13 @@ Expr = Sizzle.selectors = { // Cache the index of each encountered element if ( useCache ) { - outerCache = node[ expando ] || (node[ expando ] = {}); + outerCache = node[ expando ] || + ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); + ( outerCache[ node.uniqueID ] = {} ); uniqueCache[ type ] = [ dirruns, diff ]; } @@ -1898,6 +2044,7 @@ Expr = Sizzle.selectors = { }, "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters @@ -1917,15 +2064,15 @@ Expr = Sizzle.selectors = { if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { + markFunction( function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { - idx = indexOf( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); } - }) : + } ) : function( elem ) { return fn( elem, 0, args ); }; @@ -1936,8 +2083,10 @@ Expr = Sizzle.selectors = { }, pseudos: { + // Potentially complex pseudos - "not": markFunction(function( selector ) { + "not": markFunction( function( selector ) { + // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators @@ -1946,39 +2095,40 @@ Expr = Sizzle.selectors = { matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { + markFunction( function( seed, matches, _context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); } } - }) : - function( elem, context, xml ) { - input[0] = elem; + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; matcher( input, null, xml, results ); + // Don't keep the element (issue #299) - input[0] = null; + input[ 0 ] = null; return !results.pop(); }; - }), + } ), - "has": markFunction(function( selector ) { + "has": markFunction( function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; - }), + } ), - "contains": markFunction(function( text ) { + "contains": markFunction( function( text ) { text = text.replace( runescape, funescape ); return function( elem ) { return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; }; - }), + } ), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value @@ -1988,25 +2138,26 @@ Expr = Sizzle.selectors = { // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { + // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { + if ( !ridentifier.test( lang || "" ) ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { - if ( (elemLang = documentIsHTML ? + if ( ( elemLang = documentIsHTML ? elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); return false; }; - }), + } ), // Miscellaneous "target": function( elem ) { @@ -2019,7 +2170,9 @@ Expr = Sizzle.selectors = { }, "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); }, // Boolean properties @@ -2027,16 +2180,20 @@ Expr = Sizzle.selectors = { "disabled": createDisabledPseudo( true ), "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); }, "selected": function( elem ) { + // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions elem.parentNode.selectedIndex; } @@ -2045,6 +2202,7 @@ Expr = Sizzle.selectors = { // Contents "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) @@ -2058,7 +2216,7 @@ Expr = Sizzle.selectors = { }, "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); + return !Expr.pseudos[ "empty" ]( elem ); }, // Element/input types @@ -2082,39 +2240,40 @@ Expr = Sizzle.selectors = { // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); }, // Position-in-collection - "first": createPositionalPseudo(function() { + "first": createPositionalPseudo( function() { return [ 0 ]; - }), + } ), - "last": createPositionalPseudo(function( matchIndexes, length ) { + "last": createPositionalPseudo( function( _matchIndexes, length ) { return [ length - 1 ]; - }), + } ), - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; - }), + } ), - "even": createPositionalPseudo(function( matchIndexes, length ) { + "even": createPositionalPseudo( function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; - }), + } ), - "odd": createPositionalPseudo(function( matchIndexes, length ) { + "odd": createPositionalPseudo( function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; - }), + } ), - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument > length ? @@ -2124,19 +2283,19 @@ Expr = Sizzle.selectors = { matchIndexes.push( i ); } return matchIndexes; - }), + } ), - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; - }) + } ) } }; -Expr.pseudos["nth"] = Expr.pseudos["eq"]; +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { @@ -2167,37 +2326,39 @@ tokenize = Sizzle.tokenize = function( selector, parseOnly ) { while ( soFar ) { // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { if ( match ) { + // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; + soFar = soFar.slice( match[ 0 ].length ) || soFar; } - groups.push( (tokens = []) ); + groups.push( ( tokens = [] ) ); } matched = false; // Combinators - if ( (match = rcombinators.exec( soFar )) ) { + if ( ( match = rcombinators.exec( soFar ) ) ) { matched = match.shift(); - tokens.push({ + tokens.push( { value: matched, + // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); + type: match[ 0 ].replace( rtrim, " " ) + } ); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { matched = match.shift(); - tokens.push({ + tokens.push( { value: matched, type: type, matches: match - }); + } ); soFar = soFar.slice( matched.length ); } } @@ -2214,6 +2375,7 @@ tokenize = Sizzle.tokenize = function( selector, parseOnly ) { soFar.length : soFar ? Sizzle.error( selector ) : + // Cache the tokens tokenCache( selector, groups ).slice( 0 ); }; @@ -2223,7 +2385,7 @@ function toSelector( tokens ) { len = tokens.length, selector = ""; for ( ; i < len; i++ ) { - selector += tokens[i].value; + selector += tokens[ i ].value; } return selector; } @@ -2236,9 +2398,10 @@ function addCombinator( matcher, combinator, base ) { doneName = done++; return combinator.first ? + // Check against closest ancestor/preceding element function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { + while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } @@ -2253,7 +2416,7 @@ function addCombinator( matcher, combinator, base ) { // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { - while ( (elem = elem[ dir ]) ) { + while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; @@ -2261,27 +2424,29 @@ function addCombinator( matcher, combinator, base ) { } } } else { - while ( (elem = elem[ dir ]) ) { + while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); if ( skip && skip === elem.nodeName.toLowerCase() ) { elem = elem[ dir ] || elem; - } else if ( (oldCache = uniqueCache[ key ]) && + } else if ( ( oldCache = uniqueCache[ key ] ) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); + return ( newCache[ 2 ] = oldCache[ 2 ] ); } else { + // Reuse newcache so results back-propagate to previous elements uniqueCache[ key ] = newCache; // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { return true; } } @@ -2297,20 +2462,20 @@ function elementMatcher( matchers ) { function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { + if ( !matchers[ i ]( elem, context, xml ) ) { return false; } } return true; } : - matchers[0]; + matchers[ 0 ]; } function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); + Sizzle( selector, contexts[ i ], results ); } return results; } @@ -2323,7 +2488,7 @@ function condense( unmatched, map, filter, context, xml ) { mapped = map != null; for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { + if ( ( elem = unmatched[ i ] ) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { @@ -2343,14 +2508,18 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } - return markFunction(function( seed, results, context, xml ) { + return markFunction( function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? @@ -2358,6 +2527,7 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS elems, matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? @@ -2381,8 +2551,8 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); } } } @@ -2390,25 +2560,27 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { - if ( (elem = matcherOut[i]) ) { + if ( ( elem = matcherOut[ i ] ) ) { + // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); + temp.push( ( matcherIn[ i ] = elem ) ); } } - postFinder( null, (matcherOut = []), temp, xml ); + postFinder( null, ( matcherOut = [] ), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { - seed[temp] = !(results[temp] = elem); + seed[ temp ] = !( results[ temp ] = elem ); } } } @@ -2426,14 +2598,14 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS push.apply( results, matcherOut ); } } - }); + } ); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) @@ -2445,38 +2617,43 @@ function matcherFromTokens( tokens ) { }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? + ( checkContext = context ).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) checkContext = null; return ret; } ]; for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { + if ( Expr.relative[ tokens[ j ].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), j < len && toSelector( tokens ) ); } @@ -2497,28 +2674,40 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { unmatched = seed && [], setMatched = [], contextBackup = outermostContext, + // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), len = elems.length; if ( outermost ) { - outermostContext = context === document || context || outermost; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { if ( byElement && elem ) { j = 0; - if ( !context && elem.ownerDocument !== document ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { setDocument( elem ); xml = !documentIsHTML; } - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context || document, xml) ) { + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { results.push( elem ); break; } @@ -2530,8 +2719,9 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { // Track unmatched elements for set filters if ( bySet ) { + // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { + if ( ( elem = !matcher && elem ) ) { matchedCount--; } @@ -2555,16 +2745,17 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; - while ( (matcher = setMatchers[j++]) ) { + while ( ( matcher = setMatchers[ j++ ] ) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); } } } @@ -2605,13 +2796,14 @@ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { cached = compilerCache[ selector + " " ]; if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element if ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { - cached = matcherFromTokens( match[i] ); + cached = matcherFromTokens( match[ i ] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { @@ -2620,7 +2812,10 @@ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { } // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); // Save selector and tokenization cached.selector = selector; @@ -2640,7 +2835,7 @@ compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); results = results || []; @@ -2649,11 +2844,12 @@ select = Sizzle.select = function( selector, context, results, seed ) { if ( match.length === 1 ) { // Reduce context if the leading compound selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; if ( !context ) { return results; @@ -2666,20 +2862,22 @@ select = Sizzle.select = function( selector, context, results, seed ) { } // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; while ( i-- ) { - token = tokens[i]; + token = tokens[ i ]; // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { + if ( Expr.relative[ ( type = token.type ) ] ) { break; } - if ( (find = Expr.find[ type ]) ) { + if ( ( find = Expr.find[ type ] ) ) { + // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); @@ -2710,7 +2908,7 @@ select = Sizzle.select = function( selector, context, results, seed ) { // One-time assignments // Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function @@ -2721,58 +2919,59 @@ setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( el ) { +support.sortDetached = assert( function( el ) { + // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; -}); + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( el ) { +if ( !assert( function( el ) { el.innerHTML = ""; - return el.firstChild.getAttribute("href") === "#" ; -}) ) { + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { addHandle( "type|href|height|width", function( elem, name, isXML ) { if ( !isXML ) { return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); } - }); + } ); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( el ) { +if ( !support.attributes || !assert( function( el ) { el.innerHTML = ""; el.firstChild.setAttribute( "value", "" ); return el.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { return elem.defaultValue; } - }); + } ); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( el ) { - return el.getAttribute("disabled") == null; -}) ) { +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { addHandle( booleans, function( elem, name, isXML ) { var val; if ( !isXML ) { return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? + ( val = elem.getAttributeNode( name ) ) && val.specified ? val.value : - null; + null; } - }); + } ); } return Sizzle; -})( window ); +} )( window ); @@ -3141,7 +3340,7 @@ jQuery.each( { parents: function( elem ) { return dir( elem, "parentNode" ); }, - parentsUntil: function( elem, i, until ) { + parentsUntil: function( elem, _i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { @@ -3156,10 +3355,10 @@ jQuery.each( { prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, - nextUntil: function( elem, i, until ) { + nextUntil: function( elem, _i, until ) { return dir( elem, "nextSibling", until ); }, - prevUntil: function( elem, i, until ) { + prevUntil: function( elem, _i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { @@ -3169,7 +3368,13 @@ jQuery.each( { return siblings( elem.firstChild ); }, contents: function( elem ) { - if ( typeof elem.contentDocument !== "undefined" ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + return elem.contentDocument; } @@ -3512,7 +3717,7 @@ jQuery.extend( { var fns = arguments; return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { + jQuery.each( tuples, function( _i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; @@ -3965,7 +4170,7 @@ var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { // ...except when executing function values } else { bulk = fn; - fn = function( elem, key, value ) { + fn = function( elem, _key, value ) { return bulk.call( jQuery( elem ), value ); }; } @@ -4000,7 +4205,7 @@ var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace() -function fcamelCase( all, letter ) { +function fcamelCase( _all, letter ) { return letter.toUpperCase(); } @@ -4528,27 +4733,6 @@ var isHiddenWithinTree = function( elem, el ) { jQuery.css( elem, "display" ) === "none"; }; -var swap = function( elem, options, callback, args ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.apply( elem, args || [] ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - function adjustCSS( elem, prop, valueParts, tween ) { @@ -4719,11 +4903,40 @@ var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); -// We have to close these tags to support XHTML (#13200) -var wrapMap = { +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; // Support: IE <=9 only - option: [ 1, "" ], + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten @@ -4736,12 +4949,14 @@ var wrapMap = { _default: [ 0, "", "" ] }; -// Support: IE <=9 only -wrapMap.optgroup = wrapMap.option; - wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + function getAll( context, tag ) { @@ -4874,32 +5089,6 @@ function buildFragment( elems, context, scripts, selection, ignored ) { } -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -} )(); - - var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, @@ -5008,8 +5197,8 @@ jQuery.event = { special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { return; } @@ -5033,7 +5222,7 @@ jQuery.event = { // Init the element's event structure and main handler, if this is the first if ( !( events = elemData.events ) ) { - events = elemData.events = {}; + events = elemData.events = Object.create( null ); } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { @@ -5191,12 +5380,15 @@ jQuery.event = { dispatch: function( nativeEvent ) { - // Make a writable jQuery.Event from the native event object - var event = jQuery.event.fix( nativeEvent ); - var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), - handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event @@ -5771,13 +5963,6 @@ jQuery.fn.extend( { var - /* eslint-disable max-len */ - - // See https://github.com/eslint/eslint/issues/3229 - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, - - /* eslint-enable */ - // Support: IE <=10 - 11, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ @@ -5814,7 +5999,7 @@ function restoreScript( elem ) { } function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + var i, l, type, pdataOld, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; @@ -5822,13 +6007,11 @@ function cloneCopyEvent( src, dest ) { // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.access( src ); - pdataCur = dataPriv.set( dest, pdataOld ); + pdataOld = dataPriv.get( src ); events = pdataOld.events; if ( events ) { - delete pdataCur.handle; - pdataCur.events = {}; + dataPriv.remove( dest, "handle events" ); for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { @@ -5864,7 +6047,7 @@ function fixInput( src, dest ) { function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays - args = concat.apply( [], args ); + args = flat( args ); var fragment, first, scripts, hasScripts, node, doc, i = 0, @@ -5939,7 +6122,7 @@ function domManip( collection, args, callback, ignored ) { if ( jQuery._evalUrl && !node.noModule ) { jQuery._evalUrl( node.src, { nonce: node.nonce || node.getAttribute( "nonce" ) - } ); + }, doc ); } } else { DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); @@ -5976,7 +6159,7 @@ function remove( elem, selector, keepData ) { jQuery.extend( { htmlPrefilter: function( html ) { - return html.replace( rxhtmlTag, "<$1>" ); + return html; }, clone: function( elem, dataAndEvents, deepDataAndEvents ) { @@ -6238,6 +6421,27 @@ var getStyles = function( elem ) { return view.getComputedStyle( elem ); }; +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); @@ -6295,7 +6499,7 @@ var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); } var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableMarginLeftVal, + reliableTrDimensionsVal, reliableMarginLeftVal, container = document.createElement( "div" ), div = document.createElement( "div" ); @@ -6330,6 +6534,35 @@ var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); scrollboxSize: function() { computeStyleTests(); return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; } } ); } )(); @@ -6454,7 +6687,7 @@ var fontWeight: "400" }; -function setPositiveNumber( elem, value, subtract ) { +function setPositiveNumber( _elem, value, subtract ) { // Any relative (+/-) values have already been // normalized at this point @@ -6559,17 +6792,26 @@ function getWidthOrHeight( elem, dimension, extra ) { } - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - // Support: IE 9-11 only - // Also use offsetWidth/offsetHeight for when box sizing is unreliable - // We use getClientRects() to check for hidden/disconnected. - // In those cases, the computed value can be trusted to be border-box + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected elem.getClientRects().length ) { isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; @@ -6764,7 +7006,7 @@ jQuery.extend( { } } ); -jQuery.each( [ "height", "width" ], function( i, dimension ) { +jQuery.each( [ "height", "width" ], function( _i, dimension ) { jQuery.cssHooks[ dimension ] = { get: function( elem, computed, extra ) { if ( computed ) { @@ -7537,7 +7779,7 @@ jQuery.fn.extend( { clearQueue = type; type = undefined; } - if ( clearQueue && type !== false ) { + if ( clearQueue ) { this.queue( type || "fx", [] ); } @@ -7620,7 +7862,7 @@ jQuery.fn.extend( { } } ); -jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? @@ -7841,7 +8083,7 @@ boolHook = { } }; -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { var getter = attrHandle[ name ] || jQuery.find.attr; attrHandle[ name ] = function( elem, name, isXML ) { @@ -8465,7 +8707,9 @@ jQuery.extend( jQuery.event, { special.bindType || type; // jQuery handler - handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); @@ -8576,7 +8820,10 @@ if ( !support.focusin ) { jQuery.event.special[ fix ] = { setup: function() { - var doc = this.ownerDocument || this, + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ); if ( !attaches ) { @@ -8585,7 +8832,7 @@ if ( !support.focusin ) { dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { - var doc = this.ownerDocument || this, + var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ) - 1; if ( !attaches ) { @@ -8601,7 +8848,7 @@ if ( !support.focusin ) { } var location = window.location; -var nonce = Date.now(); +var nonce = { guid: Date.now() }; var rquery = ( /\?/ ); @@ -8733,7 +8980,7 @@ jQuery.fn.extend( { rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); } ) - .map( function( i, elem ) { + .map( function( _i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { @@ -9346,7 +9593,8 @@ jQuery.extend( { // Add or update anti-cache param if needed if ( s.cache === false ) { cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) @@ -9479,6 +9727,11 @@ jQuery.extend( { response = ajaxHandleResponses( s, jqXHR, responses ); } + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert( s, response, jqXHR, isSuccess ); @@ -9569,7 +9822,7 @@ jQuery.extend( { } } ); -jQuery.each( [ "get", "post" ], function( i, method ) { +jQuery.each( [ "get", "post" ], function( _i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted @@ -9590,8 +9843,17 @@ jQuery.each( [ "get", "post" ], function( i, method ) { }; } ); +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); -jQuery._evalUrl = function( url, options ) { + +jQuery._evalUrl = function( url, options, doc ) { return jQuery.ajax( { url: url, @@ -9609,7 +9871,7 @@ jQuery._evalUrl = function( url, options ) { "text script": function() {} }, dataFilter: function( response ) { - jQuery.globalEval( response, options ); + jQuery.globalEval( response, options, doc ); } } ); }; @@ -9931,7 +10193,7 @@ var oldCallbacks = [], jQuery.ajaxSetup( { jsonp: "callback", jsonpCallback: function() { - var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); this[ callback ] = true; return callback; } @@ -10148,23 +10410,6 @@ jQuery.fn.load = function( url, params, callback ) { -// Attach a bunch of functions for handling common AJAX events -jQuery.each( [ - "ajaxStart", - "ajaxStop", - "ajaxComplete", - "ajaxError", - "ajaxSuccess", - "ajaxSend" -], function( i, type ) { - jQuery.fn[ type ] = function( fn ) { - return this.on( type, fn ); - }; -} ); - - - - jQuery.expr.pseudos.animated = function( elem ) { return jQuery.grep( jQuery.timers, function( fn ) { return elem === fn.elem; @@ -10221,6 +10466,12 @@ jQuery.offset = { options.using.call( elem, props ); } else { + if ( typeof props.top === "number" ) { + props.top += "px"; + } + if ( typeof props.left === "number" ) { + props.left += "px"; + } curElem.css( props ); } } @@ -10371,7 +10622,7 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 // getComputedStyle returns percent when specified for top/left/bottom/right; // rather than make the css module depend on the offset module, just check for it here -jQuery.each( [ "top", "left" ], function( i, prop ) { +jQuery.each( [ "top", "left" ], function( _i, prop ) { jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, function( elem, computed ) { if ( computed ) { @@ -10434,25 +10685,19 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { } ); -jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup contextmenu" ).split( " " ), - function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); +jQuery.each( [ + "ajaxStart", + "ajaxStop", + "ajaxComplete", + "ajaxError", + "ajaxSuccess", + "ajaxSend" +], function( _i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); }; } ); -jQuery.fn.extend( { - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -} ); - @@ -10474,9 +10719,33 @@ jQuery.fn.extend( { return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); } } ); +jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup contextmenu" ).split( " " ), + function( _i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + } ); + + + + +// Support: Android <=4.0 only +// Make sure we trim BOM and NBSP +var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + // Bind a function to a context, optionally partially applying any // arguments. // jQuery.proxy is deprecated to promote standards (specifically Function#bind) @@ -10539,6 +10808,11 @@ jQuery.isNumeric = function( obj ) { !isNaN( obj - parseFloat( obj ) ); }; +jQuery.trim = function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); +}; @@ -10587,7 +10861,7 @@ jQuery.noConflict = function( deep ) { // Expose jQuery and $ identifiers, even in AMD // (#7102#comment:10, https://github.com/jquery/jquery/pull/557) // and CommonJS for browser emulators (#13566) -if ( !noGlobal ) { +if ( typeof noGlobal === "undefined" ) { window.jQuery = window.$ = jQuery; } diff --git a/htdocs/includes/jquery/js/jquery.min.js b/htdocs/includes/jquery/js/jquery.min.js index 07c00cd227d..d467083b62c 100644 --- a/htdocs/includes/jquery/js/jquery.min.js +++ b/htdocs/includes/jquery/js/jquery.min.js @@ -1,2 +1,2 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 Date: Mon, 27 Jul 2020 14:04:41 +0200 Subject: [PATCH 059/434] FIX DO not erase variable $key and $label during output of extrafields --- htdocs/core/tpl/extrafields_view.tpl.php | 74 ++++++++++++------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 1f28ba50bdf..f3a181f0b2e 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -54,48 +54,48 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] $extrafields_collapse_num = ''; $extrafields_collapse_num_old = ''; $i = 0; - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + foreach ($extrafields->attributes[$object->table_element]['label'] as $tmpkeyextra => $tmplabelextra) { $i++; // Discard if extrafield is a hidden field on form $enabled = 1; - if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key])) + if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$tmpkeyextra])) { - $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1); + $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$tmpkeyextra], 1); } - if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$key])) + if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$tmpkeyextra])) { - $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$key], 1); + $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$tmpkeyextra], 1); } $perms = 1; - if ($perms && isset($extrafields->attributes[$object->table_element]['perms'][$key])) + if ($perms && isset($extrafields->attributes[$object->table_element]['perms'][$tmpkeyextra])) { - $perms = dol_eval($extrafields->attributes[$object->table_element]['perms'][$key], 1); + $perms = dol_eval($extrafields->attributes[$object->table_element]['perms'][$tmpkeyextra], 1); } - //print $key.'-'.$enabled.'-'.$perms.'-'.$label.$_POST["options_" . $key].'
'."\n"; + //print $tmpkeyextra.'-'.$enabled.'-'.$perms.'-'.$tmplabelextra.$_POST["options_" . $tmpkeyextra].'
'."\n"; if (empty($enabled)) continue; // 0 = Never visible field if (abs($enabled) != 1 && abs($enabled) != 3 && abs($enabled) != 5 && abs($enabled) != 4) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list <> 4 = not visible at the creation if (empty($perms)) continue; // 0 = Not visible // Load language if required - if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); + if (!empty($extrafields->attributes[$object->table_element]['langfile'][$tmpkeyextra])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$tmpkeyextra]); if ($action == 'edit_extras') { - $value = (isset($_POST["options_".$key]) ? $_POST["options_".$key] : $object->array_options["options_".$key]); + $value = (isset($_POST["options_".$tmpkeyextra]) ? $_POST["options_".$tmpkeyextra] : $object->array_options["options_".$tmpkeyextra]); } else { - $value = $object->array_options["options_".$key]; - //var_dump($key.' - '.$value); + $value = $object->array_options["options_".$tmpkeyextra]; + //var_dump($tmpkeyextra.' - '.$value); } // Print line tr of extra field - if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') + if ($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra] == 'separate') { $extrafields_collapse_num = ''; - $extrafield_param = $extrafields->attributes[$object->table_element]['param'][$key]; + $extrafield_param = $extrafields->attributes[$object->table_element]['param'][$tmpkeyextra]; if (!empty($extrafield_param) && is_array($extrafield_param)) { $extrafield_param_list = array_keys($extrafield_param['options']); @@ -103,14 +103,14 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] $extrafield_collapse_display_value = intval($extrafield_param_list[0]); if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) { - $extrafields_collapse_num = $extrafields->attributes[$object->table_element]['pos'][$key]; + $extrafields_collapse_num = $extrafields->attributes[$object->table_element]['pos'][$tmpkeyextra]; } } } - print $extrafields->showSeparator($key, $object); + print $extrafields->showSeparator($tmpkeyextra, $object); - $lastseparatorkeyfound = $key; + $lastseparatorkeyfound = $tmpkeyextra; } else { print 'attributes[$object->table_element]['required'][$key])) print ' fieldrequired'; + if ((!empty($action) && ($action == 'create' || $action == 'edit')) && !empty($extrafields->attributes[$object->table_element]['required'][$tmpkeyextra])) print ' fieldrequired'; print '">'; - if (!empty($extrafields->attributes[$object->table_element]['help'][$key])) print $form->textwithpicto($langs->trans($label), $langs->trans($extrafields->attributes[$object->table_element]['help'][$key])); - else print $langs->trans($label); + if (!empty($extrafields->attributes[$object->table_element]['help'][$tmpkeyextra])) print $form->textwithpicto($langs->trans($tmplabelextra), $langs->trans($extrafields->attributes[$object->table_element]['help'][$tmpkeyextra])); + else print $langs->trans($tmplabelextra); print ''; //TODO Improve element and rights detection @@ -147,52 +147,52 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] if ($object->element == 'mo') $permok = $user->rights->mrp->write; $isdraft = ((isset($object->statut) && $object->statut == 0) || (isset($object->status) && $object->status == 0)); - if (($isdraft || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$key])) - && $permok && $enabled != 5 && ($action != 'edit_extras' || GETPOST('attribute') != $key) - && empty($extrafields->attributes[$object->table_element]['computed'][$key])) + if (($isdraft || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$tmpkeyextra])) + && $permok && $enabled != 5 && ($action != 'edit_extras' || GETPOST('attribute') != $tmpkeyextra) + && empty($extrafields->attributes[$object->table_element]['computed'][$tmpkeyextra])) { $fieldid = 'id'; if ($object->table_element == 'societe') $fieldid = 'socid'; - print ''.img_edit().''; + print ''.img_edit().''; } print ''; print ''; - $html_id = !empty($object->id) ? $object->element.'_extras_'.$key.'_'.$object->id : ''; + $html_id = !empty($object->id) ? $object->element.'_extras_'.$tmpkeyextra.'_'.$object->id : ''; - print ''; + print ''; // Convert date into timestamp format - if (in_array($extrafields->attributes[$object->table_element]['type'][$key], array('date', 'datetime'))) + if (in_array($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra], array('date', 'datetime'))) { - $datenotinstring = $object->array_options['options_'.$key]; - // print 'X'.$object->array_options['options_' . $key].'-'.$datenotinstring.'x'; - if (!is_numeric($object->array_options['options_'.$key])) // For backward compatibility + $datenotinstring = $object->array_options['options_'.$tmpkeyextra]; + // print 'X'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.'x'; + if (!is_numeric($object->array_options['options_'.$tmpkeyextra])) // For backward compatibility { $datenotinstring = $db->jdate($datenotinstring); } - //print 'x'.$object->array_options['options_' . $key].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); - $value = isset($_POST["options_".$key]) ? dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]) : $datenotinstring; + //print 'x'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); + $value = isset($_POST["options_".$tmpkeyextra]) ? dol_mktime($_POST["options_".$tmpkeyextra."hour"], $_POST["options_".$tmpkeyextra."min"], 0, $_POST["options_".$tmpkeyextra."month"], $_POST["options_".$tmpkeyextra."day"], $_POST["options_".$tmpkeyextra."year"]) : $datenotinstring; } //TODO Improve element and rights detection - if ($action == 'edit_extras' && $permok && GETPOST('attribute', 'none') == $key) + if ($action == 'edit_extras' && $permok && GETPOST('attribute', 'none') == $tmpkeyextra) { $fieldid = 'id'; if ($object->table_element == 'societe') $fieldid = 'socid'; print '
'; print ''; - print ''; + print ''; print ''; print ''; - print $extrafields->showInputField($key, $value, '', '', '', 0, $object->id, $object->table_element); + print $extrafields->showInputField($tmpkeyextra, $value, '', '', '', 0, $object->id, $object->table_element); print ''; print '
'; } else { - //var_dump($key.'-'.$value.'-'.$object->table_element); - print $extrafields->showOutputField($key, $value, '', $object->table_element); + //var_dump($tmpkeyextra.'-'.$value.'-'.$object->table_element); + print $extrafields->showOutputField($tmpkeyextra, $value, '', $object->table_element); } print ''; From b93f60c446425836bac90c905cadeb471670143a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Jul 2020 14:19:50 +0200 Subject: [PATCH 060/434] Look and feel v13 --- htdocs/projet/ganttview.php | 17 ++++++++++++++--- htdocs/projet/tasks.php | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index d578f372777..81b7be12e33 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -235,10 +235,11 @@ if ($user->rights->projet->all->creer || $user->rights->projet->creer) { $linktocreatetask = dolGetButtonTitle($langs->trans('AddTask'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id.'&action=create'.$param.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$object->id), '', $linktocreatetaskUserRight, $linktocreatetaskParam); -$linktolist = dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-list-alt paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition')); +$linktotasks = dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-list-alt paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition')); +$linktotasks .= dolGetButtonTitle($langs->trans('ViewGantt'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/ganttview.php?id='.$object->id.'&withproject=1', '', 1, array('morecss'=>'reposition marginleftonly btnTitleSelected')); //print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1); -print load_fiche_titre($title, $linktolist.'   '.$linktocreatetask, 'generic'); +print load_fiche_titre($title, $linktotasks.'   '.$linktocreatetask, 'generic'); // Get list of tasks in tasksarray and taskarrayfiltered @@ -369,7 +370,17 @@ if (count($tasksarray) > 0) //var_dump($dateformatinput); //var_dump($dateformatinput2); - print '
'; + $moreforfilter = '
'; + + $moreforfilter .= '
'; + //$moreforfilter .= $langs->trans("TasksAssignedTo").': '; + //$moreforfilter .= $form->select_dolusers($tmpuser->id > 0 ? $tmpuser->id : '', 'search_user_id', 1); + $moreforfilter .= ' '; + $moreforfilter .= '
'; + + $moreforfilter .= '
'; + + print $moreforfilter; print '
'; diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index f395a4ee27a..c11ffcd8d6f 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -632,7 +632,8 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third print ''; $title = $langs->trans("ListOfTasks"); - $linktotasks = dolGetButtonTitle($langs->trans('ViewGantt'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/ganttview.php?id='.$object->id.'&withproject=1', '', 1, array('morecss'=>'reposition')); + $linktotasks = dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-list-alt paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition btnTitleSelected')); + $linktotasks .= dolGetButtonTitle($langs->trans('ViewGantt'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/ganttview.php?id='.$object->id.'&withproject=1', '', 1, array('morecss'=>'reposition marginleftonly')); //print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1); print load_fiche_titre($title, $linktotasks.'   '.$linktocreatetask, 'generic'); From 6d8060bc502784a439c47d939a412807ea467d28 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Jul 2020 14:04:41 +0200 Subject: [PATCH 061/434] FIX DO not erase variable $key and $label during output of extrafields Conflicts: htdocs/core/tpl/extrafields_view.tpl.php --- htdocs/core/tpl/extrafields_view.tpl.php | 86 +++++++++++------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 9b324817464..f3a181f0b2e 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -54,50 +54,48 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] $extrafields_collapse_num = ''; $extrafields_collapse_num_old = ''; $i = 0; - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + foreach ($extrafields->attributes[$object->table_element]['label'] as $tmpkeyextra => $tmplabelextra) { $i++; // Discard if extrafield is a hidden field on form $enabled = 1; - if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key])) + if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$tmpkeyextra])) { - $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1); + $enabled = dol_eval($extrafields->attributes[$object->table_element]['enabled'][$tmpkeyextra], 1); } - if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$key])) + if ($enabled && isset($extrafields->attributes[$object->table_element]['list'][$tmpkeyextra])) { - $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$key], 1); + $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$tmpkeyextra], 1); } $perms = 1; - if ($perms && isset($extrafields->attributes[$object->table_element]['perms'][$key])) + if ($perms && isset($extrafields->attributes[$object->table_element]['perms'][$tmpkeyextra])) { - $perms = dol_eval($extrafields->attributes[$object->table_element]['perms'][$key], 1); + $perms = dol_eval($extrafields->attributes[$object->table_element]['perms'][$tmpkeyextra], 1); } - //print $key.'-'.$enabled.'-'.$perms.'-'.$label.$_POST["options_" . $key].'
'."\n"; + //print $tmpkeyextra.'-'.$enabled.'-'.$perms.'-'.$tmplabelextra.$_POST["options_" . $tmpkeyextra].'
'."\n"; if (empty($enabled)) continue; // 0 = Never visible field if (abs($enabled) != 1 && abs($enabled) != 3 && abs($enabled) != 5 && abs($enabled) != 4) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list <> 4 = not visible at the creation if (empty($perms)) continue; // 0 = Not visible // Load language if required - if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); + if (!empty($extrafields->attributes[$object->table_element]['langfile'][$tmpkeyextra])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$tmpkeyextra]); if ($action == 'edit_extras') { - $value = (isset($_POST["options_".$key]) ? $_POST["options_".$key] : $object->array_options["options_".$key]); - } - else - { - $value = $object->array_options["options_".$key]; - //var_dump($key.' - '.$value); + $value = (isset($_POST["options_".$tmpkeyextra]) ? $_POST["options_".$tmpkeyextra] : $object->array_options["options_".$tmpkeyextra]); + } else { + $value = $object->array_options["options_".$tmpkeyextra]; + //var_dump($tmpkeyextra.' - '.$value); } // Print line tr of extra field - if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') + if ($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra] == 'separate') { $extrafields_collapse_num = ''; - $extrafield_param = $extrafields->attributes[$object->table_element]['param'][$key]; + $extrafield_param = $extrafields->attributes[$object->table_element]['param'][$tmpkeyextra]; if (!empty($extrafield_param) && is_array($extrafield_param)) { $extrafield_param_list = array_keys($extrafield_param['options']); @@ -105,17 +103,15 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] $extrafield_collapse_display_value = intval($extrafield_param_list[0]); if ($extrafield_collapse_display_value == 1 || $extrafield_collapse_display_value == 2) { - $extrafields_collapse_num = $extrafields->attributes[$object->table_element]['pos'][$key]; + $extrafields_collapse_num = $extrafields->attributes[$object->table_element]['pos'][$tmpkeyextra]; } } } - print $extrafields->showSeparator($key, $object); + print $extrafields->showSeparator($tmpkeyextra, $object); - $lastseparatorkeyfound = $key; - } - else - { + $lastseparatorkeyfound = $tmpkeyextra; + } else { print 'attributes[$object->table_element]['required'][$key])) print ' fieldrequired'; + if ((!empty($action) && ($action == 'create' || $action == 'edit')) && !empty($extrafields->attributes[$object->table_element]['required'][$tmpkeyextra])) print ' fieldrequired'; print '">'; - if (!empty($extrafields->attributes[$object->table_element]['help'][$key])) print $form->textwithpicto($langs->trans($label), $langs->trans($extrafields->attributes[$object->table_element]['help'][$key])); - else print $langs->trans($label); + if (!empty($extrafields->attributes[$object->table_element]['help'][$tmpkeyextra])) print $form->textwithpicto($langs->trans($tmplabelextra), $langs->trans($extrafields->attributes[$object->table_element]['help'][$tmpkeyextra])); + else print $langs->trans($tmplabelextra); print ''; //TODO Improve element and rights detection @@ -151,54 +147,52 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] if ($object->element == 'mo') $permok = $user->rights->mrp->write; $isdraft = ((isset($object->statut) && $object->statut == 0) || (isset($object->status) && $object->status == 0)); - if (($isdraft || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$key])) - && $permok && $enabled != 5 && ($action != 'edit_extras' || GETPOST('attribute') != $key) - && empty($extrafields->attributes[$object->table_element]['computed'][$key])) + if (($isdraft || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$tmpkeyextra])) + && $permok && $enabled != 5 && ($action != 'edit_extras' || GETPOST('attribute') != $tmpkeyextra) + && empty($extrafields->attributes[$object->table_element]['computed'][$tmpkeyextra])) { $fieldid = 'id'; if ($object->table_element == 'societe') $fieldid = 'socid'; - print ''.img_edit().''; + print ''.img_edit().''; } print ''; print ''; - $html_id = !empty($object->id) ? $object->element.'_extras_'.$key.'_'.$object->id : ''; + $html_id = !empty($object->id) ? $object->element.'_extras_'.$tmpkeyextra.'_'.$object->id : ''; - print ''; + print ''; // Convert date into timestamp format - if (in_array($extrafields->attributes[$object->table_element]['type'][$key], array('date', 'datetime'))) + if (in_array($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra], array('date', 'datetime'))) { - $datenotinstring = $object->array_options['options_'.$key]; - // print 'X'.$object->array_options['options_' . $key].'-'.$datenotinstring.'x'; - if (!is_numeric($object->array_options['options_'.$key])) // For backward compatibility + $datenotinstring = $object->array_options['options_'.$tmpkeyextra]; + // print 'X'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.'x'; + if (!is_numeric($object->array_options['options_'.$tmpkeyextra])) // For backward compatibility { $datenotinstring = $db->jdate($datenotinstring); } - //print 'x'.$object->array_options['options_' . $key].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); - $value = isset($_POST["options_".$key]) ? dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]) : $datenotinstring; + //print 'x'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); + $value = isset($_POST["options_".$tmpkeyextra]) ? dol_mktime($_POST["options_".$tmpkeyextra."hour"], $_POST["options_".$tmpkeyextra."min"], 0, $_POST["options_".$tmpkeyextra."month"], $_POST["options_".$tmpkeyextra."day"], $_POST["options_".$tmpkeyextra."year"]) : $datenotinstring; } //TODO Improve element and rights detection - if ($action == 'edit_extras' && $permok && GETPOST('attribute', 'none') == $key) + if ($action == 'edit_extras' && $permok && GETPOST('attribute', 'none') == $tmpkeyextra) { $fieldid = 'id'; if ($object->table_element == 'societe') $fieldid = 'socid'; print '
'; print ''; - print ''; + print ''; print ''; print ''; - print $extrafields->showInputField($key, $value, '', '', '', 0, $object->id, $object->table_element); + print $extrafields->showInputField($tmpkeyextra, $value, '', '', '', 0, $object->id, $object->table_element); print ''; print '
'; - } - else - { - //var_dump($key.'-'.$value.'-'.$object->table_element); - print $extrafields->showOutputField($key, $value, '', $object->table_element); + } else { + //var_dump($tmpkeyextra.'-'.$value.'-'.$object->table_element); + print $extrafields->showOutputField($tmpkeyextra, $value, '', $object->table_element); } print ''; From 25994e61bce5d8d165dd5fd91fcd9d5113b8b6da Mon Sep 17 00:00:00 2001 From: VERDOL Gauthier Date: Mon, 27 Jul 2020 16:04:21 +0200 Subject: [PATCH 062/434] FIX : We need to see unit line on PDF even though it's an option --- htdocs/core/lib/pdf.lib.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index af1da161dc7..1d9d218f7af 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1826,7 +1826,6 @@ function pdf_getlineunit($object, $i, $outputlangs, $hidedetails = 0, $hookmanag } if (empty($reshook)) { - if ($object->lines[$i]->special_code == 3) return ''; if (empty($hidedetails) || $hidedetails > 1) $result.=$langs->transnoentitiesnoconv($object->lines[$i]->getLabelOfUnit('short')); } return $result; From 5aa4e2353a9d2faa8134690e30d5dfdab7a7c80a Mon Sep 17 00:00:00 2001 From: abb Date: Mon, 27 Jul 2020 14:27:49 +0100 Subject: [PATCH 063/434] fix:fetch and update model_pdf attribute for societe --- htdocs/societe/class/societe.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index c3600ce75e0..067558c445c 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -1314,6 +1314,7 @@ class Societe extends CommonObject $sql .= ", fk_user_modif = ".($user->id > 0 ? $user->id : "null"); $sql .= ", fk_multicurrency = ".(int) $this->fk_multicurrency; $sql .= ", multicurrency_code = '".$this->db->escape($this->multicurrency_code)."'"; + $sql .= ", model_pdf = '".$this->db->escape($this->model_pdf)."'"; $sql .= " WHERE rowid = ".(int) $id; $resql = $this->db->query($sql); @@ -1491,7 +1492,7 @@ class Societe extends CommonObject $sql .= ', st.libelle as stcomm'; $sql .= ', te.code as typent_code'; $sql .= ', i.libelle as label_incoterms'; - $sql .= ', sr.remise_client'; + $sql .= ', sr.remise_client, model_pdf'; $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as e ON s.fk_effectif = e.id'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid'; @@ -1652,6 +1653,7 @@ class Societe extends CommonObject // multicurrency $this->fk_multicurrency = $obj->fk_multicurrency; $this->multicurrency_code = $obj->multicurrency_code; + $this->model_pdf = $obj->model_pdf; $result = 1; From 8c06e3577df185428c01cc971d3e2a06f6e14865 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Jul 2020 19:33:24 +0200 Subject: [PATCH 064/434] Fix several trouble with diret debit module and credit transfer module --- dev/resources/sepa/sample-credit-transfer.xml | 172 ++++++++++++++++++ .../{test.xml => sample-direct-debit.xml} | 0 htdocs/compta/paymentbybanktransfer/index.php | 5 +- htdocs/compta/prelevement/card.php | 29 ++- .../class/bonprelevement.class.php | 137 ++++++++++++-- htdocs/compta/prelevement/create.php | 6 +- htdocs/compta/prelevement/demandes.php | 8 + htdocs/compta/prelevement/factures.php | 57 ++++-- htdocs/compta/prelevement/fiche-rejet.php | 35 ++-- htdocs/compta/prelevement/fiche-stat.php | 41 +++-- htdocs/core/lib/prelevement.lib.php | 7 +- htdocs/langs/en_US/withdrawals.lang | 8 +- 12 files changed, 426 insertions(+), 79 deletions(-) create mode 100644 dev/resources/sepa/sample-credit-transfer.xml rename dev/resources/sepa/{test.xml => sample-direct-debit.xml} (100%) diff --git a/dev/resources/sepa/sample-credit-transfer.xml b/dev/resources/sepa/sample-credit-transfer.xml new file mode 100644 index 00000000000..087fd2f57d7 --- /dev/null +++ b/dev/resources/sepa/sample-credit-transfer.xml @@ -0,0 +1,172 @@ + + + + + message-id-001 + 2010-09-28T14:07:00 + 1 + 10.1 + + Bedrijfsnaam + + + + 123456789123456 + + + + + + + minimaal gevuld + TRF + 1 + 10.1 + 2009-11-01 + + Naam + + + + NL44RABO0123456789 + + + + + RABONL2U + + + + + non ref + + + 10.1 + + SLEV + + + ABNANL2A + + + + Naam creditor + + + + NL90ABNA0111111111 + + + + vrije tekst + + + + + maximaal gevuld + TRF + true + 1 + 20.2 + + NORM + + SEPA + + + IDEAL + + + SECU + + + 2009-11-01 + + Naam + + NL + Debtor straat 1 + 9999 XX Plaats debtor + + + + + NL44RABO0123456789 + + + + + RABONL2U + + + + + + + 12345678 + + klantnummer + + klantnummer uitgifte instantie + + + + + SLEV + + + debtor-to-debtor-bank-01 + End-to-end-id-debtor-to-creditor-01 + + + 20.2 + + + + ABNANL2A + + + + Naam creditor + + NL + Straat creditor 1 + 9999 XX Plaats creditor + + + + + NL90ABNA0111111111 + + + + + + + 1969-07-03 + PLAATS + NL + + + + + + CHAR + + + + + + + SCOR + + CUR + + 1234567 + + + + + + + diff --git a/dev/resources/sepa/test.xml b/dev/resources/sepa/sample-direct-debit.xml similarity index 100% rename from dev/resources/sepa/test.xml rename to dev/resources/sepa/sample-direct-debit.xml diff --git a/htdocs/compta/paymentbybanktransfer/index.php b/htdocs/compta/paymentbybanktransfer/index.php index 1fc6c53cf99..79bb2f6e7fb 100644 --- a/htdocs/compta/paymentbybanktransfer/index.php +++ b/htdocs/compta/paymentbybanktransfer/index.php @@ -94,7 +94,7 @@ print '

'; */ $sql = "SELECT f.ref, f.rowid, f.total_ttc, f.fk_statut, f.paye, f.type,"; $sql .= " pfd.date_demande, pfd.amount,"; -$sql .= " s.nom as name, s.email, s.rowid as socid"; +$sql .= " s.nom as name, s.email, s.rowid as socid, s.tva_intra"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -138,13 +138,14 @@ if ($resql) $thirdpartystatic->id = $obj->socid; $thirdpartystatic->name = $obj->name; $thirdpartystatic->email = $obj->email; + $thirdpartystatic->tva_intra = $obj->tva_intra; print ''; print $invoicestatic->getNomUrl(1, 'withdraw'); print ''; print ''; - print $thirdpartystatic->getNomUrl(1, 'customer'); + print $thirdpartystatic->getNomUrl(1, 'supplier'); print ''; print ''; diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index 3ad145e2f56..23b6fdac500 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -31,10 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.p require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Load translation files required by the page -$langs->loadLangs(array('banks', 'categories', 'bills', 'withdrawals')); - -if (!$user->rights->prelevement->bons->lire) -accessforbidden(); +$langs->loadLangs(array('banks', 'categories', 'bills', 'companies', 'withdrawals')); // Security check if ($user->socid > 0) accessforbidden(); @@ -44,7 +41,6 @@ $action = GETPOST('action', 'alpha'); $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $socid = GETPOST('socid', 'int'); - $type = GETPOST('type', 'aZ09'); // Load variable for pagination @@ -67,6 +63,13 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ $hookmanager->initHooks(array('directdebitprevcard', 'globalcard', 'directdebitprevlist')); +if (!$user->rights->prelevement->bons->lire && $object->type != 'bank-transfer') { + accessforbidden(); +} +if (!$user->rights->paymentbybanktransfer->read && $object->type == 'bank-transfer') { + accessforbidden(); +} + /* * Actions @@ -174,7 +177,7 @@ if ($id > 0 || $ref) }*/ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref'); @@ -200,7 +203,7 @@ if ($id > 0 || $ref) print ''.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print ''; @@ -223,7 +226,9 @@ if ($id > 0 || $ref) $result = $acc->fetch($conf->global->PRELEVEMENT_ID_BANKACCOUNT); print ''; - print $langs->trans("BankToReceiveWithdraw"); + $labelofbankfield = "BankToReceiveWithdraw"; + if ($object->type == 'bank-transfer') $labelofbankfield = 'BankToPayCreditTransfer'; + print $langs->trans($labelofbankfield); print ''; print ''; if ($acc->id > 0) @@ -232,9 +237,13 @@ if ($id > 0 || $ref) print ''; print ''; - print $langs->trans("WithdrawalFile").''; + $labelfororderfield = 'WithdrawalFile'; + if ($object->type == 'bank-transfer') $labelfororderfield = 'CreditTransferFile'; + print $langs->trans($labelfororderfield).''; $relativepath = 'receipts/'.$object->ref.'.xml'; - print ''.$relativepath.''; + $modulepart = 'prelevement'; + if ($object->type == 'bank-transfer') $modulepart = 'paymentbybanktransfer'; + print ''.$relativepath.''; print ''; print ''; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 8cf77667a62..29c70ba8fab 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -295,6 +295,7 @@ class BonPrelevement extends CommonObject $sql .= ", p.method_trans, p.fk_user_trans"; $sql .= ", p.date_credit as date_credit"; $sql .= ", p.fk_user_credit"; + $sql .= ", p.type"; $sql .= ", p.statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql .= " WHERE p.entity IN (".getEntity('invoice').")"; @@ -322,6 +323,8 @@ class BonPrelevement extends CommonObject $this->date_credit = $this->db->jdate($obj->date_credit); $this->user_credit = $obj->fk_user_credit; + $this->type = $obj->type; + $this->status = $obj->status; $this->statut = $obj->status; // For backward compatibility @@ -930,14 +933,14 @@ class BonPrelevement extends CommonObject foreach ($factures as $key => $fac) { if ($type != 'bank-transfer') { - $fact = new Facture($this->db); + $tmpinvoice = new Facture($this->db); } else { - $fact = new FactureFournisseur($this->db); + $tmpinvoice = new FactureFournisseur($this->db); } - $resfetch = $fact->fetch($fac[0]); + $resfetch = $tmpinvoice->fetch($fac[0]); if ($resfetch >= 0) // Field 0 of $fac is rowid of invoice { - if ($soc->fetch($fact->socid) >= 0) + if ($soc->fetch($tmpinvoice->socid) >= 0) { $bac = new CompanyBankAccount($this->db); $bac->fetch(0, $soc->id); @@ -963,9 +966,9 @@ class BonPrelevement extends CommonObject } else { - dol_syslog(__METHOD__."::Check BAN Error on default bank number IBAN/BIC for thirdparty reported by verif() ".$fact->socid." ".$soc->name, LOG_WARNING); - $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for invoice ".$fact->getNomUrl(0)." for thirdparty ".$soc->getNomUrl(0); - $this->thirdparty_in_error[$soc->id] = "Error on default bank number IBAN/BIC for invoice ".$fact->getNomUrl(0)." for thirdparty ".$soc->getNomUrl(0); + dol_syslog(__METHOD__."::Check BAN Error on default bank number IBAN/BIC for thirdparty reported by verif() ".$tmpinvoice->socid." ".$soc->name, LOG_WARNING); + $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for invoice ".$tmpinvoice->getNomUrl(0)." for thirdparty ".$soc->getNomUrl(0); + $this->thirdparty_in_error[$soc->id] = "Error on default bank number IBAN/BIC for invoice ".$tmpinvoice->getNomUrl(0)." for thirdparty ".$soc->getNomUrl(0); } } else @@ -1142,7 +1145,7 @@ class BonPrelevement extends CommonObject * Create file of direct debit order or credit transfer into a XML file */ - dol_syslog(__METHOD__."::Init direct debit file for ".count($factures_prev)." invoices", LOG_DEBUG); + dol_syslog(__METHOD__."::Init direct debit or credit transfer file for ".count($factures_prev)." invoices", LOG_DEBUG); if (count($factures_prev) > 0) { @@ -1168,8 +1171,8 @@ class BonPrelevement extends CommonObject $this->factures = $factures_prev_id; $this->context['factures_prev'] = $factures_prev; - // Generation of SEPA file $this->filename - // This also the the property $this->total that is included into file + // Generation of direct debit or credti transfer file $this->filename (May be a SEPA file for european countries) + // This also set the property $this->total with amount that is included into file $result = $this->generate($format, $executiondate, $type); } dol_syslog(__METHOD__."::End withdraw receipt, file ".$this->filename, LOG_DEBUG); @@ -1499,8 +1502,110 @@ class BonPrelevement extends CommonObject $found++; if ($type == 'bank-transfer') { - print 'TODO'; - exit; + /** + * SECTION CREATION FICHIER SEPA - CREDIT TRANSFER + */ + // SEPA Initialisation + $CrLf = "\n"; + + $now = dol_now(); + + $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S'); + + $date_actu = $now; + if (!empty($executiondate)) $date_actu = $executiondate; + + $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d'); + $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S'); + $fileCrediteurSection = ''; + $fileEmetteurSection = ''; + $i = 0; + + /* + * Section Creditor (sepa Crediteurs bloc lines) + */ + + $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; + $sql .= " f.ref as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " FROM"; + $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; + $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf,"; + $sql .= " ".MAIN_DB_PREFIX."societe as soc,"; + $sql .= " ".MAIN_DB_PREFIX."c_country as c,"; + $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib"; + $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; + $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; + $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND soc.fk_pays = c.rowid"; + $sql .= " AND soc.rowid = f.fk_soc"; + $sql .= " AND rib.fk_soc = f.fk_soc"; + $sql .= " AND rib.default_rib = 1"; + $sql .= " AND rib.type = 'ban'"; + //print $sql; + + // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); + $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum); + $this->total = $this->total + $obj->somme; + $i++; + } + $nbtotalDrctDbtTxInf = $i; + } + else + { + fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers + $result = -2; + } + + // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf + if ($result != -2) + { + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format); + } + + /** + * SECTION CREATION SEPA FILE - CREDTI TRANSFER - ISO200022 + */ + // SEPA File Header + fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); + fputs($this->file, ''.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA Group header + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.('CREDTRANS'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); + fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); + fputs($this->file, ' '.$i.''.$CrLf); + fputs($this->file, ' '.$this->total.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$conf->global->PRELEVEMENT_ICS.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA File Emetteur (mycompany) + if ($result != -2) + { fputs($this-> file, $fileEmetteurSection); } + // SEPA File Creditors + if ($result != -2) + { fputs($this-> file, $fileCrediteurSection); } + // SEPA FILE FOOTER + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ''.$CrLf); } else { /** * SECTION CREATION FICHIER SEPA @@ -1566,18 +1671,14 @@ class BonPrelevement extends CommonObject $result = -2; } - // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all DrctDbtTxInf + // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf if ($result != -2) { $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format); } - else - { - fputs($this->file, 'ERROR CREDITOR'.$CrLf); // CREDITOR = My company - } /** - * SECTION CREATION SEPA FILE + * SECTION CREATION SEPA FILE - ISO200022 */ // SEPA File Header fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index ff25af5e0e9..fdbb6189c5c 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -104,7 +104,11 @@ if (empty($reshook)) } else { - setEventMessages($langs->trans("DirectDebitOrderCreated", $bprev->getNomUrl(1)), null); + if ($type != 'bank-transfer') { + setEventMessages($langs->trans("DirectDebitOrderCreated", $bprev->getNomUrl(1)), null); + } else { + setEventMessages($langs->trans("CreditTransferOrderCreated", $bprev->getNomUrl(1)), null); + } header("Location: ".DOL_URL_ROOT.'/compta/prelevement/card.php?id='.$bprev->id); exit; diff --git a/htdocs/compta/prelevement/demandes.php b/htdocs/compta/prelevement/demandes.php index b92df4e446c..2d2be116aaf 100644 --- a/htdocs/compta/prelevement/demandes.php +++ b/htdocs/compta/prelevement/demandes.php @@ -192,6 +192,14 @@ print ''; $param = ''; +$label = 'NewStandingOrder'; +$typefilter = ''; +if ($type == 'bank-transfer') { + $label = 'NewPaymentByBankTransfer'; + $typefilter = 'type='.$type; +} +$newcardbutton .= dolGetButtonTitle($langs->trans($label), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/compta/prelevement/create.php'.($typefilter ? '?'.$typefilter : '')); + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit); print ''; diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 556f40de9be..816795bfdbd 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -32,21 +32,21 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Load translation files required by the page -$langs->loadLangs(array('banks', 'categories', 'companies', 'withdrawals', 'bills')); +$langs->loadLangs(array('banks', 'categories', 'bills', 'companies', 'withdrawals')); // Securite acces client if ($user->socid > 0) accessforbidden(); // Get supervariables $id = GETPOST('id', 'int'); -$socid = GETPOST('socid', 'int'); $ref = GETPOST('ref', 'alpha'); - +$socid = GETPOST('socid', 'int'); $type = GETPOST('type', 'aZ09'); +// Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); +$sortfield = GETPOST('sortfield', 'alpha'); +$sortorder = GETPOST('sortorder', 'alpha'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $offset = $limit * $page; @@ -57,6 +57,17 @@ if (!$sortorder) $sortorder = 'DESC'; $object = new BonPrelevement($db); +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals + +$hookmanager->initHooks(array('directdebitprevcard', 'globalcard', 'directdebitprevlist')); + +if (!$user->rights->prelevement->bons->lire && $object->type != 'bank-transfer') { + accessforbidden(); +} +if (!$user->rights->paymentbybanktransfer->read && $object->type == 'bank-transfer') { + accessforbidden(); +} /* @@ -75,19 +86,17 @@ if ($id > 0 || $ref) $head = prelevement_prepare_head($object); dol_fiche_head($head, 'invoices', $langs->trans("WithdrawalsReceipts"), -1, 'payment'); - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref'); print '
'; print '
'; - print '
'; + print '
'."\n"; //print ''; print ''; print ''; - // Status - //print ''; if ($object->date_trans <> 0) { @@ -119,7 +128,9 @@ if ($id > 0 || $ref) $result = $acc->fetch($conf->global->PRELEVEMENT_ID_BANKACCOUNT); print ''; print ''; print '
'.$langs->trans("Ref").''.$object->getNomUrl(1).'
'.$langs->trans("Date").''.dol_print_date($object->datec, 'day').'
'.$langs->trans("Amount").''.price($object->amount).'
'.$langs->trans('Status').''.$object->getLibStatut(1).'
'; - print $langs->trans("BankToReceiveWithdraw"); + $labelofbankfield = "BankToReceiveWithdraw"; + if ($object->type == 'bank-transfer') $labelofbankfield = 'BankToPayCreditTransfer'; + print $langs->trans($labelofbankfield); print ''; if ($acc->id > 0) @@ -128,9 +139,13 @@ if ($id > 0 || $ref) print '
'; - print $langs->trans("WithdrawalFile").''; + $labelfororderfield = 'WithdrawalFile'; + if ($object->type == 'bank-transfer') $labelfororderfield = 'CreditTransferFile'; + print $langs->trans($labelfororderfield).''; $relativepath = 'receipts/'.$object->ref.'.xml'; - print ''.$relativepath.''; + $modulepart = 'prelevement'; + if ($object->type == 'bank-transfer') $modulepart = 'paymentbybanktransfer'; + print ''.$relativepath.''; print '
'; print ''; @@ -151,13 +166,25 @@ $sql .= " s.rowid as socid, s.nom as name, pl.statut, pl.amount as amount_reques $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql .= ", ".MAIN_DB_PREFIX."prelevement_lignes as pl"; $sql .= ", ".MAIN_DB_PREFIX."prelevement_facture as pf"; -$sql .= ", ".MAIN_DB_PREFIX."facture as f"; +if ($object->type != 'bank-transfer') { + $sql .= ", ".MAIN_DB_PREFIX."facture as f"; +} else { + $sql .= ", ".MAIN_DB_PREFIX."facture_fourn as f"; +} $sql .= ", ".MAIN_DB_PREFIX."societe as s"; $sql .= " WHERE pf.fk_prelevement_lignes = pl.rowid"; $sql .= " AND pl.fk_prelevement_bons = p.rowid"; $sql .= " AND f.fk_soc = s.rowid"; -$sql .= " AND pf.fk_facture = f.rowid"; -$sql .= " AND f.entity IN (".getEntity('invoice').")"; +if ($object->type != 'bank-transfer') { + $sql .= " AND pf.fk_facture = f.rowid"; +} else { + $sql .= " AND pf.fk_facture_fourn = f.rowid"; +} +if ($object->type != 'bank-transfer') { + $sql .= " AND f.entity IN (".getEntity('invoice').")"; +} else { + $sql .= " AND f.entity IN (".getEntity('supplier_invoice').")"; +} if ($object->id > 0) $sql .= " AND p.rowid=".$object->id; if ($socid) $sql .= " AND s.rowid = ".$socid; $sql .= $db->order($sortfield, $sortorder); diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index 75cff74da8a..10abbcf5166 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -21,7 +21,7 @@ /** * \file htdocs/compta/prelevement/fiche-rejet.php * \ingroup prelevement - * \brief Withdraw reject + * \brief Debit order or credit transfer reject */ require '../../main.inc.php'; @@ -34,7 +34,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Load translation files required by the page $langs->loadLangs(array("banks", "categories", 'withdrawals', 'bills')); -// Securite acces client +// Security check if ($user->socid > 0) accessforbidden(); // Get supervariables @@ -55,6 +55,15 @@ $pagenext = $page + 1; $object = new BonPrelevement($db); +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals + +if (!$user->rights->prelevement->bons->lire && $object->type != 'bank-transfer') { + accessforbidden(); +} +if (!$user->rights->paymentbybanktransfer->read && $object->type == 'bank-transfer') { + accessforbidden(); +} @@ -71,7 +80,7 @@ if ($prev_id > 0 || $ref) $head = prelevement_prepare_head($object); dol_fiche_head($head, 'rejects', $langs->trans("WithdrawalsReceipts"), -1, 'payment'); - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref'); @@ -83,13 +92,6 @@ if ($prev_id > 0 || $ref) print ''.$langs->trans("Date").''.dol_print_date($object->datec, 'day').''; print ''.$langs->trans("Amount").''.price($object->amount).''; - // Status - /* - print ''.$langs->trans('Status').''; - print ''.$object->getLibStatut(1).''; - print ''; - */ - if ($object->date_trans <> 0) { $muser = new User($db); @@ -120,7 +122,9 @@ if ($prev_id > 0 || $ref) $result = $acc->fetch($conf->global->PRELEVEMENT_ID_BANKACCOUNT); print ''; - print $langs->trans("BankToReceiveWithdraw"); + $labelofbankfield = "BankToReceiveWithdraw"; + if ($object->type == 'bank-transfer') $labelofbankfield = 'BankToPayCreditTransfer'; + print $langs->trans($labelofbankfield); print ''; print ''; if ($acc->id > 0) @@ -129,9 +133,13 @@ if ($prev_id > 0 || $ref) print ''; print ''; - print $langs->trans("WithdrawalFile").''; + $labelfororderfield = 'WithdrawalFile'; + if ($object->type == 'bank-transfer') $labelfororderfield = 'CreditTransferFile'; + print $langs->trans($labelfororderfield).''; $relativepath = 'receipts/'.$object->ref.'.xml'; - print ''.$relativepath.''; + $modulepart = 'prelevement'; + if ($object->type == 'bank-transfer') $modulepart = 'paymentbybanktransfer'; + print ''.$relativepath.''; print ''; print ''; @@ -144,6 +152,7 @@ if ($prev_id > 0 || $ref) } } + $rej = new RejetPrelevement($db, $user); /* diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php index 899ff69fea1..49508cdde46 100644 --- a/htdocs/compta/prelevement/fiche-stat.php +++ b/htdocs/compta/prelevement/fiche-stat.php @@ -20,7 +20,7 @@ /** * \file htdocs/compta/prelevement/fiche-stat.php * \ingroup prelevement - * \brief Prelevement statistics + * \brief Debit order or credit transfer statistics */ require '../../main.inc.php'; @@ -54,6 +54,17 @@ $pagenext = $page + 1; $object = new BonPrelevement($db); +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals + +if (!$user->rights->prelevement->bons->lire && $object->type != 'bank-transfer') { + accessforbidden(); +} +if (!$user->rights->paymentbybanktransfer->read && $object->type == 'bank-transfer') { + accessforbidden(); +} + + /* * View @@ -68,7 +79,7 @@ if ($prev_id > 0 || $ref) $head = prelevement_prepare_head($object); dol_fiche_head($head, 'statistics', $langs->trans("WithdrawalsReceipts"), -1, 'payment'); - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref'); @@ -80,13 +91,6 @@ if ($prev_id > 0 || $ref) print ''.$langs->trans("Date").''.dol_print_date($object->datec, 'day').''; print ''.$langs->trans("Amount").''.price($object->amount).''; - // Status - /* - print ''.$langs->trans('Status').''; - print ''.$object->getLibStatut(1).''; - print ''; - */ - if ($object->date_trans <> 0) { $muser = new User($db); @@ -117,7 +121,9 @@ if ($prev_id > 0 || $ref) $result = $acc->fetch($conf->global->PRELEVEMENT_ID_BANKACCOUNT); print ''; - print $langs->trans("BankToReceiveWithdraw"); + $labelofbankfield = "BankToReceiveWithdraw"; + if ($object->type == 'bank-transfer') $labelofbankfield = 'BankToPayCreditTransfer'; + print $langs->trans($labelofbankfield); print ''; print ''; if ($acc->id > 0) @@ -126,9 +132,13 @@ if ($prev_id > 0 || $ref) print ''; print ''; - print $langs->trans("WithdrawalFile").''; + $labelfororderfield = 'WithdrawalFile'; + if ($object->type == 'bank-transfer') $labelfororderfield = 'CreditTransferFile'; + print $langs->trans($labelfororderfield).''; $relativepath = 'receipts/'.$object->ref.'.xml'; - print ''.$relativepath.''; + $modulepart = 'prelevement'; + if ($object->type == 'bank-transfer') $modulepart = 'paymentbybanktransfer'; + print ''.$relativepath.''; print ''; print ''; @@ -137,14 +147,13 @@ if ($prev_id > 0 || $ref) } else { - $langs->load("errors"); - print $langs->trans("Error"); + dol_print_error($db); } /* * Stats */ - $ligne = new LignePrelevement($db); + $line = new LignePrelevement($db); $sql = "SELECT sum(pl.amount), pl.statut"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_lignes as pl"; @@ -170,7 +179,7 @@ if ($prev_id > 0 || $ref) print ''; - print $ligne->LibStatut($row[1], 1); + print $line->LibStatut($row[1], 1); print ''; print price($row[0]); diff --git a/htdocs/core/lib/prelevement.lib.php b/htdocs/core/lib/prelevement.lib.php index a404e19184e..8008c9fd51f 100644 --- a/htdocs/core/lib/prelevement.lib.php +++ b/htdocs/core/lib/prelevement.lib.php @@ -39,8 +39,13 @@ function prelevement_prepare_head(BonPrelevement $object) $h = 0; $head = array(); + $titleoftab = "WithdrawalsReceipts"; + if ($object->type == 'bank-transfer') { + $titleoftab = "BankTransferReceipts"; + } + $head[$h][0] = DOL_URL_ROOT.'/compta/prelevement/card.php?id='.$object->id; - $head[$h][1] = $langs->trans("WithdrawalsReceipts"); + $head[$h][1] = $langs->trans($titleoftab); $head[$h][2] = 'prelevement'; $h++; diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 841a9c2d480..662c587108a 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -77,12 +77,12 @@ StatusMotif8=Other reason CreateForSepaFRST=Create direct debit file (SEPA FRST) CreateForSepaRCUR=Create direct debit file (SEPA RCUR) CreateAll=Create direct debit file (all) -CreateFileForPaymentByBankTransfer=Create credit transfer (all) +CreateFileForPaymentByBankTransfer=Create file for credit transfer (all) CreateSepaFileForPaymentByBankTransfer=Create credit transfer file (SEPA) CreateGuichet=Only office CreateBanque=Only bank OrderWaiting=Waiting for treatment -NotifyTransmision=Withdrawal Transmission +NotifyTransmision=File transmission NotifyCredit=Withdrawal Credit NumeroNationalEmetter=National Transmitter Number WithBankUsingRIB=For bank accounts using RIB @@ -95,7 +95,8 @@ ShowWithdraw=Show Direct Debit Order IfInvoiceNeedOnWithdrawPaymentWontBeClosed=However, if invoice has at least one direct debit payment order not yet processed, it won't be set as paid to allow prior withdrawal management. DoStandingOrdersBeforePayments=This tab allows you to request a direct debit payment order. Once done, go into menu Bank->Payment by direct debit to generate and manage the direct debit order. When direct debit order is closed, payment on invoices will be automatically recorded, and invoices closed if remainder to pay is null. DoCreditTransferBeforePayments=This tab allows you to request a credit transfer order. Once done, go into menu Bank->Payment by credit transfer to generate and manage the credit transfer order. When credit transfer order is closed, payment on invoices will be automatically recorded, and invoices closed if remainder to pay is null. -WithdrawalFile=Withdrawal file +WithdrawalFile=Debit order file +CreditTransferFile=Credit transfer file SetToStatusSent=Set to status "File Sent" ThisWillAlsoAddPaymentOnInvoice=This will also record payments on invoices and will classify them as "Paid" if remain to pay is null StatisticsByLineStatus=Statistics by status of lines @@ -121,6 +122,7 @@ SEPAFrstOrRecur=Type of payment ModeRECUR=Recurring payment ModeFRST=One-off payment PleaseCheckOne=Please check one only +CreditTransferOrderCreated=Credit transfer order %s created DirectDebitOrderCreated=Direct debit order %s created AmountRequested=Amount requested SEPARCUR=SEPA CUR From ee55b82a8d7449b53f649417102ffb43e2e9e5cb Mon Sep 17 00:00:00 2001 From: Marc DLL <68746600@users.noreply.github.com> Date: Mon, 27 Jul 2020 23:27:44 +0200 Subject: [PATCH 065/434] FIX: shipping creation: checks not done on weight and sizes --- htdocs/expedition/class/expedition.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index b623ea9c629..8417ddb9bfb 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -321,10 +321,10 @@ class Expedition extends CommonObject $sql.= ", ".($this->fk_delivery_address>0?$this->fk_delivery_address:"null"); $sql.= ", ".($this->shipping_method_id>0?$this->shipping_method_id:"null"); $sql.= ", '".$this->db->escape($this->tracking_number)."'"; - $sql.= ", ".$this->weight; - $sql.= ", ".$this->sizeS; // TODO Should use this->trueDepth - $sql.= ", ".$this->sizeW; // TODO Should use this->trueWidth - $sql.= ", ".$this->sizeH; // TODO Should use this->trueHeight + $sql.= ", ".(is_numeric($this->weight)?$this->weight:'NULL'); + $sql.= ", ".(is_numeric($this->sizeS)?$this->sizeS:'NULL'); // TODO Should use this->trueDepth + $sql.= ", ".(is_numeric($this->sizeW)?$this->sizeW:'NULL'); // TODO Should use this->trueWidth + $sql.= ", ".(is_numeric($this->sizeH)?$this->sizeH:'NULL'); // TODO Should use this->trueHeight $sql.= ", ".($this->weight_units != '' ? (int) $this->weight_units : 'NULL'); $sql.= ", ".($this->size_units != '' ? (int) $this->size_units : 'NULL'); $sql.= ", ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null"); From a4427bd2d214071b22955b6715b4dc9130b95f09 Mon Sep 17 00:00:00 2001 From: Marc DLL <68746600@users.noreply.github.com> Date: Mon, 27 Jul 2020 23:58:06 +0200 Subject: [PATCH 066/434] FIX: product stock/reassort list: add hooks --- htdocs/product/reassort.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index 6ee13633139..86019c78b00 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -83,6 +83,9 @@ if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global $virtualdiffersfromphysical=1; // According to increase/decrease stock options, virtual and physical stock may differs. } +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('productreassortlist')); + /* @@ -121,6 +124,10 @@ $sql.= ' p.fk_product_type, p.tms as datem,'; $sql.= ' p.duration, p.tosell as statut, p.tobuy, p.seuil_stock_alerte, p.desiredstock,'; $sql.= ' SUM(s.reel) as stock_physique'; if (! empty($conf->global->PRODUCT_USE_UNITS)) $sql.= ', u.short_label as unit_short'; +// Add fields from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; $sql.= ' FROM '.MAIN_DB_PREFIX.'product as p'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s on p.rowid = s.fk_product'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'entrepot as e on s.fk_entrepot = e.rowid AND e.entity IN ('.getEntity('entrepot').')'; @@ -152,8 +159,16 @@ if($catid) $sql.= " AND cp.fk_categorie = ".$catid; if ($fourn_id > 0) $sql.= " AND p.rowid = pf.fk_product AND pf.fk_soc = ".$fourn_id; // Insert categ filter if ($search_categ) $sql .= " AND cp.fk_categorie = ".$db->escape($search_categ); +// Add where from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; $sql.= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type, p.entity,"; $sql.= " p.fk_product_type, p.tms, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock"; +// Add fields from hooks +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldSelect', $parameters); // Note that $action and $object may have been modified by hook +$sql.=$hookmanager->resPrint; if ($toolowstock) $sql.= " HAVING SUM(".$db->ifsql('s.reel IS NULL', '0', 's.reel').") < p.seuil_stock_alerte"; $sql.= $db->order($sortfield, $sortorder); @@ -298,6 +313,9 @@ if ($resql) print ' '; print ' '; print ''; + $parameters=array(); + $reshook=$hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print ''; $searchpicto=$form->showFilterAndCheckAddButtons(0); print $searchpicto; @@ -329,6 +347,10 @@ if ($resql) print_liste_field_titre(''); print_liste_field_titre("ProductStatusOnSell", $_SERVER["PHP_SELF"], "p.tosell", $param, "", '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ProductStatusOnBuy", $_SERVER["PHP_SELF"], "p.tobuy", $param, "", '', $sortfield, $sortorder, 'right '); + // Hook fields + $parameters=array('param'=>$param,'sortfield'=>$sortfield,'sortorder'=>$sortorder); + $reshook=$hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print_liste_field_titre(''); print "\n"; @@ -393,6 +415,10 @@ if ($resql) print ''.$langs->trans("Movements").''; print ''.$product->LibStatut($objp->statut, 5, 0).''; print ''.$product->LibStatut($objp->tobuy, 5, 1).''; + // Fields from hook + $parameters=array('obj'=>$objp); + $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print ''; print "\n"; $i++; From 8c425ae7967dd63597088d983e2f5a2c425bca04 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Jul 2020 02:47:46 +0200 Subject: [PATCH 067/434] FIX Bad param --- htdocs/modulebuilder/template/admin/myobject_extrafields.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/admin/myobject_extrafields.php b/htdocs/modulebuilder/template/admin/myobject_extrafields.php index 13a6e7b54c5..065feb6cebe 100644 --- a/htdocs/modulebuilder/template/admin/myobject_extrafields.php +++ b/htdocs/modulebuilder/template/admin/myobject_extrafields.php @@ -68,7 +68,7 @@ $linkback = 'trans("MyObjectExtraFields"), -1, 'account'); From fef180cf86cab3b43deeac0dbda12c116c9b602b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Jul 2020 02:54:37 +0200 Subject: [PATCH 068/434] Fix scrutinizer errors --- htdocs/admin/bom_extrafields.php | 2 +- htdocs/admin/mrp_extrafields.php | 2 +- .../template/class/myobject.class.php | 15 +- htdocs/recruitment/COPYING | 621 ------------------ .../class/recruitmentjobposition.class.php | 22 +- .../phpunit/RecruitmentFunctionalTest.php | 304 --------- 6 files changed, 17 insertions(+), 949 deletions(-) delete mode 100644 htdocs/recruitment/COPYING delete mode 100644 htdocs/recruitment/test/phpunit/RecruitmentFunctionalTest.php diff --git a/htdocs/admin/bom_extrafields.php b/htdocs/admin/bom_extrafields.php index 70d7720e994..70303f1dcda 100644 --- a/htdocs/admin/bom_extrafields.php +++ b/htdocs/admin/bom_extrafields.php @@ -68,7 +68,7 @@ $linkback = 'trans("ExtraFields"), -1, 'account'); diff --git a/htdocs/admin/mrp_extrafields.php b/htdocs/admin/mrp_extrafields.php index 55df2a065d0..cab7232f569 100644 --- a/htdocs/admin/mrp_extrafields.php +++ b/htdocs/admin/mrp_extrafields.php @@ -68,7 +68,7 @@ $linkback = 'trans("ExtraFields"), -1, 'account'); diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 9c3bbe0bec0..455f0a3e3d1 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -1060,11 +1060,24 @@ class MyObject extends CommonObject } } + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; + /** * Class MyObjectLine. You can also remove this and generate a CRUD class for lines objects. */ -class MyObjectLine +class MyObjectLine extends CommonObjectLine { // To complete with content of an object MyObjectLine // We should have a field rowid, fk_myobject and position + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } } diff --git a/htdocs/recruitment/COPYING b/htdocs/recruitment/COPYING deleted file mode 100644 index 94a04532226..00000000000 --- a/htdocs/recruitment/COPYING +++ /dev/null @@ -1,621 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index adc33ab638d..6d38f47211c 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -884,18 +884,7 @@ class RecruitmentJobPosition extends CommonObject { $this->lines = array(); - $objectline = new RecruitmentJobPositionLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_recruitmentjobposition = '.$this->id)); - - if (is_numeric($result)) - { - $this->error = $this->error; - $this->errors = $this->errors; - return $result; - } else { - $this->lines = $result; - return $this->lines; - } + return $this->lines; } /** @@ -1026,12 +1015,3 @@ class RecruitmentJobPosition extends CommonObject return $error; } } - -/** - * Class RecruitmentJobPositionLine. You can also remove this and generate a CRUD class for lines objects. - */ -class RecruitmentJobPositionLine -{ - // To complete with content of an object RecruitmentJobPositionLine - // We should have a field rowid, fk_recruitmentjobposition and position -} diff --git a/htdocs/recruitment/test/phpunit/RecruitmentFunctionalTest.php b/htdocs/recruitment/test/phpunit/RecruitmentFunctionalTest.php deleted file mode 100644 index 0d4de50fe68..00000000000 --- a/htdocs/recruitment/test/phpunit/RecruitmentFunctionalTest.php +++ /dev/null @@ -1,304 +0,0 @@ - - * Copyright (C) 2020 Adminson Alicealalalamdskfldmjgdfgdfhfghgfh - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file test/phpunit/RecruitmentFunctionalTest.php - * \ingroup recruitment - * \brief Example Selenium test. - * - * Put detailed description here. - */ - -namespace test\functional; - -use PHPUnit_Extensions_Selenium2TestCase_WebDriverException; - -/** - * Class RecruitmentFunctionalTest - * - * Requires chromedriver for Google Chrome - * Requires geckodriver for Mozilla Firefox - * - * @fixme Firefox (Geckodriver/Marionette) support - * @todo Opera linux support - * @todo Windows support (IE, Google Chrome, Mozilla Firefox, Safari) - * @todo OSX support (Safari, Google Chrome, Mozilla Firefox) - * - * @package Testrecruitment - */ -class RecruitmentFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase -{ - // TODO: move to a global configuration file? - /** @var string Base URL of the webserver under test */ - protected static $base_url = 'http://dev.zenfusion.fr'; - /** - * @var string Dolibarr admin username - * @see authenticate - */ - protected static $dol_admin_user = 'admin'; - /** - * @var string Dolibarr admin password - * @see authenticate - */ - protected static $dol_admin_pass = 'admin'; - /** @var int Dolibarr module ID */ - private static $module_id = 500000; // TODO: autodetect? - - /** @var array Browsers to test with */ - public static $browsers = array( - array( - 'browser' => 'Google Chrome on Linux', - 'browserName' => 'chrome', - 'sessionStrategy' => 'shared', - 'desiredCapabilities' => array() - ), - // Geckodriver does not keep the session at the moment?! - // XPath selectors also don't seem to work - //array( - // 'browser' => 'Mozilla Firefox on Linux', - // 'browserName' => 'firefox', - // 'sessionStrategy' => 'shared', - // 'desiredCapabilities' => array( - // 'marionette' => true, - // ), - //) - ); - - /** - * Helper function to select links by href - * - * @param string $value Href - * @return mixed Helper string - */ - protected function byHref($value) - { - $anchor = null; - $anchors = $this->elements($this->using('tag name')->value('a')); - foreach ($anchors as $anchor) { - if (strstr($anchor->attribute('href'), $value)) { - break; - } - } - return $anchor; - } - - /** - * Global test setup - * @return void - */ - public static function setUpBeforeClass() - { - } - - /** - * Unit test setup - * @return void - */ - public function setUp() - { - $this->setSeleniumServerRequestsTimeout(3600); - $this->setBrowserUrl(self::$base_url); - } - - /** - * Verify pre conditions - * @return void - */ - protected function assertPreConditions() - { - } - - /** - * Handle Dolibarr authentication - * @return void - */ - private function authenticate() - { - try { - if ($this->byId('login')) { - $login = $this->byId('username'); - $login->clear(); - $login->value('admin'); - $password = $this->byId('password'); - $password->clear(); - $password->value('admin'); - $this->byId('login')->submit(); - } - } catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) { - // Login does not exist. Assume we are already authenticated - } - } - - /** - * Test enabling developer mode - * @return bool - */ - public function testEnableDeveloperMode() - { - $this->url('/admin/const.php'); - $this->authenticate(); - $main_features_level_path = '//input[@value="MAIN_FEATURES_LEVEL"]/following::input[@type="text"]'; - $main_features_level = $this->byXPath($main_features_level_path); - $main_features_level->clear(); - $main_features_level->value('2'); - $this->byName('update')->click(); - // Page reloaded, we need a new XPath - $main_features_level = $this->byXPath($main_features_level_path); - return $this->assertEquals('2', $main_features_level->value(), "MAIN_FEATURES_LEVEL value is 2"); - } - - /** - * Test enabling the module - * - * @depends testEnableDeveloperMode - * @return bool - */ - public function testModuleEnabled() - { - $this->url('/admin/modules.php'); - $this->authenticate(); - $module_status_image_path = '//a[contains(@href, "'.self::$module_id.'")]/img'; - $module_status_image = $this->byXPath($module_status_image_path); - if (strstr($module_status_image->attribute('src'), 'switch_off.png')) { - // Enable the module - $this->byHref('modRecruitment')->click(); - } else { - // Disable the module - $this->byHref('modRecruitment')->click(); - // Reenable the module - $this->byHref('modRecruitment')->click(); - } - // Page reloaded, we need a new Xpath - $module_status_image = $this->byXPath($module_status_image_path); - return $this->assertContains('switch_on.png', $module_status_image->attribute('src'), "Module enabled"); - } - - /** - * Test access to the configuration page - * - * @depends testModuleEnabled - * @return bool - */ - public function testConfigurationPage() - { - $this->url('/custom/recruitment/admin/setup.php'); - $this->authenticate(); - return $this->assertContains('recruitment/admin/setup.php', $this->url(), 'Configuration page'); - } - - /** - * Test access to the about page - * - * @depends testConfigurationPage - * @return bool - */ - public function testAboutPage() - { - $this->url('/custom/recruitment/admin/about.php'); - $this->authenticate(); - return $this->assertContains('recruitment/admin/about.php', $this->url(), 'About page'); - } - - /** - * Test about page is rendering Markdown - * - * @depends testAboutPage - * @return bool - */ - public function testAboutPageRendersMarkdownReadme() - { - $this->url('/custom/recruitment/admin/about.php'); - $this->authenticate(); - return $this->assertEquals( - 'Dolibarr Module Template (aka My Module)', - $this->byTag('h1')->text(), - "Readme title" - ); - } - - /** - * Test box is properly declared - * - * @depends testModuleEnabled - * @return bool - */ - public function testBoxDeclared() - { - $this->url('/admin/boxes.php'); - $this->authenticate(); - return $this->assertContains('recruitmentwidget1', $this->source(), "Box enabled"); - } - - /** - * Test trigger is properly enabled - * - * @depends testModuleEnabled - * @return bool - */ - public function testTriggerDeclared() - { - $this->url('/admin/triggers.php'); - $this->authenticate(); - return $this->assertContains( - 'interface_99_modRecruitment_RecruitmentTriggers.class.php', - $this->byTag('body')->text(), - "Trigger declared" - ); - } - - /** - * Test trigger is properly declared - * - * @depends testTriggerDeclared - * @return bool - */ - public function testTriggerEnabled() - { - $this->url('/admin/triggers.php'); - $this->authenticate(); - return $this->assertContains( - 'tick.png', - $this->byXPath('//td[text()="interface_99_modRecruitment_MyTrigger.class.php"]/following::img')->attribute('src'), - "Trigger enabled" - ); - } - - /** - * Verify post conditions - * @return void - */ - protected function assertPostConditions() - { - } - - /** - * Unit test teardown - * @return void - */ - public function tearDown() - { - } - - /** - * Global test teardown - * @return void - */ - public static function tearDownAfterClass() - { - } -} From 98064f73298fe6e33b7bfcbca8abe7f9526c81e6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Jul 2020 02:47:46 +0200 Subject: [PATCH 069/434] FIX Bad param --- htdocs/modulebuilder/template/admin/myobject_extrafields.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/admin/myobject_extrafields.php b/htdocs/modulebuilder/template/admin/myobject_extrafields.php index 13a6e7b54c5..065feb6cebe 100644 --- a/htdocs/modulebuilder/template/admin/myobject_extrafields.php +++ b/htdocs/modulebuilder/template/admin/myobject_extrafields.php @@ -68,7 +68,7 @@ $linkback = 'trans("MyObjectExtraFields"), -1, 'account'); From 4e4f0a4575cbff32534b77a7af37174533030dab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Jul 2020 09:44:48 +0200 Subject: [PATCH 070/434] Use same case for all sql files --- htdocs/admin/system/database-tables.php | 2 +- htdocs/install/mysql/tables/llx_c_format_cards.sql | 2 +- htdocs/install/mysql/tables/llx_establishment.sql | 2 +- htdocs/install/mysql/tables/llx_expeditiondet_batch.sql | 2 +- htdocs/install/mysql/tables/llx_expensereport_rules.sql | 2 +- htdocs/install/mysql/tables/llx_inventory.sql | 2 +- htdocs/install/mysql/tables/llx_inventorydet.sql | 2 +- htdocs/install/mysql/tables/llx_oauth_state.sql | 2 +- htdocs/install/mysql/tables/llx_oauth_token.sql | 2 +- htdocs/install/mysql/tables/llx_opensurvey_comments.sql | 2 +- htdocs/install/mysql/tables/llx_opensurvey_formquestions.sql | 2 +- htdocs/install/mysql/tables/llx_opensurvey_sondage.sql | 2 +- htdocs/install/mysql/tables/llx_opensurvey_user_formanswers.sql | 2 +- htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql | 2 +- htdocs/install/mysql/tables/llx_product_batch.sql | 2 +- htdocs/install/mysql/tables/llx_product_lot.sql | 2 +- htdocs/install/mysql/tables/llx_propal_merge_pdf_product.sql | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index 323d9b4c115..97b8237c6f2 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -119,7 +119,7 @@ else print ''.$obj->Engine.''; if (isset($obj->Engine) && $obj->Engine == "MyISAM") { - print ''.$langs->trans("Convert").' InnoDB'; + print ''.$langs->trans("Convert").' InnoDb'; } else { diff --git a/htdocs/install/mysql/tables/llx_c_format_cards.sql b/htdocs/install/mysql/tables/llx_c_format_cards.sql index b69b9eb19d1..d3885b5d256 100644 --- a/htdocs/install/mysql/tables/llx_c_format_cards.sql +++ b/htdocs/install/mysql/tables/llx_c_format_cards.sql @@ -36,4 +36,4 @@ CREATE TABLE llx_c_format_cards custom_x double(24,8) NOT NULL, custom_y double(24,8) NOT NULL, active integer NOT NULL -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_establishment.sql b/htdocs/install/mysql/tables/llx_establishment.sql index 89fec8f54e2..83cfadb7307 100644 --- a/htdocs/install/mysql/tables/llx_establishment.sql +++ b/htdocs/install/mysql/tables/llx_establishment.sql @@ -37,5 +37,5 @@ CREATE TABLE llx_establishment ( datec datetime NOT NULL, tms timestamp NOT NULL, status tinyint DEFAULT 1 -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_expeditiondet_batch.sql b/htdocs/install/mysql/tables/llx_expeditiondet_batch.sql index 7a6a3bfd777..43b64451364 100644 --- a/htdocs/install/mysql/tables/llx_expeditiondet_batch.sql +++ b/htdocs/install/mysql/tables/llx_expeditiondet_batch.sql @@ -23,5 +23,5 @@ CREATE TABLE llx_expeditiondet_batch ( batch varchar(128) DEFAULT NULL, qty double NOT NULL DEFAULT '0', fk_origin_stock integer NOT NULL -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_expensereport_rules.sql b/htdocs/install/mysql/tables/llx_expensereport_rules.sql index aa6d7553639..2a10cc24a7d 100644 --- a/htdocs/install/mysql/tables/llx_expensereport_rules.sql +++ b/htdocs/install/mysql/tables/llx_expensereport_rules.sql @@ -31,4 +31,4 @@ CREATE TABLE llx_expensereport_rules ( code_expense_rules_type varchar(50) NOT NULL, is_for_all tinyint DEFAULT 0, entity integer DEFAULT 1 -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_inventory.sql b/htdocs/install/mysql/tables/llx_inventory.sql index 70e409193aa..4ccb234e26e 100644 --- a/htdocs/install/mysql/tables/llx_inventory.sql +++ b/htdocs/install/mysql/tables/llx_inventory.sql @@ -35,4 +35,4 @@ CREATE TABLE llx_inventory date_validation datetime DEFAULT NULL, import_key varchar(14) -- import key ) -ENGINE=InnoDB; +ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_inventorydet.sql b/htdocs/install/mysql/tables/llx_inventorydet.sql index b4df529433e..161e34183a0 100644 --- a/htdocs/install/mysql/tables/llx_inventorydet.sql +++ b/htdocs/install/mysql/tables/llx_inventorydet.sql @@ -30,4 +30,4 @@ qty_stock double DEFAULT NULL, -- The targeted value. can be filled during dra qty_view double DEFAULT NULL, -- must be filled once regulation is done qty_regulated double DEFAULT NULL -- must be filled once regulation is done ) -ENGINE=InnoDB; +ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_oauth_state.sql b/htdocs/install/mysql/tables/llx_oauth_state.sql index 39ade6bc529..77093f6d1b4 100644 --- a/htdocs/install/mysql/tables/llx_oauth_state.sql +++ b/htdocs/install/mysql/tables/llx_oauth_state.sql @@ -22,4 +22,4 @@ CREATE TABLE llx_oauth_state ( fk_user integer, fk_adherent integer, entity integer DEFAULT 1 -)ENGINE=InnoDB; +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_oauth_token.sql b/htdocs/install/mysql/tables/llx_oauth_token.sql index bbc236be6c1..145e646230d 100644 --- a/htdocs/install/mysql/tables/llx_oauth_token.sql +++ b/htdocs/install/mysql/tables/llx_oauth_token.sql @@ -24,4 +24,4 @@ CREATE TABLE llx_oauth_token ( fk_user integer, fk_adherent integer, entity integer DEFAULT 1 -)ENGINE=InnoDB; +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_opensurvey_comments.sql b/htdocs/install/mysql/tables/llx_opensurvey_comments.sql index 74a9d9ec3cb..3fcc5a0abf9 100644 --- a/htdocs/install/mysql/tables/llx_opensurvey_comments.sql +++ b/htdocs/install/mysql/tables/llx_opensurvey_comments.sql @@ -21,5 +21,5 @@ CREATE TABLE llx_opensurvey_comments ( comment text NOT NULL, tms timestamp, usercomment text -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_opensurvey_formquestions.sql b/htdocs/install/mysql/tables/llx_opensurvey_formquestions.sql index 044fabc5029..8a15936c86f 100644 --- a/htdocs/install/mysql/tables/llx_opensurvey_formquestions.sql +++ b/htdocs/install/mysql/tables/llx_opensurvey_formquestions.sql @@ -20,5 +20,5 @@ CREATE TABLE llx_opensurvey_formquestions ( id_sondage VARCHAR(16), question TEXT, available_answers TEXT -- List of available answers -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_opensurvey_sondage.sql b/htdocs/install/mysql/tables/llx_opensurvey_sondage.sql index c3f1cdbfee1..0521f533fdd 100644 --- a/htdocs/install/mysql/tables/llx_opensurvey_sondage.sql +++ b/htdocs/install/mysql/tables/llx_opensurvey_sondage.sql @@ -31,4 +31,4 @@ CREATE TABLE llx_opensurvey_sondage ( allow_spy tinyint NOT NULL DEFAULT 1, tms TIMESTAMP, sujet TEXT -- Not filled if format = 'F'. Question are into table llx_opensurvey_formquestions -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_opensurvey_user_formanswers.sql b/htdocs/install/mysql/tables/llx_opensurvey_user_formanswers.sql index bd55d256a06..957818db4a1 100644 --- a/htdocs/install/mysql/tables/llx_opensurvey_user_formanswers.sql +++ b/htdocs/install/mysql/tables/llx_opensurvey_user_formanswers.sql @@ -19,4 +19,4 @@ CREATE TABLE llx_opensurvey_user_formanswers ( fk_user_survey INTEGER NOT NULL, fk_question INTEGER NOT NULL, reponses TEXT -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql b/htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql index 16ef0b2cf7e..a2ddafa1b54 100644 --- a/htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql +++ b/htdocs/install/mysql/tables/llx_opensurvey_user_studs.sql @@ -21,4 +21,4 @@ CREATE TABLE llx_opensurvey_user_studs ( id_sondage VARCHAR(16) NOT NULL, reponses VARCHAR(100) NOT NULL, -- Not used for 'F' surveys tms timestamp -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_batch.sql b/htdocs/install/mysql/tables/llx_product_batch.sql index 7b09d6a0024..9b736278e3a 100644 --- a/htdocs/install/mysql/tables/llx_product_batch.sql +++ b/htdocs/install/mysql/tables/llx_product_batch.sql @@ -27,5 +27,5 @@ CREATE TABLE llx_product_batch ( batch varchar(128) NOT NULL, qty double NOT NULL DEFAULT 0, import_key varchar(14) DEFAULT NULL -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_lot.sql b/htdocs/install/mysql/tables/llx_product_lot.sql index 885f699d800..4d59a46c153 100644 --- a/htdocs/install/mysql/tables/llx_product_lot.sql +++ b/htdocs/install/mysql/tables/llx_product_lot.sql @@ -29,4 +29,4 @@ CREATE TABLE llx_product_lot ( fk_user_creat integer, fk_user_modif integer, import_key integer -) ENGINE=InnoDB; +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_propal_merge_pdf_product.sql b/htdocs/install/mysql/tables/llx_propal_merge_pdf_product.sql index e081b97969f..0c636b2507c 100644 --- a/htdocs/install/mysql/tables/llx_propal_merge_pdf_product.sql +++ b/htdocs/install/mysql/tables/llx_propal_merge_pdf_product.sql @@ -24,5 +24,5 @@ CREATE TABLE llx_propal_merge_pdf_product ( datec datetime NOT NULL, tms timestamp NOT NULL, import_key varchar(14) DEFAULT NULL -) ENGINE=InnoDB; +) ENGINE=innodb; From 364fb05ed378a004d43cc34ba96f114400c79660 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Jul 2020 09:46:31 +0200 Subject: [PATCH 071/434] Fix phpcs --- htdocs/compta/prelevement/class/bonprelevement.class.php | 4 +--- htdocs/fourn/class/fournisseur.commande.class.php | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 8399485b29b..1ac0926792e 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1485,9 +1485,7 @@ class BonPrelevement extends CommonObject $i++; } $nbtotalDrctDbtTxInf = $i; - } - else - { + } else { fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers $result = -2; } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index e7803ea4d0f..c7440c03500 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1246,7 +1246,7 @@ class CommandeFournisseur extends CommonOrder // $date_commande is deprecated $date = ($this->date_commande ? $this->date_commande : $this->date); // in case of date is set - if(empty($date)) $date = $now; + if (empty($date)) $date = $now; // Clean parameters if (empty($this->source)) $this->source = 0; From d46d34915eebd58a0a81768b65c857ffff54f560 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Jul 2020 10:23:09 +0200 Subject: [PATCH 072/434] FIX Checkbox "drop table" was not checked when using php method for dump --- htdocs/admin/tools/dolibarr_export.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 6bbaeb7c6c8..e168f5fbdc0 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -302,7 +302,7 @@ if (in_array($type, array('mysql', 'mysqli'))) { print '
'; print '
'.$langs->trans('ExportStructure').''; - print ''; + print ''; print ''; print '
'; print '
'; From c5816478d93c4d2db3a1aacb6ef0bbb3fadcdedf Mon Sep 17 00:00:00 2001 From: Tim Otte Date: Tue, 28 Jul 2020 11:14:55 +0200 Subject: [PATCH 073/434] Added fetch_thirdparty (without the site crashes) --- htdocs/comm/propal/card.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 72c7826e61b..f275f16ee03 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -230,6 +230,7 @@ if (empty($reshook)) $outputlangs->setDefaultLang($newlang); } $ret = $object->fetch($id); // Reload to get new records + if ($ret > 0) $object->fetch_thirdparty(); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } @@ -767,6 +768,7 @@ if (empty($reshook)) $outputlangs->setDefaultLang($newlang); } $ret = $object->fetch($id); // Reload to get new records + if ($ret > 0) $object->fetch_thirdparty(); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } } elseif ($action == "setabsolutediscount" && $usercancreate) { @@ -1240,6 +1242,7 @@ if (empty($reshook)) $outputlangs->setDefaultLang($newlang); } $ret = $object->fetch($id); // Reload to get new records + if ($ret > 0) $object->fetch_thirdparty(); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } From 9f0c3b0db1a665a3daeb3d099fc357363f382933 Mon Sep 17 00:00:00 2001 From: atm-lena Date: Tue, 28 Jul 2020 15:13:56 +0200 Subject: [PATCH 074/434] fetch() command fourn : Same management as commande.class.php of entity --- htdocs/fourn/class/fournisseur.commande.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index cd35e1d34de..c6c06a8d9b7 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -331,8 +331,11 @@ class CommandeFournisseur extends CommonOrder $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_input_method as cm ON cm.rowid = c.fk_input_method"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON c.fk_incoterms = i.rowid'; $sql .= " WHERE c.entity IN (".getEntity('supplier_order').")"; + + if(empty($id)) $sql .= " WHERE c.entity IN (".getEntity('supplier_order').")"; + else $sql .= " WHERE c.rowid=".$id; + if ($ref) $sql .= " AND c.ref='".$this->db->escape($ref)."'"; - else $sql .= " AND c.rowid=".$id; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql = $this->db->query($sql); From b480fb2dfcf73c3331a66b9cbb0bc33c1cd5e3c9 Mon Sep 17 00:00:00 2001 From: atm-lena Date: Tue, 28 Jul 2020 15:32:58 +0200 Subject: [PATCH 075/434] Delete double line --- htdocs/fourn/class/fournisseur.commande.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index c6c06a8d9b7..fc76a158cab 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -330,7 +330,6 @@ class CommandeFournisseur extends CommonOrder $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON c.fk_mode_reglement = p.id"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_input_method as cm ON cm.rowid = c.fk_input_method"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON c.fk_incoterms = i.rowid'; - $sql .= " WHERE c.entity IN (".getEntity('supplier_order').")"; if(empty($id)) $sql .= " WHERE c.entity IN (".getEntity('supplier_order').")"; else $sql .= " WHERE c.rowid=".$id; From d214dbb5fd4f99216466265254d84e6c1148965a Mon Sep 17 00:00:00 2001 From: VERDOL Gauthier Date: Tue, 28 Jul 2020 15:42:54 +0200 Subject: [PATCH 076/434] FIX : Order by amount in product propal stats must be done on d.total_ht and not p.total --- htdocs/product/stats/propal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stats/propal.php b/htdocs/product/stats/propal.php index 208ff49e158..52f0510cb80 100644 --- a/htdocs/product/stats/propal.php +++ b/htdocs/product/stats/propal.php @@ -208,7 +208,7 @@ if ($id > 0 || ! empty($ref)) print_liste_field_titre("Company", $_SERVER["PHP_SELF"], "s.nom", "", $option, '', $sortfield, $sortorder); print_liste_field_titre("DatePropal", $_SERVER["PHP_SELF"], "p.datep", "", $option, 'align="center"', $sortfield, $sortorder); print_liste_field_titre("Qty", $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "p.total", "", $option, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "d.total_ht", "", $option, 'align="right"', $sortfield, $sortorder); print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "p.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder); print "\n"; From 8ee5b16e895f39b3126a553a61ace03cbe29b14b Mon Sep 17 00:00:00 2001 From: lvessiller Date: Wed, 29 Jul 2020 12:00:22 +0200 Subject: [PATCH 077/434] FIX redirect on contact card from main search --- htdocs/contact/list.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index b0db8b0affb..b8f9d3d14a4 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -389,8 +389,8 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql.= $db->plimit($limit+1, $offset); -$result = $db->query($sql); -if (! $result) +$resql = $db->query($sql); +if (! $resql) { dol_print_error($db); exit; @@ -763,7 +763,7 @@ $i = 0; $totalarray=array(); while ($i < min($num, $limit)) { - $obj = $db->fetch_object($result); + $obj = $db->fetch_object($resql); print ''; @@ -980,7 +980,7 @@ while ($i < min($num, $limit)) $i++; } -$db->free($result); +$db->free($resql); $parameters=array('arrayfields'=>$arrayfields, 'sql'=>$sql); $reshook=$hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook From 41483df6893333edebdd80ccfda593a4061bf3b9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 12:31:03 +0200 Subject: [PATCH 078/434] FIX #14076 --- htdocs/theme/md/dropdown.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/md/dropdown.inc.php b/htdocs/theme/md/dropdown.inc.php index aae84a27c1b..b86b935c5d1 100644 --- a/htdocs/theme/md/dropdown.inc.php +++ b/htdocs/theme/md/dropdown.inc.php @@ -147,7 +147,7 @@ button.dropdown-item.global-search-item { * MENU Dropdown */ .login_block.usedropdown .logout-btn{ - display: none; + /* display: none; */ } .tmenu .open.dropdown, .tmenu .open.dropdown { From 44cfb776227c21c8d1b2ba25890a1dd50d2c94c0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 12:43:53 +0200 Subject: [PATCH 079/434] FIX #14292 --- htdocs/install/pgsql/functions/functions.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/install/pgsql/functions/functions.sql b/htdocs/install/pgsql/functions/functions.sql index 40628f93ac6..22c122a1164 100644 --- a/htdocs/install/pgsql/functions/functions.sql +++ b/htdocs/install/pgsql/functions/functions.sql @@ -58,6 +58,7 @@ CREATE OR REPLACE FUNCTION dol_util_triggerall(DoEnable boolean) RETURNS integer -- Add triggers for timestamp fields named tms CREATE OR REPLACE FUNCTION update_modified_column_tms() RETURNS TRIGGER AS $$ BEGIN NEW.tms = now(); RETURN NEW; END; $$ LANGUAGE plpgsql; + CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_accounting_account FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_accounting_fiscalyear FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_actioncomm FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); @@ -127,6 +128,9 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_localtax FOR EACH RO CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mailing FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mailing_cibles FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_menu FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify_def FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_opensurvey_comments FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); From 391fcc799bf8f03487c7da946c2b9f1dc50b2352 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 12:51:18 +0200 Subject: [PATCH 080/434] FIX #14279 --- htdocs/api/index.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 112eb58059f..b5b34658551 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -254,15 +254,17 @@ if (!empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/swagger.json' && if ($tmpmodule != 'api') $tmpmodule = preg_replace('/api$/i', '', $tmpmodule); $classfile = str_replace('_', '', $tmpmodule); - if ($module == 'supplierproposals') + + // Special cases that does not match name rules conventions + if ($moduleobject == 'supplierproposals') $classfile = 'supplier_proposals'; - if ($module == 'supplierorders') + if ($moduleobject == 'supplierorders') $classfile = 'supplier_orders'; - if ($module == 'supplierinvoices') + if ($moduleobject == 'supplierinvoices') $classfile = 'supplier_invoices'; - if ($module == 'ficheinter') + if ($moduleobject == 'ficheinter') $classfile = 'interventions'; - if ($module == 'interventions') + if ($moduleobject == 'interventions') $classfile = 'interventions'; $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_'.$classfile.'.class.php', 0, 2); From 85c5f423b119ee58a99e01480266461a8c4c0b63 Mon Sep 17 00:00:00 2001 From: Tim Otte Date: Tue, 28 Jul 2020 11:14:55 +0200 Subject: [PATCH 081/434] Added fetch_thirdparty (without the site crashes) --- htdocs/comm/propal/card.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index e07f69ea5dc..eddf967c7d1 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -236,6 +236,7 @@ if (empty($reshook)) $outputlangs->setDefaultLang($newlang); } $ret = $object->fetch($id); // Reload to get new records + if ($ret > 0) $object->fetch_thirdparty(); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } @@ -803,6 +804,7 @@ if (empty($reshook)) $outputlangs->setDefaultLang($newlang); } $ret = $object->fetch($id); // Reload to get new records + if ($ret > 0) $object->fetch_thirdparty(); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } } @@ -1284,6 +1286,7 @@ if (empty($reshook)) $outputlangs->setDefaultLang($newlang); } $ret = $object->fetch($id); // Reload to get new records + if ($ret > 0) $object->fetch_thirdparty(); $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } From d9191c74d8f3212d20125e47c4faed056d6e4214 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 12:59:59 +0200 Subject: [PATCH 082/434] Update fournisseur.commande.class.php --- htdocs/fourn/class/fournisseur.commande.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index fc76a158cab..dd34555dd79 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -331,7 +331,7 @@ class CommandeFournisseur extends CommonOrder $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_input_method as cm ON cm.rowid = c.fk_input_method"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON c.fk_incoterms = i.rowid'; - if(empty($id)) $sql .= " WHERE c.entity IN (".getEntity('supplier_order').")"; + if (empty($id)) $sql .= " WHERE c.entity IN (".getEntity('supplier_order').")"; else $sql .= " WHERE c.rowid=".$id; if ($ref) $sql .= " AND c.ref='".$this->db->escape($ref)."'"; From 3c6eb5e0e2b669fe5121dc40e0e4290a37f28c5e Mon Sep 17 00:00:00 2001 From: AXeL Date: Sat, 25 Jul 2020 14:07:44 +0100 Subject: [PATCH 083/434] Add missing "Default values" menu entry to auguria menu --- htdocs/core/menus/init_menu_auguria.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 03f8951b0f8..ec75b35073c 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -29,6 +29,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 101__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/company.php?mainmenu=home&leftmenu=setup', 'MenuCompanySetup', 1, 'admin', '', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 102__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/ihm.php?mainmenu=home&leftmenu=setup', 'GUISetup', 1, 'admin', '', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 114__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/translation.php?mainmenu=home&leftmenu=setup', 'Translation', 1, 'admin', '', '', 2, 4, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 115__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/defaultvalues.php?mainmenu=home&leftmenu=setup', 'DefaultValues', 1, 'admin', '', '', 2, 4, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 103__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/modules.php?mainmenu=home&leftmenu=setup', 'Modules', 1, 'admin', '', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 104__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/boxes.php?mainmenu=home&leftmenu=setup', 'Boxes', 1, 'admin', '', '', 2, 6, __ENTITY__); From af177f2833202b096c2034221c521729f32c53cc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 13:07:02 +0200 Subject: [PATCH 084/434] Update reassort.php --- htdocs/product/reassort.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index c0591e79062..90c616fcd6b 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -311,8 +311,8 @@ if ($resql) print ' '; print ' '; print ''; - $parameters=array(); - $reshook=$hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print ''; $searchpicto = $form->showFilterAndCheckAddButtons(0); @@ -346,8 +346,8 @@ if ($resql) print_liste_field_titre("ProductStatusOnSell", $_SERVER["PHP_SELF"], "p.tosell", $param, "", '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ProductStatusOnBuy", $_SERVER["PHP_SELF"], "p.tobuy", $param, "", '', $sortfield, $sortorder, 'right '); // Hook fields - $parameters=array('param'=>$param,'sortfield'=>$sortfield,'sortorder'=>$sortorder); - $reshook=$hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('param'=>$param,'sortfield'=>$sortfield,'sortorder'=>$sortorder); + $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print_liste_field_titre(''); print "\n"; @@ -413,8 +413,8 @@ if ($resql) print ''.$product->LibStatut($objp->statut, 5, 0).''; print ''.$product->LibStatut($objp->tobuy, 5, 1).''; // Fields from hook - $parameters=array('obj'=>$objp); - $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('obj'=>$objp); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print ''; print "\n"; From 6bd450dcd022b33ad5cf2a75cad42ab50ea8d4d5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 13:10:31 +0200 Subject: [PATCH 085/434] Doc --- dev/dolibarr_changes.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 48c6bf342a9..169fa27b5bd 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -8,6 +8,7 @@ ALL: Check "@CHANGE" + PrestaShopWebservice: --------------------- Replace @@ -27,6 +28,19 @@ With +DEBUGBAR: +--------- + +Move + this.options = { + bodyMarginBottom: true, + bodyMarginBottomHeight: parseInt($('body').css('margin-bottom')), + }; +few line lower in the + initialize: function() { + + + ESCPOS: ------- Replace From 1d686a0d4c18ba7c621feaac0a3f1f1f9f106f83 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 13:18:49 +0200 Subject: [PATCH 086/434] Update product.class.php --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index d617d98b500..07450eef805 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2033,7 +2033,7 @@ class Product extends CommonObject $sql .= " accountancy_code_buy, accountancy_code_buy_intra, accountancy_code_buy_export,"; $sql .= " accountancy_code_sell, accountancy_code_sell_intra, accountancy_code_sell_export, stock, pmp,"; $sql .= " datec, tms, import_key, entity, desiredstock, tobatch, fk_unit,"; - $sql .= " fk_price_expression, price_autogen,model_pdf"; + $sql .= " fk_price_expression, price_autogen, model_pdf"; $sql .= " FROM ".MAIN_DB_PREFIX."product"; if ($id) { $sql .= " WHERE rowid = ".(int) $id; From eaef99b7af5b8a86bb81e17c8387b2069a8aac6e Mon Sep 17 00:00:00 2001 From: Romain DESCHAMPS Date: Fri, 24 Jul 2020 14:11:42 +0200 Subject: [PATCH 087/434] second approval back in stable feature as is the setting for minimum amount --- htdocs/fourn/commande/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 71ed66ffc09..ff79524f874 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -2390,7 +2390,7 @@ elseif (!empty($object->id)) { if ($user->rights->fournisseur->commande->approuver) { - if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $conf->global->MAIN_FEATURES_LEVEL > 0 && $object->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED && !empty($object->user_approve_id)) + if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $object->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED && !empty($object->user_approve_id)) { print ''.$langs->trans("ApproveOrder").''; } @@ -2406,7 +2406,7 @@ elseif (!empty($object->id)) } // Second approval (if option SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set) - if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $conf->global->MAIN_FEATURES_LEVEL > 0 && $object->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) + if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $object->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) { if ($object->statut == CommandeFournisseur::STATUS_VALIDATED) { From 4a291f181fadca23d9843e1043ec15112d5dbf38 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 13:47:04 +0200 Subject: [PATCH 088/434] Fix regression --- htdocs/contact/list.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index bb8f9497969..dbdc9388404 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -365,8 +365,8 @@ else $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + $resql = $db->query($sql); + $nbtotalofrecords = $db->num_rows($resql); if (($page * $limit) > $nbtotalofrecords) // if total resultset is smaller then paging size (filtering), goto and load page 0 { $page = 0; @@ -376,18 +376,18 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql.= $db->plimit($limit+1, $offset); -$result = $db->query($sql); -if (! $result) +$resql = $db->query($sql); +if (! $resql) { dol_print_error($db); exit; } -$num = $db->num_rows($result); +$num = $db->num_rows($resql); $arrayofselected=is_array($toselect)?$toselect:array(); -if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && ($sall != '' || $seearch_cti != '')) +if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && ($sall != '' || $search_cti != '')) { $obj = $db->fetch_object($resql); $id = $obj->rowid; @@ -715,7 +715,7 @@ $i = 0; $totalarray=array(); while ($i < min($num,$limit)) { - $obj = $db->fetch_object($result); + $obj = $db->fetch_object($resql); print ''; @@ -914,7 +914,7 @@ while ($i < min($num,$limit)) $i++; } -$db->free($result); +$db->free($resql); $parameters=array('arrayfields'=>$arrayfields, 'sql'=>$sql); $reshook=$hookmanager->executeHooks('printFieldListFooter',$parameters); // Note that $action and $object may have been modified by hook From 3d79950c27369c1f049863f6eae8233f0b3a4bbf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Jul 2020 14:13:29 +0200 Subject: [PATCH 089/434] Update commonobject.class.php --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9d71fa663cd..4786b5817fe 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7549,11 +7549,11 @@ abstract class CommonObject if (array_key_exists('ref', $fieldvalues)) $fieldvalues['ref'] = dol_string_nospecial($fieldvalues['ref']); // If field is a ref, we sanitize data $keys = array(); - $values = array(); + $values = array(); // Array to store string forged for SQL syntax foreach ($fieldvalues as $k => $v) { $keys[$k] = $k; $value = $this->fields[$k]; - $values[$k] = $this->quote($v, $value); + $values[$k] = $this->quote($v, $value); // May return string 'NULL' if $value is null } // Clean and check mandatory From 54410189bc912edad202ad97dd8dbb835657cd22 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Wed, 29 Jul 2020 17:00:39 +0200 Subject: [PATCH 090/434] Fix hidden option STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO When product ajax search used a dash is show, so virtual stock looks like being negative value. --- htdocs/core/class/html.form.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 9c4e2526249..14db0028606 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2743,9 +2743,9 @@ class Form $outval .= ' - '.$langs->transnoentities("VirtualStock").':'; if ($virtualstock > 0) { - $outval .= ' - '; + $outval .= ''; }elseif ($virtualstock <= 0) { - $outval .= ' - '; + $outval .= ''; } $outval .= $virtualstock; $outval .= ''; From c79d617a50a6bb3573078211e6b05ada9d463c16 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 03:50:27 +0200 Subject: [PATCH 091/434] Add public page of job position offers --- htdocs/langs/en_US/main.lang | 4 +- htdocs/langs/en_US/recruitment.lang | 14 +- htdocs/public/onlinesign/newonlinesign.php | 6 +- htdocs/public/recruitment/view.php | 329 +++++++++--------- htdocs/recruitment/admin/public_interface.php | 194 +++++++++++ htdocs/recruitment/admin/setup.php | 6 +- htdocs/recruitment/lib/recruitment.lib.php | 8 +- ...recruitment_recruitmentjobposition.lib.php | 37 ++ .../recruitmentjobposition_card.php | 16 + 9 files changed, 426 insertions(+), 188 deletions(-) create mode 100644 htdocs/recruitment/admin/public_interface.php diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 2f673ea445b..d52478dbbdb 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -1041,4 +1041,6 @@ SwitchInEditModeToAddTranslation=Switch in edit mode to add translations for thi NotUsedForThisCustomer=Not used for this customer AmountMustBePositive=Amount must be positive ByStatus=By status -InformationMessage=Information \ No newline at end of file +InformationMessage=Information +ASAP=As Soon As Possible + \ No newline at end of file diff --git a/htdocs/langs/en_US/recruitment.lang b/htdocs/langs/en_US/recruitment.lang index de5f96fe082..4e20a42fbb5 100644 --- a/htdocs/langs/en_US/recruitment.lang +++ b/htdocs/langs/en_US/recruitment.lang @@ -27,8 +27,10 @@ ModuleRecruitmentDesc = Manage and follow recruitment campaigns for new job posi # RecruitmentSetup = Recruitment setup Settings = Settings -RecruitmentSetupPage = Recruitment setup page +RecruitmentSetupPage = Enter here the setup of main options for the recruitment module RecruitmentArea=Recruitement area +PublicInterfaceRecruitmentDesc=Public interface is public URLs to show and answer to open jobs. There is one different link for each open job. +EnablePublicRecruitmentPages=Enable public recruitment pages # # About page @@ -43,8 +45,10 @@ DateExpected=Expected date FutureManager=Future manager ResponsibleOfRecruitement=Responsible of recruitment IfJobIsLocatedAtAPartner=If job is located at a partner place -PositionToBeFilled=Position to be filled -PositionsToBeFilled=Positions to be filled -ListOfPositionsToBeFilled=List of positions to be filled -NewPositionToBeFilled=New position to be filled +PositionToBeFilled=Job offer to be filled +PositionsToBeFilled=Job offers to be filled +ListOfPositionsToBeFilled=List of job offers to be filled +NewPositionToBeFilled=New job offers to be filled +JobOfferToBeFilled=Job offer to be filled +ThisIsInformationOnJobPosition=Information of the job position to be filled \ No newline at end of file diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php index 2031c11a3ad..d29d441c611 100644 --- a/htdocs/public/onlinesign/newonlinesign.php +++ b/htdocs/public/onlinesign/newonlinesign.php @@ -45,6 +45,7 @@ $langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", // Security check // No check on module enabled. Done later according to $validpaymentmethod +// Get parameters $action = GETPOST('action', 'aZ09'); // Input are: @@ -70,9 +71,6 @@ if (!$action) } - - - // Define $urlwithroot //$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); //$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file @@ -132,7 +130,7 @@ $conf->dol_hide_leftmenu = 1; $replacemainarea = (empty($conf->dol_hide_leftmenu) ? '
' : '').'
'; llxHeader($head, $langs->trans("OnlineSignature"), '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea); -// Check link validity +// Check link validity for param 'source' if (!empty($source) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) { $langs->load("errors"); diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index b4d13747d3f..253409c8b53 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -1,6 +1,5 @@ - * Copyright (C) 2018 Frédéric France +/* Copyright (C) 2020 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,18 +21,9 @@ * \brief Public file to show on job */ -if (!defined('NOCSRFCHECK')) { - define('NOCSRFCHECK', '1'); -} -// Do not check anti CSRF attack test -if (!defined('NOREQUIREMENU')) { - define('NOREQUIREMENU', '1'); -} -// If there is no need to load and show top and left menu -if (!defined("NOLOGIN")) { - define("NOLOGIN", '1'); -} -// If this page is public (can be called outside logged session) +if (!defined('NOLOGIN')) define("NOLOGIN", 1); // This means this output page does not require to be logged. +if (!defined('NOCSRFCHECK')) define("NOCSRFCHECK", 1); // We accept to go on this page from external web site. +if (!defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; @@ -45,9 +35,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; $langs->loadLangs(array("companies", "other", "recruitment")); // Get parameters -$cancel = GETPOST('cancel', 'alpha'); $action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'alpha'); $email = GETPOST('email', 'alpha'); +$backtopage = ''; $ref = GETPOST('ref', 'alpha'); @@ -60,6 +51,22 @@ if (isset($_SESSION['email_customer'])) { $object = new RecruitmentJobPosition($db); +if (!$action) +{ + if (!$ref) + { + print $langs->trans('ErrorBadParameters')." - ref missing"; + exit; + } else { + $object->fetch('', $ref); + } +} + +// Define $urlwithroot +//$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); +//$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +$urlwithroot = DOL_MAIN_URL_ROOT; // This is to use same domain name than current. For Paypal payment, we can use internal URL like localhost. + /* * Actions @@ -141,7 +148,11 @@ include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; * View */ -$form = new Form($db); +$head = ''; +if (!empty($conf->global->MAIN_RECRUITMENT_CSS_URL)) $head = ''."\n"; + +$conf->dol_hide_topmenu = 1; +$conf->dol_hide_leftmenu = 1; if (!$conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE) { print '
'.$langs->trans('PublicInterfaceForbidden').'
'; @@ -150,170 +161,148 @@ if (!$conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE) { } $arrayofjs = array(); -$arrayofcss = array('/ticket/css/styles.css.php'); +$arrayofcss = array(); -llxHeaderRecruitment($langs->trans("Jobs"), "", 0, 0, $arrayofjs, $arrayofcss); +$replacemainarea = (empty($conf->dol_hide_leftmenu) ? '
' : '').'
'; +llxHeader($head, $langs->trans("PositionToBeFilled"), '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea); -print '
'; -if ($action == "view" || $action == "presend" || $action == "close" || $action == "confirm_public_close") { - if ($display_ticket) - { - // Confirmation close - if ($action == 'close') { - print $form->formconfirm($_SERVER["PHP_SELF"]."?track_id=".$track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1); - } +print ''."\n"; +print '
'."\n"; +print '
'."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''; +print "\n"; +print ''."\n"; - print '
'; +print ''."\n"; - print '
'; - - // Ref - print ''; - - // Tracking ID - print ''; - - // Subject - print ''; - - // Statut - print ''; - - // Type - print ''; - - // Category - print ''; - - // Severity - print ''; - - // Creation date - print ''; - - // Author - print ''; - - // Read date - if (!empty($object->dao->date_read)) { - print ''; - } - - // Close date - if (!empty($object->dao->date_close)) { - print ''; - } - - // User assigned - print ''; - - // Progression - print ''; - - print '
'.$langs->trans("Ref").''; - print $object->dao->ref; - print '
'.$langs->trans("TicketTrackId").''; - print $object->dao->track_id; - print '
'.$langs->trans("Subject").''; - print $object->dao->subject; - print '
'.$langs->trans("Status").''; - print $object->dao->getLibStatut(2); - print '
'.$langs->trans("Type").''; - print $object->dao->type_label; - print '
'.$langs->trans("Category").''; - print $object->dao->category_label; - print '
'.$langs->trans("Severity").''; - print $object->dao->severity_label; - print '
'.$langs->trans("DateCreation").''; - print dol_print_date($object->dao->datec, 'dayhour'); - print '
'.$langs->trans("Author").''; - if ($object->dao->fk_user_create > 0) { - $langs->load("users"); - $fuser = new User($db); - $fuser->fetch($object->dao->fk_user_create); - print $fuser->getFullName($langs); - } else { - print dol_escape_htmltag($object->dao->origin_email); - } - - print '
'.$langs->trans("TicketReadOn").''; - print dol_print_date($object->dao->date_read, 'dayhour'); - print '
'.$langs->trans("TicketCloseOn").''; - print dol_print_date($object->dao->date_close, 'dayhour'); - print '
'.$langs->trans("AssignedTo").''; - if ($object->dao->fk_user_assign > 0) { - $fuser = new User($db); - $fuser->fetch($object->dao->fk_user_assign); - print $fuser->getFullName($langs, 1); - } - print '
'.$langs->trans("Progression").''; - print ($object->dao->progress > 0 ? $object->dao->progress : '0').'%'; - print '
'; - - print '
'; - - print '
'; - - if ($action == 'presend') { - print load_fiche_titre($langs->trans('AddMessage'), '', 'messages@ticket'); - - /*$formticket = new FormTicket($db); - - $formticket->action = "add_message"; - $formticket->track_id = $object->dao->track_id; - $formticket->id = $object->dao->id; - - $formticket->param = array('track_id' => $object->dao->track_id, 'fk_user_create' => '-1', 'returnurl' => DOL_URL_ROOT.'/public/ticket/view.php'); - - $formticket->withfile = 2; - $formticket->withcancel = 1; - - $formticket->showMessageForm('100%'); - */ - print 'TODO Show message form'; - } - - if ($action != 'presend') { - print ''; - print ''; - print ''; - print ''; - print ''; - //print ''; - print "
\n"; - - print '
'; - - // List ticket - print ''; - - if ($object->dao->fk_statut < Ticket::STATUS_CLOSED) { - // New message - print ''; - - // Close ticket - if ($object->dao->fk_statut >= Ticket::STATUS_NOT_READ && $object->dao->fk_statut < Ticket::STATUS_CLOSED) { - print ''; - } - } - - print '
'; - } - - // Message list - print load_fiche_titre($langs->trans('JobMessagesList'), '', 'object_conversation'); - //$object->viewTicketMessages(false, true, $object->dao); - } else { - print ''; +// Show logo (search order: logo defined by ONLINE_SIGN_LOGO_suffix, then ONLINE_SIGN_LOGO_, then small company logo, large company logo, theme logo, common logo) +$width = 0; +// Define logo and logosmall +$logosmall = $mysoc->logo_small; +$logo = $mysoc->logo; +$paramlogo = 'ONLINE_RECRUITMENT_LOGO_'.$suffix; +if (!empty($conf->global->$paramlogo)) $logosmall = $conf->global->$paramlogo; +elseif (!empty($conf->global->ONLINE_RECRUITMENT_LOGO)) $logosmall = $conf->global->ONLINE_RECRUITMENT_LOGO_; +//print ''."\n"; +// Define urllogo +$urllogo = ''; +$urllogofull = ''; +if (!empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall)) +{ + $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall); + $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall); + $width = 150; +} elseif (!empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo)) +{ + $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo); + $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo); + $width = 150; +} +// Output html code for logo +if ($urllogo) +{ + print '
'; + print '
'; + print ''; + print '
'; + if (empty($conf->global->MAIN_HIDE_POWERED_BY)) { + print ''; } + print '
'; } -print "
"; +// Output introduction text +$text = ''; +if (!empty($conf->global->RECRUITMENT_NEWFORM_TEXT)) +{ + $langs->load("recruitment"); + if (preg_match('/^\((.*)\)$/', $conf->global->RECRUITMENT_NEWFORM_TEXT, $reg)) $text .= $langs->trans($reg[1])."
\n"; + else $text .= $conf->global->RECRUITMENT_NEWFORM_TEXT."
\n"; + $text = '
'.$text.'
'."\n"; +} +if (empty($text)) +{ + $text .= '
'.$langs->trans("JobOfferToBeFilled", $mysoc->name).''; + $text .= '   -   '.dol_print_date($object->date_creation); + $text .= ''."\n"; + $text .= '

'.$object->label.'


'."\n"; +} +print $text; -// End of page -htmlPrintOnlinePaymentFooter($mysoc, $langs, 0, $suffix, $object); +// Output payment summary form +print ''; +print ''; +print ''."\n"; + +$error = 0; +$var = false; + +// Label + +print ''."\n"; + +// Date + +print ''."\n"; + + + + +if (!$found && !$mesg) $mesg = $langs->trans("ErrorBadParameters"); + +if ($mesg) print ''."\n"; + +print '
'.$langs->trans("ThisIsInformationOnJobPosition").' :
'.$langs->trans("JobLabel"); +print ''; +print ''.$object->label.''; +print '
'.$langs->trans("DateExpected"); +print ''; +if ($object->date_planned > $now) { + print dol_print_date('day', $object->date_planned); +} else { + print $langs->trans("ASAP"); +} +print ''; + +// Description + +$text = $object->description; +print '
'.$langs->trans("Description"); +print ''.$text; +print ''; +print '

'.$mesg.'
'."\n"; +print "\n"; + +if ($action != 'dosign') +{ + if ($found && !$error) // We are in a management option and no error + { + } else { + dol_print_error_email('ERRORNEWONLINESIGN'); + } +} else { + // Print +} + +print ''."\n"; + +print ''."\n"; +print ''."\n"; +print '
'."\n"; +print '
'; + + +htmlPrintOnlinePaymentFooter($mysoc, $langs); llxFooter('', 'public'); $db->close(); + diff --git a/htdocs/recruitment/admin/public_interface.php b/htdocs/recruitment/admin/public_interface.php new file mode 100644 index 00000000000..f8985507081 --- /dev/null +++ b/htdocs/recruitment/admin/public_interface.php @@ -0,0 +1,194 @@ + + * Copyright (C) 2006-2020 Laurent Destailleur + * Copyright (C) 2006-2012 Regis Houssin + * Copyright (C) 2011 Juanjo Menent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/recruitment/admin/public_interface.php + * \ingroup recruitment + * \brief File of main public page for open job position + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/recruitment/lib/recruitment.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("admin", "recruitment")); + +$action = GETPOST('action', 'alpha'); + +if (!$user->admin) accessforbidden(); + +$error = 0; + + +/* + * Actions + */ + +if ($action == 'setRECRUITMENT_ENABLE_PUBLIC_INTERFACE') { + if (GETPOST('value')) dolibarr_set_const($db, 'RECRUITMENT_ENABLE_PUBLIC_INTERFACE', 1, 'chaine', 0, '', $conf->entity); + else dolibarr_set_const($db, 'RECRUITMENT_ENABLE_PUBLIC_INTERFACE', 0, 'chaine', 0, '', $conf->entity); +} + +if ($action == 'update') { + $public = GETPOST('RECRUITMENT_ENABLE_PUBLIC_INTERFACE'); + + $res = dolibarr_set_const($db, "RECRUITMENT_ENABLE_PUBLIC_INTERFACE", $public, 'chaine', 0, '', $conf->entity); + + if (!$res > 0) $error++; + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} + + +/* + * View + */ + +$form = new Form($db); + +//$help_url = 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros'; +$help_url = ''; +llxHeader('', $langs->trans("RecruitmentSetup"), $help_url); + + +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("RecruitmentSetup"), $linkback, 'title_setup'); + +$head = recruitmentAdminPrepareHead(); + + + +print '
'; +print ''; +print ''; + +dol_fiche_head($head, 'publicurl', '', -1, ''); + + +print ''.$langs->trans("PublicInterfaceRecruitmentDesc").'

'; + + +$enabledisablehtml = $langs->trans("EnablePublicRecruitmentPages").' '; +if (empty($conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE)) { + // Button off, click to enable + $enabledisablehtml .= ''; + $enabledisablehtml .= img_picto($langs->trans("Disabled"), 'switch_off'); + $enabledisablehtml .= ''; +} else { + // Button on, click to disable + $enabledisablehtml .= ''; + $enabledisablehtml .= img_picto($langs->trans("Activated"), 'switch_on'); + $enabledisablehtml .= ''; +} +print $enabledisablehtml; +print ''; + + +print '
'; + +/* +if (!empty($conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE)) { + print '
'; + + print ''; + + print ''; + print ''; + print ''; + print "\n"; + + // Force Type + $adht = new AdherentType($db); + print '\n"; + + // Amount + print '\n"; + + // Can edit + print '\n"; + + // Jump to an online payment page + print '\n"; + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print $langs->trans("ForceMemberType"); + print ''; + $listofval = array(); + $listofval += $adht->liste_array(); + $forcetype = $conf->global->MEMBER_NEWFORM_FORCETYPE ?: -1; + print $form->selectarray("MEMBER_NEWFORM_FORCETYPE", $listofval, $forcetype, count($listofval) > 1 ? 1 : 0); + print "
'; + print $langs->trans("DefaultAmount"); + print ''; + print ''; + print "
'; + print $langs->trans("CanEditAmount"); + print ''; + print $form->selectyesno("MEMBER_NEWFORM_EDITAMOUNT", (!empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT) ? $conf->global->MEMBER_NEWFORM_EDITAMOUNT : 0), 1); + print "
'; + print $langs->trans("MEMBER_NEWFORM_PAYONLINE"); + print ''; + $listofval = array(); + $listofval['-1'] = $langs->trans('No'); + $listofval['all'] = $langs->trans('Yes').' ('.$langs->trans("VisitorCanChooseItsPaymentMode").')'; + if (!empty($conf->paybox->enabled)) $listofval['paybox'] = 'Paybox'; + if (!empty($conf->paypal->enabled)) $listofval['paypal'] = 'PayPal'; + if (!empty($conf->stripe->enabled)) $listofval['stripe'] = 'Stripe'; + print $form->selectarray("MEMBER_NEWFORM_PAYONLINE", $listofval, (!empty($conf->global->MEMBER_NEWFORM_PAYONLINE) ? $conf->global->MEMBER_NEWFORM_PAYONLINE : ''), 0); + print "
'; + + print '
'; + print ''; + print '
'; +} +*/ + +dol_fiche_end(); + +print '
'; + +/* +if (!empty($conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE)) { + print '
'; + //print $langs->trans('FollowingLinksArePublic').'
'; + print img_picto('', 'globe').' '.$langs->trans('BlankSubscriptionForm').':
'; + if ($conf->multicompany->enabled) { + $entity_qr = '?entity='.$conf->entity; + } else { + $entity_qr = ''; + } + + // Define $urlwithroot + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + print ''.$urlwithroot.'/public/members/new.php'.$entity_qr.''; +} +*/ + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/recruitment/admin/setup.php b/htdocs/recruitment/admin/setup.php index 7de9764c1aa..562531262f9 100644 --- a/htdocs/recruitment/admin/setup.php +++ b/htdocs/recruitment/admin/setup.php @@ -40,7 +40,7 @@ global $langs, $user; // Libraries require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; -require_once '../lib/recruitment.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/recruitment/lib/recruitment.lib.php'; require_once DOL_DOCUMENT_ROOT."/recruitment/class/recruitmentjobposition.class.php"; // Translations @@ -194,10 +194,10 @@ print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); // Configuration header $head = recruitmentAdminPrepareHead(); -dol_fiche_head($head, 'settings', '', -1, "object_recruitment"); +dol_fiche_head($head, 'settings', '', -1, ''); // Setup page goes here -echo ''.$langs->trans("RecruitmentSetupPage").'

'; +//echo ''.$langs->trans("RecruitmentSetupPage").'

'; if ($action == 'edit') diff --git a/htdocs/recruitment/lib/recruitment.lib.php b/htdocs/recruitment/lib/recruitment.lib.php index ad03a4b30d1..44f356e8061 100644 --- a/htdocs/recruitment/lib/recruitment.lib.php +++ b/htdocs/recruitment/lib/recruitment.lib.php @@ -40,12 +40,10 @@ function recruitmentAdminPrepareHead() $head[$h][2] = 'settings'; $h++; - /* - $head[$h][0] = dol_buildpath("/recruitment/admin/about.php", 1); - $head[$h][1] = $langs->trans("About"); - $head[$h][2] = 'about'; + $head[$h][0] = dol_buildpath("/recruitment/admin/public_interface.php", 1); + $head[$h][1] = $langs->trans("PublicUrl"); + $head[$h][2] = 'publicurl'; $h++; - */ // Show more tabs from modules // Entries must be declared in modules descriptor with line diff --git a/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php b/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php index 052f4274526..f34bf5cbf59 100644 --- a/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php +++ b/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php @@ -88,3 +88,40 @@ function recruitmentjobpositionPrepareHead($object) return $head; } + + +/** + * Return string with full Url + * + * @param int $mode 0=True url, 1=Url formated with colors + * @param string $ref Ref of object + * @param string $localorexternal 0=Url for browser, 1=Url for external access + * @return string Url string + */ +function getPublicJobPositionUrl($mode, $ref = '', $localorexternal = 0) +{ + global $conf, $dolibarr_main_url_root; + + $ref = str_replace(' ', '', $ref); + $out = ''; + + // Define $urlwithroot + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + $urltouse = DOL_MAIN_URL_ROOT; + if ($localorexternal) $urltouse = $urlwithroot; + + $out = $urltouse.'/public/recruitment/view.php?ref='.($mode ? '' : '').$ref.($mode ? '' : ''); + /*if (!empty($conf->global->RECRUITMENT_SECURITY_TOKEN)) + { + if (empty($conf->global->RECRUITMENT_SECURITY_TOKEN)) $out .= '&securekey='.$conf->global->RECRUITMENT_SECURITY_TOKEN; + else $out .= '&securekey='.dol_hash($conf->global->RECRUITMENT_SECURITY_TOKEN, 2); + }*/ + + // For multicompany + if (!empty($out) && !empty($conf->multicompany->enabled)) $out .= "&entity=".$conf->entity; // Check the entity because we may have the same reference in several entities + + return $out; +} diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index 349624729e0..4c01e74a338 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -572,6 +572,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $linktoelem = $form->showLinkToObjectBlock($object, null, array('recruitmentjobposition')); $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + // Show link to public job page + if ($object->status != RecruitmentJobPosition::STATUS_DRAFT) + { + print '
'."\n"; + // Load translation files required by the page + $langs->loadLangs(array('recruitment')); + + $out = img_picto('', 'globe').' '.$langs->trans("PublicUrl").'
'; + + $url = getPublicJobPositionUrl(0, $object->ref); + $out .= ''; + $out .= ''.img_picto('', 'globe').''; + $out .= ajax_autoselect("recruitmentjobpositionurl", 0); + + print $out; + } print '
'; From f937f5beea411620306be54ed480ff594b96bbff Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 04:06:27 +0200 Subject: [PATCH 092/434] Work on recruitment module --- htdocs/public/recruitment/view.php | 2 +- ...recruitment_recruitmentjobposition.lib.php | 2 +- .../recruitmentjobposition_agenda.php | 21 +- .../recruitmentjobposition_candidature.php | 606 ++++++++++++++++++ .../recruitmentjobposition_card.php | 16 - .../recruitmentjobposition_document.php | 63 +- .../recruitmentjobposition_note.php | 63 +- 7 files changed, 683 insertions(+), 90 deletions(-) create mode 100644 htdocs/recruitment/recruitmentjobposition_candidature.php diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index 253409c8b53..c55de12ca2d 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -247,7 +247,7 @@ $var = false; // Label -print ''.$langs->trans("JobLabel"); +print ''.$langs->trans("Label"); print ''; print ''.$object->label.''; print ''."\n"; diff --git a/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php b/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php index f34bf5cbf59..a5739a53153 100644 --- a/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php +++ b/htdocs/recruitment/lib/recruitment_recruitmentjobposition.lib.php @@ -43,7 +43,7 @@ function recruitmentjobpositionPrepareHead($object) $head[$h][0] = dol_buildpath("/recruitment/recruitmentjobposition_candidature.php", 1).'?id='.$object->id; $head[$h][1] = $langs->trans("Candidatures"); - $head[$h][2] = 'candidature'; + $head[$h][2] = 'candidatures'; $h++; if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) diff --git a/htdocs/recruitment/recruitmentjobposition_agenda.php b/htdocs/recruitment/recruitmentjobposition_agenda.php index d841636c437..d54cec57e9a 100644 --- a/htdocs/recruitment/recruitmentjobposition_agenda.php +++ b/htdocs/recruitment/recruitmentjobposition_agenda.php @@ -150,26 +150,27 @@ if ($object->id > 0) $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); // Thirdparty $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + */ // Project if (! empty($conf->projet->enabled)) { $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; + $morehtmlref .= $langs->trans('Project') . ' '; if ($permissiontoadd) { if ($action != 'classify') //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref.=' : '; + $morehtmlref .=' : '; if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
'; + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
'; } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); } } else { if (! empty($object->fk_project)) { @@ -180,7 +181,7 @@ if ($object->id > 0) $morehtmlref .= ''; } } - }*/ + } $morehtmlref .= '
'; diff --git a/htdocs/recruitment/recruitmentjobposition_candidature.php b/htdocs/recruitment/recruitmentjobposition_candidature.php new file mode 100644 index 00000000000..bf2c766771f --- /dev/null +++ b/htdocs/recruitment/recruitmentjobposition_candidature.php @@ -0,0 +1,606 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file recruitmentjobposition_candidature.php + * \ingroup recruitment + * \brief Page to see/add candidatures + */ + +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Do not create database handler $db +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Do not load object $user +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); // Do not load object $mysoc +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Do not load object $langs +//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check injection attack on GET parameters +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check injection attack on POST parameters +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library +//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. +//if (! defined('NOIPCHECK')) define('NOIPCHECK','1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value +//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler +//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("FORCECSP")) define('FORCECSP','none'); // Disable all Content Security Policies + + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +// Try main.inc.php using relative path +if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; +if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; +if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; +if (!$res) die("Include of main fails"); + +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +dol_include_once('/recruitment/class/recruitmentjobposition.class.php'); +dol_include_once('/recruitment/lib/recruitment_recruitmentjobposition.lib.php'); + +// Load translation files required by the page +$langs->loadLangs(array("recruitment", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'recruitmentjobpositioncard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +//$lineid = GETPOST('lineid', 'int'); + +// Initialize technical objects +$object = new RecruitmentJobPosition($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->recruitment->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('recruitmentjobpositioncard', 'globalcard')); // Note that conf->hooks_modules contains array + +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Initialize array of search criterias +$search_all = trim(GETPOST("search_all", 'alpha')); +$search = array(); +foreach ($object->fields as $key => $val) +{ + if (GETPOST('search_'.$key, 'alpha')) $search[$key] = GETPOST('search_'.$key, 'alpha'); +} + +if (empty($action) && empty($id) && empty($ref)) $action = 'view'; + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + + +$permissiontoread = $user->rights->recruitment->recruitmentjobposition->read; +$permissiontoadd = $user->rights->recruitment->recruitmentjobposition->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->recruitment->recruitmentjobposition->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); +$permissionnote = $user->rights->recruitment->recruitmentjobposition->write; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $user->rights->recruitment->recruitmentjobposition->write; // Used by the include of actions_dellink.inc.php +$upload_dir = $conf->recruitment->multidir_output[isset($object->entity) ? $object->entity : 1]; + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +//$isdraft = (($object->statut == $object::STATUS_DRAFT) ? 1 : 0); +//$result = restrictedArea($user, 'recruitment', $object->id, '', '', 'fk_soc', 'rowid', $isdraft); + +//if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + +if (empty($reshook)) +{ + $error = 0; + + $backurlforlist = dol_buildpath('/recruitment/recruitmentjobposition_list.php', 1); + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) $backtopage = $backurlforlist; + else $backtopage = dol_buildpath('/recruitment/recruitmentjobposition_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + } + } + $triggermodname = 'RECRUITMENT_RECRUITMENTJOBPOSITION_MODIFY'; // Name of trigger action code to execute when we modify record + + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen + include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php'; + + // Actions when linking object each other + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; + + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + + // Action to move up and down lines of object + //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; + + // Action to build doc + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + + if ($action == 'set_thirdparty' && $permissiontoadd) + { + $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'RECRUITMENTJOBPOSITION_MODIFY'); + } + if ($action == 'classin' && $permissiontoadd) + { + $object->setProject(GETPOST('projectid', 'int')); + } + + // Actions to send emails + $triggersendname = 'RECRUITMENTJOBPOSITION_SENTBYMAIL'; + $autocopy = 'MAIN_MAIL_AUTOCOPY_RECRUITMENTJOBPOSITION_TO'; + $trackid = 'recruitmentjobposition'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; +} + + + + +/* + * View + * + * Put here all code to build page + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formproject = new FormProjets($db); + +$title = $langs->trans("PositionToBeFilled"); +$help_url = ''; +llxHeader('', $title, $help_url); + +// Part to create +if ($action == 'create') +{ + print load_fiche_titre($langs->trans("NewPositionToBeFilled"), '', 'object_'.$object->picto); + + print '
'; + print ''; + print ''; + if ($backtopage) print ''; + if ($backtopageforcancel) print ''; + + // Set some default values + if (! GETPOSTISSET('fk_user_recruiter')) $_POST['fk_user_recruiter'] = $user->id; + + dol_fiche_head(array(), ''); + + print ''."\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; + + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; + + print '
'."\n"; + + dol_fiche_end(); + + print '
'; + print ''; + print '  '; + print ''; // Cancel for create does not post form if we don't know the backtopage + print '
'; + + print '
'; + + //dol_set_focus('input[name="ref"]'); +} + +// Part to edit record +if (($id || $ref) && $action == 'edit') +{ + print load_fiche_titre($langs->trans("PositionToBeFilled"), '', 'object_'.$object->picto); + + print '
'; + print ''; + print ''; + print ''; + if ($backtopage) print ''; + if ($backtopageforcancel) print ''; + + dol_fiche_head(); + + print ''."\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php'; + + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; + + print '
'; + + dol_fiche_end(); + + print '
'; + print '   '; + print '
'; + + print '
'; +} + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) +{ + $res = $object->fetch_optionals(); + + $head = recruitmentjobpositionPrepareHead($object); + dol_fiche_head($head, 'candidatures', $langs->trans("RecruitmentCandidatures"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') + { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteRecruitmentJobPosition'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } + // Confirmation to delete line + if ($action == 'deleteline') + { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); + } + // Clone confirmation + if ($action == 'clone') { + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + } + + // Confirmation of action xxxx + if ($action == 'xxx') + { + $formquestion = array(); + /* + $forcecombo=0; + if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy + $formquestion = array( + // 'text' => $langs->trans("ConfirmClone"), + // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), + // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), + // array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo)) + ); + */ + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220); + } + + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; + elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; + + // Print form confirm + print $formconfirm; + + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
'; + /* + // Ref customer + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + */ + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.=$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; + $morehtmlref.=' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref.='
'; + $morehtmlref.=''; + $morehtmlref.=''; + $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref.=''; + $morehtmlref.='
'; + } else { + $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + } + $morehtmlref .= '
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + print '
'; + print '
'; + print ''."\n"; + + // Common attributes + $keyforbreak='description'; // We change column just after this field + unset($object->fields['fk_project']); // Hide field already shown in banner + //unset($object->fields['fk_soc']); // Hide field already shown in banner + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + + // Other attributes. Fields from hook formObjectOptions and Extrafields. + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + + print '
'; + print '
'; + print '
'; + + print '
'; + + dol_fiche_end(); + + + /* + * Lines + */ + + if (!empty($object->table_element_line)) + { + // Show object lines + $result = $object->getLinesArray(); + + print '
+ + + + + '; + + if (!empty($conf->use_javascript_ajax) && $object->status == 0) { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } + + print '
'; + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) + { + print ''; + } + + if (!empty($object->lines)) + { + $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1); + } + + // Form to add new line + if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') + { + if ($action != 'editline') + { + // Add products/services form + $object->formAddObjectLine(1, $mysoc, $soc); + + $parameters = array(); + $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + } + } + + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) + { + print '
'; + } + print '
'; + + print "
\n"; + } + + + // Buttons for actions + + if ($action != 'presend' && $action != 'editline') { + print '
'."\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + + if (empty($reshook)) + { + // Send + if (empty($user->socid)) { + print ''.$langs->trans('SendMail').''."\n"; + } + + // Back to draft + if ($object->status == $object::STATUS_VALIDATED) + { + if ($permissiontoadd) + { + print ''.$langs->trans("SetToDraft").''; + } + } + + // Modify + if ($permissiontoadd) + { + print ''.$langs->trans("Modify").''."\n"; + } else { + print ''.$langs->trans('Modify').''."\n"; + } + + // Validate + if ($object->status == $object::STATUS_DRAFT) + { + if ($permissiontoadd) + { + if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) + { + print ''.$langs->trans("Validate").''; + } else { + $langs->load("errors"); + print ''.$langs->trans("Validate").''; + } + } + } + + // Clone + if ($permissiontoadd) + { + print ''.$langs->trans("ToClone").''."\n"; + } + + /* + if ($permissiontoadd) + { + if ($object->status == $object::STATUS_ENABLED) + { + print ''.$langs->trans("Disable").''."\n"; + } + else + { + print ''.$langs->trans("Enable").''."\n"; + } + } + if ($permissiontoadd) + { + if ($object->status == $object::STATUS_VALIDATED) + { + print ''.$langs->trans("Cancel").''."\n"; + } + else + { + print ''.$langs->trans("Re-Open").''."\n"; + } + } + */ + + // Delete (need delete permission, or if draft, just need create/modify permission) + if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) + { + print ''.$langs->trans('Delete').''."\n"; + } else { + print ''.$langs->trans('Delete').''."\n"; + } + } + print '
'."\n"; + } + + + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + if ($action != 'presend') + { + print '
'; + print ''; // ancre + + $includedocgeneration = 1; + + // Documents + if ($includedocgeneration) { + $objref = dol_sanitizeFileName($object->ref); + $relativepath = $objref . '/' . $objref . '.pdf'; + $filedir = $conf->recruitment->dir_output.'/'.$object->element.'/'.$objref; + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->recruitment->recruitmentjobposition->read; // If you can read, you can build the PDF to read content + $delallowed = $user->rights->recruitment->recruitmentjobposition->write; // If you can create/edit, you can remove a file on card + print $formfile->showdocuments('recruitment:RecruitmentJobPosition', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); + } + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, array('recruitmentjobposition')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + // Show link to public job page + if ($object->status != RecruitmentJobPosition::STATUS_DRAFT) + { + print '
'."\n"; + // Load translation files required by the page + $langs->loadLangs(array('recruitment')); + + $out = img_picto('', 'globe').' '.$langs->trans("PublicUrl").'
'; + + $url = getPublicJobPositionUrl(0, $object->ref); + $out .= ''; + $out .= ''.img_picto('', 'globe').''; + $out .= ajax_autoselect("recruitmentjobpositionurl", 0); + + print $out; + } + + print '
'; + + $MAXEVENT = 10; + + $morehtmlright = ''; + $morehtmlright .= $langs->trans("SeeAll"); + $morehtmlright .= ''; + + // List of actions on element + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, $object->element.'@recruitment', (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); + + print '
'; + } + + //Select mail models is same action as presend + if (GETPOST('modelselected')) $action = 'presend'; + + // Presend form + $modelmail = 'recruitmentjobposition'; + $defaulttopic = 'InformationMessage'; + $diroutput = $conf->recruitment->dir_output; + $trackid = 'recruitmentjobposition'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index 4c01e74a338..137afdd597f 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -188,22 +188,6 @@ $title = $langs->trans("PositionToBeFilled"); $help_url = ''; llxHeader('', $title, $help_url); -// Example : Adding jquery code -print ''; - - // Part to create if ($action == 'create') { diff --git a/htdocs/recruitment/recruitmentjobposition_document.php b/htdocs/recruitment/recruitmentjobposition_document.php index be8be1bcf42..b549c22d632 100644 --- a/htdocs/recruitment/recruitmentjobposition_document.php +++ b/htdocs/recruitment/recruitmentjobposition_document.php @@ -136,37 +136,38 @@ if ($object->id) $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); // Thirdparty $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; - if ($permissiontoadd) - { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref.=' : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
'; - } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); - } - } else { - if (! empty($object->fk_project)) { - $proj = new Project($db); - $proj->fetch($object->fk_project); - $morehtmlref .= ': '.$proj->getNomUrl(); - } else { - $morehtmlref .= ''; - } - } - }*/ + */ + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref .= $langs->trans('Project') . ' '; + if ($permissiontoadd) + { + if ($action != 'classify') + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + $morehtmlref .=' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
'; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + } $morehtmlref .= '
'; dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/recruitment/recruitmentjobposition_note.php b/htdocs/recruitment/recruitmentjobposition_note.php index 41268ca1c6d..b8f873309d7 100644 --- a/htdocs/recruitment/recruitmentjobposition_note.php +++ b/htdocs/recruitment/recruitmentjobposition_note.php @@ -108,37 +108,38 @@ if ($id > 0 || !empty($ref)) $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); // Thirdparty $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; - if ($permissiontoadd) - { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref.=' : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
'; - } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); - } - } else { - if (! empty($object->fk_project)) { - $proj = new Project($db); - $proj->fetch($object->fk_project); - $morehtmlref .= ': '.$proj->getNomUrl(); - } else { - $morehtmlref .= ''; - } - } - }*/ + */ + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref .= $langs->trans('Project') . ' '; + if ($permissiontoadd) + { + if ($action != 'classify') + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + $morehtmlref .=' : '; + if ($action == 'classify') { + //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); + $morehtmlref .= '
'; + $morehtmlref .= ''; + $morehtmlref .= ''; + $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= ''; + $morehtmlref .= '
'; + } else { + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + } + } else { + if (! empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + } $morehtmlref .= '
'; From 4ed1da1632947c0ac98938d5c1c2a629e2cc4c98 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 04:17:05 +0200 Subject: [PATCH 093/434] Work on recruitment module --- htdocs/public/recruitment/view.php | 42 ++++++++++++++---------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index c55de12ca2d..47116db671b 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -238,50 +238,46 @@ if (empty($text)) print $text; // Output payment summary form -print ''; -print ''; -print ''."\n"; +print ''."\n"; +print $langs->trans("Label").' '; +print ''.$object->label.'
'; // Date -print ''."\n"; - - - -if (!$found && !$mesg) $mesg = $langs->trans("ErrorBadParameters"); - -if ($mesg) print ''."\n"; - -print '
'.$langs->trans("ThisIsInformationOnJobPosition").' :
'; + +print '
'; +print '
'.$langs->trans("ThisIsInformationOnJobPosition").' :
'."\n"; $error = 0; $var = false; +$found = true; + +print '
'; // Label -print '
'.$langs->trans("Label"); -print ''; -print ''.$object->label.''; -print '
'.$langs->trans("DateExpected"); -print ''; +print $langs->trans("DateExpected").' '; +print ''; if ($object->date_planned > $now) { - print dol_print_date('day', $object->date_planned); + print dol_print_date($object->date_planned, 'day'); } else { print $langs->trans("ASAP"); } -print ''; +print '
'; + +print '
'; // Description $text = $object->description; -print '
'.$langs->trans("Description"); -print ''.$text; +print $text; print ''; -print '

'.$mesg.'
'."\n"; +print '
'."\n"; print "\n"; -if ($action != 'dosign') + +if ($action != 'dosubmit') { if ($found && !$error) // We are in a management option and no error { From 2ff6791e5354db378763a0247a191a50681628a3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 04:23:23 +0200 Subject: [PATCH 094/434] css --- htdocs/public/recruitment/view.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index 47116db671b..3cddbef74a0 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -251,12 +251,12 @@ print '
'; // Label -print $langs->trans("Label").' '; +print $langs->trans("Label").' : '; print ''.$object->label.'
'; // Date -print $langs->trans("DateExpected").' '; +print $langs->trans("DateExpected").' : '; print ''; if ($object->date_planned > $now) { print dol_print_date($object->date_planned, 'day'); From 05531f95d6ad5be7dbf8fb8b09353d187a78bdab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 14:03:01 +0200 Subject: [PATCH 095/434] Fix phpcs --- htdocs/public/recruitment/view.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index 3cddbef74a0..e34908dd0a7 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -301,4 +301,3 @@ htmlPrintOnlinePaymentFooter($mysoc, $langs); llxFooter('', 'public'); $db->close(); - From 8b879ee23b58860733abc76a41f5ee8f66ef936f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 14:47:51 +0200 Subject: [PATCH 096/434] FIX Edit extrafield of type long text loose carriage returns --- htdocs/core/class/extrafields.class.php | 4 ++++ htdocs/core/lib/functions.lib.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 90fc879bd17..1f38719dbb1 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -2098,6 +2098,10 @@ class ExtraFields { $value_key = GETPOST("options_".$key, 'alpha'); } + elseif (in_array($key_type, array('text'))) + { + $value_key = GETPOST("options_".$key, 'alphanohtml'); + } else { $value_key = GETPOST("options_".$key); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 967849d775a..91a3061dd41 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -601,7 +601,7 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null // '"' is dangerous because param in url can close the href= or src= and add javascript functions. // '../' is dangerous because it allows dir transversals $out = str_replace(array('"', '../'), '', trim($out)); - $out = dol_string_nohtmltag($out, 1); + $out = dol_string_nohtmltag($out, 0); } break; case 'restricthtml': // Recommended for most html textarea From 618c85ceb141fa405d396696172bcbe669a4096f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 14:49:31 +0200 Subject: [PATCH 097/434] FIX Filter too large for extrafields with type text or html --- htdocs/core/tpl/extrafields_list_search_input.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/tpl/extrafields_list_search_input.tpl.php b/htdocs/core/tpl/extrafields_list_search_input.tpl.php index d6ebb8b919f..6e1dae186b1 100644 --- a/htdocs/core/tpl/extrafields_list_search_input.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_input.tpl.php @@ -43,7 +43,7 @@ if (!empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_e { // for the type as 'checkbox', 'chkbxlst', 'sellist' we should use code instead of id (example: I declare a 'chkbxlst' to have a link with dictionnairy, I have to extend it with the 'code' instead 'rowid') $morecss = ''; - if (in_array($typeofextrafield, array('link', 'sellist'))) $morecss = 'maxwidth200'; + if (in_array($typeofextrafield, array('link', 'sellist', 'text', 'html'))) $morecss = 'maxwidth200'; echo $extrafields->showInputField($key, $search_array_options[$search_options_pattern.$tmpkey], '', '', $search_options_pattern, $morecss, 0, $extrafieldsobjectkey, 1); } print ''; From 0bf678e09e734f3241c66aa0980ec827b0248c8f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 14:57:33 +0200 Subject: [PATCH 098/434] Fix label of extrafields --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- htdocs/core/class/extrafields.class.php | 4 ++-- .../core/tpl/admin_extrafields_edit.tpl.php | 19 +++++++++++++++++++ htdocs/langs/en_US/admin.lang | 2 ++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 912c9953229..37a39e7d1f0 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -219,7 +219,7 @@ if ($action == "update_extras" && !empty($permissiontoadd)) $object->array_options['options_'.$attributekey] = dol_mktime(GETPOST($attributekeylong.'hour', 'int'), GETPOST($attributekeylong.'min', 'int'), GETPOST($attributekeylong.'sec', 'int'), GETPOST($attributekeylong.'month', 'int'), GETPOST($attributekeylong.'day', 'int'), GETPOST($attributekeylong.'year', 'int')); //var_dump(dol_print_date($object->array_options['options_'.$attributekey]));exit; } else { - $object->array_options['options_'.$attributekey] = GETPOST($attributekeylong, ' alpha'); + $object->array_options['options_'.$attributekey] = GETPOST($attributekeylong, 'alpha'); } $result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user); diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 1f38719dbb1..eecb5b54330 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -154,8 +154,8 @@ class ExtraFields public static $type2label = array( - 'varchar'=>'String', - 'text'=>'TextLong', + 'varchar'=>'String1Line', + 'text'=>'TextLongNLines', 'html'=>'HtmlText', 'int'=>'Int', 'double'=>'Float', diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 80a7cac7de3..191b4cf40c8 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -186,8 +186,10 @@ elseif (($type == 'sellist') || ($type == 'chkbxlst') || ($type == 'link') || ($ ?> trans("LabelOrTranslationKey"); ?> + trans("AttributeCode"); ?> + trans("Type"); ?> array('varchar', 'phone', 'mail', 'url', 'select'), 'select'=>array('varchar', 'phone', 'mail', 'url', 'select') ); +/* Disabled because text is text on several lines, when varchar is text on 1 line, we should not be able to convert +if ($size <= 255 && in_array($type, array('text', 'html'))) { + $typewecanchangeinto['text'][] = 'varchar'; +}*/ if (in_array($type, array_keys($typewecanchangeinto))) { @@ -225,8 +231,10 @@ else } ?> + trans("Size"); ?> + @@ -247,33 +255,44 @@ else + trans("Position"); ?> + trans("LanguageFile"); ?> + global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { ?> textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?> textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?> + trans("DefaultValue").' ('.$langs->trans("Database").')'; ?> + trans("Unique"); ?>> + trans("Required"); ?>> + trans("AlwaysEditable"); ?>> + textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?> + textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")); ?> textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")); ?>> + textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?> + multicompany->enabled) { ?> trans("AllEntities"); ?>> diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index c99c436915d..33590b17141 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -409,7 +409,9 @@ PriceBaseTypeToChange=Modify on prices with base reference value defined on MassConvert=Launch bulk conversion PriceFormatInCurrentLanguage=Price Format In Current Language String=String +String1Line=String (1 line) TextLong=Long text +TextLongNLines=Long text (n lines) HtmlText=Html text Int=Integer Float=Float From e7fedd5c2db7cca4fe884f82076f909e79461ca1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 19:14:40 +0200 Subject: [PATCH 099/434] FIX Sql error on stat by referring entries of a product --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index d557dd90392..a202004ed02 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3603,7 +3603,7 @@ class Product extends CommonObject $sql = "SELECT sum(d.qty), date_format(d.date_valid, '%Y%m')"; if ($mode == 'bynumber') { - $sql .= ", count(DISTINCT c.rowid)"; + $sql .= ", count(DISTINCT d.rowid)"; } $sql .= " FROM ".MAIN_DB_PREFIX."mrp_mo as d LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON d.fk_soc = s.rowid"; if ($filteronproducttype >= 0) { From f5d7e94d7e26f8fcd2a7445c2f27bb87b2d79e6f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Jul 2020 19:32:06 +0200 Subject: [PATCH 100/434] NEW Add a stat page to list popularity of products on invoices Merge duplicate pages into 1. --- htdocs/langs/en_US/other.lang | 2 + htdocs/product/popucom.php | 212 ---------------------------------- htdocs/product/popuprop.php | 189 +++++++++++++++++------------- htdocs/product/stats/card.php | 9 +- 4 files changed, 114 insertions(+), 298 deletions(-) delete mode 100644 htdocs/product/popucom.php diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 5dc70fa068f..4555d3a6bc5 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -280,7 +280,9 @@ LinesToImport=Lines to import MemoryUsage=Memory usage RequestDuration=Duration of request +ProductsPerPopularity=Products/Services by popularity PopuProp=Products/Services by popularity in Proposals PopuCom=Products/Services by popularity in Orders ProductStatistics=Products/Services Statistics NbOfQtyInOrders=Qty in orders +SelectTheTypeOfObjectToAnalyze=Select the type of object to analyze... diff --git a/htdocs/product/popucom.php b/htdocs/product/popucom.php deleted file mode 100644 index a0ee53a5758..00000000000 --- a/htdocs/product/popucom.php +++ /dev/null @@ -1,212 +0,0 @@ - - * Copyright (C) 2004-2005 Laurent Destailleur - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2014 Marcos García - * Copyright (C) 2015 Jean-François Ferry - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/product/popucom.php - * \ingroup commande, produit - * \brief Liste des produits/services par popularite - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - -// Load translation files required by the page -//Required to translate NbOfCommande -$langs->load('commande'); - -$type = GETPOST("type", "int"); - -// Security check -if (!empty($user->socid)) $socid = $user->socid; -$result = restrictedArea($user, 'produit|service'); - -$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST("sortfield", 'alpha'); -$sortorder = GETPOST("sortorder", 'alpha'); -$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -if (!$sortfield) $sortfield = "c"; -if (!$sortorder) $sortorder = "DESC"; -$offset = $limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; - - -$staticproduct = new Product($db); - - -/* - * View - */ - -$helpurl = ''; -if ($type == '0') -{ - $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos'; -} elseif ($type == '1') -{ - $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; -} else { - $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; -} -$title = $langs->trans("Statistics"); - - -llxHeader('', $title, $helpurl); - -print load_fiche_titre($title, $mesg, 'product'); - - -$param = ''; -$title = $langs->trans("ListProductServiceByPopularity"); -if ((string) $type == '1') { - $title = $langs->trans("ListServiceByPopularity"); -} -if ((string) $type == '0') { - $title = $langs->trans("ListProductByPopularity"); -} - -if ($type != '') $param .= '&type='.$type; - - -$h = 0; -$head = array(); - -$head[$h][0] = DOL_URL_ROOT.'/product/stats/card.php?id=all'; -$head[$h][1] = $langs->trans("Chart"); -$head[$h][2] = 'chart'; -$h++; - -$head[$h][0] = DOL_URL_ROOT.'/product/popuprop.php'; -$head[$h][1] = $langs->trans("PopuProp"); -$head[$h][2] = 'popularityprop'; -$h++; - -$head[$h][0] = DOL_URL_ROOT.'/product/popucom.php'; -$head[$h][1] = $langs->trans("PopuCom"); -$head[$h][2] = 'popularitycommande'; -$h++; - -dol_fiche_head($head, 'popularitycommande', $langs->trans("Statistics"), -1); - - -// Array of liens to show -$infoprod = array(); - - -// Add lines for commande -$sql = "SELECT p.rowid, p.label, p.ref, p.fk_product_type as type, SUM(pd.qty) as c"; -$sql .= " FROM ".MAIN_DB_PREFIX."commandedet as pd"; -$sql .= ", ".MAIN_DB_PREFIX."product as p"; -$sql .= ' WHERE p.entity IN ('.getEntity('product').')'; -$sql .= " AND p.rowid = pd.fk_product"; -if ($type !== '') { - $sql .= " AND fk_product_type = ".$type; -} -$sql .= " GROUP BY p.rowid, p.label, p.ref, p.fk_product_type"; - -$result = $db->query($sql); -if ($result) -{ - $totalnboflines = $db->num_rows($result); -} - -$sql .= $db->order($sortfield, $sortorder); -$sql .= $db->plimit($limit + 1, $offset); - -$resql = $db->query($sql); -if ($resql) -{ - $num = $db->num_rows($resql); - $i = 0; - - while ($i < $num) - { - $objp = $db->fetch_object($resql); - - $infoprod[$objp->rowid] = array('type'=>$objp->type, 'ref'=>$objp->ref, 'label'=>$objp->label); - $infoprod[$objp->rowid]['nblinecommande'] = $objp->c; - - $i++; - } - $db->free($resql); -} else { - dol_print_error($db); -} -//var_dump($infoprod); - - -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, "", $num, $totalnboflines, ''); - -print ''; - -print ""; -print_liste_field_titre('Ref', $_SERVER["PHP_SELF"], 'p.ref', '', $param, '', $sortfield, $sortorder); -print_liste_field_titre('Type', $_SERVER["PHP_SELF"], 'p.fk_product_type', '', $param, '', $sortfield, $sortorder); -print_liste_field_titre('Label', $_SERVER["PHP_SELF"], 'p.label', '', $param, '', $sortfield, $sortorder); -print_liste_field_titre('NbOfQtyInOrders', $_SERVER["PHP_SELF"], 'c', '', $param, '', $sortfield, $sortorder, 'right '); -print "\n"; - -foreach ($infoprod as $prodid => $vals) -{ - // Multilangs - if (!empty($conf->global->MAIN_MULTILANGS)) // si l'option est active - { - $sql = "SELECT label"; - $sql .= " FROM ".MAIN_DB_PREFIX."product_lang"; - $sql .= " WHERE fk_product=".$prodid; - $sql .= " AND lang='".$langs->getDefaultLang()."'"; - $sql .= " LIMIT 1"; - - $resultp = $db->query($sql); - if ($resultp) - { - $objtp = $db->fetch_object($resultp); - if (!empty($objtp->label)) $vals['label'] = $objtp->label; - } - } - - print ""; - print ''; - print ''; - print ''; - print ''; - print "\n"; - $i++; -} - -print "
'; - if ($vals['type'] == 1) print img_object($langs->trans("ShowService"), "service"); - else print img_object($langs->trans("ShowProduct"), "product"); - print " "; - print $vals['ref'].''; - if ($vals['type'] == 1) print $langs->trans("Service"); - else print $langs->trans("Product"); - print ''.$vals['label'].''.$vals['nblinecommande'].'
"; - - - -dol_fiche_end(); - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php index b48afc6d162..affd5a8b3f2 100644 --- a/htdocs/product/popuprop.php +++ b/htdocs/product/popuprop.php @@ -1,10 +1,10 @@ - * Copyright (C) 2004-2005 Laurent Destailleur + * Copyright (C) 2004-2020 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2014 Marcos García - * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Jean-François Ferry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,18 +22,21 @@ /** * \file htdocs/product/popuprop.php - * \ingroup propal, produit - * \brief Liste des produits/services par popularite + * \ingroup propal, commande, facture, produit + * \brief List of products or services by popularity */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; // Load translation files required by the page -//Required to translate NbOfProposals -$langs->load('propal'); +$langs->loadLangs(array('commande', 'propal', 'bills', 'other')); + +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); $type = GETPOST("type", "int"); +$mode = GETPOST('mode', 'alpha') ? GETPOST('mode', 'alpha') : ''; // Security check if (!empty($user->socid)) $socid = $user->socid; @@ -58,12 +61,12 @@ $staticproduct = new Product($db); * View */ +$form = new Form($db); + $helpurl = ''; -if ($type == '0') -{ +if ($type == '0') { $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:Módulo_Productos'; -} elseif ($type == '1') -{ +} elseif ($type == '1') { $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; } else { $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:Módulo_Servicios'; @@ -85,8 +88,8 @@ if ((string) $type == '0') { $title = $langs->trans("ListProductByPopularity"); } -if ($type != '') $param .= '&type='.$type; - +if ($type != '') $param .= '&type='.urlencode($type); +if ($mode != '') $param .= '&mode='.urlencode($mode); $h = 0; $head = array(); @@ -97,25 +100,30 @@ $head[$h][2] = 'chart'; $h++; $head[$h][0] = DOL_URL_ROOT.'/product/popuprop.php'; -$head[$h][1] = $langs->trans("PopuProp"); -$head[$h][2] = 'popularityprop'; +$head[$h][1] = $langs->trans("ProductsPerPopularity"); +$head[$h][2] = 'popularity'; $h++; -$head[$h][0] = DOL_URL_ROOT.'/product/popucom.php'; -$head[$h][1] = $langs->trans("PopuCom"); -$head[$h][2] = 'popularitycommande'; -$h++; -dol_fiche_head($head, 'popularityprop', $langs->trans("Statistics"), -1); +dol_fiche_head($head, 'popularity', $langs->trans("Statistics"), -1); // Array of liens to show $infoprod = array(); -// Add lines for proposals +// Add lines for object $sql = "SELECT p.rowid, p.label, p.ref, p.fk_product_type as type, SUM(pd.qty) as c"; -$sql .= " FROM ".MAIN_DB_PREFIX."propaldet as pd"; +$textforqty = 'Qty'; +if ($mode == 'facture') { + $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as pd"; +} elseif ($mode == 'commande') { + $textforqty = 'NbOfQtyInOrders'; + $sql .= " FROM ".MAIN_DB_PREFIX."commandedet as pd"; +} elseif ($mode == 'propal') { + $textforqty = 'NbOfQtyInProposals'; + $sql .= " FROM ".MAIN_DB_PREFIX."propaldet as pd"; +} $sql .= ", ".MAIN_DB_PREFIX."product as p"; $sql .= ' WHERE p.entity IN ('.getEntity('product').')'; $sql .= " AND p.rowid = pd.fk_product"; @@ -124,38 +132,58 @@ if ($type !== '') { } $sql .= " GROUP BY p.rowid, p.label, p.ref, p.fk_product_type"; -$result = $db->query($sql); -if ($result) -{ - $totalnboflines = $db->num_rows($result); -} - -$sql .= $db->order($sortfield, $sortorder); -$sql .= $db->plimit($limit + 1, $offset); - -$resql = $db->query($sql); -if ($resql) -{ - $num = $db->num_rows($resql); - $i = 0; - - while ($i < $num) +if (! empty($mode) && $mode != '-1') { + $result = $db->query($sql); + if ($result) { - $objp = $db->fetch_object($resql); - - $infoprod[$objp->rowid] = array('type'=>$objp->type, 'ref'=>$objp->ref, 'label'=>$objp->label); - $infoprod[$objp->rowid]['nblineproposal'] = $objp->c; - - $i++; + $totalnboflines = $db->num_rows($result); + } + + $sql .= $db->order($sortfield, $sortorder); + $sql .= $db->plimit($limit + 1, $offset); + + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + while ($i < $num) + { + $objp = $db->fetch_object($resql); + + $infoprod[$objp->rowid] = array('type'=>$objp->type, 'ref'=>$objp->ref, 'label'=>$objp->label); + $infoprod[$objp->rowid]['nbline'] = $objp->c; + + $i++; + } + $db->free($resql); + } else { + dol_print_error($db); } - $db->free($resql); -} else { - dol_print_error($db); } //var_dump($infoprod); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, "", $num, $totalnboflines, ''); +$arrayofmode = array( + 'propal' => 'Proposals', + 'commande' => 'Orders', + 'facture' => 'Facture' + ); +$title .= ' '.$form->selectarray('mode', $arrayofmode, $mode, 1); +$title .= ' '; + + +print '
'; +print ''; +print ''; +print ''; +print ''; +if ($backtopage) print ''; +if ($backtopageforcancel) print ''; + + +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, "", $num, $totalnboflines, '', 0, '', '', -1, 0, 0, 1); print ''; @@ -163,47 +191,50 @@ print ""; print_liste_field_titre('Ref', $_SERVER["PHP_SELF"], 'p.ref', '', $param, '', $sortfield, $sortorder); print_liste_field_titre('Type', $_SERVER["PHP_SELF"], 'p.fk_product_type', '', $param, '', $sortfield, $sortorder); print_liste_field_titre('Label', $_SERVER["PHP_SELF"], 'p.label', '', $param, '', $sortfield, $sortorder); -print_liste_field_titre('NbOfQtyInProposals', $_SERVER["PHP_SELF"], 'c', '', $param, '', $sortfield, $sortorder, 'right '); +print_liste_field_titre($textforqty, $_SERVER["PHP_SELF"], 'c', '', $param, '', $sortfield, $sortorder, 'right '); print "\n"; -foreach ($infoprod as $prodid => $vals) -{ - // Multilangs - if (!empty($conf->global->MAIN_MULTILANGS)) // si l'option est active +if ($mode && $mode != '-1') { + foreach ($infoprod as $prodid => $vals) { - $sql = "SELECT label"; - $sql .= " FROM ".MAIN_DB_PREFIX."product_lang"; - $sql .= " WHERE fk_product=".$prodid; - $sql .= " AND lang='".$langs->getDefaultLang()."'"; - $sql .= " LIMIT 1"; - - $resultp = $db->query($sql); - if ($resultp) + // Multilangs + if (!empty($conf->global->MAIN_MULTILANGS)) // si l'option est active { - $objtp = $db->fetch_object($resultp); - if (!empty($objtp->label)) $vals['label'] = $objtp->label; + $sql = "SELECT label"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_lang"; + $sql .= " WHERE fk_product=".$prodid; + $sql .= " AND lang='".$langs->getDefaultLang()."'"; + $sql .= " LIMIT 1"; + + $resultp = $db->query($sql); + if ($resultp) + { + $objtp = $db->fetch_object($resultp); + if (!empty($objtp->label)) $vals['label'] = $objtp->label; + } } + + print ""; + print ''; + print ''; + print ''; + print ''; + print "\n"; + $i++; } - - print ""; - print ''; - print ''; - print ''; - print ''; - print "\n"; - $i++; +} else { + print ''; } - print "
'; + if ($vals['type'] == 1) print img_object($langs->trans("ShowService"), "service"); + else print img_object($langs->trans("ShowProduct"), "product"); + print " "; + print $vals['ref'].''; + if ($vals['type'] == 1) print $langs->trans("Service"); + else print $langs->trans("Product"); + print ''.$vals['label'].''.$vals['nbline'].'
'; - if ($vals['type'] == 1) print img_object($langs->trans("ShowService"), "service"); - else print img_object($langs->trans("ShowProduct"), "product"); - print " "; - print $vals['ref'].''; - if ($vals['type'] == 1) print $langs->trans("Service"); - else print $langs->trans("Product"); - print ''.$vals['label'].''.$vals['nblineproposal'].'
'.$langs->trans("SelectTheTypeOfObjectToAnalyze").'
"; - +print '
'; dol_fiche_end(); diff --git a/htdocs/product/stats/card.php b/htdocs/product/stats/card.php index d77c03f4d0d..4d4b0820e18 100644 --- a/htdocs/product/stats/card.php +++ b/htdocs/product/stats/card.php @@ -159,13 +159,8 @@ if (empty($id) & empty($ref)) } $head[$h][0] = DOL_URL_ROOT.'/product/popuprop.php'.($type != '' ? '?type='.$type : ''); - $head[$h][1] = $langs->trans("PopuProp"); - $head[$h][2] = 'popularityprop'; - $h++; - - $head[$h][0] = DOL_URL_ROOT.'/product/popucom.php'.($type != '' ? '?type='.$type : ''); - $head[$h][1] = $langs->trans("PopuCom"); - $head[$h][2] = 'popularitycommande'; + $head[$h][1] = $langs->trans("ProductsPerPopularity"); + $head[$h][2] = 'popularity'; $h++; dol_fiche_head($head, 'chart', $langs->trans("Statistics"), -1); From d1560c3e75917be919313cd634cdac886b1aec03 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 30 Jul 2020 21:10:06 +0200 Subject: [PATCH 101/434] NEW: Introduce constant FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM --- htdocs/fourn/facture/card.php | 8 +++----- htdocs/product/stock/list.php | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 80301dcdc43..7e8796e44f6 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1724,6 +1724,9 @@ if ($action == 'create') $mode_reglement_id = GETPOST("mode_reglement_id"); } + $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)); + $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)); + print '
'; print ''; print ''; @@ -2048,8 +2051,6 @@ if ($action == 'create') // Public note print ''.$langs->trans('NotePublic').''; print ''; - $note_public = $object->getDefaultCreateValueFor('note_public'); - if (empty($note_public))$note_public = $objectsrc->note_public; $doleditor = new DolEditor('note_public', (GETPOSTISSET('note_public') ?GETPOST('note_public', 'none') : $note_public), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); print ''; @@ -2059,9 +2060,6 @@ if ($action == 'create') // Private note print ''.$langs->trans('NotePrivate').''; print ''; - $note_private = $object->getDefaultCreateValueFor('note_private'); - if (empty($note_private))$note_private = $objectsrc->note_private; - $doleditor = new DolEditor('note_private', (GETPOSTISSET('note_private') ?GETPOST('note_private', 'none') : $note_private), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); print ''; diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 3151df07507..15ee5c2e52b 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -654,8 +654,8 @@ if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $n $urlsource .= str_replace('&', '&', $param); $filedir = $diroutputmassaction; - $genallowed = $user->rights->mymodule->read; - $delallowed = $user->rights->mymodule->create; + $genallowed = $user->rights->stock->lire; + $delallowed = $user->rights->stock->creer; print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); } From 9a9eef428be2ec9081e88010e4db4b4332e43022 Mon Sep 17 00:00:00 2001 From: altairis Date: Fri, 31 Jul 2020 12:22:21 +0200 Subject: [PATCH 102/434] fix duration fields size with firefox --- htdocs/core/class/html.form.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 627e5ee8a2b..d1a76c712e5 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5649,7 +5649,7 @@ class Form } elseif ($typehour=='text' || $typehour=='textselect') { - $retstring.=''; + $retstring.=''; } else return 'BadValueForParameterTypeHour'; @@ -5673,7 +5673,7 @@ class Form } elseif ($typehour=='text' ) { - $retstring.=''; + $retstring.=''; } if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); From 255dc718238a5e9a4bf85d3d2765000407a2bb8c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Jul 2020 13:20:05 +0200 Subject: [PATCH 103/434] Missing translation --- htdocs/langs/en_US/cashdesk.lang | 1 + htdocs/takepos/admin/receipt.php | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index c7d7dd95cb7..ce5cdaf4ba6 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -117,3 +117,4 @@ HideCategoryImages=Hide Category Images HideProductImages=Hide Product Images NumberOfLinesToShow=Number of lines of images to show DefineTablePlan=Define tables plan +ModuleReceiptPrinterMustBeEnabled=Module Receipt printer must have been enabled first diff --git a/htdocs/takepos/admin/receipt.php b/htdocs/takepos/admin/receipt.php index 62e083110f1..d6d0574e0ed 100644 --- a/htdocs/takepos/admin/receipt.php +++ b/htdocs/takepos/admin/receipt.php @@ -92,7 +92,7 @@ print load_fiche_titre($langs->trans("PrintMethod"), '', ''); print ''; print ''; -print ''; +print ''; print "\n"; // Browser method @@ -100,7 +100,7 @@ print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status").''.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status").'
'; print $langs->trans('Browser'); print ''; print $langs->trans('BrowserMethodDescription'); -print ''; +print ''; if ($conf->global->TAKEPOS_PRINT_METHOD == "browser") { print img_picto($langs->trans("Activated"), 'switch_on'); @@ -119,7 +119,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 1) { print $langs->trans('ReceiptPrinterMethodDescription'); print '
'; print ''.$langs->trans("Setup").''; - print '
'; + print ''; if ($conf->receiptprinter->enabled) { if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter") { @@ -142,7 +142,7 @@ print '
'; print "TakePOS Connector"; print ''; print $langs->trans('TakeposConnectorMethodDescription'); -print ''; +print ''; if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { print img_picto($langs->trans("Activated"), 'switch_on'); From d4e21538db87183a71d5d24ab6e94782837f48d1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Jul 2020 13:40:36 +0200 Subject: [PATCH 104/434] FIX Debug setup of receipt printer module --- htdocs/admin/receiptprinter.php | 132 ++++++++++-------- htdocs/core/class/dolreceiptprinter.class.php | 20 +++ htdocs/langs/en_US/admin.lang | 3 + 3 files changed, 100 insertions(+), 55 deletions(-) diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index 76aaa14d84c..5951aeaf2b2 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -65,13 +65,13 @@ if (!function_exists('gzdecode')) { } } + /* * Action */ if ($action == 'addprinter' && $user->admin) { $error = 0; - $db->begin(); if (empty($printername)) { $error++; setEventMessages($langs->trans("PrinterNameEmpty"), null, 'errors'); @@ -82,7 +82,8 @@ if ($action == 'addprinter' && $user->admin) { } if (!$error) { - $result = $printer->addPrinter($printername, GETPOST('printertypeid', 'int'), GETPOST('printerprofileid', 'int'), $parameter); + $db->begin(); + $result = $printer->addPrinter($printername, GETPOST('printertypeid', 'int'), GETPOST('printerprofileid', 'int'), $parameter); if ($result > 0) $error++; if (!$error) @@ -101,14 +102,14 @@ if ($action == 'addprinter' && $user->admin) { if ($action == 'deleteprinter' && $user->admin) { $error = 0; - $db->begin(); if (empty($printerid)) { $error++; setEventMessages($langs->trans("PrinterIdEmpty"), null, 'errors'); } if (!$error) { - $result = $printer->deletePrinter($printerid); + $db->begin(); + $result = $printer->deletePrinter($printerid); if ($result > 0) $error++; if (!$error) @@ -127,14 +128,14 @@ if ($action == 'deleteprinter' && $user->admin) { if ($action == 'updateprinter' && $user->admin) { $error = 0; - $db->begin(); if (empty($printerid)) { $error++; setEventMessages($langs->trans("PrinterIdEmpty"), null, 'errors'); } if (!$error) { - $result = $printer->updatePrinter($printername, GETPOST('printertypeid', 'int'), GETPOST('printerprofileid', 'int'), $parameter, $printerid); + $db->begin(); + $result = $printer->updatePrinter($printername, GETPOST('printertypeid', 'int'), GETPOST('printerprofileid', 'int'), $parameter, $printerid); if ($result > 0) $error++; if (!$error) { @@ -193,14 +194,14 @@ if ($action == 'testtemplate' && $user->admin) { if ($action == 'updatetemplate' && $user->admin) { $error = 0; - $db->begin(); if (empty($templateid)) { $error++; setEventMessages($langs->trans("TemplateIdEmpty"), null, 'errors'); } if (!$error) { - $result = $printer->updateTemplate($templatename, $template, $templateid); + $db->begin(); + $result = $printer->updateTemplate($templatename, $template, $templateid); if ($result > 0) $error++; if (!$error) { @@ -216,14 +217,14 @@ if ($action == 'updatetemplate' && $user->admin) { if ($action == 'addtemplate' && $user->admin) { $error = 0; - $db->begin(); if (empty($templatename)) { $error++; setEventMessages($langs->trans("TemplateNameEmpty"), null, 'errors'); } if (!$error) { - $result = $printer->addTemplate($templatename, $template); + $db->begin(); + $result = $printer->addTemplate($templatename, $template); if ($result > 0) $error++; if (!$error) { @@ -237,6 +238,29 @@ if ($action == 'addtemplate' && $user->admin) { $action = ''; } +if ($action == 'deletetemplate' && $user->admin) { + $error = 0; + if (empty($templateid)) { + $error++; + setEventMessages($langs->trans("TemplateIdEmpty"), null, 'errors'); + } + + if (!$error) { + $db->begin(); + $result = $printer->deleteTemplate($templateid); + if ($result > 0) $error++; + + if (!$error) { + $db->commit(); + setEventMessages($langs->trans("TemplateDeleted", $templatename), null); + } else { + $db->rollback(); + dol_print_error($db); + } + } + $action = ''; +} + /* * View @@ -251,6 +275,7 @@ print load_fiche_titre($langs->trans("ReceiptPrinterSetup"), $linkback, 'title_s $head = receiptprinteradmin_prepare_head($mode); +// mode = config if ($mode == 'config' && $user->admin) { print ''; print ''; @@ -263,7 +288,7 @@ if ($mode == 'config' && $user->admin) { dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), -1, 'technic'); - print $langs->trans("ReceiptPrinterDesc")."

\n"; + print ''.$langs->trans("ReceiptPrinterDesc")."

\n"; print ''."\n"; print ''; @@ -276,6 +301,22 @@ if ($mode == 'config' && $user->admin) { $ret = $printer->listprinters(); $nbofprinters = count($printer->listprinters); + if ($action != 'editprinter') { + print ''; + print ''; + $ret = $printer->selectTypePrinter(); + print ''; + $ret = $printer->selectProfilePrinter(); + print ''; + print ''; + print ''; + print ''; + } + if ($ret > 0) { setEventMessages($printer->error, $printer->errors, 'errors'); } else { @@ -289,7 +330,9 @@ if ($mode == 'config' && $user->admin) { $ret = $printer->selectProfilePrinter($printer->listprinters[$line]['fk_profile']); print ''; print ''; - print ''; + print ''; print ''; } else { print ''; @@ -297,15 +340,15 @@ if ($mode == 'config' && $user->admin) { print ''; print ''; // edit icon - print ''; print ''; @@ -313,38 +356,10 @@ if ($mode == 'config' && $user->admin) { } } - if ($action != 'editprinter') { - if ($nbofprinters > 0) { - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - } - - print ''; - print ''; - $ret = $printer->selectTypePrinter(); - print ''; - $ret = $printer->selectProfilePrinter(); - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - } print '
'.$printer->resprint.''.$printer->profileresprint.''; + if ($action != 'editprinter') { + print '
'; + } + print '
'.$printer->profileresprint.''; + print '
'; + print '
'.$printer->listprinters[$line]['name'].''.$langs->trans($printer->listprinters[$line]['fk_profile_name']).''.$printer->listprinters[$line]['parameter'].''; + print ''; print img_picto($langs->trans("Edit"), 'edit'); print ''; // delete icon - print ''; + print ''; print img_picto($langs->trans("Delete"), 'delete'); print ''; // test icon - print ''; + print ''; print img_picto($langs->trans("TestPrinter"), 'printer'); print '
'.$langs->trans("Name").''.$langs->trans("Type").''.$langs->trans("Profile").''.$langs->trans("Parameters").'
'.$printer->resprint.''.$printer->profileresprint.'
'; dol_fiche_end(); - if ($action != 'editprinter') { - print '
'; - } else { - print '
'; - } print ''; print '
'; @@ -374,6 +389,7 @@ if ($mode == 'config' && $user->admin) { print '
'; } +// mode = template if ($mode == 'template' && $user->admin) { print '
'; print ''; @@ -383,16 +399,13 @@ if ($mode == 'template' && $user->admin) { print ''; } - - print load_fiche_titre($langs->trans("ReceiptPrinterTemplateDesc"), '', '')."

\n"; + print load_fiche_titre($langs->trans("ReceiptPrinterTemplateDesc"), '', ''); print ''."\n"; print ''; print ''; print ''; print ''; - print ''; - print ''; print "\n"; $ret = $printer->listPrintersTemplates(); //print '
'.print_r($printer->listprinterstemplates, true).'
'; @@ -405,22 +418,23 @@ if ($mode == 'template' && $user->admin) { if ($action == 'edittemplate' && $printer->listprinterstemplates[$line]['rowid'] == $templateid) { print ''; print ''; - print ''; print ''; } else { print ''; print ''; // edit icon - print ''; } @@ -428,15 +442,23 @@ if ($mode == 'template' && $user->admin) { } } - print '
'.$langs->trans("Name").''.$langs->trans("Template").'
'; + print ''; + print ''; print ''.$printer->listprinterstemplates[$line]['name'].''.nl2br(htmlentities($printer->listprinterstemplates[$line]['template'])).''; + print ''; print img_picto($langs->trans("Edit"), 'edit'); print ''; // delete icon - print ''; + print ''; print img_picto($langs->trans("Delete"), 'delete'); print ''; // test icon - print ''; + print ''; print img_picto($langs->trans("TestPrinterTemplate"), 'printer'); print '
'; if ($action != 'edittemplate') { - print ''; + print ''; print ''; - print ''; + print ''; + print ''; print ''; print ''; + print ''; + } - print '
'; + print ''; + + if ($action != 'edittemplate') { + print ''; + print '
'; } else { print '
'; } diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 8d9c449b972..09dcc3681b7 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -468,6 +468,26 @@ class dolReceiptPrinter extends Printer return $error; } + /** + * Function to delete a printer template in db + * + * @param int $templateid Template ID + * @return int 0 if OK; >0 if KO + */ + public function deleteTemplate($templateid) + { + global $conf; + $error = 0; + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'printer_receipt_template'; + $sql .= " WHERE rowid = ".((int) $this->db->escape($templateid)); + $sql .= " AND entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = $this->db->lasterror; + } + return $error; + } /** * Function to Update a printer template in db diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 33590b17141..57d430fc9e4 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -2008,3 +2008,6 @@ RssNote=Note: Each RSS feed definition provides a widget that you must enable to JumpToBoxes=Jump to Setup -> Widgets MeasuringUnitTypeDesc=Use here a value like "size", "surface", "volume", "weight", "time" MeasuringScaleDesc=The scale is the number of places you have to move the decimal part to match the default reference unit. For "time" unit type, it is the number of seconds. Values between 80 and 99 are reserved values. +TemplateAdded=Template added +TemplateUpdated=Template updated +TemplateDeleted=Template deleted \ No newline at end of file From f80b54e573578022be5d1f8fd11598edf25494ad Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Jul 2020 13:44:55 +0200 Subject: [PATCH 105/434] Debug setup of receipt printer module --- htdocs/admin/receiptprinter.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index 5951aeaf2b2..7af626ef0bb 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -391,7 +391,10 @@ if ($mode == 'config' && $user->admin) { // mode = template if ($mode == 'template' && $user->admin) { - print ''; + + dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), -1, 'technic'); + + print ''; print ''; if ($action != 'edittemplate') { print ''; @@ -399,8 +402,6 @@ if ($mode == 'template' && $user->admin) { print ''; } - print load_fiche_titre($langs->trans("ReceiptPrinterTemplateDesc"), '', ''); - print ''."\n"; print ''; print ''; @@ -464,6 +465,8 @@ if ($mode == 'template' && $user->admin) { } print ''; + dol_fiche_end(); + print '
'; print '
'.$langs->trans("Name").'
'."\n"; From 0d71cd4279593e2e2c297d30109d88eb9173d815 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Jul 2020 13:51:49 +0200 Subject: [PATCH 106/434] Fix td not closed --- htdocs/takepos/admin/bar.php | 86 ++++++++++++++++++---------------- htdocs/takepos/public/menu.php | 4 +- 2 files changed, 48 insertions(+), 42 deletions(-) diff --git a/htdocs/takepos/admin/bar.php b/htdocs/takepos/admin/bar.php index 3d4bd490dde..5afa8dc060b 100644 --- a/htdocs/takepos/admin/bar.php +++ b/htdocs/takepos/admin/bar.php @@ -105,14 +105,16 @@ print "\n"; if ($conf->global->TAKEPOS_BAR_RESTAURANT && $conf->global->TAKEPOS_PRINT_METHOD != "browser") { print ''; + print ''; print ''; + print ''; @@ -120,14 +122,16 @@ if ($conf->global->TAKEPOS_BAR_RESTAURANT && $conf->global->TAKEPOS_PRINT_METHOD print ''; +print ''; print ''; +print ''; @@ -136,55 +140,30 @@ if ($conf->global->TAKEPOS_SUPPLEMENTS) { print ''; + print '\n"; } -print ''; - print ''; +print ''; +print ''; +print ''; + print '
'; print $langs->trans("OrderPrinters").' ('.$langs->trans("Setup").')'; - print ''; + print ''; print ajax_constantonoff("TAKEPOS_ORDER_PRINTERS", array(), $conf->entity, 0, 0, 1, 0); //print $form->selectyesno("TAKEPOS_ORDER_PRINTERS", $conf->global->TAKEPOS_ORDER_PRINTERS, 1); print '
'; print $langs->trans("OrderNotes"); - print ''; + print ''; print ajax_constantonoff("TAKEPOS_ORDER_NOTES", array(), $conf->entity, 0, 0, 1, 0); //print $form->selectyesno("TAKEPOS_ORDER_NOTES", $conf->global->TAKEPOS_ORDER_NOTES, 1); print '
'; print $langs->trans("BasicPhoneLayout"); -print ''; +print ''; //print $form->selectyesno("TAKEPOS_PHONE_BASIC_LAYOUT", $conf->global->TAKEPOS_PHONE_BASIC_LAYOUT, 1); print ajax_constantonoff("TAKEPOS_PHONE_BASIC_LAYOUT", array(), $conf->entity, 0, 0, 1, 0); print '
'; print $langs->trans("ProductSupplements"); -print ''; +print ''; //print $form->selectyesno("TAKEPOS_SUPPLEMENTS", $conf->global->TAKEPOS_SUPPLEMENTS, 1); print ajax_constantonoff("TAKEPOS_SUPPLEMENTS", array(), $conf->entity, 0, 0, 1, 0); print '
'; print $langs->trans("SupplementCategory"); - print ''; + print ''; print $form->select_all_categories(Categorie::TYPE_PRODUCT, $conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, 'TAKEPOS_SUPPLEMENTS_CATEGORY', 64, 0, 0); print ajax_combobox('TAKEPOS_SUPPLEMENTS_CATEGORY'); print "
'; -print 'QR - '.$langs->trans("AutoOrder"); -print ''; -print ajax_constantonoff("TAKEPOS_AUTO_ORDER", array(), $conf->entity, 0, 0, 1, 0); -print '
'; print 'QR - '.$langs->trans("CustomerMenu"); -print ''; +print ''; print ajax_constantonoff("TAKEPOS_QR_MENU", array(), $conf->entity, 0, 0, 1, 0); print '
'; +print 'QR - '.$langs->trans("AutoOrder"); +print ''; +print ajax_constantonoff("TAKEPOS_AUTO_ORDER", array(), $conf->entity, 0, 0, 1, 0); +print '
'; -if ($conf->global->TAKEPOS_AUTO_ORDER) -{ - print '
'; - print ''; - print ''; - print ''; - print "\n"; - - //global $dolibarr_main_url_root; - $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); - $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file - $sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables"; - $resql = $db->query($sql); - $rows = array(); - while ($row = $db->fetch_array($resql)) { - print ''; - } - - print '
'.$langs->trans("Table").''.$langs->trans("URL").''.$langs->trans("QR").'
'; - print $langs->trans("Table")." ".$row['label']; - print ''; - print "".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid']).""; - print ''; - print ""; - print '
'; -} - - if ($conf->global->TAKEPOS_QR_MENU) { $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); @@ -202,6 +181,33 @@ if ($conf->global->TAKEPOS_QR_MENU) print ''; } +if ($conf->global->TAKEPOS_AUTO_ORDER) +{ + print '
'; + print ''; + print ''; + print ''; + print "\n"; + + //global $dolibarr_main_url_root; + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + $sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables"; + $resql = $db->query($sql); + $rows = array(); + while ($row = $db->fetch_array($resql)) { + print ''; + } + + print '
'.$langs->trans("Table").''.$langs->trans("URL").''.$langs->trans("QR").'
'; + print $langs->trans("Table")." ".$row['label']; + print ''; + print "".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid']).""; + print ''; + print ""; + print '
'; +} + print '
'; print '
'; diff --git a/htdocs/takepos/public/menu.php b/htdocs/takepos/public/menu.php index c051ae4d673..217da157c2f 100644 --- a/htdocs/takepos/public/menu.php +++ b/htdocs/takepos/public/menu.php @@ -45,7 +45,7 @@ if (!$conf->global->TAKEPOS_QR_MENU) accessforbidden(); // If Restaurant Menu is
From 0b46fcb4f899df0a5d060a529601654c14e16535 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 31 Jul 2020 14:02:08 +0200 Subject: [PATCH 107/434] Debug --- htdocs/takepos/admin/bar.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/takepos/admin/bar.php b/htdocs/takepos/admin/bar.php index 5afa8dc060b..b6a06dee9fb 100644 --- a/htdocs/takepos/admin/bar.php +++ b/htdocs/takepos/admin/bar.php @@ -171,11 +171,12 @@ if ($conf->global->TAKEPOS_QR_MENU) print '
'; print ''; print ''; - print ''; + print ''; print "\n"; print ''; + print ''; print '
'.$langs->trans("URL").''.$langs->trans("QR").''.$langs->trans("URL").''.$langs->trans("QR").'
'; print "".$urlwithroot."/takepos/public/menu.php"; - print ''; + print ''; print ""; print '
'; @@ -186,7 +187,7 @@ if ($conf->global->TAKEPOS_AUTO_ORDER) print '
'; print ''; print ''; - print ''; + print ''; print "\n"; //global $dolibarr_main_url_root; @@ -198,9 +199,11 @@ if ($conf->global->TAKEPOS_AUTO_ORDER) while ($row = $db->fetch_array($resql)) { print ''; print ''; + print ''; } From 164e3bff2cb6943c81a2a682bb173f0dbd11dd82 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 31 Jul 2020 15:23:26 +0200 Subject: [PATCH 108/434] add formConfirm hook --- htdocs/product/card.php | 42 +++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 67e6e9e70f3..0327456615c 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -2082,35 +2082,45 @@ if ($result > 0) $tmpcode = ''; if (!empty($modCodeProduct->code_auto)) $tmpcode = $modCodeProduct->getNextValue($object, $object->type); -// Define confirmation messages -$formquestionclone = array( - 'text' => $langs->trans("ConfirmClone"), - array('type' => 'text', 'name' => 'clone_ref', 'label' => $langs->trans("NewRefForClone"), 'value' => empty($tmpcode) ? $langs->trans("CopyOf").' '.$object->ref : $tmpcode, 'size'=>24), - array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneContentProduct"), 'value' => 1), - array('type' => 'checkbox', 'name' => 'clone_categories', 'label' => $langs->trans("CloneCategoriesProduct"), 'value' => 1), -); -if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - $formquestionclone[] = array('type' => 'checkbox', 'name' => 'clone_prices', 'label' => $langs->trans("ClonePricesProduct").' ('.$langs->trans("CustomerPrices").')', 'value' => 0); -} -if (!empty($conf->global->PRODUIT_SOUSPRODUITS)) -{ - $formquestionclone[] = array('type' => 'checkbox', 'name' => 'clone_composition', 'label' => $langs->trans('CloneCompositionProduct'), 'value' => 1); -} +$formconfirm=''; // Confirm delete product if (($action == 'delete' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) // Output when action = clone if jmobile or no js || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) // Always output when not jmobile nor js { - print $form->formconfirm("card.php?id=".$object->id, $langs->trans("DeleteProduct"), $langs->trans("ConfirmDeleteProduct"), "confirm_delete", '', 0, "action-delete"); + $formconfirm = $form->formconfirm("card.php?id=".$object->id, $langs->trans("DeleteProduct"), $langs->trans("ConfirmDeleteProduct"), "confirm_delete", '', 0, "action-delete"); } // Clone confirmation if (($action == 'clone' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) // Output when action = clone if jmobile or no js || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) // Always output when not jmobile nor js { - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneProduct', $object->ref), 'confirm_clone', $formquestionclone, 'yes', 'action-clone', 350, 600); + // Define confirmation messages + $formquestionclone = array( + 'text' => $langs->trans("ConfirmClone"), + array('type' => 'text', 'name' => 'clone_ref', 'label' => $langs->trans("NewRefForClone"), 'value' => empty($tmpcode) ? $langs->trans("CopyOf").' '.$object->ref : $tmpcode, 'size'=>24), + array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneContentProduct"), 'value' => 1), + array('type' => 'checkbox', 'name' => 'clone_categories', 'label' => $langs->trans("CloneCategoriesProduct"), 'value' => 1), + ); + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $formquestionclone[] = array('type' => 'checkbox', 'name' => 'clone_prices', 'label' => $langs->trans("ClonePricesProduct").' ('.$langs->trans("CustomerPrices").')', 'value' => 0); + } + if (!empty($conf->global->PRODUIT_SOUSPRODUITS)) + { + $formquestionclone[] = array('type' => 'checkbox', 'name' => 'clone_composition', 'label' => $langs->trans('CloneCompositionProduct'), 'value' => 1); + } + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneProduct', $object->ref), 'confirm_clone', $formquestionclone, 'yes', 'action-clone', 350, 600); } +// Call Hook formConfirm +$parameters = array('formConfirm' => $formconfirm, 'object' => $object); +$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +if (empty($reshook)) $formconfirm .= $hookmanager->resPrint; +elseif ($reshook > 0) $formconfirm = $hookmanager->resPrint; + +// Print form confirm +print $formconfirm; /* ************************************************************************** */ /* */ From e44a1fd33f5a06f0056a247e2edf6e8cfe0ce412 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 31 Jul 2020 16:09:38 +0200 Subject: [PATCH 109/434] ->error rather than dol_print_error into product --- htdocs/adherents/subscription.php | 10 ++++++++-- htdocs/api/class/api_documents.class.php | 6 ++++-- htdocs/barcode/printsheet.php | 8 +++++--- htdocs/bom/class/bom.class.php | 6 +++++- htdocs/bom/tpl/linkedobjectblock.tpl.php | 11 +++++++++-- htdocs/product/class/product.class.php | 14 +++++++------- 6 files changed, 38 insertions(+), 17 deletions(-) diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 06b8cecf7f3..f2cb8c440c2 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -890,7 +890,10 @@ if ($rowid > 0) { if (empty($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) || $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS != 'defaultforfoundationcountry') print '. '.$langs->trans("NoVatOnSubscription", 0).''; if (!empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) && (!empty($conf->product->enabled) || !empty($conf->service->enabled))) { $prodtmp = new Product($db); - $prodtmp->fetch($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + $result = $prodtmp->fetch($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + if ($result < 0) { + setEventMessage($prodtmp->error, 'errors'); + } print '. '.$langs->transnoentitiesnoconv("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS", $prodtmp->getNomUrl(1)); // must use noentitiesnoconv to avoid to encode html into getNomUrl of product } print '
'; @@ -912,7 +915,10 @@ if ($rowid > 0) { if (empty($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) || $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS != 'defaultforfoundationcountry') print '. '.$langs->trans("NoVatOnSubscription", 0).''; if (!empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) && (!empty($conf->product->enabled) || !empty($conf->service->enabled))) { $prodtmp = new Product($db); - $prodtmp->fetch($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + $result = $prodtmp->fetch($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + if ($result < 0) { + setEventMessage($prodtmp->error, 'errors'); + } print '. '.$langs->transnoentitiesnoconv("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS", $prodtmp->getNomUrl(1)); // must use noentitiesnoconv to avoid to encode html into getNomUrl of product } print '
'; diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index ce734aadeb5..69fef80fd6b 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -419,8 +419,10 @@ class Documents extends DolibarrApi $object = new Product($this->db); $result = $object->fetch($id, $ref); - if (!$result) { + if ($result==0) { throw new RestException(404, 'Product not found'); + } elseif ($result<0) { + throw new RestException(500, 'Error while fetching object: '.$object->error); } $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 0, $object, 'product').dol_sanitizeFileName($object->ref); @@ -630,7 +632,7 @@ class Documents extends DolibarrApi } elseif ($result < 0) { - throw new RestException(500, 'Error while fetching object.'); + throw new RestException(500, 'Error while fetching object: '.$object->error); } } diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index f6dea256f6a..1ac908f361a 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -57,9 +57,11 @@ $thirdpartytmp = new Societe($db); if (GETPOST('submitproduct') && GETPOST('submitproduct')) { $action = ''; // We reset because we don't want to build doc - if (GETPOST('productid') > 0) - { - $producttmp->fetch(GETPOST('productid')); + if (GETPOST('productid') > 0) { + $result = $producttmp->fetch(GETPOST('productid')); + if ($result < 0) { + setEventMessage($producttmp->error, 'errors'); + } $forbarcode = $producttmp->barcode; $fk_barcode_type = $producttmp->barcode_type; diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 4a1c4e2f179..f6fe33aa932 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1004,7 +1004,11 @@ class BOM extends CommonObject foreach ($this->lines as &$line) { $tmpproduct = new Product($this->db); - $tmpproduct->fetch($line->fk_product); + $result= $tmpproduct->fetch($line->fk_product); + if ($result < 0) { + $this->error=$tmpproduct->error; + return -1; + } $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); if (empty($line->unit_cost)) { if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) diff --git a/htdocs/bom/tpl/linkedobjectblock.tpl.php b/htdocs/bom/tpl/linkedobjectblock.tpl.php index d6b8ebf9a7c..45340577228 100644 --- a/htdocs/bom/tpl/linkedobjectblock.tpl.php +++ b/htdocs/bom/tpl/linkedobjectblock.tpl.php @@ -52,8 +52,15 @@ foreach ($linkedObjectBlock as $key => $objectlink) } echo ''; echo '
'; - $product_static->fetch($objectlink->fk_product); - echo ''; + + echo ''; echo ''; echo ''; // Save price From 3bfd7644a43b1ad58b539c30d9b539159a5c462b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 1 Aug 2020 20:17:49 +0200 Subject: [PATCH 112/434] Fix return link --- htdocs/compta/prelevement/card.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index 23b6fdac500..ab8b5b8ae40 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -86,7 +86,11 @@ if (empty($reshook)) $res = $object->delete($user); if ($res > 0) { - header("Location: index.php"); + if ($object->type == 'bank-transfer') { + header("Location: ".DOL_URL_ROOT.'/compta/paymentbybanktransfer/index.php'); + } else { + header("Location: ".DOL_URL_ROOT.'/compta/prelevement/index.php'); + } exit; } } From d08c42a205b5b20e2c0823b14fef62390331e8da Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 00:15:21 +0200 Subject: [PATCH 113/434] CSS Better visibility for buttons and status --- htdocs/core/lib/functions.lib.php | 13 ++++++------- htdocs/theme/eldy/badges.inc.php | 12 ++++++++++++ htdocs/theme/eldy/btn.inc.php | 9 ++++++--- htdocs/theme/eldy/global.inc.php | 14 ++++++++------ htdocs/theme/eldy/theme_vars.inc.php | 6 +++--- 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1cf166c4d19..1d7f327af29 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8215,14 +8215,13 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st } // TODO : add a hook - if ($displayMode == 0) { - $return = !empty($html) ? $html : $statusLabel; + $return = !empty($html) ? $html : (empty($conf->dol_optimize_smallscreen) ? $statusLabel : (empty($statusLabelShort) ? $statusLabel : $statusLabelShort)); } elseif ($displayMode == 1) { - $return = !empty($html) ? $html : (!empty($statusLabelShort) ? $statusLabelShort : $statusLabel); + $return = !empty($html) ? $html : (empty($statusLabelShort) ? $statusLabel : $statusLabelShort); } // Use status with images (for backward compatibility) elseif (!empty($conf->global->MAIN_STATUS_USES_IMAGES)) { - $return = ''; + $return = ''; $htmlLabel = (in_array($displayMode, array(1, 2, 5)) ? '' : '').(!empty($html) ? $html : $statusLabel).(in_array($displayMode, array(1, 2, 5)) ? '' : ''); $htmlLabelShort = (in_array($displayMode, array(1, 2, 5)) ? '' : '').(!empty($html) ? $html : (!empty($statusLabelShort) ? $statusLabelShort : $statusLabel)).(in_array($displayMode, array(1, 2, 5)) ? '' : ''); @@ -8267,17 +8266,17 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st } } // Use new badge elseif (empty($conf->global->MAIN_STATUS_USES_IMAGES) && !empty($displayMode)) { - $statusLabelShort = !empty($statusLabelShort) ? $statusLabelShort : $statusLabel; + $statusLabelShort = (empty($statusLabelShort) ? $statusLabel : $statusLabelShort); $dolGetBadgeParams['attr']['class'] = 'badge-status'; $dolGetBadgeParams['attr']['title'] = $statusLabel; if ($displayMode == 3) { - $return = dolGetBadge($statusLabel, '', $statusType, 'dot', $url, $dolGetBadgeParams); + $return = dolGetBadge((empty($conf->dol_optimize_smallscreen) ? $statusLabel : (empty($statusLabelShort) ? $statusLabel : $statusLabelShort)), '', $statusType, 'dot', $url, $dolGetBadgeParams); } elseif ($displayMode === 5) { $return = dolGetBadge($statusLabelShort, $html, $statusType, '', $url, $dolGetBadgeParams); } else { - $return = dolGetBadge($statusLabel, $html, $statusType, '', $url, $dolGetBadgeParams); + $return = dolGetBadge((empty($conf->dol_optimize_smallscreen) ? $statusLabel : (empty($statusLabelShort) ? $statusLabel : $statusLabelShort)), $html, $statusType, '', $url, $dolGetBadgeParams); } } diff --git a/htdocs/theme/eldy/badges.inc.php b/htdocs/theme/eldy/badges.inc.php index d2a59447bb9..381f75fe2d0 100644 --- a/htdocs/theme/eldy/badges.inc.php +++ b/htdocs/theme/eldy/badges.inc.php @@ -24,6 +24,18 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); font-size: 0.95em; padding: .19em .35em; /* more than 0.19 generate a change into heigth of lines */ } +.tabBar .arearef .statusref .badge-status { + font-size: 1.1em; + padding: .4em .4em; +} +/* Force values for small screen 767 */ +@media only screen and (max-width: 767px) +{ + .tabBar .arearef .statusref .badge-status { + font-size: 0.95em; + padding: .3em .2em; + } +} .badge-pill, .tabs .badge { padding-right: .5em; diff --git a/htdocs/theme/eldy/btn.inc.php b/htdocs/theme/eldy/btn.inc.php index e78d82592bb..e1315ed62ee 100644 --- a/htdocs/theme/eldy/btn.inc.php +++ b/htdocs/theme/eldy/btn.inc.php @@ -9,8 +9,9 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> --btncolorborder: #FFF; --butactiondeletebg: rgb(234,228,225); /* tertiary color */ - --butactionbg:rgb(218, 235, 225); + /* --butactionbg:rgb(218, 235, 225); */ /* --butactionbg:rgb(228, 218, 235); */ + --butactionbg:rgb(118, 145, 225); } ; --colorboxiconbg: #eee; --refidnocolor:#444; @@ -186,6 +186,12 @@ input, select { } #mainbody input.button:not(.buttongen):not(.bordertransp) { background: var(--butactionbg); + color: #FFF !important; + + /* -webkit-box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); + box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); */ + + border-radius: 3px; border-collapse: collapse; border: none; } @@ -3245,11 +3251,7 @@ div.pagination li:first-child span { /*border-top-left-radius: 4px; border-bottom-left-radius: 4px;*/ } -div.pagination li:last-child a, -div.pagination li:last-child span { - /*border-top-right-radius: 4px; - border-bottom-right-radius: 4px;*/ -} + div.pagination li a:hover, div.pagination li:not(.paginationafterarrows,.title-button) span:hover, div.pagination li a:focus, diff --git a/htdocs/theme/eldy/theme_vars.inc.php b/htdocs/theme/eldy/theme_vars.inc.php index 3ce29206c0d..cd88654e309 100644 --- a/htdocs/theme/eldy/theme_vars.inc.php +++ b/htdocs/theme/eldy/theme_vars.inc.php @@ -65,7 +65,7 @@ $colorbacklinepairhover = '230,237,244'; // line hover $colorbacklinepairchecked = '230,237,244'; // line checked $colorbacklinebreak = '248,247,244'; // line break $colorbackbody = '255,255,255'; -$colortexttitlenotab = '0,123,140'; // 150,90,121 140,80,10 or 10,140,80 #875a7b green=0,123,140, violet: 0,50,120 +$colortexttitlenotab = '10,120,140'; // 150,90,121 140,80,10 or 10,140,80 #875a7b green=0,123,140, violet: 0,50,120 $colortexttitlenotab2 = '100,0,100'; // 150,90,121 140,80,10 or 10,140,80 #875a7b green=0,123,140, violet: 0,50,120 $colortexttitle = '0,0,0'; $colortexttitlelink = '10, 20, 100'; @@ -87,11 +87,11 @@ $colorblind_deuteranopes_textWarning = $textWarning; // currently not tested wit // Badges colors $badgePrimary = '#007bff'; -$badgeSecondary = '#cccccc'; +$badgeSecondary = '#aaaabb'; +$badgeInfo = '#aaaabb'; $badgeSuccess = '#55a580'; $badgeWarning = '#bc9526'; // See $textWarning bc9526 $badgeDanger = '#9f4705'; // See $textDanger -$badgeInfo = '#aaaabb'; $badgeDark = '#343a40'; $badgeLight = '#f8f9fa'; From 8aa968a27caeda5112c558464921420db36602a8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 00:41:26 +0200 Subject: [PATCH 114/434] NEW Can use THEME_DARKMODEENABLED=2 for a preview of theme in dark mode --- htdocs/main.inc.php | 11 ++++++----- htdocs/theme/eldy/btn.inc.php | 13 +++++++++---- htdocs/theme/eldy/global.inc.php | 16 ++++++++++------ htdocs/theme/eldy/style.css.php | 1 + 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1084c07f755..e9caccf436b 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -850,13 +850,13 @@ if (GETPOST('theme', 'alpha')) } // Set javascript option -if (!GETPOST('nojs', 'int')) // If javascript was not disabled on URL -{ - if (!empty($user->conf->MAIN_DISABLE_JAVASCRIPT)) - { +if (GETPOST('nojs', 'int')) { // If javascript was not disabled on URL + $conf->use_javascript_ajax = 0; +} else { + if (!empty($user->conf->MAIN_DISABLE_JAVASCRIPT)) { $conf->use_javascript_ajax = !$user->conf->MAIN_DISABLE_JAVASCRIPT; } -} else $conf->use_javascript_ajax = 0; +} // Set MAIN_OPTIMIZEFORTEXTBROWSER for user (must be after login part) if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && !empty($user->conf->MAIN_OPTIMIZEFORTEXTBROWSER)) { @@ -1233,6 +1233,7 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr if (GETPOSTISSET('dol_optimize_smallscreen')) { $themeparam .= '&dol_optimize_smallscreen='.GETPOST('dol_optimize_smallscreen', 'int'); } if (GETPOSTISSET('dol_no_mouse_hover')) { $themeparam .= '&dol_no_mouse_hover='.GETPOST('dol_no_mouse_hover', 'int'); } if (GETPOSTISSET('dol_use_jmobile')) { $themeparam .= '&dol_use_jmobile='.GETPOST('dol_use_jmobile', 'int'); $conf->dol_use_jmobile = GETPOST('dol_use_jmobile', 'int'); } + if (GETPOSTISSET('THEME_DARKMODEENABLED')) { $themeparam .= '&THEME_DARKMODEENABLED='.GETPOST('THEME_DARKMODEENABLED', 'int'); } if (GETPOSTISSET('THEME_SATURATE_RATIO')) { $themeparam .= '&THEME_SATURATE_RATIO='.GETPOST('THEME_SATURATE_RATIO', 'int'); } if (!defined('DISABLE_JQUERY') && !$disablejs && $conf->use_javascript_ajax) diff --git a/htdocs/theme/eldy/btn.inc.php b/htdocs/theme/eldy/btn.inc.php index e1315ed62ee..dc3245abc4c 100644 --- a/htdocs/theme/eldy/btn.inc.php +++ b/htdocs/theme/eldy/btn.inc.php @@ -15,9 +15,12 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> } global->MAIN_THEME_DARKMODEENABLED)) { +if (!empty($conf->global->THEME_DARKMODEENABLED)) { + print "/* For dark mode */\n"; + if ($conf->global->THEME_DARKMODEENABLED != 2) { + print "@media (prefers-color-scheme: dark) {"; + } print " - @media (prefers-color-scheme: dark) { :root { --btncolortext: ; @@ -27,8 +30,10 @@ if (!empty($conf->global->MAIN_THEME_DARKMODEENABLED)) { --butactionbg:rgb(173,140,79); --butactiondeletebg: rgb(252,84,91); - } - }"; + }\n"; + if ($conf->global->THEME_DARKMODEENABLED != 2) { + print "}"; + } } ?> diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index faca7b60451..576d1a2013a 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -45,10 +45,12 @@ } global->MAIN_THEME_DARKMODEENABLED)) { - print "@media (prefers-color-scheme: dark) { - :root { - +if (!empty($conf->global->THEME_DARKMODEENABLED)) { + print "/* For dark mode */\n"; + if ($conf->global->THEME_DARKMODEENABLED != 2) { + print "@media (prefers-color-scheme: dark) {"; + } + print ":root { --colorbackhmenu1: #1d1e20; --colorbackvmenu1: #2b2c2e; --colorbacktitle1: #2b2d2f; @@ -84,8 +86,10 @@ if (!empty($conf->global->MAIN_THEME_DARKMODEENABLED)) { --amountremaintopaycolor:rgb(252,84,91); --amountpaymentcomplete:rgb(101,184,77); --amountremaintopaybackcolor:rbg(245,130,46); - } - }"; + }\n"; + if ($conf->global->THEME_DARKMODEENABLED != 2) { + print "}\n"; + } } ?> diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 98f9e311274..b9f630872ae 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -66,6 +66,7 @@ else header('Cache-Control: no-cache'); if (GETPOST('theme', 'alpha')) $conf->theme = GETPOST('theme', 'alpha'); // If theme was forced on URL if (GETPOST('lang', 'aZ09')) $langs->setDefaultLang(GETPOST('lang', 'aZ09')); // If language was forced on URL +if (GETPOST('THEME_DARKMODEENABLED', 'int')) $conf->global->THEME_DARKMODEENABLED = GETPOST('THEME_DARKMODEENABLED', 'int'); // If darkmode was forced on URL $langs->load("main", 0, 1); $right = ($langs->trans("DIRECTION") == 'rtl' ? 'left' : 'right'); From 34cbdaf2ffa4dcb0eaba70c575d40531b3531ec8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 00:52:01 +0200 Subject: [PATCH 115/434] Look and feel v13 --- htdocs/ticket/agenda.php | 3 ++- htdocs/ticket/messaging.php | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/ticket/agenda.php b/htdocs/ticket/agenda.php index 3d1b89e6c65..13874eb7ecb 100644 --- a/htdocs/ticket/agenda.php +++ b/htdocs/ticket/agenda.php @@ -235,6 +235,8 @@ if (!empty($object->id)) $messagingUrl = DOL_URL_ROOT.'/ticket/messaging.php?track_id='.$object->track_id; $morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1); + $messagingUrl = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id; + $morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-list-alt imgforviewmode', $messagingUrl, '', 1, array('morecss'=>'btnTitleSelected')); // Show link to add a message (if read and not closed) $btnstatus = $object->fk_statut < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage"; @@ -246,7 +248,6 @@ if (!empty($object->id)) $url = dol_buildpath('/comm/action/card.php', 1).'?action=create&datep='.date('YmdHi').'&origin=ticket&originid='.$object->id.'&projectid='.$object->fk_project.'&backtopage='.urlencode($_SERVER["PHP_SELF"]); $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', $url, 'add-new-ticket-even-button', $btnstatus); - print_barre_liste($langs->trans("ActionsOnTicket"), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1); // List of all actions diff --git a/htdocs/ticket/messaging.php b/htdocs/ticket/messaging.php index b7d4c3d7b21..fc0bce96cb8 100644 --- a/htdocs/ticket/messaging.php +++ b/htdocs/ticket/messaging.php @@ -232,9 +232,12 @@ if (!empty($object->id)) $morehtmlright = ''; + $messagingUrl = DOL_URL_ROOT.'/ticket/messaging.php?track_id='.$object->track_id; + $morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1, array('morecss'=>'btnTitleSelected')); $messagingUrl = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id; $morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-list-alt imgforviewmode', $messagingUrl, '', 1); + // Show link to add a message (if read and not closed) $btnstatus = $object->fk_statut < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage"; $url = 'card.php?track_id='.$object->track_id.'&action=presend_addmessage&mode=init'; From 328a25abeaa74a43b5c5cbbd3161d1f1cce418db Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 00:59:53 +0200 Subject: [PATCH 116/434] FIX Bad back to link --- htdocs/bom/bom_agenda.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/bom/bom_agenda.php b/htdocs/bom/bom_agenda.php index a5b66b9886f..e2386dcee0b 100644 --- a/htdocs/bom/bom_agenda.php +++ b/htdocs/bom/bom_agenda.php @@ -132,7 +132,7 @@ if ($object->id > 0) // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
'; /* From 728460fa1b8ac4910b300a04fbccab6a488b5b41 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 01:01:40 +0200 Subject: [PATCH 117/434] Look and feel v13 --- htdocs/theme/eldy/badges.inc.php | 4 ++-- htdocs/theme/eldy/global.inc.php | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/badges.inc.php b/htdocs/theme/eldy/badges.inc.php index 381f75fe2d0..36296bb0b8a 100644 --- a/htdocs/theme/eldy/badges.inc.php +++ b/htdocs/theme/eldy/badges.inc.php @@ -24,14 +24,14 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); font-size: 0.95em; padding: .19em .35em; /* more than 0.19 generate a change into heigth of lines */ } -.tabBar .arearef .statusref .badge-status { +.tabBar .arearef .statusref .badge-status, .tabBar .arearefnobottom .statusref .badge-status { font-size: 1.1em; padding: .4em .4em; } /* Force values for small screen 767 */ @media only screen and (max-width: 767px) { - .tabBar .arearef .statusref .badge-status { + .tabBar .arearef .statusref .badge-status, .tabBar .arearefnobottom .statusref .badge-status { font-size: 0.95em; padding: .3em .2em; } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 576d1a2013a..96fb14ca49c 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1806,6 +1806,9 @@ img.photoref, div.photoref { width: 80px; object-fit: contain; } +div.photoref .fa, div.photoref .fas, div.photoref .far { + font-size: 2.5em; +} img.fitcontain { object-fit: contain; } From 817912ea40d1419859184e88a12ad3608ca05dfe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 01:11:23 +0200 Subject: [PATCH 118/434] FIX #14291 --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index a202004ed02..4dd4c7b3420 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -565,7 +565,7 @@ class Product extends CommonObject return -1; } - if (empty($this->ref)) { + if (empty($this->ref) || $this->ref == 'auto') { // Load object modCodeProduct $module = (!empty($conf->global->PRODUCT_CODEPRODUCT_ADDON) ? $conf->global->PRODUCT_CODEPRODUCT_ADDON : 'mod_codeproduct_leopard'); if ($module != 'mod_codeproduct_leopard') // Do not load module file for leopard From 9aa9852e85423c5bebde431d4d3c8429379d593b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 01:35:03 +0200 Subject: [PATCH 119/434] Fix perms --- htdocs/product/stock/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 47c3ac9d1b5..f5121ea0089 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -659,8 +659,8 @@ if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $n $urlsource .= str_replace('&', '&', $param); $filedir = $diroutputmassaction; - $genallowed = $user->rights->mymodule->read; - $delallowed = $user->rights->mymodule->create; + $genallowed = $user->rights->stock->read; + $delallowed = $user->rights->stock->create; print $formfile->showdocuments('massfilesarea_mymodule', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); } From 593c7242c4eda425bfbd856d94340aec5d783405 Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Sun, 2 Aug 2020 11:13:41 +0200 Subject: [PATCH 120/434] NEW: TakePOS Gift Receipt --- htdocs/langs/en_US/cashdesk.lang | 2 ++ htdocs/takepos/admin/setup.php | 7 +++++++ htdocs/takepos/invoice.php | 7 +++++-- htdocs/takepos/receipt.php | 22 ++++++++++++---------- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index c7d7dd95cb7..b755a388f5b 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -117,3 +117,5 @@ HideCategoryImages=Hide Category Images HideProductImages=Hide Product Images NumberOfLinesToShow=Number of lines of images to show DefineTablePlan=Define tables plan +GiftReceiptButton=Gift receipt button +GiftReceipt=Gift receipt diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php index 830e5d203d3..22355c70d9d 100644 --- a/htdocs/takepos/admin/setup.php +++ b/htdocs/takepos/admin/setup.php @@ -365,6 +365,13 @@ print '
\n"; +// Gift receipt +print '\n"; + // Numbering module //print ' - - + + @@ -140,8 +142,8 @@ if ($conf->global->TAKEPOS_SHOW_CUSTOMER) else echo $line->description; ?> - - + + global->TAKEPOS_SHOW_CUSTOMER)
'.$langs->trans("Table").''.$langs->trans("URL").''.$langs->trans("QR").''.$langs->trans("Table").''.$langs->trans("URL").''.$langs->trans("QR").'
'; print $langs->trans("Table")." ".$row['label']; + print ''; print "".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid']).""; - print ''; + print ''; print ""; print '
'.$objectlink->getNomUrl(1).''.$product_static->getNomUrl(1).''; + $result=$product_static->fetch($objectlink->fk_product); + if ($result<0) { + setEventMessage($product_static->error, 'errors'); + } elseif ($result>0) { + $product_static->getNomUrl(1); + } + print ''.dol_print_date($objectlink->date_creation, 'day').''; if ($user->rights->commande->lire) { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 07450eef805..33733a8901d 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2209,7 +2209,7 @@ class Product extends CommonObject } }*/ } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } @@ -2254,12 +2254,12 @@ class Product extends CommonObject } $this->prices_by_qty_list[0] = $resultat; } else { - dol_print_error($this->db); - return -1; + $this->error=$this->db->lasterror; + return -1; } } } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES) && empty($ignore_price_load)) // prices per customer and quantity @@ -2313,12 +2313,12 @@ class Product extends CommonObject } $this->prices_by_qty_list[$i] = $resultat; } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } @@ -2345,7 +2345,7 @@ class Product extends CommonObject return 0; } } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } From 5087d35f86d4430b0361420b8724a468a88881ee Mon Sep 17 00:00:00 2001 From: Marc DLL <68746600@users.noreply.github.com> Date: Fri, 31 Jul 2020 17:48:44 +0200 Subject: [PATCH 110/434] NEW: thirdparty REST API: endpoint to set price level --- .../societe/class/api_thirdparties.class.php | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 535d4e68967..1efe6287c66 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -490,6 +490,66 @@ class Thirdparties extends DolibarrApi } $this->company->oldcopy = clone $this->company; return $this->company->delete($id); + } + + /** + * Set new price level for the given thirdparty + * + * @param int $id ID of thirdparty + * @param int $priceLevel Price level to apply to thirdparty + * @return object Thirdparty data without useless information + * + * @url PUT {id}/setpricelevel + * + * @throws RestException 400 Price level out of bounds + * @throws RestException 401 Access not allowed for your login + * @throws RestException 404 Thirdparty not found + * @throws RestException 500 Error fetching/setting price level + * @throws RestException 501 Request needs modules "Thirdparties" and "Products" and setting Multiprices activated + */ + public function setThirdpartyPriceLevel($id, $priceLevel) + { + global $conf; + + if (empty($conf->societe->enabled)) { + throw new RestException(501, 'Module "Thirdparties" needed for this request'); + } + + if (empty($conf->product->enabled)) { + throw new RestException(501, 'Module "Products" needed for this request'); + } + + if (empty($conf->global->PRODUIT_MULTIPRICES)) { + throw new RestException(501, 'Multiprices features activation needed for this request'); + } + + if ($priceLevel < 1 || $priceLevel > $conf->global->PRODUIT_MULTIPRICES_LIMIT) { + throw new RestException(400, 'Price level must be between 1 and ' . $conf->global->PRODUIT_MULTIPRICES_LIMIT); + } + + if (empty(DolibarrApiAccess::$user->rights->societe->creer)) { + throw new RestException(401, 'Access to thirdparty ' . $id . ' not allowed for login '. DolibarrApiAccess::$user->login); + } + + $result = $this->company->fetch($id); + if ($result < 0) { + throw new RestException(404, 'Thirdparty ' . $id . ' not found'); + } + + if (empty($result)) { + throw new RestException(500, 'Error fetching thirdparty ' . $id, array_merge(array($this->company->error), $this->company->errors)); + } + + if (empty(DolibarrApi::_checkAccessToResource('societe', $this->company->id))) { + throw new RestException(401, 'Access to thirdparty ' . $id . ' not allowed for login ' . DolibarrApiAccess::$user->login); + } + + $result = $this->company->set_price_level($priceLevel, DolibarrApiAccess::$user); + if ($result <= 0) { + throw new RestException(500, 'Error setting new price level for thirdparty ' . $id, array($this->company->db->lasterror())); + } + + return $this->_cleanObjectDatas($this->company); } /** From 6d3cebfa3c6f80c18d1343876703ac315da092ac Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Fri, 31 Jul 2020 18:38:56 +0100 Subject: [PATCH 111/434] fix:erroneous input id name --- htdocs/fourn/commande/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 6f665a381df..0c0f084a230 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -971,7 +971,7 @@ if ($id > 0 || !empty($ref)) { // Discount print ''; - print ''; + print ''; print ''; print ajax_constantonoff("TAKEPOS_CONTROL_CASH_OPENING", array(), $conf->entity, 0, 0, 1, 0); print "
'; +print $langs->trans('GiftReceiptButton'); +print ''; +print ajax_constantonoff("TAKEPOS_GIFT_RECEIPT", array(), $conf->entity, 0, 0, 1, 0); +print "
'; //print $langs->trans("BillsNumberingModule"); diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index c6b7bb2c734..aee36f9ddfc 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -597,6 +597,9 @@ if ($action == "valid" || $action == "history") $sectionwithinvoicelink .= ' '; } else { $sectionwithinvoicelink .= ' '; + if ($conf->global->TAKEPOS_GIFT_RECEIPT) { + $sectionwithinvoicelink .= '
'; + } } if ($conf->global->TAKEPOS_EMAIL_TEMPLATE_INVOICE > 0) { @@ -700,8 +703,8 @@ function SendTicket(id) $.colorbox({href:"send.php?facid="+id, width:"70%", height:"30%", transition:"none", iframe:"true", title:"trans("SendTicket"); ?>"}); } -function Print(id){ - $.colorbox({href:"receipt.php?facid="+id, width:"40%", height:"90%", transition:"none", iframe:"true", title:"trans("PrintTicket"); ?>"}); } diff --git a/htdocs/takepos/receipt.php b/htdocs/takepos/receipt.php index 1da92de8827..99000c278de 100644 --- a/htdocs/takepos/receipt.php +++ b/htdocs/takepos/receipt.php @@ -34,6 +34,8 @@ $place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : 0); // $place is $facid = GETPOST('facid', 'int'); +$gift = GETPOST('gift', 'int'); + if (empty($user->rights->takepos->run)) { accessforbidden(); } @@ -125,8 +127,8 @@ if ($conf->global->TAKEPOS_SHOW_CUSTOMER)
trans("Label"); ?> trans("Qty"); ?>trans("Price"); ?>trans("TotalTTC"); ?>trans("Price"); ?>trans("TotalTTC"); ?>
qty; ?>total_ttc / $line->qty, 'MT'), 1); ?>total_ttc, 1); ?>total_ttc / $line->qty, 'MT'), 1); ?>total_ttc, 1); ?>
- - + + global->TAKEPOS_TICKET_VAT_GROUPPED) { $vat_groups = array(); @@ -166,18 +168,18 @@ if ($conf->global->TAKEPOS_SHOW_CUSTOMER) foreach ($vat_groups as $key => $val) { ?> - - + + - + - +
trans("TotalHT"); ?>total_ht, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>trans("TotalHT"); ?>total_ht, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>
trans("VAT").' '.vatrate($key, 1); ?>currency)."\n"; ?>trans("VAT").' '.vatrate($key, 1); ?>currency)."\n"; ?>
trans("TotalVAT").''.price($object->total_tva, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>trans("TotalVAT").''.price($object->total_tva, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>
trans("TotalTTC").''.price($object->total_ttc, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>trans("TotalTTC").''.price($object->total_ttc, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>
From 367914015c69f98bdf6ea3d9483158e753709f65 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 15:53:34 +0200 Subject: [PATCH 121/434] NEW Add a counter of number of words of pages in website module --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/theme/eldy/global.inc.php | 3 +++ htdocs/website/index.php | 12 ++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1d7f327af29..53ea0565ff6 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5465,7 +5465,7 @@ function picto_required() * @param integer $strip_tags 0=Use internal strip, 1=Use strip_tags() php function (bugged when text contains a < char that is not for a html tag) * @return string String cleaned * - * @see dol_escape_htmltag() strip_tags() dol_string_onlythesehtmltags() dol_string_neverthesehtmltags() + * @see dol_escape_htmltag() strip_tags() dol_string_onlythesehtmltags() dol_string_neverthesehtmltags(), dolStripPhpCode() */ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto = 'UTF-8', $strip_tags = 0) { diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 96fb14ca49c..cfa811b232f 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -199,6 +199,9 @@ input, select { border-collapse: collapse; border: none; } +#mainbody span.websitetools input.button:not(.buttongen):not(.bordertransp) { + color: #000 !important; +} #mainbody input.buttongen, #mainbody button.buttongen { padding: 3px 4px; } diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 1393f8254f3..c4f132ff030 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -3832,6 +3832,7 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print getTitleFieldOfList("Categories", 0, $_SERVER['PHP_SELF']); print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']); print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']); + print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']); print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; print ''; @@ -3891,6 +3892,17 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print $answerrecord->lang; print ''; + // Number of words + print ''; + $textwithouthtml = dol_string_nohtmltag(dolStripPhpCode($answerrecord->content)); + $characterMap = 'áàéèëíóúüñùç0123456789'; + $nbofwords = str_word_count($textwithouthtml, 0, $characterMap); + if ($nbofwords) { + print $nbofwords.' '.$langs->trans("words"); + } + print ''; + + // Edit properties, HTML sources, status print ''; $disabled = ''; From d685aec482a16fc0bb8a346e8004d3cf38e27e8e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 16:19:34 +0200 Subject: [PATCH 122/434] css --- htdocs/website/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index c4f132ff030..f5b32369d88 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -3893,7 +3893,7 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print ''; // Number of words - print ''; + print ''; $textwithouthtml = dol_string_nohtmltag(dolStripPhpCode($answerrecord->content)); $characterMap = 'áàéèëíóúüñùç0123456789'; $nbofwords = str_word_count($textwithouthtml, 0, $characterMap); From 723923252880cd50709098f957866674da652dbf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 16:28:59 +0200 Subject: [PATCH 123/434] Add total --- htdocs/website/index.php | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index f5b32369d88..539e7533af6 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -3839,6 +3839,8 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $c = new Categorie($db); + $totalnbwords = 0; + foreach ($listofpages['list'] as $answerrecord) { if (get_class($answerrecord) == 'WebsitePage') @@ -3899,6 +3901,7 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = $nbofwords = str_word_count($textwithouthtml, 0, $characterMap); if ($nbofwords) { print $nbofwords.' '.$langs->trans("words"); + $totalnbwords += $nbofwords; } print ''; @@ -3979,6 +3982,15 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print ''; print ''; + // Categories - Tags + print ''; + print ''; + + // Nb of words + print ''; + print ''; + + // Edit properties, HTML sources, status print ''; print ''; @@ -3989,6 +4001,44 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print ''; } } + + if (count($listofpages['list']) >= 2) { + // Total + print ''; + + // Type of container + print ''; + print $langs->trans("Total"); + print ''; + + // Container url and label + print ''; + print ''; + + // Language + print ''; + print ''; + + // Categories - Tags + print ''; + print ''; + + // Nb of words + print ''; + print $totalnbwords.' '.$langs->trans("words"); + print ''; + + // Edit properties, HTML sources, status + print ''; + print ''; + + // Action column + print ''; + print ''; + + print ''; + } + print ''; print '
'; print '
'; From 7149cbb532bf516ebeee4cfecdde7c56a205a61b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 17:09:21 +0200 Subject: [PATCH 124/434] NEW Add public note on products. This also partially fix the #14342 --- htdocs/core/class/commonobject.class.php | 8 +++++--- htdocs/core/tpl/notes.tpl.php | 19 ++++++++----------- htdocs/product/class/product.class.php | 7 ++++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 711707414a2..c15c074a351 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2847,12 +2847,14 @@ abstract class CommonObject dol_syslog(get_class($this)."::update_note Parameter suffix must be empty, '_private' or '_public'", LOG_ERR); return -2; } + + $newsuffix = $suffix; + // Special cas - //var_dump($this->table_element);exit; - if ($this->table_element == 'product') $suffix = ''; + if ($this->table_element == 'product' && $newsuffix == '_private') $newsuffix = ''; $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= " SET note".$suffix." = ".(!empty($note) ? ("'".$this->db->escape($note)."'") : "NULL"); + $sql .= " SET note".$newsuffix." = ".(!empty($note) ? ("'".$this->db->escape($note)."'") : "NULL"); $sql .= " ,".(in_array($this->table_element, array('actioncomm', 'adherent', 'advtargetemailing', 'cronjob', 'establishment')) ? "fk_user_mod" : "fk_user_modif")." = ".$user->id; $sql .= " WHERE rowid =".$this->id; diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index f387725bece..e646be4842a 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -87,17 +87,14 @@ else $typeofdata = 'textarea:12:95%'; print ''."\n"; print '
'."\n"; -if ($module != 'product') { - // No public note yet on products - print '
'."\n"; - print '
'."\n"; - print $form->editfieldkey("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, $moreparam, '', 0); - print '
'."\n"; - print '
'."\n"; - print $form->editfieldval("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, '', null, null, $moreparam, 1)."\n"; - print '
'."\n"; - print '
'."\n"; -} +print '
'."\n"; +print '
'."\n"; +print $form->editfieldkey("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, $moreparam, '', 0); +print '
'."\n"; +print '
'."\n"; +print $form->editfieldval("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, '', null, null, $moreparam, 1)."\n"; +print '
'."\n"; +print '
'."\n"; if (empty($user->socid)) { // Private notes (always hidden to external users) print '
'."\n"; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 28ca230a56b..055a0702cab 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2025,7 +2025,7 @@ class Product extends CommonObject return -1; } - $sql = "SELECT rowid, ref, ref_ext, label, description, url, note as note_private, customcode, fk_country, price, price_ttc,"; + $sql = "SELECT rowid, ref, ref_ext, label, description, url, note_public, note as note_private, customcode, fk_country, price, price_ttc,"; $sql .= " price_min, price_min_ttc, price_base_type, cost_price, default_vat_code, tva_tx, recuperableonly as tva_npr, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, tosell,"; $sql .= " tobuy, fk_product_type, duration, fk_default_warehouse, seuil_stock_alerte, canvas, net_measure, net_measure_units, weight, weight_units,"; $sql .= " length, length_units, width, width_units, height, height_units,"; @@ -2061,8 +2061,9 @@ class Product extends CommonObject $this->label = $obj->label; $this->description = $obj->description; $this->url = $obj->url; - $this->note_private = $obj->note_private; - $this->note = $obj->note_private; // deprecated + $this->note_public = $obj->note_public; + $this->note_private = $obj->note_private; + $this->note = $obj->note_private; // deprecated $this->type = $obj->fk_product_type; $this->status = $obj->tosell; From 04903460b186f8db7ef26e149f3235b45f124738 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 18:09:53 +0200 Subject: [PATCH 125/434] Add contact on job page --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/langs/en_US/recruitment.lang | 3 ++- htdocs/public/recruitment/view.php | 17 +++++++++++++++-- .../class/recruitmentjobposition.class.php | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0db2a6e48d3..57d05d263f4 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3012,7 +3012,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ '1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected', 'accountancy', 'address', 'bank_account', 'barcode', 'bank', 'bill', 'bookmark', 'bom', 'building', 'cash-register', 'category', 'check', 'clock', 'close_title', 'company', 'contact', 'contract', 'cubes', - 'delete', 'dolly', 'dollyrevert', 'edit', 'ellipsis-h', 'external-link-alt', 'external-link-square-alt', + 'delete', 'dolly', 'dollyrevert', 'edit', 'ellipsis-h', 'email', 'external-link-alt', 'external-link-square-alt', 'filter', 'file-code', 'file-export', 'file-import', 'file-upload', 'folder', 'folder-open', 'globe', 'globe-americas', 'grip', 'grip_title', 'help', 'intervention', 'label', 'language', 'list', 'listlight', 'lot', 'map-marker-alt', 'money-bill-alt', 'mrp', 'note', diff --git a/htdocs/langs/en_US/recruitment.lang b/htdocs/langs/en_US/recruitment.lang index 4e20a42fbb5..ad58f1d33be 100644 --- a/htdocs/langs/en_US/recruitment.lang +++ b/htdocs/langs/en_US/recruitment.lang @@ -51,4 +51,5 @@ ListOfPositionsToBeFilled=List of job offers to be filled NewPositionToBeFilled=New job offers to be filled JobOfferToBeFilled=Job offer to be filled -ThisIsInformationOnJobPosition=Information of the job position to be filled \ No newline at end of file +ThisIsInformationOnJobPosition=Information of the job position to be filled +ContactForRecruitment=Contact for recruitment \ No newline at end of file diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index e34908dd0a7..88e6a36f582 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -250,12 +250,10 @@ $found = true; print '
'; // Label - print $langs->trans("Label").' : '; print ''.$object->label.'
'; // Date - print $langs->trans("DateExpected").' : '; print ''; if ($object->date_planned > $now) { @@ -265,6 +263,21 @@ if ($object->date_planned > $now) { } print '
'; +// Contact +print $langs->trans("ContactForRecruitment").' : '; +$tmpuser = new User($db); +$tmpuser->fetch($object->fk_user_recruiter); +print ''; +print $tmpuser->getFullName(-1); +$emailforcontact = $tmpuser->email; +if (empty($emailforcontact)) { + $emailforcontact = $mysoc->email; +} +print ' - '.img_picto('', 'email', 'class="paddingrightonly"').dol_print_email($emailforcontact); +print ''; +print '

'; + + print '
'; // Description diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 6d38f47211c..4029833afd0 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -99,7 +99,7 @@ class RecruitmentJobPosition extends CommonObject 'label' => array('type'=>'varchar(255)', 'label'=>'JobLabel', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth500', 'showoncombobox'=>'1', 'autofocusoncreate'=>1), 'qty' => array('type'=>'integer', 'label'=>'NbOfEmployeesExpected', 'enabled'=>'1', 'position'=>45, 'notnull'=>1, 'visible'=>1, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp',), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'1', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), - 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid',), + 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>-1, 'foreignkey'=>'user.rowid',), 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid',), 'fk_establishment' => array('type'=>'integer:Establishment:hrm/class/establishment.class.php', 'label'=>'Establishment', 'enabled'=>'$conf->hrm->enabled', 'position'=>56, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'establishment.rowid',), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'WorkPlace', 'enabled'=>'1', 'position'=>57, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'help'=>"IfJobIsLocatedAtAPartner",), From d054aedc80dc91c35ff616b35d44a83b1b9a2bca Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 18:32:54 +0200 Subject: [PATCH 126/434] Sync language --- htdocs/langs/fr_FR/admin.lang | 13 ++++--- htdocs/langs/fr_FR/agenda.lang | 8 ++--- htdocs/langs/fr_FR/cashdesk.lang | 2 +- htdocs/langs/fr_FR/compta.lang | 1 + htdocs/langs/fr_FR/contracts.lang | 4 +-- htdocs/langs/fr_FR/errors.lang | 3 +- htdocs/langs/fr_FR/languages.lang | 16 ++++++++- htdocs/langs/fr_FR/main.lang | 5 +++ htdocs/langs/fr_FR/other.lang | 2 ++ htdocs/langs/fr_FR/products.lang | 2 ++ htdocs/langs/fr_FR/projects.lang | 1 + htdocs/langs/fr_FR/recruitment.lang | 54 +++++++++++++++++++++++++++++ htdocs/langs/fr_FR/stocks.lang | 8 +++-- htdocs/langs/fr_FR/suppliers.lang | 4 +-- htdocs/langs/fr_FR/users.lang | 1 + htdocs/langs/fr_FR/withdrawals.lang | 12 ++++--- 16 files changed, 112 insertions(+), 24 deletions(-) create mode 100644 htdocs/langs/fr_FR/recruitment.lang diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index c4025fb1577..363dff21b08 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -300,8 +300,9 @@ MAIN_MAIL_DEFAULT_FROMTYPE=Expéditeur par défaut des e-mails pour les envois m UserEmail=Email utilisateur CompanyEmail=Email organization FeatureNotAvailableOnLinux=Fonctionnalité non disponible sous systèmes Unix. Tester votre sendmail localement. +FixOnTransifex=Corriger la traduction sur la plate-forme en ligne de traduction du projet SubmitTranslation=Si la traduction de cette langue est incomplète ou si vous trouvez des erreurs, vous pouvez corriger cela en éditant les fichiers dans le répertoire langs/%s et soumettre vos changements sur www.transifex.com/dolibarr-association/dolibarr/ -SubmitTranslationENUS=Si la traduction pour cette langue est incomplète ou si vous trouvez des erreurs, vous pouvez les corriger en éditant les fichiers dans le répertoire langs/%s et soumettre les modifications sur le forum dolibarr.org/forum ou pour les développeurs sur github.com/Dolibarr/dolibarr. +SubmitTranslationENUS=Si la traduction pour cette langue est incomplète ou si vous trouvez des erreurs, vous pouvez les corriger en éditant les fichiers dans le dossier langs/%s et soumettre les fichiers modifiés sur le forum dolibarr.org/forum ou, pour les développeurs, via une PR sur github.com/Dolibarr/dolibarr ModuleSetup=Configuration du module ModulesSetup=Configuration Modules/Application ModuleFamilyBase=Système @@ -387,7 +388,7 @@ SecurityToken=Clé de sécurisation des URLs NoSmsEngine=Aucun gestionnaire d'envoi de SMS n'est disponible. Les gestionnaires d'envois SMS ne sont pas installés en standard, car dépendent d'un fournisseur externe, mais vous pourrez en trouver depuis la plateforme %s PDF=PDF PDFDesc=Options globales sur la génération des PDF -PDFAddressForging=Règles de fabrication des zones adresses +PDFAddressForging=Règles pour le contenu des sections Adresse HideAnyVATInformationOnPDF=Masquer toutes les informations relatives à la Taxe de vente / TVA sur les PDF générés PDFRulesForSalesTax=Règles pour la taxe de vente / TVA PDFLocaltax=Règles pour %s @@ -1240,6 +1241,7 @@ WarningAtLeastKeyOrTranslationRequired=Un critère de recherche est nécessaire NewTranslationStringToShow=Nouvelle traduction à afficher OriginalValueWas=La traduction d'origine est écrasée. La valeur initiale était:

%s TransKeyWithoutOriginalValue=Vous avez forcé une nouvelle traduction pour la clé de traduction '%s' qui n'existe dans aucun fichier de langue +TitleNumberOfActivatedModules=Modules activés TotalNumberOfActivatedModules=Modules activés : %s / %s YouMustEnableOneModule=Vous devez activer au moins une fonctionnalité ClassNotFoundIntoPathWarning=La classe %s n'a pas été trouvée dans le chemin PHP @@ -1686,8 +1688,8 @@ AGENDA_SHOW_LINKED_OBJECT=Afficher l'objet lié dans la vue agenda ##### Clicktodial ##### ClickToDialSetup=Configuration du module Click To Dial ClickToDialUrlDesc=URL appelée quand un clic sur l'icône téléphone est fait. Dans l'URL, vous pouvez utiliser les tags
__PHONETO__ qui sera remplacée par le numéro de téléphone de la personne à appeler
__PHONEFROM__ qui sera remplacée par le numéro de l'appelant (vous)
__LOGIN__ qui sera remplacée par l'identifiant d'accès de l'utilisateur à l'application d'appel (à définir sur la fiche utilisateur) et
__PASS__ qui sera remplacée par le mot de passe d'accès de l'utilisateur à l'application d'appel (également à définir sur la fiche utilisateur). -ClickToDialDesc=Ce module permet de rendre les numéros de téléphone cliquables. Un clic sur cette icône appellera votre téléphone à composer le numéro de téléphone. Cela peut être utilisé pour appeler un système de centre d'appels de Dolibarr qui peut appeler le numéro de téléphone d'un système SIP, par exemple. -ClickToDialUseTelLink=Utiliser un lien «Tel.» sur les numéros de téléphone +ClickToDialDesc=Ce module permet de rendre les numéros de téléphone cliquables lorsque vous utilisez l'application sur un ordinateur de bureau. Un clic sur cette icône composera le numéro de téléphone. Cela peut être utilisé pour commencer une conversation avec un soft phone sur votre bureau ou lorsque vous utilisez un système basé sur le protocole SIP par exemple. Note: Sur un smartphone, les numéros de téléphones sont toujours clicables. +ClickToDialUseTelLink=Utiliser un lien "tel:" sur les numéros de téléphone ClickToDialUseTelLinkDesc=Utilisez cette méthode si vos utilisateurs ont un softphone ou une interface de logiciel installé sur un même ordinateur que le navigateur, et a appelé lorsque vous cliquez sur un lien dans votre navigateur qui commencent par "tel:". Si vous avez besoin d'une solution de serveur complet (pas besoin d'installation locale du logiciel), vous devez définir ceci à "Non" et remplir le champ suivant. ##### Point Of Sale (CashDesk) ##### CashDesk=Point de Vente @@ -1881,7 +1883,7 @@ UrlToGetKeyToUseAPIs=Url pour obtenir le jeton pour utiliser l'API (une fois le ListOfAvailableAPIs=Liste des APIs disponibles activateModuleDependNotSatisfied=Le module "%s" dépend du module "%s" qui est manquant, aussi le module "%1$s" peut ne pas fonctionner correctement. Merci d'installer le module "%2$s" ou désactiver le module "%1$s" si vous ne souhaitez pas avoir de mauvaise surprise CommandIsNotInsideAllowedCommands=La commande que vous essayez d'exécuter ne figure pas dans la liste des commandes autorisées définies dans le paramètre $dolibarr_main_restrict_os_commands du fichier conf.php . -LandingPage=Page cible +LandingPage=Page d'accueil SamePriceAlsoForSharedCompanies=Si vous utilisez un module multi-société, avec le choix «prix unique», le prix sera aussi le même pour toutes les sociétés si les produits sont partagés entre les environnements ModuleEnabledAdminMustCheckRights=Le module a été activé. Les permissions pour le(s) module(s) activé(s) ont été donnés aux utilisateurs admin uniquement. Vous devrez peut-être accorder des autorisations aux autres utilisateurs ou groupes manuellement si nécessaire. UserHasNoPermissions=Cet utilisateur n'a pas de permission définie @@ -1894,6 +1896,7 @@ MAIN_PDF_MARGIN_LEFT=Marge gauche sur les PDF MAIN_PDF_MARGIN_RIGHT=Marge droite sur les PDF MAIN_PDF_MARGIN_TOP=Marge haute sur les PDF MAIN_PDF_MARGIN_BOTTOM=Marge bas sur les PDF +MAIN_DOCUMENTS_LOGO_HEIGHT=Hauteur du logo sur les PDFs NothingToSetup=Aucune configuration particulière n'est requise pour ce module. SetToYesIfGroupIsComputationOfOtherGroups=Réglez ceci sur Oui si ce groupe est un calcul d'autres groupes EnterCalculationRuleIfPreviousFieldIsYes=Entrez la règle de calcul si le champ précédent a été défini sur Oui (par exemple, 'CODEGRP1 + CODEGRP2') diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 2e0ac6e5ed1..6da45f7976d 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -14,7 +14,7 @@ EventsNb=Nombre d'événements ListOfActions=Liste des événements EventReports=Rapport des évènements Location=Lieu -ToUserOfGroup=à tout utilisateur du groupe +ToUserOfGroup=Assigné à tout utilisateur du groupe EventOnFullDay=Événement sur la(les) journée(s) MenuToDoActions=Événements incomplets MenuDoneActions=Événements terminés @@ -121,10 +121,10 @@ MRP_MO_CANCELInDolibarr=OF annulé AgendaModelModule=Modèle de document pour les événements DateActionStart=Date de début DateActionEnd=Date de fin -AgendaUrlOptions1=Vous pouvez aussi ajouter les paramètres suivants pour filtrer les réponses : +AgendaUrlOptions1=Vous pouvez aussi ajouter les paramètres suivants pour filtrer les réponses : AgendaUrlOptions3=logina=%s pour limiter l'export aux actions dont l'utilisateur %s est propriétaire. -AgendaUrlOptionsNotAdmin=logina=!%s pour limiter l'export aux actions non assignées à l'utilisateur %s. -AgendaUrlOptions4=logint=%s pour limiter l'export aux actions assignées à l'utilisateur %s (propriétaire et autres). +AgendaUrlOptionsNotAdmin=logina=!%s pour limiter l'export aux actions n'appartenant pas à l'utilisateur %s. +AgendaUrlOptions4=logint=%spour limiter l'export aux actions assignées à l'utilisateur %s (propriétaire et autres). AgendaUrlOptionsProject=project=__PROJECT_ID__ pour restreindre aux événements associés au projet __PROJECT_ID__. AgendaUrlOptionsNotAutoEvent=notactiontype=systemauto pour exclure les événements automatiques. AgendaUrlOptionsIncludeHolidays=includeholidays=1 pour inclure les événements de type congé. diff --git a/htdocs/langs/fr_FR/cashdesk.lang b/htdocs/langs/fr_FR/cashdesk.lang index 8ed5994e3f3..2ab64973e1a 100644 --- a/htdocs/langs/fr_FR/cashdesk.lang +++ b/htdocs/langs/fr_FR/cashdesk.lang @@ -115,5 +115,5 @@ ScanToOrder=Scannez le code QR pour commander Appearance=Apparence HideCategoryImages=Masquer les images de catégorie HideProductImages=Masquer les images de produits -NumberOfLinesToShow=Nombre de lignes d'image à afficher +NumberOfLinesToShow=Nombre de lignes d'images à afficher DefineTablePlan=Définir le plan des tables diff --git a/htdocs/langs/fr_FR/compta.lang b/htdocs/langs/fr_FR/compta.lang index 6245901d321..bc79d32d709 100644 --- a/htdocs/langs/fr_FR/compta.lang +++ b/htdocs/langs/fr_FR/compta.lang @@ -69,6 +69,7 @@ SocialContribution=Charge sociale ou fiscale SocialContributions=Charges fiscales ou sociales SocialContributionsDeductibles=Charge ou taxe déductible SocialContributionsNondeductibles=Charge ou taxe non déductible +DateOfSocialContribution=Date de la charge fiscale ou sociale LabelContrib=Libellé de la dépense TypeContrib=Type de la charge MenuSpecialExpenses=Dépenses spéciales diff --git a/htdocs/langs/fr_FR/contracts.lang b/htdocs/langs/fr_FR/contracts.lang index f2910a8e76e..1d6a99378d3 100644 --- a/htdocs/langs/fr_FR/contracts.lang +++ b/htdocs/langs/fr_FR/contracts.lang @@ -99,6 +99,6 @@ TypeContact_contrat_internal_SALESREPFOLL=Commercial suivi du contrat TypeContact_contrat_external_BILLING=Contact client facturation contrat TypeContact_contrat_external_CUSTOMER=Contact client suivi contrat TypeContact_contrat_external_SALESREPSIGN=Contact client signataire contrat -HideClosedServiceByDefault=Cacher les services fermés sur les contrats par défaut +HideClosedServiceByDefault=Masquer les services fermés par défaut ShowClosedServices=Afficher les services fermés -HideClosedServices=Cacher les services fermés +HideClosedServices=Masquer les services fermés diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index 5bfcd36ce0b..4080466f427 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -136,7 +136,8 @@ ErrorNewValueCantMatchOldValue=La nouvelle valeur ne peut être égale à l'anci ErrorFailedToValidatePasswordReset=Echec de la réinitialisation du mot de passe. Il est possible que ce lien ait déjà été utilisé (l'utilisation de ce lien ne fonctionne qu'une fois). Si ce n'est pas le cas, essayez de recommencer le processus de réinitialisation de mot de passe depuis le début. ErrorToConnectToMysqlCheckInstance=Echec de la connection au serveur de base de données. Vérifier que votre serveur est bien lancé (par exemple, avec MySQL/MariaDB, vous pouvez le lancer depuis la ligne de commande avec 'sudo service mysql start'). ErrorFailedToAddContact=Echec à l'ajout du contact -ErrorDateMustBeBeforeToday=La date ne peut pas être supérieure à aujourd'hui +ErrorDateMustBeBeforeToday=La date doit être inférieure à la date courante +ErrorDateMustBeInFuture=La date doit être postérieure à la date courante ErrorPaymentModeDefinedToWithoutSetup=Un mode de paiement a été défini de type %s mais la configuration du module Facture n'a pas été complétée pour définir les informations affichées pour ce mode de paiement. ErrorPHPNeedModule=Erreur, votre PHP doit avoir le module %s installé pour utiliser cette fonctionnalité. ErrorOpenIDSetupNotComplete=Vous avez configuré Dolibarr pour accepter l'authentication OpenID, mais l'URL du service OpenID n'est pas défini dans la constante %s diff --git a/htdocs/langs/fr_FR/languages.lang b/htdocs/langs/fr_FR/languages.lang index 9da1ef41151..9a980afffe8 100644 --- a/htdocs/langs/fr_FR/languages.lang +++ b/htdocs/langs/fr_FR/languages.lang @@ -1,8 +1,11 @@ # Dolibarr language file - Source file is en_US - languages +Language_am_ET=Ethiopien Language_ar_AR=Arabe Language_ar_EG=Arabe (Egypte) Language_ar_SA=Arabe +Language_az_AZ=Azerbaïdjanais Language_bn_BD=Bengalais +Language_bn_IN=Bengali (Inde) Language_bg_BG=Bulgare Language_bs_BA=Bosniaque Language_ca_ES=Catalan @@ -20,6 +23,7 @@ Language_en_GB=Anglais (Royaume-Uni) Language_en_IN=Anglais (Inde) Language_en_NZ=Anglais (Nouvelle Zeland) Language_en_SA=Anglais (Arabie Saoudite) +Language_en_SG=Anglais (Singapour) Language_en_US=Anglais (Etats-Unis) Language_en_ZA=Anglais (Afrique du Sud) Language_es_ES=Espagnol @@ -29,6 +33,7 @@ Language_es_CL=Espagnol (Chili) Language_es_CO=Espagnol (Colombie) Language_es_DO=Espagnol (République dominicaine) Language_es_EC=Espagnol (Équateur) +Language_es_GT=Espagnol (Guatemala) Language_es_HN=Espagnol (Honduras) Language_es_MX=Espagnol (Mexique) Language_es_PA=Espagnol (Panama) @@ -36,6 +41,7 @@ Language_es_PY=Espagnol (Paraguay) Language_es_PE=Espagnol (Peru) Language_es_PR=Espagnol (Puerto Rico) Language_es_UY=Espagnol (Uruguay) +Language_es_GT=Espagnol (Guatemala) Language_es_VE=Espagnol (Venezuela) Language_et_EE=Estonien Language_eu_ES=Basque @@ -44,15 +50,21 @@ Language_fi_FI=Finlandais Language_fr_BE=Français (Belgique) Language_fr_CA=Français (Canada) Language_fr_CH=Français (Suisse) +Language_fr_CI=Français (Cote d'Ivoire) +Language_fr_CM=Français (Cameroun) Language_fr_FR=Français +Language_fr_GA=Français (Gabon) Language_fr_NC=Français (Nouvelle Calédonie) Language_fy_NL=Frisian +Language_gl_ES=Galicien Language_he_IL=Hébreux +Language_hi_IN=Hindi (Inde) Language_hr_HR=Croate Language_hu_HU=Hongrois Language_id_ID=Indonésien Language_is_IS=Islandais Language_it_IT=Italien +Language_it_CH=Italien (Suisse) Language_ja_JP=Japonais Language_ka_GE=Géorgien Language_km_KH=Khmer @@ -64,8 +76,9 @@ Language_lv_LV=Léton Language_mk_MK=Macédonien Language_mn_MN=Mongol Language_nb_NO=Norvégien (Bokmal) +Language_ne_NP=Népalais Language_nl_BE=Néerlandais (Belgique) -Language_nl_NL=Dutch +Language_nl_NL=Néerlandais Language_pl_PL=Polonais Language_pt_BR=Portugais (Brésil) Language_pt_PT=Portugais @@ -86,4 +99,5 @@ Language_uz_UZ=Ouzbek Language_vi_VN=Vietnamien Language_zh_CN=Chinois Language_zh_TW=Chinois (Traditionel) +Language_zh_HK=Chinois (Hong-Kong) Language_bh_MY=Malais diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index 670a486345c..bea3097d2ff 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -485,6 +485,7 @@ Categories=Tags/catégories Category=Tag/catégorie By=Par From=Du +FromDate=A partir du FromLocation=A partir du to=au To=au @@ -703,6 +704,7 @@ MenuECM=Documents MenuAWStats=AWStats MenuMembers=Adhérents MenuAgendaGoogle=Agenda Google +MenuTaxesAndSpecialExpenses=Charges | Dépenses spéciales ThisLimitIsDefinedInSetup=Limite Dolibarr (Menu accueil-configuration-sécurité): %s Ko, Limite PHP: %s Ko NoFileFound=Pas de documents stockés dans cette rubrique CurrentUserLanguage=Langue utilisateur actuelle @@ -1039,3 +1041,6 @@ SwitchInEditModeToAddTranslation=Passer en mode édition pour ajouter des traduc NotUsedForThisCustomer=Non utilisé pour ce client AmountMustBePositive=Le montant doit être positif. ByStatus=Par statut +InformationMessage=Information +ASAP=Dès que possible + diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang index 09c378008f3..bd75f6c9035 100644 --- a/htdocs/langs/fr_FR/other.lang +++ b/htdocs/langs/fr_FR/other.lang @@ -280,7 +280,9 @@ LinesToImport=Lignes à importer MemoryUsage=Utilisation de la mémoire RequestDuration=Durée de la demande +ProductsPerPopularity=Produits / services par popularité PopuProp=Produits / services par popularité dans les propositions PopuCom=Produits/services par popularité dans les commandes ProductStatistics=Statistiques sur les produits / services NbOfQtyInOrders=Qté en commandes +SelectTheTypeOfObjectToAnalyze=Sélectionnez le type d'objet à analyser ... diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 8366e029c2f..09c470552e5 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -169,6 +169,8 @@ SuppliersPricesOfProductsOrServices=Prix fournisseurs (des produits ou services) CustomCode=Nomenclature douanière / Code SH CountryOrigin=Pays d'origine Nature=Nature du produit (matière première / produit fini) +NatureOfProductShort=Nature de produit +NatureOfProductDesc=Matière première ou produit fini ShortLabel=Libellé court Unit=Unité p=u. diff --git a/htdocs/langs/fr_FR/projects.lang b/htdocs/langs/fr_FR/projects.lang index c521a0a965a..fda884c6203 100644 --- a/htdocs/langs/fr_FR/projects.lang +++ b/htdocs/langs/fr_FR/projects.lang @@ -178,6 +178,7 @@ TypeContact_project_task_internal_TASKCONTRIBUTOR=Contributeur TypeContact_project_task_external_TASKCONTRIBUTOR=Contributeur SelectElement=Séléctionnez l'élément AddElement=Associer l'élément +LinkToElementShort=Lier à # Documents models DocumentModelBeluga=Modèle de document project pour l'aperçu des objets liées DocumentModelBaleine=Modèles de document de rapport de tâches de projets diff --git a/htdocs/langs/fr_FR/recruitment.lang b/htdocs/langs/fr_FR/recruitment.lang new file mode 100644 index 00000000000..d95d76cd421 --- /dev/null +++ b/htdocs/langs/fr_FR/recruitment.lang @@ -0,0 +1,54 @@ +# Copyright (C) 2020 Laurent Destailleur +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# +# Generic +# + +# Module label 'ModuleRecruitmentName' +ModuleRecruitmentName = Recrutement +# Module description 'ModuleRecruitmentDesc' +ModuleRecruitmentDesc = Gestion et suivi des campagnes de recrutement + +# +# Admin page +# +RecruitmentSetup = Paramétrages du recrutement +Settings = Paramétrages +RecruitmentSetupPage = Entrez ici la configuration des principales options du module de recrutement +RecruitmentArea=Espace recrutement +PublicInterfaceRecruitmentDesc=L'interface publique est une URL publique pour afficher et répondre aux postes en cours de recrutement. Il existe un lien différent pour chaque poste. +EnablePublicRecruitmentPages=Activer les pages de recrutement publiques + +# +# About page +# +About = À propos +RecruitmentAbout = À propos du module Recrutement +RecruitmentAboutPage = À propos du module Recrutement +NbOfEmployeesExpected=Nombre de postes disponibles +JobLabel=Intitulé du poste +WorkPlace=Poste de travail +DateExpected=Date souhaitée +FutureManager=Responsable futur +ResponsibleOfRecruitement=Responsable du recrutement +IfJobIsLocatedAtAPartner=Si le poste est localisé chez un partenaire +PositionToBeFilled=Poste à pourvoir +PositionsToBeFilled=Postes à pourvoir +ListOfPositionsToBeFilled=Liste des postes à pourvoir +NewPositionToBeFilled=Nouveau poste à pourvoir + +JobOfferToBeFilled=Poste à pourvoir +ThisIsInformationOnJobPosition=Informations sur le poste à pourvoir diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index fa44e8e1172..dc1428b6e19 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -95,14 +95,16 @@ RealStock=Stock réel RealStockDesc=Le stock physique ou réel est le stock présent dans les entrepôts. RealStockWillAutomaticallyWhen=Le stock réel sera modifié selon ces règles (voir la configuration du module Stock) : VirtualStock=Stock virtuel -VirtualStockDesc=Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...) +VirtualStockAtDate=Stock virtuel à date +VirtualStockAtDateDesc=Stock virtuel une fois que toutes les commandes en attente qui doivent être effectuées avant la date seront terminées +VirtualStockDesc=Le stock virtuel est la quantité de produit en stock après que les opérations en cours (et qui affectent les stocks) soient terminées (réceptions de commandes fournisseurs, expéditions de commandes clients, production des ordres de fabrications, etc) IdWarehouse=Identifiant entrepôt DescWareHouse=Description entrepôt LieuWareHouse=Lieu entrepôt WarehousesAndProducts=Entrepôts et produits WarehousesAndProductsBatchDetail=Entrepôts et produits (avec détail par lot/série) AverageUnitPricePMPShort=Prix moyen pondéré (PMP) -AverageUnitPricePMP=Prix moyen pondéré (PMP) d'acquisition +AverageUnitPricePMPDesc=Le prix unitaire moyen d'entrée que nous avons dû payer aux fournisseurs pour intégrer le produit dans notre stock. SellPriceMin=Prix de vente unitaire EstimatedStockValueSellShort=Valeur à la vente EstimatedStockValueSell=Valeur vente @@ -141,7 +143,7 @@ Replenishments=Réapprovisionnement NbOfProductBeforePeriod=Quantité du produit %s en stock avant la période sélectionnée (< %s) NbOfProductAfterPeriod=Quantité du produit %s en stock après la période sélectionnée (> %s) MassMovement=Mouvement en masse -SelectProductInAndOutWareHouse=Sélectionner un produit, une quantité à transférer, un entrepôt source et destination et cliquer sur "%s". Une fois tous les mouvements choisis, cliquer sur "%s". +SelectProductInAndOutWareHouse=Sélectionner un entrepôt source et destination, un produit et une quantité à transférer, puis cliquer sur "%s". Une fois tous les mouvements choisis, cliquer sur "%s". RecordMovement=Enregistrer transfert ReceivingForSameOrder=Réceptions pour cette commande StockMovementRecorded=Mouvement de stocks enregistré diff --git a/htdocs/langs/fr_FR/suppliers.lang b/htdocs/langs/fr_FR/suppliers.lang index 81860c25a45..2b4ab9dcf70 100644 --- a/htdocs/langs/fr_FR/suppliers.lang +++ b/htdocs/langs/fr_FR/suppliers.lang @@ -1,4 +1,4 @@ -# Dolibarr language file - Source file is en_US - suppliers +# Dolibarr language file - Source file is en_US - vendors Suppliers=Fournisseurs SuppliersInvoice=Facture fournisseur ShowSupplierInvoice=Montrer la facture fournisseur @@ -15,7 +15,7 @@ SomeSubProductHaveNoPrices=Certains sous-produits n'ont pas de prix définis AddSupplierPrice=Ajouter un prix d'achat ChangeSupplierPrice=Modifier un prix d'achat SupplierPrices=Prix fournisseurs -ReferenceSupplierIsAlreadyAssociatedWithAProduct=Cette référence fournisseur est déjà associée à la référence : %s +ReferenceSupplierIsAlreadyAssociatedWithAProduct=Cette référence fournisseur est déjà associée à un produit : %s NoRecordedSuppliers=Pas de fournisseur enregistré SupplierPayment=Paiement fournisseur SuppliersArea=Espace fournisseurs diff --git a/htdocs/langs/fr_FR/users.lang b/htdocs/langs/fr_FR/users.lang index 1ed6c956e66..5e951464dff 100644 --- a/htdocs/langs/fr_FR/users.lang +++ b/htdocs/langs/fr_FR/users.lang @@ -108,6 +108,7 @@ DisabledInMonoUserMode=Désactivé en mode maintenance UserAccountancyCode=Code comptable de l'utilisateur UserLogoff=Déconnexion de l'utilisateur UserLogged=Utilisateur connecté +DateOfEmployment=Date d'embauche DateEmployment=Date d'embauche DateEmploymentEnd=Date de fin d'emploi CantDisableYourself=Vous ne pouvez pas désactiver votre propre compte utilisateur diff --git a/htdocs/langs/fr_FR/withdrawals.lang b/htdocs/langs/fr_FR/withdrawals.lang index 446de9e09d3..35654186b71 100644 --- a/htdocs/langs/fr_FR/withdrawals.lang +++ b/htdocs/langs/fr_FR/withdrawals.lang @@ -10,7 +10,7 @@ PaymentByBankTransferReceipts=Ordres de virement bancaire PaymentByBankTransferLines=Lignes d'ordre de virement bancaire WithdrawalsReceipts=Bons de prélèvements WithdrawalReceipt=Bon de prélèvement -BankTransferReceipts=Ordres de virement +BankTransferReceipts=Ordres de virement bancaire BankTransferReceipt=Ordre de virement LatestBankTransferReceipts=Les %s derniers ordres de virement bancaire LastWithdrawalReceipts=Les %s derniers bons de prélèvements @@ -77,12 +77,12 @@ StatusMotif8=Autre motif CreateForSepaFRST=Créer fichier de prélèvement (SEPA FRST) CreateForSepaRCUR=Créer fichier de prélèvement (SEPA RCUR) CreateAll=Créer le fichier de prélèvement (tout) -CreateFileForPaymentByBankTransfer=Créer un virement (tout) +CreateFileForPaymentByBankTransfer=Créer fichier pour les virements (tous) CreateSepaFileForPaymentByBankTransfer=Créer un fichier de virement (SEPA) CreateGuichet=Seulement guichet CreateBanque=Seulement banque OrderWaiting=En attente de traitement -NotifyTransmision=Transmission du bon +NotifyTransmision=Transmission du fichier NotifyCredit=Crédit du bon NumeroNationalEmetter=Numéro National Émetteur WithBankUsingRIB=Pour les comptes bancaires utilisant le RIB @@ -93,9 +93,10 @@ CreditDate=Crédité le WithdrawalFileNotCapable=Impossible de générer le fichier de reçu des prélèvement pour votre pays %s (Votre pays n'est pas supporté) ShowWithdraw=Afficher ordre de prélèvement IfInvoiceNeedOnWithdrawPaymentWontBeClosed=Toutefois, si la facture a au moins une demande de prélèvement non traité, elle ne sera pas classée payée afin de permettre le prélèvement d'abord. -DoStandingOrdersBeforePayments=Cet onglet vous permet de demander un prélèvement. Une fois la demande faite, allez dans le menu Banque->Paiement par prélèvement pour gérer l'ordre de prélèvement. Lorsque l'ordre de paiement est clos, le paiement sur la facture sera automatiquement enregistrée, et la facture fermée si le reste à payer est nul. -DoCreditTransferBeforePayments=Cet onglet vous permet de demander un ordre de virement. Une fois fait, allez dans le menu Banque -> Paiements par virement pour gérer l'ordre de virement. Lorsque le virement est clôturé, le paiement des factures sera automatiquement enregistré et les factures clôturées si le solde à payer est nul. +DoStandingOrdersBeforePayments=Cet onglet vous permet de demander un prélèvement. Une fois la demande faite, allez dans le menu Banque->Paiement par prélèvement pour générer l'ordre de prélèvement. Lorsque l'ordre de paiement est clos, le paiement sur les factures seront automatiquement enregistrés, et les factures fermées si le reste à payer est nul. +DoCreditTransferBeforePayments=Cet onglet vous permet de demander un ordre de virement. Une fois fait, allez dans le menu Banque ->Paiements par virement pour gérer l'ordre de virement. Lorsque le virement est clôturé, le paiement des factures fournisseurs sera automatiquement enregistré et les factures clôturées si le solde à payer est nul. WithdrawalFile=Fichier de prélèvement +CreditTransferFile=Fichier de virement SetToStatusSent=Mettre au statut "Fichier envoyé" ThisWillAlsoAddPaymentOnInvoice=Cette action enregistrera aussi les règlements des factures et les classera au statut "Payé" si le solde est nul StatisticsByLineStatus=Statistiques par statut des lignes @@ -121,6 +122,7 @@ SEPAFrstOrRecur=Type de paiement ModeRECUR=Payment récurrent ModeFRST=Paiement unitaire PleaseCheckOne=Cocher un choix uniquement +CreditTransferOrderCreated=Ordre de virement %s créé DirectDebitOrderCreated=Ordre de prélèvement %s créé AmountRequested=Montant réclamé SEPARCUR=SEPA RCUR From a300eae994d6ca9a6150ad8ff1ad6049fc3456da Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 18:33:15 +0200 Subject: [PATCH 127/434] Sync transifex --- htdocs/langs/de_AT/main.lang | 1 - htdocs/langs/de_CH/main.lang | 1 - htdocs/langs/de_CH/stocks.lang | 1 - htdocs/langs/en_AU/admin.lang | 1 - htdocs/langs/en_AU/main.lang | 1 - htdocs/langs/en_AU/website.lang | 2 -- htdocs/langs/en_CA/admin.lang | 1 - htdocs/langs/en_CA/main.lang | 1 - htdocs/langs/en_CA/website.lang | 2 -- htdocs/langs/en_GB/admin.lang | 1 - htdocs/langs/en_GB/main.lang | 1 - htdocs/langs/en_GB/website.lang | 1 - htdocs/langs/en_IN/admin.lang | 1 - htdocs/langs/en_IN/main.lang | 1 - htdocs/langs/en_IN/website.lang | 2 -- htdocs/langs/en_SG/admin.lang | 1 - htdocs/langs/en_SG/main.lang | 1 - htdocs/langs/en_SG/website.lang | 2 -- htdocs/langs/es_AR/main.lang | 1 - htdocs/langs/es_BO/main.lang | 1 - htdocs/langs/es_CL/main.lang | 1 - htdocs/langs/es_CL/stocks.lang | 1 - htdocs/langs/es_CO/main.lang | 1 - htdocs/langs/es_DO/main.lang | 1 - htdocs/langs/es_EC/main.lang | 1 - htdocs/langs/es_EC/stocks.lang | 1 - htdocs/langs/es_GT/main.lang | 1 - htdocs/langs/es_HN/main.lang | 1 - htdocs/langs/es_MX/main.lang | 1 - htdocs/langs/es_PA/main.lang | 1 - htdocs/langs/es_PE/main.lang | 1 - htdocs/langs/es_PY/main.lang | 1 - htdocs/langs/es_US/main.lang | 1 - htdocs/langs/es_UY/main.lang | 1 - htdocs/langs/es_VE/main.lang | 1 - htdocs/langs/fr_BE/admin.lang | 1 - htdocs/langs/fr_BE/main.lang | 1 - htdocs/langs/fr_BE/website.lang | 2 -- htdocs/langs/fr_CA/admin.lang | 1 - htdocs/langs/fr_CA/main.lang | 1 - htdocs/langs/fr_CA/stocks.lang | 1 - htdocs/langs/fr_CA/website.lang | 1 - htdocs/langs/fr_CH/admin.lang | 1 - htdocs/langs/fr_CH/main.lang | 1 - htdocs/langs/fr_CH/website.lang | 2 -- htdocs/langs/fr_CI/admin.lang | 1 - htdocs/langs/fr_CI/main.lang | 1 - htdocs/langs/fr_CI/website.lang | 2 -- htdocs/langs/fr_CM/admin.lang | 1 - htdocs/langs/fr_CM/main.lang | 1 - htdocs/langs/fr_CM/website.lang | 2 -- htdocs/langs/fr_GA/admin.lang | 1 - htdocs/langs/fr_GA/main.lang | 1 - htdocs/langs/fr_GA/website.lang | 2 -- htdocs/langs/nl_BE/admin.lang | 1 - htdocs/langs/nl_BE/main.lang | 1 - htdocs/langs/nl_BE/website.lang | 1 - htdocs/langs/pt_BR/stocks.lang | 1 - 58 files changed, 67 deletions(-) delete mode 100644 htdocs/langs/en_AU/website.lang delete mode 100644 htdocs/langs/en_CA/website.lang delete mode 100644 htdocs/langs/en_IN/website.lang delete mode 100644 htdocs/langs/en_SG/website.lang delete mode 100644 htdocs/langs/fr_BE/website.lang delete mode 100644 htdocs/langs/fr_CH/website.lang delete mode 100644 htdocs/langs/fr_CI/website.lang delete mode 100644 htdocs/langs/fr_CM/website.lang delete mode 100644 htdocs/langs/fr_GA/website.lang diff --git a/htdocs/langs/de_AT/main.lang b/htdocs/langs/de_AT/main.lang index 545ae518ec7..124392e3512 100644 --- a/htdocs/langs/de_AT/main.lang +++ b/htdocs/langs/de_AT/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias NoRecordFound=Kein Eintrag gefunden NoRecordDeleted=Kein Eintrag gelöscht NoError=Kein Fehler diff --git a/htdocs/langs/de_CH/main.lang b/htdocs/langs/de_CH/main.lang index 60ec3c2adff..ba91e452a89 100644 --- a/htdocs/langs/de_CH/main.lang +++ b/htdocs/langs/de_CH/main.lang @@ -21,7 +21,6 @@ FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M NoTemplateDefined=Für diesen Emailtyp habe ich keine Vorlage.. AvailableVariables=Verfügbare Ersatzvariablen -EmptySearchString=Enter non empty search criterias NoRecordDeleted=Es wurde kein Datensatz gelöscht NotEnoughDataYet=Nicht genügend Daten NoError=Kein Fehler diff --git a/htdocs/langs/de_CH/stocks.lang b/htdocs/langs/de_CH/stocks.lang index a7776df946c..fc51f5818de 100644 --- a/htdocs/langs/de_CH/stocks.lang +++ b/htdocs/langs/de_CH/stocks.lang @@ -14,7 +14,6 @@ StockLimit=Sicherungsbestand für autom. Benachrichtigung RealStock=Realer Lagerbestand VirtualStock=Theoretisches Warenlager AverageUnitPricePMPShort=Gewichteter Durchschnitts-Einstandspreis -AverageUnitPricePMP=Gewichteter Durchschnittpreis bei Erwerb DesiredStockDesc=Dieser Bestand wird für die Nachbestellfunktion verwendet. UseVirtualStockByDefault=Nutze theoretische Lagerbestände anstatt des physischem Bestands für die Nachbestellungsfunktion UseVirtualStock=theoretisches Warenlager verwenden diff --git a/htdocs/langs/en_AU/admin.lang b/htdocs/langs/en_AU/admin.lang index 50add47a7d4..0980facb414 100644 --- a/htdocs/langs/en_AU/admin.lang +++ b/htdocs/langs/en_AU/admin.lang @@ -1,5 +1,4 @@ # Dolibarr language file - Source file is en_US - admin -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. OldVATRates=Old GST rate NewVATRates=New GST rate DictionaryVAT=GST Rates or Sales Tax Rates diff --git a/htdocs/langs/en_AU/main.lang b/htdocs/langs/en_AU/main.lang index f51ad592766..dac6a875c2d 100644 --- a/htdocs/langs/en_AU/main.lang +++ b/htdocs/langs/en_AU/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %I:%M %p FormatDateHourSecShort=%d/%m/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias ErrorNoVATRateDefinedForSellerCountry=Error, no GST rates defined for country '%s'. Quadri=Quarter PriceUTTC=U.P. (incl GST) diff --git a/htdocs/langs/en_AU/website.lang b/htdocs/langs/en_AU/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/en_AU/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_CA/admin.lang b/htdocs/langs/en_CA/admin.lang index a7c6cc9d271..62dd510c5e0 100644 --- a/htdocs/langs/en_CA/admin.lang +++ b/htdocs/langs/en_CA/admin.lang @@ -1,5 +1,4 @@ # Dolibarr language file - Source file is en_US - admin -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. LocalTax1Management=PST Management CompanyZip=Postal code LDAPFieldZip=Postal code diff --git a/htdocs/langs/en_CA/main.lang b/htdocs/langs/en_CA/main.lang index 7ce3e998978..6d4ce6e30f2 100644 --- a/htdocs/langs/en_CA/main.lang +++ b/htdocs/langs/en_CA/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d.%m.%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias ErrorNoVATRateDefinedForSellerCountry=Error, no vat rate defined for country '%s'. AmountVAT=Amount GST AmountLT1=Amount PST diff --git a/htdocs/langs/en_CA/website.lang b/htdocs/langs/en_CA/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/en_CA/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_GB/admin.lang b/htdocs/langs/en_GB/admin.lang index 1d26334c78d..11a52c3a368 100644 --- a/htdocs/langs/en_GB/admin.lang +++ b/htdocs/langs/en_GB/admin.lang @@ -20,7 +20,6 @@ ImportPostgreSqlDesc=To import a backup file, you must use the pg_restore comman CommandsToDisableForeignKeysForImportWarning=This is mandatory if you want to restore your sql dumps later ModulesMarketPlaceDesc=You can find more modules to download from external websites on the Internet... ModulesMarketPlaces=Find external applications and modules -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. AvailableOnlyIfJavascriptAndAjaxNotDisabled=Available only if JavaScript is enabled InstrucToEncodePass=To have password encoded into the conf.php file, replace the line
$dolibarr_main_db_pass="...";
with
$dolibarr_main_db_pass="crypted:%s"; InstrucToClearPass=To have password decoded (clear) into the conf.php file, replace the line
$dolibarr_main_db_pass="crypted:...";
with
$dolibarr_main_db_pass="%s"; diff --git a/htdocs/langs/en_GB/main.lang b/htdocs/langs/en_GB/main.lang index b712cacaa69..5617fe77778 100644 --- a/htdocs/langs/en_GB/main.lang +++ b/htdocs/langs/en_GB/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias ErrorNoVATRateDefinedForSellerCountry=Error, no VAT rates defined for country '%s'. NotAuthorized=You are not authorised to do that. BackgroundColorByDefault=Default background colour diff --git a/htdocs/langs/en_GB/website.lang b/htdocs/langs/en_GB/website.lang index f2cfbf3456c..ef8e16da6ad 100644 --- a/htdocs/langs/en_GB/website.lang +++ b/htdocs/langs/en_GB/website.lang @@ -1,3 +1,2 @@ # Dolibarr language file - Source file is en_US - website PageNameAliasHelp=Name or alias of the page.
This alias is also used to forge an SEO URL when the website is run from a Virtual host of a Web server (like Apache, Nginx, ...). Use the button "%s" to edit this alias. -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_IN/admin.lang b/htdocs/langs/en_IN/admin.lang index ebfc7deb6d3..4b3c42b80b1 100644 --- a/htdocs/langs/en_IN/admin.lang +++ b/htdocs/langs/en_IN/admin.lang @@ -1,5 +1,4 @@ # Dolibarr language file - Source file is en_US - admin -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. Module20Name=Quotations Module20Desc=Management of quotations Permission21=Read quotations diff --git a/htdocs/langs/en_IN/main.lang b/htdocs/langs/en_IN/main.lang index 15902ff1c4d..46aef779403 100644 --- a/htdocs/langs/en_IN/main.lang +++ b/htdocs/langs/en_IN/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %I:%M %p FormatDateHourSecShort=%d/%m/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias CommercialProposalsShort=Quotations LinkToProposal=Link to quotation SearchIntoCustomerProposals=Quotations diff --git a/htdocs/langs/en_IN/website.lang b/htdocs/langs/en_IN/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/en_IN/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_SG/admin.lang b/htdocs/langs/en_SG/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/en_SG/admin.lang +++ b/htdocs/langs/en_SG/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. OperationParamDesc=Define the values to use for the object of the action, or how to extract values. For example:
objproperty1=SET:the value to set
objproperty2=SET:a value with replacement of __objproperty1__
objproperty3=SETIFEMPTY:value used if objproperty3 is not already defined
objproperty4=EXTRACT:HEADER:X-Myheaderkey:\\s*([^\\s]*)
options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
object.objproperty5=EXTRACT:BODY:My company name is\\s([^\\s]*)

Use a ; char as separator to extract or set several properties. EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/en_SG/main.lang b/htdocs/langs/en_SG/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/en_SG/main.lang +++ b/htdocs/langs/en_SG/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/en_SG/website.lang b/htdocs/langs/en_SG/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/en_SG/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/es_AR/main.lang b/htdocs/langs/es_AR/main.lang index 7f068578411..6bcf44704f7 100644 --- a/htdocs/langs/es_AR/main.lang +++ b/htdocs/langs/es_AR/main.lang @@ -22,7 +22,6 @@ FormatDateHourText=%B %d, %Y, %I:%M %p DatabaseConnection=Conexión de base de datos NoTemplateDefined=No hay plantilla para este tipo de email AvailableVariables=Variables disponibles de substitución -EmptySearchString=Enter non empty search criterias NoRecordFound=Sin registros NoRecordDeleted=Sin registros eliminados NotEnoughDataYet=Sin datos suficientes diff --git a/htdocs/langs/es_BO/main.lang b/htdocs/langs/es_BO/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/es_BO/main.lang +++ b/htdocs/langs/es_BO/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_CL/main.lang b/htdocs/langs/es_CL/main.lang index 0c12ed62b34..e6342fa3f44 100644 --- a/htdocs/langs/es_CL/main.lang +++ b/htdocs/langs/es_CL/main.lang @@ -22,7 +22,6 @@ FormatDateHourText=%d %B %Y %H:%M DatabaseConnection=Conexión a la base NoTemplateDefined=No hay plantilla disponible para este tipo de correo electrónico AvailableVariables=Variables de sustitución disponibles -EmptySearchString=Enter non empty search criterias NoRecordFound=Ningún record fue encontrado NoRecordDeleted=No se eliminó ningún registro NoError=No hay error diff --git a/htdocs/langs/es_CL/stocks.lang b/htdocs/langs/es_CL/stocks.lang index ffd436fb51a..ba63c7f81bf 100644 --- a/htdocs/langs/es_CL/stocks.lang +++ b/htdocs/langs/es_CL/stocks.lang @@ -66,7 +66,6 @@ IdWarehouse=Id almacén LieuWareHouse=Almacén de localización WarehousesAndProductsBatchDetail=Almacenes y productos (con detalle por lote / serie) AverageUnitPricePMPShort=Precio de entrada promedio ponderado -AverageUnitPricePMP=Precio de entrada promedio ponderado SellPriceMin=Precio unitario de venta EstimatedStockValueSellShort=Valor para la venta EstimatedStockValueSell=Valor para la venta diff --git a/htdocs/langs/es_CO/main.lang b/htdocs/langs/es_CO/main.lang index 038f333d9ea..8db201ad380 100644 --- a/htdocs/langs/es_CO/main.lang +++ b/htdocs/langs/es_CO/main.lang @@ -21,7 +21,6 @@ FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M NoTemplateDefined=No hay plantilla disponible para este tipo de correo electrónico. AvailableVariables=Variables de sustitución disponibles -EmptySearchString=Enter non empty search criterias NoRecordFound=No se encontraron registros NoRecordDeleted=Ningún registro eliminado Errors=Los errores diff --git a/htdocs/langs/es_DO/main.lang b/htdocs/langs/es_DO/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/es_DO/main.lang +++ b/htdocs/langs/es_DO/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_EC/main.lang b/htdocs/langs/es_EC/main.lang index 2dd7a66de05..3227c745a02 100644 --- a/htdocs/langs/es_EC/main.lang +++ b/htdocs/langs/es_EC/main.lang @@ -22,7 +22,6 @@ FormatDateHourText=%d %B %Y %H:%M DatabaseConnection=Conexión con la base de datos NoTemplateDefined=No hay plantilla disponible para este tipo de correo electrónico AvailableVariables=Variables de sustitución disponibles -EmptySearchString=Enter non empty search criterias NoRecordFound=Ningún registro encontrado NoRecordDeleted=Ningún registro eliminado NoError=No hay error diff --git a/htdocs/langs/es_EC/stocks.lang b/htdocs/langs/es_EC/stocks.lang index 88ed5a7e742..c8f3a1758af 100644 --- a/htdocs/langs/es_EC/stocks.lang +++ b/htdocs/langs/es_EC/stocks.lang @@ -72,7 +72,6 @@ DescWareHouse=Descripción de almacén LieuWareHouse=Almacén de localización WarehousesAndProductsBatchDetail=Almacenes y productos (con detalle por lote / serie) AverageUnitPricePMPShort=Precio medio ponderado de los insumos -AverageUnitPricePMP=Precio medio ponderado de los insumos SellPriceMin=Precio unitario de venta EstimatedStockValueSellShort=Valor para la venta EstimatedStockValueSell=Valor para la venta diff --git a/htdocs/langs/es_GT/main.lang b/htdocs/langs/es_GT/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/es_GT/main.lang +++ b/htdocs/langs/es_GT/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_HN/main.lang b/htdocs/langs/es_HN/main.lang index 7579f1f4693..0d6b013ca18 100644 --- a/htdocs/langs/es_HN/main.lang +++ b/htdocs/langs/es_HN/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_MX/main.lang b/htdocs/langs/es_MX/main.lang index 7405807c6c8..1b7e397c375 100644 --- a/htdocs/langs/es_MX/main.lang +++ b/htdocs/langs/es_MX/main.lang @@ -20,7 +20,6 @@ FormatDateHourSecShort=%I:%M:%S %p %d/%m/%Y FormatDateHourTextShort=%I:%M %p, %d %b %Y FormatDateHourText=%I:%M %p, %d %B %Y AvailableVariables=Variables de sustitución disponibles -EmptySearchString=Enter non empty search criterias NoRecordFound=Ningún registro fue encontrado NoError=No hay error ErrorFieldFormat=El campo '%s' contiene un valor incorrecto diff --git a/htdocs/langs/es_PA/main.lang b/htdocs/langs/es_PA/main.lang index bcdd3f914eb..1602d6a7ffa 100644 --- a/htdocs/langs/es_PA/main.lang +++ b/htdocs/langs/es_PA/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_PE/main.lang b/htdocs/langs/es_PE/main.lang index 7140f0a388b..aa60b7d10cc 100644 --- a/htdocs/langs/es_PE/main.lang +++ b/htdocs/langs/es_PE/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias NoError=Sin error ErrorNoVATRateDefinedForSellerCountry=Error, no hay tipos de IGV definidos para el país '%s'. NotClosed=No se ha cerrado diff --git a/htdocs/langs/es_PY/main.lang b/htdocs/langs/es_PY/main.lang index bcdd3f914eb..1602d6a7ffa 100644 --- a/htdocs/langs/es_PY/main.lang +++ b/htdocs/langs/es_PY/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_US/main.lang b/htdocs/langs/es_US/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/es_US/main.lang +++ b/htdocs/langs/es_US/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_UY/main.lang b/htdocs/langs/es_UY/main.lang index bcdd3f914eb..1602d6a7ffa 100644 --- a/htdocs/langs/es_UY/main.lang +++ b/htdocs/langs/es_UY/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_VE/main.lang b/htdocs/langs/es_VE/main.lang index 1785d537814..1de75d20c42 100644 --- a/htdocs/langs/es_VE/main.lang +++ b/htdocs/langs/es_VE/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias DateEnd=Fecha finalización AmountLT1ES=Importe de retención AmountLT2ES=Importe ISLR diff --git a/htdocs/langs/fr_BE/admin.lang b/htdocs/langs/fr_BE/admin.lang index 3d058e6b61d..5d24a311ccd 100644 --- a/htdocs/langs/fr_BE/admin.lang +++ b/htdocs/langs/fr_BE/admin.lang @@ -14,7 +14,6 @@ WarningModuleNotActive=Le module %s doit être activé WarningOnlyPermissionOfActivatedModules=Seules les permissions liées à des modules activés sont montrées ici. Vous pouvez activer d'autres modules sur la page Accueil->Configuration->Modules. FormToTestFileUploadForm=Formulaire pour tester l'upload de fichiers (selon la configuration) IfModuleEnabled=Note: oui ne fonctionne que si le module %s est activé -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. Module20Name=Propales Module30Name=Factures Target=Objectif diff --git a/htdocs/langs/fr_BE/main.lang b/htdocs/langs/fr_BE/main.lang index e425c275844..3042af1642f 100644 --- a/htdocs/langs/fr_BE/main.lang +++ b/htdocs/langs/fr_BE/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias Update=Mise à jour DateStart=Date de début DateEnd=Date de fin diff --git a/htdocs/langs/fr_BE/website.lang b/htdocs/langs/fr_BE/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_BE/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_CA/admin.lang b/htdocs/langs/fr_CA/admin.lang index 09df3da74ad..88e376626be 100644 --- a/htdocs/langs/fr_CA/admin.lang +++ b/htdocs/langs/fr_CA/admin.lang @@ -39,7 +39,6 @@ CompatibleAfterUpdate=Ce module nécessite une mise à jour de votre Dolibarr %s SeeInMarkerPlace=Voir dans Market place Updated=Mis à jour AchatTelechargement=Acheter / Télécharger -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. DevelopYourModuleDesc=Quelques solutions pour développer votre propre module ... InstrucToEncodePass=Pour chiffrer le mot de passe de la base dans le fichier de configuration conf.php, remplacer la ligne
$dolibarr_main_db_pass="...";
par
$dolibarr_main_db_pass="crypted:%s"; InstrucToClearPass=Pour avoir le mot de passe de la base décodé (en clair) dans le fichier de configuration conf.php, remplacer dans ce fichier la ligne
$dolibarr_main_db_pass="crypted:..."
par
$dolibarr_main_db_pass="%s" diff --git a/htdocs/langs/fr_CA/main.lang b/htdocs/langs/fr_CA/main.lang index 0da76b0aab2..6914f73c3a7 100644 --- a/htdocs/langs/fr_CA/main.lang +++ b/htdocs/langs/fr_CA/main.lang @@ -20,7 +20,6 @@ FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M DatabaseConnection=Connexion à la base de donnée -EmptySearchString=Enter non empty search criterias ErrorCanNotCreateDir=Impossible de créer le dir %s ErrorCanNotReadDir=Impossible de lire le dir %s ErrorNoSocialContributionForSellerCountry=Erreur, aucun type de charges défini pour le pays '%s'. diff --git a/htdocs/langs/fr_CA/stocks.lang b/htdocs/langs/fr_CA/stocks.lang index 8c85ddc91fd..b94830980a7 100644 --- a/htdocs/langs/fr_CA/stocks.lang +++ b/htdocs/langs/fr_CA/stocks.lang @@ -36,7 +36,6 @@ IdWarehouse=Id entrepôt LieuWareHouse=Entrepôt de localisation WarehousesAndProductsBatchDetail=Entrepôts et produits (avec détail par lot / série) AverageUnitPricePMPShort=Prix ​​moyen pondéré des intrants -AverageUnitPricePMP=Prix ​​moyen pondéré des intrants SellPriceMin=Prix ​​unitaire de vente EstimatedStockValueSellShort=Valeur à vendre EstimatedStockValueSell=Valeur à vendre diff --git a/htdocs/langs/fr_CA/website.lang b/htdocs/langs/fr_CA/website.lang index f6c1b71c174..5255b2f9da5 100644 --- a/htdocs/langs/fr_CA/website.lang +++ b/htdocs/langs/fr_CA/website.lang @@ -7,4 +7,3 @@ EditMenu=Menu Edition ViewSiteInNewTab=Afficher le site dans un nouvel onglet ViewPageInNewTab=Afficher la page dans un nouvel onglet ViewWebsiteInProduction=Afficher le site Web à l'aide d'URL d'accueil -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_CH/admin.lang b/htdocs/langs/fr_CH/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/fr_CH/admin.lang +++ b/htdocs/langs/fr_CH/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. OperationParamDesc=Define the values to use for the object of the action, or how to extract values. For example:
objproperty1=SET:the value to set
objproperty2=SET:a value with replacement of __objproperty1__
objproperty3=SETIFEMPTY:value used if objproperty3 is not already defined
objproperty4=EXTRACT:HEADER:X-Myheaderkey:\\s*([^\\s]*)
options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
object.objproperty5=EXTRACT:BODY:My company name is\\s([^\\s]*)

Use a ; char as separator to extract or set several properties. EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/fr_CH/main.lang b/htdocs/langs/fr_CH/main.lang index 75d787bb95c..65f49b2ef5e 100644 --- a/htdocs/langs/fr_CH/main.lang +++ b/htdocs/langs/fr_CH/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%d/%m/%Y %I:%M %p FormatDateHourSecShort=%d/%m/%Y %I:%M:%S %p FormatDateHourTextShort=%d %b %Y, %I:%M %p FormatDateHourText=%d %B %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/fr_CH/website.lang b/htdocs/langs/fr_CH/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_CH/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_CI/admin.lang b/htdocs/langs/fr_CI/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/fr_CI/admin.lang +++ b/htdocs/langs/fr_CI/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. OperationParamDesc=Define the values to use for the object of the action, or how to extract values. For example:
objproperty1=SET:the value to set
objproperty2=SET:a value with replacement of __objproperty1__
objproperty3=SETIFEMPTY:value used if objproperty3 is not already defined
objproperty4=EXTRACT:HEADER:X-Myheaderkey:\\s*([^\\s]*)
options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
object.objproperty5=EXTRACT:BODY:My company name is\\s([^\\s]*)

Use a ; char as separator to extract or set several properties. EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/fr_CI/main.lang b/htdocs/langs/fr_CI/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/fr_CI/main.lang +++ b/htdocs/langs/fr_CI/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/fr_CI/website.lang b/htdocs/langs/fr_CI/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_CI/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_CM/admin.lang b/htdocs/langs/fr_CM/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/fr_CM/admin.lang +++ b/htdocs/langs/fr_CM/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. OperationParamDesc=Define the values to use for the object of the action, or how to extract values. For example:
objproperty1=SET:the value to set
objproperty2=SET:a value with replacement of __objproperty1__
objproperty3=SETIFEMPTY:value used if objproperty3 is not already defined
objproperty4=EXTRACT:HEADER:X-Myheaderkey:\\s*([^\\s]*)
options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
object.objproperty5=EXTRACT:BODY:My company name is\\s([^\\s]*)

Use a ; char as separator to extract or set several properties. EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/fr_CM/main.lang b/htdocs/langs/fr_CM/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/fr_CM/main.lang +++ b/htdocs/langs/fr_CM/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/fr_CM/website.lang b/htdocs/langs/fr_CM/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_CM/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_GA/admin.lang b/htdocs/langs/fr_GA/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/fr_GA/admin.lang +++ b/htdocs/langs/fr_GA/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. OperationParamDesc=Define the values to use for the object of the action, or how to extract values. For example:
objproperty1=SET:the value to set
objproperty2=SET:a value with replacement of __objproperty1__
objproperty3=SETIFEMPTY:value used if objproperty3 is not already defined
objproperty4=EXTRACT:HEADER:X-Myheaderkey:\\s*([^\\s]*)
options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
object.objproperty5=EXTRACT:BODY:My company name is\\s([^\\s]*)

Use a ; char as separator to extract or set several properties. EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/fr_GA/main.lang b/htdocs/langs/fr_GA/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/fr_GA/main.lang +++ b/htdocs/langs/fr_GA/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/fr_GA/website.lang b/htdocs/langs/fr_GA/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_GA/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/nl_BE/admin.lang b/htdocs/langs/nl_BE/admin.lang index 009d9292997..0b0d5b0e10f 100644 --- a/htdocs/langs/nl_BE/admin.lang +++ b/htdocs/langs/nl_BE/admin.lang @@ -67,7 +67,6 @@ SeeInMarkerPlace=Zie Marktplaats AchatTelechargement=Kopen / Downloaden GoModuleSetupArea=Ga naar het gedeelte Module-instellingen om een nieuwe module te implementeren / installeren: %s . DoliStoreDesc=DoliStore, de officiële markt voor externe Dolibarr ERP / CRM modules -DoliPartnersDesc=List of companies providing custom-developed modules or features.
Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. WebSiteDesc=Externe websites voor meer add-on (niet-basis) modules ... BoxesActivated=Geactiveerde widgets DoNotStoreClearPassword=Versleutel wachtwoorden opgeslagen in database (NIET als platte tekst). Het wordt sterk aanbevolen om deze optie te activeren. diff --git a/htdocs/langs/nl_BE/main.lang b/htdocs/langs/nl_BE/main.lang index 34b534324fb..05ff5191d8f 100644 --- a/htdocs/langs/nl_BE/main.lang +++ b/htdocs/langs/nl_BE/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d-%m-%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %I:%M:%S %p FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias NoRecordFound=Geen record gevonden ErrorCanNotCreateDir=Kan dir %s niet maken ErrorCanNotReadDir=Kan dir %s niet lezen diff --git a/htdocs/langs/nl_BE/website.lang b/htdocs/langs/nl_BE/website.lang index 05a97bd129a..e8f0a2d4af0 100644 --- a/htdocs/langs/nl_BE/website.lang +++ b/htdocs/langs/nl_BE/website.lang @@ -7,4 +7,3 @@ ViewSiteInNewTab=Bekijk de site in een nieuwe tab ViewPageInNewTab=Bekijk de pagina in een nieuwe tab SetAsHomePage=Zet als Homepagina ViewWebsiteInProduction=Bekijk website via de home URL's -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/pt_BR/stocks.lang b/htdocs/langs/pt_BR/stocks.lang index a04e49809f8..3315b8f6924 100644 --- a/htdocs/langs/pt_BR/stocks.lang +++ b/htdocs/langs/pt_BR/stocks.lang @@ -54,7 +54,6 @@ DescWareHouse=Descrição do armazém LieuWareHouse=Localização do armazenamento WarehousesAndProducts=Armazenamento de produtos AverageUnitPricePMPShort=Preço médio de entrada -AverageUnitPricePMP=Preço médio de entrada SellPriceMin=Venda Preço unitário EstimatedStockValueSellShort=Valor para venda EstimatedStockValueSell=Valor para venda From aca20c89f9601e863b1ce4047f585fe99064b99a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 18:45:42 +0200 Subject: [PATCH 128/434] Can use a generic email for recruitment --- htdocs/install/mysql/migration/12.0.0-13.0.0.sql | 2 ++ .../llx_recruitment_recruitmentjobposition.sql | 3 ++- htdocs/langs/en_US/recruitment.lang | 4 +++- htdocs/public/recruitment/view.php | 14 +++++++++----- .../class/recruitmentjobposition.class.php | 2 ++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 24b6fd687e1..5dc9bb953ab 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -112,6 +112,8 @@ ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitmen ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitment_recruitmentjobposition_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_status (status); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN email_recruiter varchar(255); + create table llx_recruitment_recruitmentjobposition_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql index c527409862d..88ad12acef1 100644 --- a/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql @@ -22,7 +22,8 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( qty integer DEFAULT 1 NOT NULL, fk_soc integer, fk_project integer, - fk_user_recruiter integer, + fk_user_recruiter integer, + email_recruiter varchar(255), fk_user_supervisor integer, fk_establishment integer, date_planned date, diff --git a/htdocs/langs/en_US/recruitment.lang b/htdocs/langs/en_US/recruitment.lang index ad58f1d33be..b4a7abbe825 100644 --- a/htdocs/langs/en_US/recruitment.lang +++ b/htdocs/langs/en_US/recruitment.lang @@ -52,4 +52,6 @@ NewPositionToBeFilled=New job offers to be filled JobOfferToBeFilled=Job offer to be filled ThisIsInformationOnJobPosition=Information of the job position to be filled -ContactForRecruitment=Contact for recruitment \ No newline at end of file +ContactForRecruitment=Contact for recruitment +EmailRecruiter=Email recruiter +ToUseAGenericEmail=To use a generic email. If not defined, the email of the responsible of recruitment will be used \ No newline at end of file diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index 88e6a36f582..b8a44089428 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -264,15 +264,19 @@ if ($object->date_planned > $now) { print '
'; // Contact -print $langs->trans("ContactForRecruitment").' : '; $tmpuser = new User($db); $tmpuser->fetch($object->fk_user_recruiter); + +print $langs->trans("ContactForRecruitment").' : '; +$emailforcontact = $object->email_recruiter; +if (empty($emailforcontact)) { + $emailforcontact = $tmpuser->email; + if (empty($emailforcontact)) { + $emailforcontact = $mysoc->email; + } +} print ''; print $tmpuser->getFullName(-1); -$emailforcontact = $tmpuser->email; -if (empty($emailforcontact)) { - $emailforcontact = $mysoc->email; -} print ' - '.img_picto('', 'email', 'class="paddingrightonly"').dol_print_email($emailforcontact); print ''; print '
'; diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 4029833afd0..048c0d4ee3a 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -100,6 +100,7 @@ class RecruitmentJobPosition extends CommonObject 'qty' => array('type'=>'integer', 'label'=>'NbOfEmployeesExpected', 'enabled'=>'1', 'position'=>45, 'notnull'=>1, 'visible'=>1, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp',), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'1', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>-1, 'foreignkey'=>'user.rowid',), + 'email_recruiter' => array('type'=>'varchar(255)', 'label'=>'EmailRecruiter', 'enabled'=>'1', 'position'=>54, 'notnull'=>0, 'visible'=>-1, 'help'=>'ToUseAGenericEmail'), 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid',), 'fk_establishment' => array('type'=>'integer:Establishment:hrm/class/establishment.class.php', 'label'=>'Establishment', 'enabled'=>'$conf->hrm->enabled', 'position'=>56, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'establishment.rowid',), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'WorkPlace', 'enabled'=>'1', 'position'=>57, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'help'=>"IfJobIsLocatedAtAPartner",), @@ -123,6 +124,7 @@ class RecruitmentJobPosition extends CommonObject public $fk_soc; public $fk_project; public $fk_user_recruiter; + public $email_recruiter; public $fk_user_supervisor; public $fk_establishment; public $date_planned; From a51829d03c60d10c81ab7eff03ff107fc300600b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 18:50:08 +0200 Subject: [PATCH 129/434] CSS --- htdocs/public/recruitment/view.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index b8a44089428..3afc6825c43 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -230,7 +230,8 @@ if (!empty($conf->global->RECRUITMENT_NEWFORM_TEXT)) } if (empty($text)) { - $text .= '
'.$langs->trans("JobOfferToBeFilled", $mysoc->name).''; + $text .= '
'.$langs->trans("JobOfferToBeFilled", $mysoc->name); + $text .= '   -   '.$mysoc->name.''; $text .= '   -   '.dol_print_date($object->date_creation); $text .= ''."\n"; $text .= '

'.$object->label.'


'."\n"; From d9818405c6f52bf9074dbefa023a92ce4ab5d87b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 22:30:23 +0200 Subject: [PATCH 130/434] Fix regression for v13 --- htdocs/admin/dict.php | 6 +- htdocs/contact/card.php | 73 ++++++++++--------- htdocs/contact/class/contact.class.php | 13 ++-- htdocs/contact/list.php | 17 +++-- .../mysql/data/llx_c_prospectcontactlevel.sql | 2 +- .../install/mysql/migration/11.0.0-12.0.0.sql | 31 -------- .../install/mysql/migration/12.0.0-13.0.0.sql | 33 +++++++++ 7 files changed, 95 insertions(+), 80 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 79032a5cca9..b6d5df3644a 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -91,7 +91,11 @@ $hookmanager->initHooks(array('admin')); // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0); +if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { + $taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0); +} else { + $taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 27, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0); +} // Name of SQL tables of dictionaries $tabname = array(); diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 3b5c61529dd..eeb51e65442 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -1351,50 +1351,51 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print ''; print ''; + print '
'; $object->fetch_thirdparty(); - if ($object->thirdparty->client == 2 || $object->thirdparty->client == 3) - { - print '
'; - print '
'; - print ''; + if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { + if ($object->thirdparty->client == 2 || $object->thirdparty->client == 3) + { + print '
'; - // Level of prospect - print '"; - print ''; + print '
'; + print '
'; - print ''; - print '
'; - print $langs->trans('ProspectLevel'); - print ''; - if ($action != 'editlevel' && $user->rights->societe->contact->creer) print 'id . '">' . img_edit($langs->trans('Modify'), 1) . '
'; - print '
'; - if ($action == 'editlevel') - { - $formcompany->formProspectContactLevel($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_prospectlevel, 'prospect_contact_level_id', 1); - } - else - { - print $object->getLibProspLevel(); - } - print "
'; - // Status - $object->loadCacheOfProspStatus(); - print '"; + print ''; + + // Status of prospection + $object->loadCacheOfProspStatus(); + print ''; + + print "
' . $langs->trans("StatusProsp") . '' . $object->getLibProspCommStatut(4, $object->cacheprospectstatus[$object->stcomm_id]['label']); - print '     '; - print '
'; - foreach ($object->cacheprospectstatus as $key => $val) - { - $titlealt = 'default'; - if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; - if ($object->stcomm_id != $val['id']) print '' . img_action($titlealt, $val['code'], $val['picto']) . ''; + // Level of prospect + print '
'; + print ''; + print '
'; + print $langs->trans('ProspectLevel'); + print ''; + if ($action != 'editlevel' && $user->rights->societe->contact->creer) print 'id . '">' . img_edit($langs->trans('Modify'), 1) . '
'; + print '
'; + if ($action == 'editlevel') { + $formcompany->formProspectContactLevel($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_prospectlevel, 'prospect_contact_level_id', 1); + } else { + print $object->getLibProspLevel(); + } + print "
' . $langs->trans("StatusProsp") . '' . $object->getLibProspCommStatut(4, $object->cacheprospectstatus[$object->stcomm_id]['label']); + print '     '; + print '
'; + foreach ($object->cacheprospectstatus as $key => $val) { + $titlealt = 'default'; + if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; + if ($object->stcomm_id != $val['id']) print '' . img_action($titlealt, $val['code'], $val['picto']) . ''; + } + print '
"; + print '
'; } - print ''; - print ""; } - print ''; print '
'; print '
'; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 16f903c153e..c475c1b439d 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -232,6 +232,10 @@ class Contact extends CommonObject if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0; if (empty($conf->mailing->enabled)) $this->fields['no_email']['enabled'] = 0; if (!empty($conf->global->SOCIETE_DISABLE_CONTACTS)) $this->fields['thirdparty']['enabled'] = 0; + if (empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { // Default behaviour + $this->field['fk_stcomm']['enabled'] = 0; + $this->field['fk_prospectlevel']['enabled'] = 0; + } $this->statut = 1; // By default, status is enabled // Unset fields that are disabled @@ -1830,8 +1834,7 @@ class Contact extends CommonObject elseif ($statut == '1' || $statut == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto) . ' ' . $langs->trans("StatusProspect1"); elseif ($statut == '2' || $statut == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto) . ' ' . $langs->trans("StatusProspect2"); elseif ($statut == '3' || $statut == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto) . ' ' . $langs->trans("StatusProspect3"); - else - { + else { return img_action(($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label, 0, $picto) . ' ' . (($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label); } } @@ -1842,8 +1845,7 @@ class Contact extends CommonObject elseif ($statut == '1' || $statut == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto); elseif ($statut == '2' || $statut == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto); elseif ($statut == '3' || $statut == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto); - else - { + else { return img_action(($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label, 0, $picto); } } @@ -1854,8 +1856,7 @@ class Contact extends CommonObject elseif ($statut == '1' || $statut == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto) . ' ' . $langs->trans("StatusProspect1"); elseif ($statut == '2' || $statut == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto) . ' ' . $langs->trans("StatusProspect2"); elseif ($statut == '3' || $statut == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto) . ' ' . $langs->trans("StatusProspect3"); - else - { + else { return img_action(($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label, 0, $picto) . ' ' . (($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label); } } diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index e8b75b24677..c86c2fdaaea 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -179,13 +179,16 @@ $arrayfields = array( 'p.no_email'=>array('label'=>"No_Email", 'position'=>41, 'checked'=>0, 'enabled'=>(!empty($conf->mailing->enabled))), 'p.thirdparty'=>array('label'=>"ThirdParty", 'position'=>50, 'checked'=>1, 'enabled'=>empty($conf->global->SOCIETE_DISABLE_CONTACTS)), 'p.priv'=>array('label'=>"ContactVisibility", 'checked'=>1, 'position'=>200), - 'p.fk_prospectcontactlevel'=>array('label'=>"ProspectLevelShort", 'checked'=>1), - 'p.fk_stcommcontact'=>array('label'=>"StatusProsp", 'checked'=>1), 'p.datec'=>array('label'=>"DateCreationShort", 'checked'=>0, 'position'=>500), 'p.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), 'p.statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), 'p.import_key'=>array('label'=>"ImportId", 'checked'=>0, 'position'=>1100), ); +if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { + $arrayfields['p.fk_prospectcontactlevel'] = array('label'=>"ProspectLevelShort", 'checked'=>1, 'position'=>210); + $arrayfields['p.fk_stcommcontact'] = array('label'=>"StatusProsp", 'checked'=>1, 'position'=>215); +} + if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { if ($value['active']) { @@ -504,10 +507,14 @@ if ($search_email != '') $param .= '&search_email='.urlencode($search_email) if ($search_no_email != '') $param .= '&search_no_email='.urlencode($search_no_email); if ($search_status != '') $param .= '&search_status='.urlencode($search_status); if ($search_priv == '0' || $search_priv == '1') $param .= "&search_priv=".urlencode($search_priv); -if ($search_stcomm != '') $param.='&search_stcomm='.$search_stcomm; -if (is_array($search_level) && count($search_level)) foreach($search_level as $slevel) $param.='&search_level[]='.urlencode($slevel); +if ($search_stcomm != '') $param.='&search_stcomm='.urlencode($search_stcomm); +if (is_array($search_level) && count($search_level)) { + foreach($search_level as $slevel) { + $param.='&search_level[]='.urlencode($slevel); + } +} if ($search_import_key != '') $param .= '&search_import_key='.urlencode($search_import_key); -if ($optioncss != '') $param .= '&optioncss='.$optioncss; +if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss); if (count($search_roles) > 0) $param .= implode('&search_roles[]=', $search_roles); // Add $param from extra fields diff --git a/htdocs/install/mysql/data/llx_c_prospectcontactlevel.sql b/htdocs/install/mysql/data/llx_c_prospectcontactlevel.sql index 7f872a344bd..b45239ca992 100644 --- a/htdocs/install/mysql/data/llx_c_prospectcontactlevel.sql +++ b/htdocs/install/mysql/data/llx_c_prospectcontactlevel.sql @@ -24,7 +24,7 @@ -- Prospect level for contacts -- -delete from llx_c_prospectcontactlevel; +--delete from llx_c_prospectcontactlevel; insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_NONE', 'None', 1); insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_LOW', 'Low', 2); insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_MEDIUM', 'Medium', 3); diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index b679e337356..df4a3e45c75 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -305,37 +305,6 @@ ALTER TABLE llx_categorie ADD COLUMN fk_user_modif integer; ALTER TABLE llx_commandedet ADD CONSTRAINT fk_commandedet_fk_commandefourndet FOREIGN KEY (fk_commandefourndet) REFERENCES llx_commande_fournisseurdet (rowid); -create table llx_c_prospectcontactlevel -( - code varchar(12) PRIMARY KEY, - label varchar(30), - sortorder smallint, - active smallint DEFAULT 1 NOT NULL, - module varchar(32) NULL -) ENGINE=innodb; -insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_NONE', 'None', 1); -insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_LOW', 'Low', 2); -insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_MEDIUM', 'Medium', 3); -insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_HIGH', 'High', 4); - -create table llx_c_stcommcontact -( - id integer PRIMARY KEY, - code varchar(12) NOT NULL, - libelle varchar(30), - picto varchar(128), - active tinyint default 1 NOT NULL -)ENGINE=innodb; -ALTER TABLE llx_c_stcommcontact ADD UNIQUE INDEX uk_c_stcommcontact(code); -insert into llx_c_stcommcontact (id,code,libelle) values (-1, 'ST_NO', 'Do not contact'); -insert into llx_c_stcommcontact (id,code,libelle) values ( 0, 'ST_NEVER', 'Never contacted'); -insert into llx_c_stcommcontact (id,code,libelle) values ( 1, 'ST_TODO', 'To contact'); -insert into llx_c_stcommcontact (id,code,libelle) values ( 2, 'ST_PEND', 'Contact in progress'); -insert into llx_c_stcommcontact (id,code,libelle) values ( 3, 'ST_DONE', 'Contacted'); - -ALTER TABLE llx_socpeople ADD COLUMN fk_prospectcontactlevel varchar(12) AFTER priv; -ALTER TABLE llx_socpeople ADD COLUMN fk_stcommcontact integer DEFAULT 0 NOT NULL AFTER fk_prospectcontactlevel; - -- VMYSQL4.3 ALTER TABLE llx_prelevement_facture_demande MODIFY COLUMN fk_facture INTEGER NULL; -- VPGSQL8.2 ALTER TABLE llx_prelevement_facture_demande ALTER COLUMN fk_facture DROP NOT NULL; ALTER TABLE llx_prelevement_facture_demande ADD COLUMN fk_facture_fourn INTEGER NULL; diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 5dc9bb953ab..e6797717711 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -125,5 +125,38 @@ create table llx_recruitment_recruitmentjobposition_extrafields ALTER TABLE llx_recruitment_recruitmentjobposition_extrafields ADD INDEX idx_fk_object(fk_object); +-- Add dictionary for prospect level and action commercial on contacts (Using this is not recommanded) + +create table llx_c_prospectcontactlevel +( + code varchar(12) PRIMARY KEY, + label varchar(30), + sortorder smallint, + active smallint DEFAULT 1 NOT NULL, + module varchar(32) NULL +) ENGINE=innodb; +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_NONE', 'None', 1); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_LOW', 'Low', 2); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_MEDIUM', 'Medium', 3); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_HIGH', 'High', 4); + +create table llx_c_stcommcontact +( + id integer PRIMARY KEY, + code varchar(12) NOT NULL, + libelle varchar(30), + picto varchar(128), + active tinyint default 1 NOT NULL +)ENGINE=innodb; +ALTER TABLE llx_c_stcommcontact ADD UNIQUE INDEX uk_c_stcommcontact(code); + +insert into llx_c_stcommcontact (id,code,libelle) values (-1, 'ST_NO', 'Do not contact'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 0, 'ST_NEVER', 'Never contacted'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 1, 'ST_TODO', 'To contact'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 2, 'ST_PEND', 'Contact in progress'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 3, 'ST_DONE', 'Contacted'); + +ALTER TABLE llx_socpeople ADD COLUMN fk_prospectcontactlevel varchar(12) AFTER priv; +ALTER TABLE llx_socpeople ADD COLUMN fk_stcommcontact integer DEFAULT 0 NOT NULL AFTER fk_prospectcontactlevel; From 87f71e7681a90cbedb87ff034fb2fdc5e50e7ae5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 22:36:14 +0200 Subject: [PATCH 131/434] FIX Look and feel v12 --- htdocs/comm/card.php | 7 ++++--- htdocs/societe/tpl/linesalesrepresentative.tpl.php | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 62fd45db7a3..a5b7cb77ea7 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -527,6 +527,7 @@ if ($object->id > 0) print ""; + // Prospection level and status if ($object->client == 2 || $object->client == 3) { print '
'; @@ -539,7 +540,7 @@ if ($object->id > 0) print ''; + if ($action != 'editlevel' && $user->rights->societe->creer) print ''; print '
'; print $langs->trans('ProspectLevel'); print ''; - if ($action != 'editlevel' && $user->rights->societe->creer) print 'id.'">'.img_edit($langs->trans('Modify'), 1).'id.'">'.img_edit($langs->trans('Modify'), 1).'
'; print ''; if ($action == 'editlevel') @@ -560,7 +561,7 @@ if ($object->id > 0) { $titlealt = 'default'; if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; - if ($object->stcomm_id != $val['id']) print '' . img_action($titlealt, $val['code'], $val['picto']) . ''; + if ($object->stcomm_id != $val['id']) print '' . img_action($titlealt, $val['code'], $val['picto']) . ''; } print '
'; print ""; @@ -1128,7 +1129,7 @@ if ($object->id > 0) } /* - * Last invoices + * Latest invoices */ if (!empty($conf->facture->enabled) && $user->rights->facture->lire) { diff --git a/htdocs/societe/tpl/linesalesrepresentative.tpl.php b/htdocs/societe/tpl/linesalesrepresentative.tpl.php index 5b9078e6b76..9c6e485e97d 100644 --- a/htdocs/societe/tpl/linesalesrepresentative.tpl.php +++ b/htdocs/societe/tpl/linesalesrepresentative.tpl.php @@ -29,7 +29,7 @@ print $langs->trans('SalesRepresentatives'); print ''; if ($action != 'editsalesrepresentatives' && $user->rights->societe->creer) { print ''; - print 'id . '">' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . ''; + print 'id . '">' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . ''; print ''; } print ''; From 66d4b7372ecc843a246bac1b85dc16c878b499d8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 22:36:14 +0200 Subject: [PATCH 132/434] FIX Look and feel v12 Conflicts: htdocs/comm/card.php htdocs/societe/tpl/linesalesrepresentative.tpl.php --- htdocs/comm/card.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 9b385ea7ead..d48c897d6bb 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -529,6 +529,7 @@ if ($object->id > 0) print ""; + // Prospection level and status if ($object->client == 2 || $object->client == 3) { print '
'; @@ -541,7 +542,7 @@ if ($object->id > 0) print ''; + if ($action != 'editlevel' && $user->rights->societe->creer) print ''; print '
'; print $langs->trans('ProspectLevel'); print ''; - if ($action != 'editlevel' && $user->rights->societe->creer) print 'id.'">'.img_edit($langs->trans('Modify'), 1).'id.'">'.img_edit($langs->trans('Modify'), 1).'
'; print ''; if ($action == 'editlevel') @@ -564,7 +565,7 @@ if ($object->id > 0) { $titlealt = 'default'; if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; - if ($object->stcomm_id != $val['id']) print ''.img_action($titlealt, $val['code']).''; + if ($object->stcomm_id != $val['id']) print ''.img_action($titlealt, $val['code']).''; } print '
'; print ""; @@ -1146,7 +1147,7 @@ if ($object->id > 0) } /* - * Last invoices + * Latest invoices */ if (!empty($conf->facture->enabled) && $user->rights->facture->lire) { From c35a1036945f643a05cf0620fece3ec46cb32220 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 22:40:17 +0200 Subject: [PATCH 133/434] Fix phpcs --- htdocs/admin/receiptprinter.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index 7af626ef0bb..3cb6c4d68d1 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -391,7 +391,6 @@ if ($mode == 'config' && $user->admin) { // mode = template if ($mode == 'template' && $user->admin) { - dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), -1, 'technic'); print '
'; From 805ad6f5fe190eefe414d8752fef099f4b3be439 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 2 Aug 2020 22:44:37 +0200 Subject: [PATCH 134/434] Several fixes --- htdocs/contact/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index c86c2fdaaea..574727f6022 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -509,7 +509,7 @@ if ($search_status != '') $param .= '&search_status='.urlencode($search_stat if ($search_priv == '0' || $search_priv == '1') $param .= "&search_priv=".urlencode($search_priv); if ($search_stcomm != '') $param.='&search_stcomm='.urlencode($search_stcomm); if (is_array($search_level) && count($search_level)) { - foreach($search_level as $slevel) { + foreach ($search_level as $slevel) { $param.='&search_level[]='.urlencode($slevel); } } @@ -742,7 +742,7 @@ if (! empty($arrayfields['p.fk_stcommcontact']['checked'])) { print ''; $arraystcomm=array(); - foreach($prospectstatic->cacheprospectstatus as $key => $val) + foreach ($contactstatic->cacheprospectstatus as $key => $val) { $arraystcomm[$val['id']]=($langs->trans("StatusProspect".$val['id']) != "StatusProspect".$val['id'] ? $langs->trans("StatusProspect".$val['id']) : $val['label']); } From ccb9d62a145846b885fa1803e0f4f27530392083 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:13:46 +0200 Subject: [PATCH 135/434] Change comment to fixe a lot of undefined method --- .../core/modules/contract/doc/pdf_strato.modules.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/contract/doc/pdf_strato.modules.php b/htdocs/core/modules/contract/doc/pdf_strato.modules.php index a3c549c48a7..4df4ec431c3 100644 --- a/htdocs/core/modules/contract/doc/pdf_strato.modules.php +++ b/htdocs/core/modules/contract/doc/pdf_strato.modules.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2011 Fabrice CHERRIER - * Copyright (C) 2013-2019 Philippe Grand + * Copyright (C) 2013-2020 Philippe Grand * Copyright (C) 2015 Marcos García * Copyright (C) 2018 Frédéric France * @@ -500,7 +500,7 @@ class pdf_strato extends ModelePDFContract /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -550,7 +550,7 @@ class pdf_strato extends ModelePDFContract /** * Show footer signature of page - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param int $tab_top tab height position * @param int $tab_height tab height * @param Translate $outputlangs Object language for output @@ -579,8 +579,8 @@ class pdf_strato extends ModelePDFContract /** * Show top header of page. * - * @param PDF $pdf Object PDF - * @param CommonObject $object Object to show + * @param TCPDF &$pdf Object PDF + * @param CommonObject $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output * @return void From 0b7528010466177b212f2f2afd539de473743c94 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:19:55 +0200 Subject: [PATCH 136/434] Change comment to fixe a lot of undefined method --- .../core/modules/expedition/doc/pdf_espadon.modules.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index 2602caf8034..ddd08558b7a 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -671,7 +671,7 @@ class pdf_espadon extends ModelePdfExpedition /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Amount already paid * @param int $posy Start Position @@ -772,7 +772,7 @@ class pdf_espadon extends ModelePdfExpedition /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -822,7 +822,7 @@ class pdf_espadon extends ModelePdfExpedition /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1065,7 +1065,7 @@ class pdf_espadon extends ModelePdfExpedition /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 83d1ff2a6cfaf6f1935a95eadfc32597cdfb5ced Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:25:17 +0200 Subject: [PATCH 137/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/expedition/doc/pdf_merou.modules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php index 5fbec0b2c68..c8035036307 100644 --- a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php @@ -438,7 +438,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -480,7 +480,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text @@ -509,7 +509,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output From 8bdf15a6a60c25e5a98e5fa4e0300a5642ab3a59 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:28:25 +0200 Subject: [PATCH 138/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/expedition/doc/pdf_rouget.modules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index dc29b6411f5..48141b36b4d 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -662,7 +662,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -769,7 +769,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -857,7 +857,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output From 38f4e0392d44850b0fb4aac14f261c5e44df0bcd Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:30:31 +0200 Subject: [PATCH 139/434] Change comment to fixe a lot of undefined method --- .../modules/expensereport/doc/pdf_standard.modules.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php index 6d3bc5e8e65..6cdc7f4ffbc 100644 --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php @@ -642,7 +642,7 @@ class pdf_standard extends ModeleExpenseReport /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -866,7 +866,7 @@ class pdf_standard extends ModeleExpenseReport /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param int $tab_top Tab top * @param int $tab_height Tab height * @param int $nexY next y @@ -980,7 +980,7 @@ class pdf_standard extends ModeleExpenseReport /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object invoice * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -1092,7 +1092,7 @@ class pdf_standard extends ModeleExpenseReport /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 0e0adcbe43dcb210c64a54ee5a0fc3c8b46ad8c9 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:33:19 +0200 Subject: [PATCH 140/434] Change comment to fixe a lot of undefined method --- .../core/modules/facture/doc/pdf_crabe.modules.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index cd2f711d23a..51f554295ec 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -780,7 +780,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object invoice * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -965,7 +965,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -1139,7 +1139,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Amount already paid (in the currency of invoice) * @param int $posy Position depart @@ -1464,7 +1464,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1586,7 +1586,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1889,7 +1889,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 857505a8873349ee681cd1d1020de3ab471c986b Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:36:23 +0200 Subject: [PATCH 141/434] Change comment to fixe a lot of undefined method --- .../modules/facture/doc/pdf_sponge.modules.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 8695a46cae5..827e09081e7 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -917,7 +917,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object invoice * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -1055,7 +1055,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param tcpdf $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -1225,7 +1225,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show total to pay * - * @param TCPDI $pdf Object PDF + * @param TCPDI $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Amount already paid (in the currency of invoice) * @param int $posy Position depart @@ -1760,7 +1760,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show table for lines * - * @param tcpdf $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1820,7 +1820,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show top header of page. * - * @param Tcpdf $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -2141,7 +2141,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text @@ -2157,8 +2157,8 @@ class pdf_sponge extends ModelePDFFactures /** * Define Array Column Field * - * @param object $object common object - * @param Translate $outputlangs langs + * @param object $object common object + * @param Translate $outputlangs langs * @param int $hidedetails Do not show line details * @param int $hidedesc Do not show desc * @param int $hideref Do not show ref From c7bf47a00b74a4cf0984b0297bc64d181101d248 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:38:05 +0200 Subject: [PATCH 142/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php index 59bed960d1e..5d4ecff0983 100644 --- a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php +++ b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php @@ -472,7 +472,7 @@ class pdf_soleil extends ModelePDFFicheinter /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -536,7 +536,7 @@ class pdf_soleil extends ModelePDFFicheinter /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -709,7 +709,7 @@ class pdf_soleil extends ModelePDFFicheinter /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 2c4d8bceb683ea6c081b98354160e6cde1fc3c8b Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:39:54 +0200 Subject: [PATCH 143/434] Change comment to fixe a lot of undefined method --- .../core/modules/livraison/doc/pdf_typhon.modules.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php index b74f25d340a..891d5fce6fa 100644 --- a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php +++ b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2014 Regis Houssin * Copyright (C) 2007 Franky Van Liedekerke * Copyright (C) 2008 Chiptronik - * Copyright (C) 2011-2019 Philippe Grand + * Copyright (C) 2011-2020 Philippe Grand * Copyright (C) 2015 Marcos García * This program is free software; you can redistribute it and/or modify @@ -627,7 +627,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -656,7 +656,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -722,7 +722,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -896,7 +896,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From ed6d83687c892203a403b6037f027f53ff2b5fe1 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:44:44 +0200 Subject: [PATCH 144/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/project/doc/pdf_baleine.modules.php | 6 +++--- htdocs/core/modules/project/doc/pdf_beluga.modules.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/project/doc/pdf_baleine.modules.php b/htdocs/core/modules/project/doc/pdf_baleine.modules.php index 7a1b0a0bfe4..c36444dc405 100644 --- a/htdocs/core/modules/project/doc/pdf_baleine.modules.php +++ b/htdocs/core/modules/project/doc/pdf_baleine.modules.php @@ -516,7 +516,7 @@ class pdf_baleine extends ModelePDFProjects /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -567,7 +567,7 @@ class pdf_baleine extends ModelePDFProjects /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Project $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -658,7 +658,7 @@ class pdf_baleine extends ModelePDFProjects /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Project $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text diff --git a/htdocs/core/modules/project/doc/pdf_beluga.modules.php b/htdocs/core/modules/project/doc/pdf_beluga.modules.php index 334fc16ca18..a43e6e628cc 100644 --- a/htdocs/core/modules/project/doc/pdf_beluga.modules.php +++ b/htdocs/core/modules/project/doc/pdf_beluga.modules.php @@ -691,7 +691,7 @@ class pdf_beluga extends ModelePDFProjects /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -742,7 +742,7 @@ class pdf_beluga extends ModelePDFProjects /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Project $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -809,7 +809,7 @@ class pdf_beluga extends ModelePDFProjects /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Project $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 703de5286f29335dc39846ce08e9bd3f5f7abe09 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:46:07 +0200 Subject: [PATCH 145/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/project/doc/pdf_timespent.modules.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/project/doc/pdf_timespent.modules.php b/htdocs/core/modules/project/doc/pdf_timespent.modules.php index a6bf7fdace7..77bc4758391 100644 --- a/htdocs/core/modules/project/doc/pdf_timespent.modules.php +++ b/htdocs/core/modules/project/doc/pdf_timespent.modules.php @@ -447,7 +447,7 @@ class pdf_timespent extends ModelePDFProjects /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -498,7 +498,7 @@ class pdf_timespent extends ModelePDFProjects /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Project $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -589,7 +589,7 @@ class pdf_timespent extends ModelePDFProjects /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Project $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 8ff27f89e5c6dd8fc92947704bca46640e517982 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:48:25 +0200 Subject: [PATCH 146/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/propale/doc/pdf_azur.modules.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 279b5be2569..d97da48126e 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -1023,7 +1023,7 @@ class pdf_azur extends ModelePDFPropales /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Propal $object Object propal * @param int $deja_regle Amount already paid * @param int $posy Start position @@ -1297,7 +1297,7 @@ class pdf_azur extends ModelePDFPropales /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1414,7 +1414,7 @@ class pdf_azur extends ModelePDFPropales /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1665,7 +1665,7 @@ class pdf_azur extends ModelePDFPropales /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text @@ -1683,7 +1683,7 @@ class pdf_azur extends ModelePDFPropales /** * Show area for the customer to sign * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $posy Position depart * @param Translate $outputlangs Objet langs From 3b80e9a08e922b0cb93b1431da1bf311e55531cc Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:50:30 +0200 Subject: [PATCH 147/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/propale/doc/pdf_cyan.modules.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index 705294979dc..f804e236d25 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -1145,7 +1145,7 @@ class pdf_cyan extends ModelePDFPropales /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -1432,7 +1432,7 @@ class pdf_cyan extends ModelePDFPropales /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1486,7 +1486,7 @@ class pdf_cyan extends ModelePDFPropales /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1737,7 +1737,7 @@ class pdf_cyan extends ModelePDFPropales /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text @@ -1753,7 +1753,7 @@ class pdf_cyan extends ModelePDFPropales /** * Show area for the customer to sign * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $posy Position depart * @param Translate $outputlangs Objet langs From 679625daeeb2581b2a6429f2e4d2f734611ffc53 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 09:51:15 +0200 Subject: [PATCH 148/434] Trans --- htdocs/langs/en_US/withdrawals.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 662c587108a..e869556f691 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -77,7 +77,7 @@ StatusMotif8=Other reason CreateForSepaFRST=Create direct debit file (SEPA FRST) CreateForSepaRCUR=Create direct debit file (SEPA RCUR) CreateAll=Create direct debit file (all) -CreateFileForPaymentByBankTransfer=Create file for credit transfer (all) +CreateFileForPaymentByBankTransfer=Create file for credit transfer CreateSepaFileForPaymentByBankTransfer=Create credit transfer file (SEPA) CreateGuichet=Only office CreateBanque=Only bank From 9fd520b5d4cc2e18858dffbf97186d4551d6dca2 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:52:11 +0200 Subject: [PATCH 149/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/reception/doc/pdf_squille.modules.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/reception/doc/pdf_squille.modules.php b/htdocs/core/modules/reception/doc/pdf_squille.modules.php index b5fe6c53c36..dd3d62fca03 100644 --- a/htdocs/core/modules/reception/doc/pdf_squille.modules.php +++ b/htdocs/core/modules/reception/doc/pdf_squille.modules.php @@ -573,7 +573,7 @@ class pdf_squille extends ModelePdfReception /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -675,7 +675,7 @@ class pdf_squille extends ModelePdfReception /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -757,7 +757,7 @@ class pdf_squille extends ModelePdfReception /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1003,7 +1003,7 @@ class pdf_squille extends ModelePdfReception /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From d446a38b34b8b4ac33bef9106e2c030e129c59c6 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:54:19 +0200 Subject: [PATCH 150/434] Change comment to fixe a lot of undefined method --- .../supplier_invoice/doc/pdf_canelle.modules.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php index 11ff7780002..974f3e186c3 100644 --- a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php +++ b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php @@ -617,7 +617,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object invoice * @param int $deja_regle Amount already paid (in the currency of invoice) * @param int $posy Position depart @@ -843,7 +843,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -949,7 +949,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -1040,7 +1040,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param FactureFournisseur $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1252,7 +1252,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param FactureFournisseur $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 1ea21ee1b850c175c9b05b1a52eca6445a676162 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:56:48 +0200 Subject: [PATCH 151/434] Change comment to fixe a lot of undefined method --- .../supplier_order/doc/pdf_cornas.modules.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php index 1fdb8b09aef..10acc9d27e2 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php @@ -808,7 +808,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param CommandeFournisseur $object Object order * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -824,7 +824,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param CommandeFournisseur $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -890,7 +890,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -1103,7 +1103,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1176,7 +1176,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param CommandeFournisseur $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1416,7 +1416,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param CommandeFournisseur $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 3a2e5274545558c971c0492660005d4cff19f3fd Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 09:58:47 +0200 Subject: [PATCH 152/434] Change comment to fixe a lot of undefined method --- .../supplier_order/doc/pdf_muscadet.modules.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php index 5dd240fb544..a2907d8b5cf 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php @@ -693,7 +693,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param CommandeFournisseur $object Object order * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -709,7 +709,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param CommandeFournisseur $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -775,7 +775,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -988,7 +988,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1094,7 +1094,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param CommandeFournisseur $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1333,7 +1333,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param CommandeFournisseur $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 6fa3e8df4e6bf6a0cf909b2af6a79c2765b8b049 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 10:00:20 +0200 Subject: [PATCH 153/434] Change comment to fixe a lot of undefined method --- .../modules/supplier_payment/doc/pdf_standard.modules.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php index a4f9bc93823..db6ce567305 100644 --- a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php @@ -508,7 +508,7 @@ class pdf_standard extends ModelePDFSuppliersPayments /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param PaiementFourn $object Object PaiementFourn * @param int $posy Position depart * @param Translate $outputlangs Objet langs @@ -567,7 +567,7 @@ class pdf_standard extends ModelePDFSuppliersPayments /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param integer $tab_top Top position of table * @param integer $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -612,7 +612,7 @@ class pdf_standard extends ModelePDFSuppliersPayments /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param FactureFournisseur $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -788,7 +788,7 @@ class pdf_standard extends ModelePDFSuppliersPayments /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param FactureFournisseur $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From d6c84ef5ce5aca5acc41aef504720cb9c41fd4a9 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 10:02:25 +0200 Subject: [PATCH 154/434] Change comment to fixe a lot of undefined method --- .../supplier_proposal/doc/pdf_aurore.modules.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index 608b3fbd392..4a0dc601fbf 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -691,7 +691,7 @@ class pdf_aurore extends ModelePDFSupplierProposal /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object proposal * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -707,7 +707,7 @@ class pdf_aurore extends ModelePDFSupplierProposal /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -874,7 +874,7 @@ class pdf_aurore extends ModelePDFSupplierProposal /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -1145,7 +1145,7 @@ class pdf_aurore extends ModelePDFSupplierProposal /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1251,7 +1251,7 @@ class pdf_aurore extends ModelePDFSupplierProposal /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1463,7 +1463,7 @@ class pdf_aurore extends ModelePDFSupplierProposal /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 0d6274c8fe6b9b46fdd5255d998926d20cfc31a6 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 10:04:54 +0200 Subject: [PATCH 155/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/bank/doc/pdf_ban.modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/bank/doc/pdf_ban.modules.php b/htdocs/core/modules/bank/doc/pdf_ban.modules.php index 3aa46add2ac..05bb4636e53 100644 --- a/htdocs/core/modules/bank/doc/pdf_ban.modules.php +++ b/htdocs/core/modules/bank/doc/pdf_ban.modules.php @@ -292,7 +292,7 @@ class pdf_ban extends ModeleBankAccountDoc /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Project $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -377,7 +377,7 @@ class pdf_ban extends ModeleBankAccountDoc /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Project $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text From 85b2adaaec3e5f07e4cdd9381acc82680ed5c897 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 10:13:18 +0200 Subject: [PATCH 156/434] Change comment to fixe a lot of undefined method --- .../core/modules/bank/doc/pdf_sepamandate.modules.php | 10 +++++----- htdocs/core/modules/cheque/doc/pdf_blochet.class.php | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php b/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php index e50acfb6c2a..5aa63711ba0 100644 --- a/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php +++ b/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php @@ -424,7 +424,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -447,7 +447,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -485,7 +485,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc /** * Show area for the customer to sign * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Facture $object Object invoice * @param int $posy Position depart * @param Translate $outputlangs Objet langs @@ -527,7 +527,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF &$pdf Object PDF * @param Project $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -617,7 +617,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Project $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text diff --git a/htdocs/core/modules/cheque/doc/pdf_blochet.class.php b/htdocs/core/modules/cheque/doc/pdf_blochet.class.php index ec6f52dfec7..30b0ea62b46 100644 --- a/htdocs/core/modules/cheque/doc/pdf_blochet.class.php +++ b/htdocs/core/modules/cheque/doc/pdf_blochet.class.php @@ -213,7 +213,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Generate Header * - * @param PDF $pdf Pdf object + * @param TCPDF &$pdf Pdf object * @param int $page Current page number * @param int $pages Total number of pages * @param Translate $outputlangs Object language for output @@ -321,7 +321,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Output array * - * @param PDF $pdf PDF object + * @param TCPDF &$pdf PDF object * @param int $pagenb Page nb * @param int $pages Pages * @param Translate $outputlangs Object lang @@ -390,7 +390,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text @@ -404,6 +404,8 @@ class BordereauChequeBlochet extends ModeleChequeReceipts $showdetails = $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; // Line of free text + $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); $newfreetext = ''; $paramfreetext = 'BANK_CHEQUERECEIPT_FREE_TEXT'; if (!empty($conf->global->$paramfreetext)) From 42fcb64700336b1235578cedf55fa472a63d8ae5 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Mon, 3 Aug 2020 10:26:01 +0200 Subject: [PATCH 157/434] Change comment to fixe a lot of undefined method --- htdocs/core/modules/member/doc/pdf_standard.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/member/doc/pdf_standard.class.php b/htdocs/core/modules/member/doc/pdf_standard.class.php index dd4b15d6135..9ba2956857a 100644 --- a/htdocs/core/modules/member/doc/pdf_standard.class.php +++ b/htdocs/core/modules/member/doc/pdf_standard.class.php @@ -37,7 +37,7 @@ class pdf_standard extends CommonStickerGenerator /** * Output a sticker on page at position _COUNTX, _COUNTY (_COUNTX and _COUNTY start from 0) * - * @param PDF $pdf PDF reference + * @param TCPDF &$pdf PDF reference * @param Translate $outputlangs Output langs * @param array $param Associative array containing label content and optional parameters * @return void @@ -53,7 +53,7 @@ class pdf_standard extends CommonStickerGenerator * - __LOGO__ is replace with company logo * - __PHOTO__ is replace with photo provided as parameter * - * @param PDF $pdf PDF + * @param TCPDF &$pdf PDF * @param string $textleft Text left * @param string $header Header * @param string $footer Footer From b026896a98b6be72835c6410f7214423b80fb2b5 Mon Sep 17 00:00:00 2001 From: quentin Date: Mon, 3 Aug 2020 10:33:48 +0200 Subject: [PATCH 158/434] FIX product label and desc were never updated when modifying trans --- htdocs/product/traduction.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index 59d30923f87..25c6eeb4caf 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -78,6 +78,7 @@ $cancel != $langs->trans("Cancel") && $object->label = $_POST["libelle"]; $object->description = dol_htmlcleanlastbr($_POST["desc"]); $object->other = dol_htmlcleanlastbr($_POST["other"]); + $object->update($object->id, $user); } else { From 63b15dd1b643d01235685220712499ae6f54f320 Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Mon, 3 Aug 2020 11:17:30 +0200 Subject: [PATCH 159/434] Fix: User can see events that are not assigned to it --- htdocs/core/lib/security.lib.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 1a8045df014..ed0424d8968 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -1,6 +1,7 @@ * Copyright (C) 2008-2017 Regis Houssin + * Copyright (C) 2020 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -247,6 +248,26 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f { if (! $user->rights->projet->lire && ! $user->rights->projet->all->lire) { $readok=0; $nbko++; } } + elseif ($feature == 'agenda') + { + if ($objectid > 0) { + require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php'; + $action = new ActionComm($db); + $action->fetch($objectid); + if (empty($user->rights->agenda->allactions->read) && (($action->authorid != $user->id && $action->userownerid != $user->id && !(array_key_exists($user->id, + $action->userassigned))) || empty($user->rights->agenda->myactions->read))) { + $readok = 0; + $nbko++; + } + } + else{ + if (empty($user->rights->agenda->myactions->read) && empty($user->rights->agenda->allactions->read)) { + $readok = 0; + $nbko++; + } + } + + } elseif (! empty($feature2)) // This is for permissions on 2 levels { $tmpreadok=1; From 72b2fb442b95fe107c05279bfb0ec606f86318f1 Mon Sep 17 00:00:00 2001 From: quentin Date: Mon, 3 Aug 2020 11:17:39 +0200 Subject: [PATCH 160/434] fix test libelle --- htdocs/core/lib/pdf.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index abff8486cc0..ade9c5f6101 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1215,7 +1215,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, global $db, $conf, $langs; $idprod=(! empty($object->lines[$i]->fk_product)?$object->lines[$i]->fk_product:false); - $label=(! empty($object->lines[$i]->label)?$object->lines[$i]->label:(! empty($object->lines[$i]->product_label)?$object->lines[$i]->product_label:'')); + $label=(!empty($object->lines[$i]->label) ? $object->lines[$i]->label : (!empty($object->lines[$i]->libelle) ? $object->lines[$i]->libelle : (!empty($object->lines[$i]->product_label) ? $object->lines[$i]->product_label : ''))); $desc=(! empty($object->lines[$i]->desc)?$object->lines[$i]->desc:(! empty($object->lines[$i]->description)?$object->lines[$i]->description:'')); $ref_supplier=(! empty($object->lines[$i]->ref_supplier)?$object->lines[$i]->ref_supplier:(! empty($object->lines[$i]->ref_fourn)?$object->lines[$i]->ref_fourn:'')); // TODO Not yet saved for supplier invoices, only supplier orders $note=(! empty($object->lines[$i]->note)?$object->lines[$i]->note:''); From e64b8eaf40de8bffb30f9f50cf88450137e4345b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 11:21:13 +0200 Subject: [PATCH 161/434] Fix debug credit transfer module --- dev/resources/sepa/text.txt | 6 + .../class/bonprelevement.class.php | 374 ++++++++++++------ htdocs/langs/en_US/admin.lang | 6 +- htdocs/langs/fr_FR/withdrawals.lang | 2 +- 4 files changed, 257 insertions(+), 131 deletions(-) diff --git a/dev/resources/sepa/text.txt b/dev/resources/sepa/text.txt index e6c05276be2..dbcfeded5a4 100644 --- a/dev/resources/sepa/text.txt +++ b/dev/resources/sepa/text.txt @@ -1,2 +1,8 @@ +Spec for credit transfer: +https://docs.oracle.com/cd/E39124_01/doc.91/e60210/fields_sepa_pay_file_appx.htm#EOAEL00515 + +To validate a SEPA file: +xmllint --schema pain.001.001.03.xsd T200801.xml --noout + To test a SEPA file: https://www.mesfluxdepaiement.fr/testez-vos-fichiers-sepa diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 29c70ba8fab..00a388e31dd 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1142,7 +1142,7 @@ class BonPrelevement extends CommonObject if (!$error) { /* - * Create file of direct debit order or credit transfer into a XML file + * Create file of type='direct-debit' for direct debit order or type='bank-transfer' for credit transfer into a XML file */ dol_syslog(__METHOD__."::Init direct debit or credit transfer file for ".count($factures_prev)." invoices", LOG_DEBUG); @@ -1569,11 +1569,11 @@ class BonPrelevement extends CommonObject // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf if ($result != -2) { - $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format); + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); } /** - * SECTION CREATION SEPA FILE - CREDTI TRANSFER - ISO200022 + * SECTION CREATION SEPA FILE - CREDIT TRANSFER - ISO200022 */ // SEPA File Header fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); @@ -1674,7 +1674,7 @@ class BonPrelevement extends CommonObject // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf if ($result != -2) { - $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format); + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); } /** @@ -1794,6 +1794,22 @@ class BonPrelevement extends CommonObject } + /** + * Build RUM number for a customer bank account + * + * @param string $row_code_client Customer code (soc.code_client) + * @param int $row_datec Creation date of bank account (rib.datec) + * @param string $row_drum Id of customer bank account (rib.rowid) + * @return string RUM number + */ + public static function buildRumNumber($row_code_client, $row_datec, $row_drum) + { + global $langs; + $pre = substr(dol_string_nospecial(dol_string_unaccent($langs->transnoentitiesnoconv('RUM'))), 0, 3); // Must always be on 3 char ('RUM' or 'UMR'. This is a protection against bad translation) + return $pre.'-'.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Write recipient of request (customer) @@ -1807,9 +1823,11 @@ class BonPrelevement extends CommonObject * @param string $ref ref of invoice * @param int $facid id of invoice * @param string $rib_dom rib domiciliation + * @param string $type 'direct-debit' or 'credit-transfer' * @return void + * @see EnregDestinataireSEPA() */ - public function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom = '') + public function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom = '', $type = 'direct-debit') { // phpcs:enable fputs($this->file, "06"); @@ -1866,22 +1884,6 @@ class BonPrelevement extends CommonObject fputs($this->file, "\n"); } - - /** - * Build RUM number for a customer bank account - * - * @param string $row_code_client Customer code (soc.code_client) - * @param int $row_datec Creation date of bank account (rib.datec) - * @param string $row_drum Id of customer bank account (rib.rowid) - * @return string RUM number - */ - public static function buildRumNumber($row_code_client, $row_datec, $row_drum) - { - global $langs; - $pre = substr(dol_string_nospecial(dol_string_unaccent($langs->transnoentitiesnoconv('RUM'))), 0, 3); // Must always be on 3 char ('RUM' or 'UMR'. This is a protection against bad translation) - return $pre.'-'.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec); - } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Write recipient of request (customer) @@ -1903,9 +1905,11 @@ class BonPrelevement extends CommonObject * @param string $row_datec rib.datec, * @param string $row_drum rib.rowid used to generate rum * @param string $row_rum rib.rum Rum defined on company bank account + * @param string $type 'direct-debit' or 'credit-transfer' * @return string Return string with SEPA part DrctDbtTxInf + * @see EnregDestinataire() */ - public function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum) + public function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum, $type = 'direct-debit') { // phpcs:enable global $conf; @@ -1913,7 +1917,7 @@ class BonPrelevement extends CommonObject include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $CrLf = "\n"; - $Rowing = sprintf("%06d", $row_idfac); + $Rowing = sprintf("%10d", $row_idfac); // Define value for RUM // Example: RUMCustomerCode-CustomerBankAccountId-01424448606 (note: Date is date of creation of CustomerBankAccountId) @@ -1922,57 +1926,108 @@ class BonPrelevement extends CommonObject // Define date of RUM signature $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); - $XML_DEBITOR = ''; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - // $XML_DEBITOR .=' '.('AS-'.dol_trunc($row_ref,20).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters - $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.round($row_somme, 2).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$Rum.''.$CrLf; - $XML_DEBITOR .= ' '.$DtOfSgntr.''.$CrLf; - $XML_DEBITOR .= ' false'.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$row_bic.''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$row_country_code.''.$CrLf; - $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); - $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); - if (trim($addressline1)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; - if (trim($addressline2)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - // $XML_DEBITOR .=' '.($row_ref.'/'.$Rowing.'/'.$Rum).''.$CrLf; - // $XML_DEBITOR .=' '.dol_trunc($row_ref, 135).''.$CrLf; // 140 max - $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - return $XML_DEBITOR; + if ($type != 'credit-transfer') { + // SEPA Paiement Information of buyer for Direct debit + $XML_DEBITOR = ''; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum) + $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.round($row_somme, 2).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$Rum.''.$CrLf; + $XML_DEBITOR .= ' '.$DtOfSgntr.''.$CrLf; + $XML_DEBITOR .= ' false'.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$row_bic.''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$row_country_code.''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); + if (trim($addressline1)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; + if (trim($addressline2)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + // A string with some information on payment - 140 max + $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + return $XML_DEBITOR; + } else { + // SEPA Paiement Information of seller for Credit Transfer + $XML_CREDITOR = ''; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum) + $XML_CREDITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.round($row_somme, 2).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + /* + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$Rum.''.$CrLf; + $XML_CREDITOR .= ' '.$DtOfSgntr.''.$CrLf; + $XML_CREDITOR .= ' false'.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + */ + //$XML_CREDITOR .= ' SLEV'.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$row_bic.''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$row_country_code.''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); + if (trim($addressline1)) $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; + if (trim($addressline2)) $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + // A string with some information on payment - 140 max + $XML_CREDITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + return $XML_CREDITOR; + } } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Write sender of request (me) + * Write sender of request (me). * + * @param string $type 'direct-debit' or 'credit-transfer' * @return void + * @see EnregEmetteurSEPA() */ - public function EnregEmetteur() + public function EnregEmetteur($type = 'direct-debit') { // phpcs:enable fputs($this->file, "03"); @@ -2044,9 +2099,11 @@ class BonPrelevement extends CommonObject * @param float $total Total * @param string $CrLf End of line character * @param string $format FRST or RCUR or ALL + * @param string $type 'direct-debit' or 'credit-transfer' * @return string String with SEPA Sender + * @see EnregEmetteur() */ - public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST') + public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST', $type = 'direct-debit') { // phpcs:enable // SEPA INITIALISATION @@ -2073,7 +2130,7 @@ class BonPrelevement extends CommonObject $this->raison_sociale = $account->proprio; } - // Récupération info demandeur + // Get pending payments $sql = "SELECT rowid, ref"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_bons as pb"; @@ -2084,69 +2141,132 @@ class BonPrelevement extends CommonObject { $obj = $this->db->fetch_object($resql); - // DONNEES BRUTES : par la suite Rows['XXX'] de la requete au dessus $country = explode(':', $configuration->global->MAIN_INFO_SOCIETE_COUNTRY); $IdBon = sprintf("%05d", $obj->rowid); $RefBon = $obj->ref; - // SEPA Paiement Information - $XML_SEPA_INFO = ''; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; - $XML_SEPA_INFO .= ' DD'.$CrLf; - $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; - $XML_SEPA_INFO .= ' '.$total.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' CORE'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$format.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$dateTime_ETAD.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; - $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); - $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); - if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; - if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - /* $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; - $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; - $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf;*/ - $XML_SEPA_INFO .= ' SLEV'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; + if ($type != 'credit-transfer') { + // SEPA Paiement Information of my company for Direct debit + $XML_SEPA_INFO = ''; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' DD'.$CrLf; + $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; + $XML_SEPA_INFO .= ' '.$total.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' CORE'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$format.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$dateTime_ETAD.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); + if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; + if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + /* $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + } else { + // SEPA Paiement Information of my company for Credit Transfer + $XML_SEPA_INFO = ''; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' TRF'.$CrLf; + //$XML_SEPA_INFO .= ' False'.$CrLf; + $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; + $XML_SEPA_INFO .= ' '.$total.''.$CrLf; + /* + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' TRF'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SECU'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + */ + $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); + if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; + if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + /* $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV + /*$XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + } } else { diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 57d430fc9e4..bd957f0ca02 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -546,9 +546,9 @@ Module54Desc=Management of contracts (services or recurring subscriptions) Module55Name=Barcodes Module55Desc=Barcode management Module56Name=Payment by credit transfer -Module56Desc=Management of payment of suppliers by credit transfer orders. It includes generation of SEPA file for European countries. -Module57Name=Bank Direct Debit payments -Module57Desc=Management of Direct Debit payment orders. It includes generation of SEPA file for European countries. +Module56Desc=Management of payment of suppliers by Credit Transfer orders. It includes generation of SEPA file for European countries. +Module57Name=Payments by Direct Debit +Module57Desc=Management of Direct Debit orders. It includes generation of SEPA file for European countries. Module58Name=ClickToDial Module58Desc=Integration of a ClickToDial system (Asterisk, ...) Module59Name=Bookmark4u diff --git a/htdocs/langs/fr_FR/withdrawals.lang b/htdocs/langs/fr_FR/withdrawals.lang index 446de9e09d3..d05f2663cfc 100644 --- a/htdocs/langs/fr_FR/withdrawals.lang +++ b/htdocs/langs/fr_FR/withdrawals.lang @@ -77,7 +77,7 @@ StatusMotif8=Autre motif CreateForSepaFRST=Créer fichier de prélèvement (SEPA FRST) CreateForSepaRCUR=Créer fichier de prélèvement (SEPA RCUR) CreateAll=Créer le fichier de prélèvement (tout) -CreateFileForPaymentByBankTransfer=Créer un virement (tout) +CreateFileForPaymentByBankTransfer=Créer un fichier de virement CreateSepaFileForPaymentByBankTransfer=Créer un fichier de virement (SEPA) CreateGuichet=Seulement guichet CreateBanque=Seulement banque From 9926eac1926877bc97e3ceab8376053e48a098f0 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 3 Aug 2020 09:26:36 +0000 Subject: [PATCH 162/434] Fixing style errors. --- htdocs/core/lib/security.lib.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index ed0424d8968..e4dde96b464 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -266,7 +266,6 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f $nbko++; } } - } elseif (! empty($feature2)) // This is for permissions on 2 levels { From 55f3a8b4f8754d7df76ef5dc3147147af1243c73 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 11:37:55 +0200 Subject: [PATCH 163/434] Fix col size too large by migrating to dynamic format on tables --- htdocs/admin/system/database-tables.php | 38 ++++++++++++++++--------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index 97b8237c6f2..e20347b954c 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -28,21 +28,27 @@ require '../../main.inc.php'; $langs->load("admin"); -if (!$user->admin) +if (!$user->admin) { accessforbidden(); +} $action = GETPOST('action', 'alpha'); if ($action == 'convert') { - $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ENGINE=INNODB"; + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ENGINE=INNODB"; $db->query($sql); } if ($action == 'convertutf8') { - $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; - $db->query($sql); + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; + $db->query($sql); +} +if ($action == 'convertdynamic') +{ + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ROW_FORMAT=DYNAMIC;"; + $db->query($sql); } @@ -87,8 +93,8 @@ else { if ($base == 1) { - print '
'; - print ''; + print '
'; + print '
'; print ''; print ''; print ''; @@ -119,13 +125,19 @@ else print ''; if (isset($obj->Engine) && $obj->Engine == "MyISAM") { - print ''; + print ''; } else { print ''; } - print ''; + print ''; print ''; print ''; print ''; @@ -136,7 +148,7 @@ else print ''; print ''; @@ -149,8 +161,8 @@ else if ($base == 2) { - print '
'; - print '
'.$langs->trans("TableName").''.$langs->trans("Type").''.$obj->Engine.''.$langs->trans("Convert").' InnoDb'.$langs->trans("Convert").' InnoDb '.$obj->Row_format.''; + print $obj->Row_format; + if (isset($obj->Row_format) && (in_array($obj->Row_format, array("Compact")))) + { + print '
'.$langs->trans("Convert").' Dynamic'; + } + print '
'.$obj->Rows.''.$obj->Avg_row_length.''.$obj->Data_length.''.$obj->Collation; if (isset($obj->Collation) && (in_array($obj->Collation, array("utf8mb4_general_ci", "utf8mb4_unicode_ci", "latin1_swedish_ci")))) { - print '
'.$langs->trans("Convert").' UTF8'; + print '
'.$langs->trans("Convert").' UTF8'; } print '
'; + print '
'; + print '
'; print ''; print ''; print ''; @@ -189,8 +201,8 @@ else if ($base == 4) { // Sqlite by PDO or by Sqlite3 - print '
'; - print '
'.$langs->trans("TableName").'Nb of tuples
'; + print '
'; + print '
'; print ''; print ''; print ''; From bbfca90260576890d2b1e77833caa7ec782c77d7 Mon Sep 17 00:00:00 2001 From: quentin Date: Mon, 3 Aug 2020 11:54:26 +0200 Subject: [PATCH 164/434] FIX Missing PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE conf in supplier order --- htdocs/fourn/commande/card.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 43964b38431..0b7eb338b69 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -460,11 +460,26 @@ if (empty($reshook)) if ($idprod > 0) { $label = $productsupplier->label; - + // Define output language + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) + $newlang = GETPOST('lang_id', 'aZ09'); + if (empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $desc = (!empty($productsupplier->multilangs [$outputlangs->defaultlang] ["description"])) ? $productsupplier->multilangs [$outputlangs->defaultlang] ["description"] : $productsupplier->description; + } else { + $desc = $productsupplier->description; + } // if we use supplier description of the products if (!empty($productsupplier->desc_supplier) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) { $desc = $productsupplier->desc_supplier; - } else $desc = $productsupplier->description; + } if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); From d59bcd3f5bd251f7574bb7460558423be3db886e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 12:08:33 +0200 Subject: [PATCH 165/434] FFIX error creating record when extrafields price exists in other entity --- htdocs/core/class/commonobject.class.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ae8ae544d52..3359dcb9a64 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5531,11 +5531,12 @@ abstract class CommonObject $new_array_options[$key] = null; } break; - case 'double': + case 'price': + case 'double': $value = price2num($value); if (!is_numeric($value) && $value != '') { - dol_syslog($langs->trans("ExtraFieldHasWrongValue")." sur ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); + dol_syslog($langs->trans("ExtraFieldHasWrongValue")." for ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); return -1; } @@ -5589,9 +5590,6 @@ abstract class CommonObject $new_array_options[$key] = $this->array_options[$key]; } break; - case 'price': - $new_array_options[$key] = price2num($this->array_options[$key]); - break; case 'date': case 'datetime': // If data is a string instead of a timestamp, we convert it @@ -5689,7 +5687,7 @@ abstract class CommonObject { if (!isset($extrafields->attributes[$this->table_element]['type'][$tmpkey])) // If field not already added previously { - if (in_array($tmpval, array('int', 'double'))) $sql .= ", 0"; + if (in_array($tmpval, array('int', 'double', 'price'))) $sql .= ", 0"; else $sql .= ", ''"; } } @@ -7963,6 +7961,7 @@ abstract class CommonObject $now = dol_now(); $fieldvalues = $this->setSaveQuery(); + if (array_key_exists('date_creation', $fieldvalues) && empty($fieldvalues['date_creation'])) $fieldvalues['date_creation'] = $this->db->idate($now); if (array_key_exists('fk_user_creat', $fieldvalues) && !($fieldvalues['fk_user_creat'] > 0)) $fieldvalues['fk_user_creat'] = $user->id; unset($fieldvalues['rowid']); // The field 'rowid' is reserved field name for autoincrement field so we don't need it into insert. From 576363f353ff6d1392d407be58b544d769379cd9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 12:26:26 +0200 Subject: [PATCH 166/434] Fix error message --- htdocs/projet/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index 1fb01bb52bb..587493709f2 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -180,14 +180,14 @@ if (empty($reshook)) if ($result < 0) { $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); $error++; } } else { $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); $error++; } if (!$error && !empty($object->id) > 0) From ce18a4f029d10a04fce28a17f8041d3f937938ec Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Mon, 3 Aug 2020 12:28:12 +0200 Subject: [PATCH 167/434] FIX 12.0 - in dol_string_onlythesehtmltags, remove the class attribute by default --- htdocs/core/lib/functions.lib.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 91a3061dd41..76b94481823 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5685,12 +5685,13 @@ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto = * Clean a string to keep only desirable HTML tags. * * @param string $stringtoclean String to clean - * @param string $cleanalsosomestyles Clean also some tags + * @param boolean $cleanalsosomestyles Remove absolute/fixed positioning from inline styles + * @param boolean $removeclassattribute Remove the class attribute from tags * @return string String cleaned * * @see dol_escape_htmltag() strip_tags() dol_string_nohtmltag() dol_string_neverthesehtmltags() */ -function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1) +function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1, $removeclassattribute = 1) { $allowed_tags = array( "html", "head", "meta", "body", "article", "a", "abbr", "b", "blockquote", "br", "cite", "div", "dl", "dd", "dt", "em", "font", "img", "ins", "hr", "i", "li", "link", @@ -5702,7 +5703,10 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1) $allowed_tags_string = '<'.$allowed_tags_string.'>'; if ($cleanalsosomestyles) { - $stringtoclean = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/', '', $stringtoclean); // Note: If hacker try to introduce css comment into string to bypass this regex, the string must also be encoded by the dol_htmlentitiesbr during output so it become harmless + $stringtoclean = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/i', '', $stringtoclean); // Note: If hacker try to introduce css comment into string to bypass this regex, the string must also be encoded by the dol_htmlentitiesbr during output so it become harmless + } + if ($removeclassattribute) { + $stringtoclean = preg_replace('/(<[^>]+)\s+class=((["\']).*?\\3|\\w*)/i', '\\1', $stringtoclean); } $temp = strip_tags($stringtoclean, $allowed_tags_string); From c2bb0431f0b0f390a3d8263d6e57504dce29623c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 12:31:30 +0200 Subject: [PATCH 168/434] FIX input field of extrafields must keep data if form submit fails. --- htdocs/core/class/commonobject.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 3359dcb9a64..9894d2e6c64 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7048,7 +7048,7 @@ abstract class CommonObject if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label']) > 0) { $out .= "\n"; - $out .= ' '; + $out .= ' '; $out .= "\n"; $extrafields_collapse_num = ''; @@ -7186,7 +7186,7 @@ abstract class CommonObject // HTML, select, integer and text add default value if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text', 'select', 'int'))) { - if ($action == 'create') $value = $extrafields->attributes[$this->table_element]['default'][$key]; + if ($action == 'create') $value = GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) ? GETPOST($keyprefix.'options_'.$key.$keysuffix, 'none', 3) : $extrafields->attributes[$this->table_element]['default'][$key]; else $value = $this->array_options['options_'.$key]; } @@ -7270,7 +7270,7 @@ abstract class CommonObject setListDependencies(); }); '."\n"; - $out .= ' '."\n"; + $out .= ' '."\n"; } } return $out; From defbd26f95f058d59c91800ecf7773a1a6f2c047 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 12:33:22 +0200 Subject: [PATCH 169/434] Help to fight errors ErrorBadValueForParamNotAString --- htdocs/core/class/translate.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index 3fc3151030a..f20fcbcd5b9 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -546,7 +546,10 @@ class Translate { global $conf, $db; - if (!is_string($key)) return 'ErrorBadValueForParamNotAString'; // Avoid multiple errors with code not using function correctly. + if (!is_string($key)) { + //xdebug_print_function_stack('ErrorBadValueForParamNotAString'); + return 'ErrorBadValueForParamNotAString'; // Avoid multiple errors with code not using function correctly. + } $newstr = $key; if (preg_match('/^Civility([0-9A-Z]+)$/i', $key, $reg)) From 8c34acbf55ae69153cfa3fa5292c5f2071bc3e21 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 14:11:15 +0200 Subject: [PATCH 170/434] FIX Warning if no bank account defined --- .../class/bonprelevement.class.php | 252 +++++++++--------- htdocs/compta/prelevement/create.php | 13 +- htdocs/societe/class/societe.class.php | 42 +-- 3 files changed, 158 insertions(+), 149 deletions(-) diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 00a388e31dd..929c0958d71 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1473,7 +1473,7 @@ class BonPrelevement extends CommonObject * * @param string $format FRST, RCUR or ALL * @param string $executiondate Date to execute transfer - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return int >=0 if OK, <0 if KO */ public function generate($format = 'ALL', $executiondate = '', $type = 'direct-debit') @@ -1501,114 +1501,9 @@ class BonPrelevement extends CommonObject { $found++; - if ($type == 'bank-transfer') { + if ($type != 'bank-transfer') { /** - * SECTION CREATION FICHIER SEPA - CREDIT TRANSFER - */ - // SEPA Initialisation - $CrLf = "\n"; - - $now = dol_now(); - - $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S'); - - $date_actu = $now; - if (!empty($executiondate)) $date_actu = $executiondate; - - $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d'); - $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S'); - $fileCrediteurSection = ''; - $fileEmetteurSection = ''; - $i = 0; - - /* - * Section Creditor (sepa Crediteurs bloc lines) - */ - - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; - $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; - $sql .= " f.ref as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; - $sql .= " FROM"; - $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; - $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf,"; - $sql .= " ".MAIN_DB_PREFIX."societe as soc,"; - $sql .= " ".MAIN_DB_PREFIX."c_country as c,"; - $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib"; - $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; - $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture_fourn = f.rowid"; - $sql .= " AND soc.fk_pays = c.rowid"; - $sql .= " AND soc.rowid = f.fk_soc"; - $sql .= " AND rib.fk_soc = f.fk_soc"; - $sql .= " AND rib.default_rib = 1"; - $sql .= " AND rib.type = 'ban'"; - //print $sql; - - // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); - $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum); - $this->total = $this->total + $obj->somme; - $i++; - } - $nbtotalDrctDbtTxInf = $i; - } - else - { - fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers - $result = -2; - } - - // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf - if ($result != -2) - { - $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); - } - - /** - * SECTION CREATION SEPA FILE - CREDIT TRANSFER - ISO200022 - */ - // SEPA File Header - fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); - fputs($this->file, ''.$CrLf); - fputs($this->file, ' '.$CrLf); - // SEPA Group header - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.('CREDTRANS'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); - fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); - fputs($this->file, ' '.$i.''.$CrLf); - fputs($this->file, ' '.$this->total.''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$conf->global->PRELEVEMENT_ICS.''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - // SEPA File Emetteur (mycompany) - if ($result != -2) - { fputs($this-> file, $fileEmetteurSection); } - // SEPA File Creditors - if ($result != -2) - { fputs($this-> file, $fileCrediteurSection); } - // SEPA FILE FOOTER - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ''.$CrLf); - } else { - /** - * SECTION CREATION FICHIER SEPA + * SECTION CREATION FICHIER SEPA - DIRECT DEBIT */ // SEPA Initialisation $CrLf = "\n"; @@ -1659,7 +1554,7 @@ class BonPrelevement extends CommonObject { $obj = $this->db->fetch_object($resql); $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); - $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum); + $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); $this->total = $this->total + $obj->somme; $i++; } @@ -1686,7 +1581,7 @@ class BonPrelevement extends CommonObject fputs($this->file, ' '.$CrLf); // SEPA Group header fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.('PREL'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); + fputs($this->file, ' '.('DD/'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); fputs($this->file, ' '.$i.''.$CrLf); fputs($this->file, ' '.$this->total.''.$CrLf); @@ -1711,21 +1606,126 @@ class BonPrelevement extends CommonObject fputs($this->file, ' '.$CrLf); fputs($this->file, ' '.$CrLf); fputs($this->file, ''.$CrLf); + } else { + /** + * SECTION CREATION FICHIER SEPA - CREDIT TRANSFER + */ + // SEPA Initialisation + $CrLf = "\n"; + + $now = dol_now(); + + $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S'); + + $date_actu = $now; + if (!empty($executiondate)) $date_actu = $executiondate; + + $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d'); + $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S'); + $fileCrediteurSection = ''; + $fileEmetteurSection = ''; + $i = 0; + + /* + * Section Creditor (sepa Crediteurs bloc lines) + */ + + $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; + $sql .= " f.ref as fac, pf.fk_facture_fourn as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " FROM"; + $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; + $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf,"; + $sql .= " ".MAIN_DB_PREFIX."societe as soc,"; + $sql .= " ".MAIN_DB_PREFIX."c_country as c,"; + $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib"; + $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; + $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; + $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND soc.fk_pays = c.rowid"; + $sql .= " AND soc.rowid = f.fk_soc"; + $sql .= " AND rib.fk_soc = f.fk_soc"; + $sql .= " AND rib.default_rib = 1"; + $sql .= " AND rib.type = 'ban'"; + //print $sql; + + // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); + $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); + $this->total = $this->total + $obj->somme; + $i++; + } + $nbtotalDrctDbtTxInf = $i; + } + else + { + fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers + $result = -2; + } + + // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf + if ($result != -2) + { + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); + } + + /** + * SECTION CREATION SEPA FILE - CREDIT TRANSFER - ISO200022 + */ + // SEPA File Header + fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); + fputs($this->file, ''.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA Group header + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.('TRF/'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); + fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); + fputs($this->file, ' '.$i.''.$CrLf); + fputs($this->file, ' '.$this->total.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$conf->global->PRELEVEMENT_ICS.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA File Emetteur (mycompany) + if ($result != -2) + { fputs($this-> file, $fileEmetteurSection); } + // SEPA File Creditors + if ($result != -2) + { fputs($this-> file, $fileCrediteurSection); } + // SEPA FILE FOOTER + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ''.$CrLf); } } // Build file for Other Countries with unknow format if (!$found) { - if ($type == 'bank-transfer') { + if ($type != 'bank-transfer') { $sql = "SELECT pl.amount"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql .= " ".MAIN_DB_PREFIX."facture as f,"; $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND pf.fk_facture = f.rowid"; // Lines $i = 0; @@ -1751,11 +1751,11 @@ class BonPrelevement extends CommonObject $sql = "SELECT pl.amount"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture as f,"; + $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture = f.rowid"; + $sql .= " AND pf.fk_facture_fourn = f.rowid"; // Lines $i = 0; @@ -1795,7 +1795,7 @@ class BonPrelevement extends CommonObject /** - * Build RUM number for a customer bank account + * Generate dynamically a RUM number for a customer bank account * * @param string $row_code_client Customer code (soc.code_client) * @param int $row_datec Creation date of bank account (rib.datec) @@ -1823,7 +1823,7 @@ class BonPrelevement extends CommonObject * @param string $ref ref of invoice * @param int $facid id of invoice * @param string $rib_dom rib domiciliation - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return void * @see EnregDestinataireSEPA() */ @@ -1905,7 +1905,7 @@ class BonPrelevement extends CommonObject * @param string $row_datec rib.datec, * @param string $row_drum rib.rowid used to generate rum * @param string $row_rum rib.rum Rum defined on company bank account - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return string Return string with SEPA part DrctDbtTxInf * @see EnregDestinataire() */ @@ -1917,7 +1917,7 @@ class BonPrelevement extends CommonObject include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $CrLf = "\n"; - $Rowing = sprintf("%10d", $row_idfac); + $Rowing = sprintf("%010d", $row_idfac); // Define value for RUM // Example: RUMCustomerCode-CustomerBankAccountId-01424448606 (note: Date is date of creation of CustomerBankAccountId) @@ -1926,7 +1926,7 @@ class BonPrelevement extends CommonObject // Define date of RUM signature $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); - if ($type != 'credit-transfer') { + if ($type != 'bank-transfer') { // SEPA Paiement Information of buyer for Direct debit $XML_DEBITOR = ''; $XML_DEBITOR .= ' '.$CrLf; @@ -2023,7 +2023,7 @@ class BonPrelevement extends CommonObject /** * Write sender of request (me). * - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return void * @see EnregEmetteurSEPA() */ @@ -2099,7 +2099,7 @@ class BonPrelevement extends CommonObject * @param float $total Total * @param string $CrLf End of line character * @param string $format FRST or RCUR or ALL - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return string String with SEPA Sender * @see EnregEmetteur() */ @@ -2145,11 +2145,11 @@ class BonPrelevement extends CommonObject $IdBon = sprintf("%05d", $obj->rowid); $RefBon = $obj->ref; - if ($type != 'credit-transfer') { + if ($type != 'bank-transfer') { // SEPA Paiement Information of my company for Direct debit $XML_SEPA_INFO = ''; $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' '.('DD/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; $XML_SEPA_INFO .= ' DD'.$CrLf; $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; $XML_SEPA_INFO .= ' '.$total.''.$CrLf; @@ -2208,7 +2208,7 @@ class BonPrelevement extends CommonObject // SEPA Paiement Information of my company for Credit Transfer $XML_SEPA_INFO = ''; $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' '.('TRF/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; $XML_SEPA_INFO .= ' TRF'.$CrLf; //$XML_SEPA_INFO .= ' False'.$CrLf; $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; @@ -2224,7 +2224,7 @@ class BonPrelevement extends CommonObject $XML_SEPA_INFO .= ' SECU'.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; */ - $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; + $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index fdbb6189c5c..e3f3e6beaf4 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -379,10 +379,15 @@ if ($resql) // RUM print ''; // Amount diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index e3d6409ddd6..6c8ab008252 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2798,7 +2798,7 @@ class Societe extends CommonObject * Return bank number property of thirdparty (label or rum) * * @param string $mode 'label' or 'rum' or 'format' - * @return string Bank number + * @return string Bank label or RUM or '' if no bank account found */ public function display_rib($mode = 'label') { @@ -2808,27 +2808,31 @@ class Societe extends CommonObject $bac = new CompanyBankAccount($this->db); $bac->fetch(0, $this->id); - if ($mode == 'label') - { - return $bac->getRibLabel(true); - } - elseif ($mode == 'rum') - { - if (empty($bac->rum)) + if ($bac->id > 0) { // If a bank account has been found for company $this->id + if ($mode == 'label') { - require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; - $prelevement = new BonPrelevement($this->db); - $bac->fetch_thirdparty(); - $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id); + return $bac->getRibLabel(true); } - return $bac->rum; + elseif ($mode == 'rum') + { + if (empty($bac->rum)) + { + require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; + $prelevement = new BonPrelevement($this->db); + $bac->fetch_thirdparty(); + $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id); + } + return $bac->rum; + } + elseif ($mode == 'format') + { + return $bac->frstrecur; + } else { + return 'BadParameterToFunctionDisplayRib'; + } + } else { + return ''; } - elseif ($mode == 'format') - { - return $bac->frstrecur; - } - - return 'BadParameterToFunctionDisplayRib'; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps From d1f92fb66b749585d779dce5795be8b88c306443 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 14:15:14 +0200 Subject: [PATCH 171/434] NEW: Add module Credit transfer SEPA to manage payment of supplier using bank credit transfer SEPA files --- ChangeLog | 2 +- htdocs/core/modules/modPaymentByBankTransfer.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c74f30755c6..5df348fce77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 13.0.0 compared to 12.0.0 ***** For users: - +NEW: Add module Credit transfer SEPA to manage payment of supplier using bank credit transfer SEPA files WARNING: diff --git a/htdocs/core/modules/modPaymentByBankTransfer.class.php b/htdocs/core/modules/modPaymentByBankTransfer.class.php index d68274e2dee..9ea1bf00f29 100644 --- a/htdocs/core/modules/modPaymentByBankTransfer.class.php +++ b/htdocs/core/modules/modPaymentByBankTransfer.class.php @@ -54,7 +54,7 @@ class modPaymentByBankTransfer extends DolibarrModules $this->description = "Management of payment by bank transfer"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'development'; + $this->version = 'dolibarr'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of png file (without png) used for this module From b6a3938921476d29138b07f73e880050d041372e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 14:32:42 +0200 Subject: [PATCH 172/434] FIX Size of image on the help popup of modules --- htdocs/admin/modulehelp.php | 2 +- htdocs/theme/eldy/global.inc.php | 3 ++- htdocs/theme/md/style.css.php | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index d5bf12f1061..ec0e5d8bb9b 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -272,7 +272,7 @@ print '
'; $picto = 'object_'.$objMod->picto; -print load_fiche_titre(($modulename ? $modulename : $moduledesc), $moreinfo, $picto); +print load_fiche_titre(($modulename ? $modulename : $moduledesc), $moreinfo, $picto, 0, '', 'titlemodulehelp'); print '
'; dol_fiche_head($head, $mode, '', -1); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 76df116ec08..9f2e00946bd 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -3948,7 +3948,8 @@ div.boximport { .fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor); } td.widthpictotitle { width: 26px; text-align: ; } -span.widthpictotitle { font-size: 1.7em; }; +span.widthpictotitle { font-size: 1.7em; } +table.titlemodulehelp tr td img.widthpictotitle { width: 80px; } .dolgraphtitle { margin-top: 6px; margin-bottom: 4px; } .dolgraphtitlecssboxes { /* margin: 0px; */ } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index b9fe51ca252..3d8f424b8ce 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3860,6 +3860,7 @@ div.boximport { .fieldrequired { font-weight: bold; color: #000055; } .widthpictotitle { width: 40px; font-size: 1.4em; text-align: ; } +table.titlemodulehelp tr td img.widthpictotitle { width: 80px; } .dolgraphtitle { margin-top: 6px; margin-bottom: 4px; } .dolgraphtitlecssboxes { /* margin: 0px; */ } From 2d192431bc7ec9c52089a561c83ddbdb887b8a09 Mon Sep 17 00:00:00 2001 From: VERDOL Gauthier Date: Mon, 3 Aug 2020 14:59:51 +0200 Subject: [PATCH 173/434] FIX : wrong element var for fetch_name_optionals_label function with expeditions --- htdocs/core/class/commondocgenerator.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 4a8e097fd6d..9f5dac2a0c3 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -513,7 +513,7 @@ abstract class CommonDocGenerator // Retrieve extrafields if (is_array($object->array_options) && count($object->array_options)) { - $extrafieldkey = $object->element; + $extrafieldkey = $object->table_element; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); From aa696d834356460b6e48d31a1905f8a41be3c0ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 15:17:37 +0200 Subject: [PATCH 174/434] Show warning in kanban view --- htdocs/admin/modules.php | 8 +++--- htdocs/core/modules/DolibarrModules.class.php | 28 +++++-------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index e5e221c529b..bd30d863bdc 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -506,10 +506,10 @@ if ($mode == 'common' || $mode == 'commonkanban') $moreforfilter .= '
'.$moreinfo.'
'.$moreinfo2.'
'; $moreforfilter .= '
'; - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Keyword').': '; $moreforfilter .= '
'; - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Origin').': '.$form->selectarray('search_nature', $arrayofnatures, dol_escape_htmltag($search_nature), 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; if (!empty($conf->global->MAIN_FEATURES_LEVEL)) @@ -518,11 +518,11 @@ if ($mode == 'common' || $mode == 'commonkanban') if ($conf->global->MAIN_FEATURES_LEVEL < 0) $array_version['deprecated'] = $langs->trans("Deprecated"); if ($conf->global->MAIN_FEATURES_LEVEL > 0) $array_version['experimental'] = $langs->trans("Experimental"); if ($conf->global->MAIN_FEATURES_LEVEL > 1) $array_version['development'] = $langs->trans("Development"); - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Version').': '.$form->selectarray('search_version', $array_version, $search_version, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; } - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Status').': '.$form->selectarray('search_status', array('active'=>$langs->transnoentitiesnoconv("Enabled"), 'disabled'=>$langs->transnoentitiesnoconv("Disabled")), $search_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; $moreforfilter .= ' '; diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 273947ec205..03afbb0c7af 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -2217,6 +2217,12 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($this))); + $version = $this->getVersion(0); + $versiontrans = ''; + if (preg_match('/development/i', $version)) $versiontrans .= 'warning'; + if (preg_match('/experimental/i', $version)) $versiontrans .= 'warning'; + if (preg_match('/deprecated/i', $version)) $versiontrans .= 'warning'; + print '
@@ -2233,39 +2239,19 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it print img_object($alttext, 'generic', 'class="inline-block valignmiddle"'); } - $version = $this->getVersion(0); - $versiontrans = ''; - if (preg_match('/development/i', $version)) $versiontrans .= 'warning'; - if (preg_match('/experimental/i', $version)) $versiontrans .= 'warning'; - if (preg_match('/deprecated/i', $version)) $versiontrans .= 'warning'; if ($this->isCoreOrExternalModule() == 'external' || preg_match('/development|experimental|deprecated/i', $version)) { print 'getVersion(1).'">'; print $this->getVersion(1); print ''; } - /*print ''; - print '
'; - print '
'; - print $codeenabledisable; - print '
'; - print '
'; - print $codetoconfig; - print '
'; - print '
'; - print '
'; - */ - print '
'.$this->getName().' '.nl2br($this->getDesc()).''; - /*print 'getVersion(1).'">'; - print $this->getVersion(1); - print ''; */ - print '
'; + if ($versiontrans) print img_warning($langs->trans("Version").' '.$this->getVersion(1)).' '; print ''.img_picto(($this->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule").' - ' : '').$langs->trans("ClickToShowDescription"), $imginfo).''; print '

'; From 15a634959f5d095a08bcd4b0a4ec188e603444f1 Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Mon, 3 Aug 2020 14:31:33 +0100 Subject: [PATCH 175/434] fix:value of checked option must be the same as in showInputfield function --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 3b13b867fd7..08b3e037499 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -156,7 +156,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == 'on' ? 1 : 0); + $value = (GETPOST($key) == '1' ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From fa26d2acdfcc7c59b1cc3a1a0ae24183bbaeeca5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 16:31:52 +0200 Subject: [PATCH 176/434] css --- htdocs/core/modules/DolibarrModules.class.php | 6 +++--- htdocs/theme/eldy/info-box.inc.php | 14 +++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 03afbb0c7af..764519862a6 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -2226,7 +2226,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it print '
-
'; +
'; $alttext = ''; //if (is_array($objMod->need_dolibarr_version)) $alttext.=($alttext?' - ':'').'Dolibarr >= '.join('.',$objMod->need_dolibarr_version); @@ -2246,12 +2246,12 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it } print '
-
+
'.$this->getName().' '.nl2br($this->getDesc()).''; print '
'; - if ($versiontrans) print img_warning($langs->trans("Version").' '.$this->getVersion(1)).' '; + //if ($versiontrans) print img_warning($langs->trans("Version").' '.$this->getVersion(1)).' '; print ''.img_picto(($this->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule").' - ' : '').$langs->trans("ClickToShowDescription"), $imginfo).''; print '

'; diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index b995b551f43..e90da687135 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -166,15 +166,17 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> padding: 5px 10px; margin-left: 84px; } - .info-box-sm .info-box-content{ margin-left: 80px; } -/*.info-box-setup span { - color: var(--colortexttitlenotab2); +.info-box-sm .info-box-module-enabled { + background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) } -.tdsetuppicto span { - color: var(--colortexttitlenotab2); +.info-box-sm .info-box-content-warning { + background: #ffd7a3; +} +/*.info-box-icon.info-box-icon-module-enabled { + background: #e4f0e4 !important; }*/ .info-box-number { @@ -212,6 +214,8 @@ a.info-box-text{ text-decoration: none;} + + /* ICONS INFO BOX */ Date: Mon, 3 Aug 2020 16:36:31 +0200 Subject: [PATCH 177/434] css --- htdocs/theme/eldy/info-box.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index e90da687135..27b0ee34481 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -170,7 +170,8 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> margin-left: 80px; } .info-box-sm .info-box-module-enabled { - background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) + /* background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) */ + background: linear-gradient(0.4turn, #fff, #fff, #fff, #e4efe8); } .info-box-sm .info-box-content-warning { background: #ffd7a3; From c78b19b3b89e49b04c0dbfee1bcc390254d8ce24 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 16:39:52 +0200 Subject: [PATCH 178/434] Move module as experimental (it is working enough). --- htdocs/core/modules/modRecruitment.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modRecruitment.class.php b/htdocs/core/modules/modRecruitment.class.php index c9093c34272..0cbe9da017b 100644 --- a/htdocs/core/modules/modRecruitment.class.php +++ b/htdocs/core/modules/modRecruitment.class.php @@ -62,7 +62,7 @@ class modRecruitment extends DolibarrModules // Used only if file README.md and README-LL.md not found. $this->descriptionlong = "Manage and follow recruitment campaign for new job positions"; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = 'development'; + $this->version = 'experimental'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; From 22f69f0da94b8669175108e836e945365b7d23cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 17:39:18 +0200 Subject: [PATCH 179/434] CSS --- htdocs/theme/eldy/global.inc.php | 2 ++ htdocs/theme/eldy/info-box.inc.php | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 67702d93ee6..45214c06a4d 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -4053,6 +4053,8 @@ div.titre { } div.fiche > table.table-fiche-title:first-of-type div { color: var(--colortexttitlenotab); + font-size: 1.05em; + /* text-transform: uppercase; */ /* font-weight: 600; */ } div.titre { diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index 27b0ee34481..bf8d6220e00 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -173,9 +173,12 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> /* background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) */ background: linear-gradient(0.4turn, #fff, #fff, #fff, #e4efe8); } -.info-box-sm .info-box-content-warning { - background: #ffd7a3; +.info-box-content-warning span.font-status4 { + color: #bc9526 !important; } +/*.info-box-sm .info-box-content-warning { + background: #ffd7a3; +}*/ /*.info-box-icon.info-box-icon-module-enabled { background: #e4f0e4 !important; }*/ From f62717a16afcb5e975dab5de8741fe0095111fe9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 3 Aug 2020 20:16:33 +0200 Subject: [PATCH 180/434] FIX Debug module direct debit order. Solve conflict with credit transfer --- htdocs/compta/prelevement/card.php | 4 +- .../class/bonprelevement.class.php | 274 ++++++++++-------- .../class/ligneprelevement.class.php | 2 +- htdocs/compta/prelevement/factures.php | 40 ++- htdocs/compta/prelevement/fiche-rejet.php | 4 +- htdocs/compta/prelevement/fiche-stat.php | 2 +- .../fourn/class/fournisseur.facture.class.php | 2 +- htdocs/langs/en_US/withdrawals.lang | 6 +- 8 files changed, 195 insertions(+), 139 deletions(-) diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index ab8b5b8ae40..00bcd088e27 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -146,11 +146,9 @@ if (empty($reshook)) $dt = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); $error = $object->set_infocredit($user, $dt); - if ($error) { - header("Location: card.php?id=".$id."&error=$error"); - exit; + setEventMessages($object->error, $object->errors, 'errors'); } } } diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 929c0958d71..9210e0e62c0 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; @@ -67,6 +68,9 @@ class BonPrelevement extends CommonObject public $emetteur_bic; public $emetteur_ics; + public $date_trans; + public $user_trans; + public $total; public $fetched; public $statut; // 0-Wait, 1-Trans, 2-Done @@ -425,7 +429,7 @@ class BonPrelevement extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Set direct debit order to "credited" status. + * Set direct debit or credit transfer order to "paid" status. * * @param User $user Id of user * @param int $date date of action @@ -440,128 +444,158 @@ class BonPrelevement extends CommonObject if ($this->fetched == 1) { - if ($date >= $this->date_trans) + if ($date < $this->date_trans) { - if ($this->db->begin()) + $this->error = 'DateOfMovementLowerThanDateOfFileTransmission'; + dol_syslog("bon-prelevment::set_infocredit 1027 ".$this->error); + return -1027; + } + + $this->db->begin(); + + $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_bons "; + $sql .= " SET fk_user_credit = ".$user->id; + $sql .= ", statut = ".self::STATUS_CREDITED; + $sql .= ", date_credit = '".$this->db->idate($date)."'"; + $sql .= " WHERE rowid=".$this->id; + $sql .= " AND entity = ".$conf->entity; + $sql .= " AND statut = ".self::STATUS_TRANSFERED; + + $resql = $this->db->query($sql); + if ($resql) + { + $langs->load('withdrawals'); + $subject = $langs->trans("InfoCreditSubject", $this->ref); + $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour')); + + //Add payment of withdrawal into bank + $bankaccount = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; + $facs = array(); + $amounts = array(); + $amountsperthirdparty = array(); + + $facs = $this->getListInvoices(1); + + // Loop on each invoice. $facs=array(0=>id, 1=>amount requested) + $num = count($facs); + for ($i = 0; $i < $num; $i++) { - $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_bons "; - $sql .= " SET fk_user_credit = ".$user->id; - $sql .= ", statut = ".self::STATUS_CREDITED; - $sql .= ", date_credit = '".$this->db->idate($date)."'"; - $sql .= " WHERE rowid=".$this->id; - $sql .= " AND entity = ".$conf->entity; - $sql .= " AND statut = ".self::STATUS_TRANSFERED; - - if ($this->db->query($sql)) - { - $langs->load('withdrawals'); - $subject = $langs->trans("InfoCreditSubject", $this->ref); - $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour')); - - //Add payment of withdrawal into bank - $bankaccount = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; - $facs = array(); - $amounts = array(); - $amountsperthirdparty = array(); - - $facs = $this->getListInvoices(1); - - // Loop on each invoice. $facs=array(0=>id, 1=>amount requested) - $num = count($facs); - for ($i = 0; $i < $num; $i++) - { - $fac = new Facture($this->db); - $fac->fetch($facs[$i][0]); - $amounts[$fac->id] = $facs[$i][1]; - $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1]; - - $totalpaye = $fac->getSommePaiement(); - $totalcreditnotes = $fac->getSumCreditNotesUsed(); - $totaldeposits = $fac->getSumDepositsUsed(); - $alreadypayed = $totalpaye + $totalcreditnotes + $totaldeposits; - - if (price2num($alreadypayed + $facs[$i][1], 'MT') == $fac->total_ttc) { - $result = $fac->set_paid($user); - } - } - - // Make one payment per customer - foreach ($amountsperthirdparty as $thirdpartyid => $cursoramounts) - { - $paiement = new Paiement($this->db); - $paiement->datepaye = $date; - $paiement->amounts = $cursoramounts; // Array with detail of dispatching of payments for each invoice - $paiement->paiementid = 3; // - $paiement->num_payment = $this->ref; // Set ref of direct debit note - $paiement->num_paiement = $this->ref; // For backward compatibility - $paiement->id_prelevement = $this->id; - - $paiement_id = $paiement->create($user); - if ($paiement_id < 0) - { - dol_syslog(get_class($this)."::set_infocredit AddPayment Error"); - $error++; - } - else - { - $result = $paiement->addPaymentToBank($user, 'payment', '(WithdrawalPayment)', $bankaccount, '', ''); - if ($result < 0) - { - dol_syslog(get_class($this)."::set_infocredit AddPaymentToBank Error"); - $error++; - } - } - //var_dump($paiement->amounts); - //var_dump($thirdpartyid); - //var_dump($cursoramounts); - } - - // Update withdrawal line - // TODO: Translate to ligneprelevement.class.php - $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; - $sql .= " SET statut = 2"; - $sql .= " WHERE fk_prelevement_bons = ".$this->id; - - if (!$this->db->query($sql)) - { - dol_syslog(get_class($this)."::set_infocredit Update lines Error"); - $error++; - } - } - else - { - dol_syslog(get_class($this)."::set_infocredit Update Bons Error"); - $error++; + if ($this->type == 'bank-transfer') { + $fac = new FactureFournisseur($this->db); + } else { + $fac = new Facture($this->db); } - /* - * End of procedure - */ - if ($error == 0) - { - $this->date_credit = $date; - $this->statut = self::STATUS_CREDITED; + $result = $fac->fetch($facs[$i][0]); - $this->db->commit(); - return 0; - } - else - { - $this->db->rollback(); - dol_syslog("bon-prelevment::set_infocredit ROLLBACK "); - return -1; + $amounts[$fac->id] = $facs[$i][1]; + $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1]; + + $totalpaye = $fac->getSommePaiement(); + $totalcreditnotes = $fac->getSumCreditNotesUsed(); + $totaldeposits = $fac->getSumDepositsUsed(); + $alreadypayed = $totalpaye + $totalcreditnotes + $totaldeposits; + + // @TODO Move this after creation of payment + if (price2num($alreadypayed + $facs[$i][1], 'MT') == $fac->total_ttc) { + $result = $fac->set_paid($user); + if ($result < 0) { + $this->error = $fac->error; + $this->errors = $fac->errors; + } } } - else + //var_dump($amountsperthirdparty);exit; + + // Make one payment per customer + foreach ($amountsperthirdparty as $thirdpartyid => $cursoramounts) { - dol_syslog(get_class($this)."::set_infocredit 1025 Open SQL transaction impossible "); - return -1025; + if ($this->type == 'bank-transfer') { + $paiement = new PaiementFourn($this->db); + } else { + $paiement = new Paiement($this->db); + } + $paiement->datepaye = $date; + $paiement->amounts = $cursoramounts; // Array with detail of dispatching of payments for each invoice + + if ($this->type == 'bank-transfer') { + $paiement->paiementid = 2; + $paiement->paiementcode = 'VIR'; + } else { + $paiement->paiementid = 3; + $paiement->paiementcode = 'PRE'; + } + + $paiement->num_payment = $this->ref; // Set ref of direct debit note + $paiement->num_paiement = $this->ref; // For backward compatibility + $paiement->id_prelevement = $this->id; + + $paiement_id = $paiement->create($user); // This use ->paiementid, that is ID of payment mode + if ($paiement_id < 0) + { + $error++; + $this->error = $paiement->error; + $this->errors = $paiement->errors; + dol_syslog(get_class($this)."::set_infocredit AddPayment Error ".$this->error); + } + else + { + if ($this->type == 'bank-transfer') { + $modeforaddpayment = 'payment_supplier'; + } else { + $modeforaddpayment = 'payment'; + } + + $result = $paiement->addPaymentToBank($user, $modeforaddpayment, '(WithdrawalPayment)', $bankaccount, '', ''); + if ($result < 0) + { + $error++; + $this->error = $paiement->error; + $this->errors = $paiement->errors; + dol_syslog(get_class($this)."::set_infocredit AddPaymentToBank Error ".$this->error); + } + } + //var_dump($paiement->amounts); + //var_dump($thirdpartyid); + //var_dump($cursoramounts); + } + + // Update withdrawal line + // TODO: Translate to ligneprelevement.class.php + if (! $error) { + $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; + $sql .= " SET statut = 2"; + $sql .= " WHERE fk_prelevement_bons = ".$this->id; + + if (!$this->db->query($sql)) + { + dol_syslog(get_class($this)."::set_infocredit Update lines Error"); + $error++; + } } } else { - dol_syslog("bon-prelevment::set_infocredit 1027 Date de credit < Date de trans "); - return -1027; + $this->error = $this->db->lasterror(); + dol_syslog(get_class($this)."::set_infocredit Update Bons Error"); + $error++; + } + + /* + * End of procedure + */ + if ($error == 0) + { + $this->date_credit = $date; + $this->statut = self::STATUS_CREDITED; + + $this->db->commit(); + return 0; + } + else + { + $this->db->rollback(); + return -1; } } else @@ -593,7 +627,7 @@ class BonPrelevement extends CommonObject $sql .= " SET fk_user_trans = ".$user->id; $sql .= " , date_trans = '".$this->db->idate($date)."'"; $sql .= " , method_trans = ".$method; - $sql .= " , statut = 1"; + $sql .= " , statut = ".self::STATUS_TRANSFERED; $sql .= " WHERE rowid = ".$this->id; $sql .= " AND entity = ".$conf->entity; $sql .= " AND statut = 0"; @@ -617,6 +651,7 @@ class BonPrelevement extends CommonObject { $this->date_trans = $date; $this->statut = 1; + $this->user_trans = $user->id; $this->db->commit(); return 0; @@ -651,7 +686,12 @@ class BonPrelevement extends CommonObject /* * Returns all invoices presented within same order */ - $sql = "SELECT fk_facture"; + $sql = "SELECT "; + if ($this->type == 'bank-transfer') { + $sql .= " pf.fk_facture_fourn"; + } else { + $sql .= " pf.fk_facture"; + } if ($amounts) $sql .= ", SUM(pl.amount)"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql .= " , ".MAIN_DB_PREFIX."prelevement_lignes as pl"; @@ -660,7 +700,13 @@ class BonPrelevement extends CommonObject $sql .= " AND pl.fk_prelevement_bons = p.rowid"; $sql .= " AND p.rowid = ".$this->id; $sql .= " AND p.entity = ".$conf->entity; - if ($amounts) $sql .= " GROUP BY fk_facture"; + if ($amounts) { + if ($this->type == 'bank-transfer') { + $sql .= " GROUP BY fk_facture_fourn"; + } else { + $sql .= " GROUP BY fk_facture"; + } + } $resql = $this->db->query($sql); if ($resql) diff --git a/htdocs/compta/prelevement/class/ligneprelevement.class.php b/htdocs/compta/prelevement/class/ligneprelevement.class.php index d2dd9f3470f..10f3c05c25a 100644 --- a/htdocs/compta/prelevement/class/ligneprelevement.class.php +++ b/htdocs/compta/prelevement/class/ligneprelevement.class.php @@ -59,7 +59,7 @@ class LignePrelevement $langs->load("withdrawals"); $this->statuts[0] = $langs->trans("StatusWaiting"); - $this->statuts[2] = $langs->trans("StatusCredited"); + $this->statuts[2] = $langs->trans("StatusPaid"); $this->statuts[3] = $langs->trans("StatusRefused"); } diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 816795bfdbd..0e4ff799ba6 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -105,7 +105,7 @@ if ($id > 0 || $ref) print '
'; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''; @@ -160,7 +160,7 @@ if ($id > 0 || $ref) // List of invoices -$sql = "SELECT pf.rowid,"; +$sql = "SELECT pf.rowid, p.type,"; $sql .= " f.rowid as facid, f.ref as ref, f.total_ttc,"; $sql .= " s.rowid as socid, s.nom as name, pl.statut, pl.amount as amount_requested"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; @@ -193,8 +193,8 @@ $sql .= $db->order($sortfield, $sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + $resql = $db->query($sql); + $nbtotalofrecords = $db->num_rows($resql); if (($page * $limit) > $nbtotalofrecords) // if total resultset is smaller then paging size (filtering), goto and load page 0 { $page = 0; @@ -204,10 +204,10 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql .= $db->plimit($limit + 1, $offset); -$result = $db->query($sql); -if ($result) +$resql = $db->query($sql); +if ($resql) { - $num = $db->num_rows($result); + $num = $db->num_rows($resql); $i = 0; $param = "&id=".$id; @@ -236,22 +236,28 @@ if ($result) print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "s.nom", '', $param, '', $sortfield, $sortorder); print_liste_field_titre("AmountInvoice", $_SERVER["PHP_SELF"], "f.total_ttc", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("AmountRequested", $_SERVER["PHP_SELF"], "pl.amount", "", $param, 'class="right"', $sortfield, $sortorder); - print_liste_field_titre("StatusDebitCredit", $_SERVER["PHP_SELF"], "", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "", "", $param, 'align="center"', $sortfield, $sortorder); print_liste_field_titre(''); print "\n"; $totalinvoices = 0; $totalamount_requested = 0; + $invoicetmpcustomer = new Facture($db); + $invoicetmpsupplier = new FactureFournisseur($db); + while ($i < min($num, $limit)) { - $obj = $db->fetch_object($result); + $obj = $db->fetch_object($resql); - $invoicetmp->id = $obj->facid; - $invoicetmp->ref = $obj->ref; + if ($obj->type == 'bank-transfer') { + $invoicetmp = $invoicetmpsupplier; + } else { + $invoicetmp = $invoicetmpcustomer; + } + $invoicetmp->fetch($obj->facid); - $thirdpartytmp->id = $obj->socid; - $thirdpartytmp->name = $obj->name; + $thirdpartytmp->fetch($obj->socid); print ''; @@ -278,7 +284,11 @@ if ($result) } elseif ($obj->statut == 2) { - print $langs->trans("StatusCredited"); + if ($obj->type == 'bank-transfer') { + print $langs->trans("StatusDebited"); + } else { + print $langs->trans("StatusCredited"); + } } elseif ($obj->statut == 3) { @@ -317,7 +327,7 @@ if ($result) print "
'.$langs->trans("TableName").''.$langs->trans("NbOfRecord").''; - print $thirdpartystatic->display_rib('rum'); - $format = $thirdpartystatic->display_rib('format'); - if ($type != 'bank-transfer') { - if ($format) print ' ('.$format.')'; + $rumtoshow = $thirdpartystatic->display_rib('rum'); + if ($rumtoshow) { + print $rumtoshow; + $format = $thirdpartystatic->display_rib('format'); + if ($type != 'bank-transfer') { + if ($format) print ' ('.$format.')'; + } + } else { + print img_warning($langs->trans("NoBankAccount")); } print '
'.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
'.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
"; print '
'; - $db->free($result); + $db->free($resql); } else { diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index 10abbcf5166..cbc1a666def 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -99,7 +99,7 @@ if ($prev_id > 0 || $ref) print ''.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print ''; @@ -234,7 +234,7 @@ if ($resql) } else { - print ''.$langs->trans("None").''; + print ''.$langs->trans("None").''; } if ($num > 0) diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php index 49508cdde46..d94edfa5107 100644 --- a/htdocs/compta/prelevement/fiche-stat.php +++ b/htdocs/compta/prelevement/fiche-stat.php @@ -98,7 +98,7 @@ if ($prev_id > 0 || $ref) print ''.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print ''; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 63ca7e0d88b..bbc8a3e6e28 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1290,7 +1290,7 @@ class FactureFournisseur extends CommonInvoice $this->db->begin(); $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn'; - $sql .= ' SET paye = 1, fk_statut=2'; + $sql .= ' SET paye = 1, fk_statut = '.self::STATUS_CLOSED; $sql .= ' WHERE rowid = '.$this->id; dol_syslog("FactureFournisseur::set_paid", LOG_DEBUG); diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 662c587108a..a1bb646bff3 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -63,7 +63,9 @@ InvoiceRefused=Invoice refused (Charge the rejection to customer) StatusDebitCredit=Status debit/credit StatusWaiting=Waiting StatusTrans=Sent +StatusDebited=Debited StatusCredited=Credited +StatusPaid=Paid StatusRefused=Refused StatusMotif0=Unspecified StatusMotif1=Insufficient funds @@ -82,8 +84,8 @@ CreateSepaFileForPaymentByBankTransfer=Create credit transfer file (SEPA) CreateGuichet=Only office CreateBanque=Only bank OrderWaiting=Waiting for treatment -NotifyTransmision=File transmission -NotifyCredit=Withdrawal Credit +NotifyTransmision=Record file transmission of order +NotifyCredit=Record credit of order NumeroNationalEmetter=National Transmitter Number WithBankUsingRIB=For bank accounts using RIB WithBankUsingBANBIC=For bank accounts using IBAN/BIC/SWIFT From 4900e85fa804af1932ed95cf561c1c32b16ba6e2 Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Mon, 3 Aug 2020 20:31:39 +0100 Subject: [PATCH 181/434] fix: reset link on supplier dispatch --- htdocs/fourn/commande/dispatch.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 0c0f084a230..ede9b22622a 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -743,7 +743,8 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("SupplierRef").''; print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; - print ''.$langs->trans("QtyToDispatchShort").''; + print ' '.$langs->trans("QtyToDispatchShort"); + print ' ('.$langs->trans("Reset").')'.''; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { @@ -1068,7 +1069,20 @@ if ($id > 0 || !empty($ref)) { $("select[name=fk_default_warehouse]").change(function() { var fk_default_warehouse = $("option:selected", this).val(); $("select[name^=entrepot_]").val(fk_default_warehouse).change(); - }); + });'; + $i = 0; + print ' + jQuery("#autoreset").click(function() {'; + $i = 0; + while ($i < $nbproduct) + { + print ' + jQuery("#qty_0_'.$i.'").val(0);'; + $i++; + } + print ' + });'; + print ' }); '; From 8dd54e24e7e6924b6b0a6a11f33698a59f1a7771 Mon Sep 17 00:00:00 2001 From: Bahfir Abbes Date: Mon, 3 Aug 2020 20:42:25 +0100 Subject: [PATCH 182/434] empty is more useful than 0 --- htdocs/fourn/commande/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index ede9b22622a..3bc69e6770b 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -1077,7 +1077,7 @@ if ($id > 0 || !empty($ref)) { while ($i < $nbproduct) { print ' - jQuery("#qty_0_'.$i.'").val(0);'; + jQuery("#qty_0_'.$i.'").val("");'; $i++; } print ' From 063b63d3488a47f7ce6328ac2d9709c763aad357 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 00:36:45 +0200 Subject: [PATCH 183/434] Fix phpcs --- .../prelevement/class/bonprelevement.class.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index e50efe4160f..7e505f97bee 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -517,9 +517,7 @@ class BonPrelevement extends CommonObject $this->error = $paiement->error; $this->errors = $paiement->errors; dol_syslog(get_class($this)."::set_infocredit AddPayment Error ".$this->error); - } - else - { + } else { if ($this->type == 'bank-transfer') { $modeforaddpayment = 'payment_supplier'; } else { @@ -1639,16 +1637,13 @@ class BonPrelevement extends CommonObject $i++; } $nbtotalDrctDbtTxInf = $i; - } - else - { + } else { fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers $result = -2; } // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf - if ($result != -2) - { + if ($result != -2) { $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); } @@ -2238,11 +2233,8 @@ class BonPrelevement extends CommonObject $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf;*/ } - } - else - { + } else { fputs($this->file, 'INCORRECT EMETTEUR '.$XML_SEPA_INFO.$CrLf); - $result = -2; } return $XML_SEPA_INFO; } From bf1f2956026347a53833d45aa152d0d4b50ab159 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 02:50:56 +0200 Subject: [PATCH 184/434] NEW Can disable, from edit page, the whole web site FIX position of a cloned website --- htdocs/theme/eldy/global.inc.php | 2 +- htdocs/website/class/website.class.php | 5 ++- htdocs/website/index.php | 50 +++++++++++++++----------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 45214c06a4d..ab7a56ea89d 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -3984,7 +3984,7 @@ div.boximport { .product_line_stock_ok { color: #002200; } .product_line_stock_too_low { color: #884400; } -.fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor); } +.fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor) !important; } td.widthpictotitle { width: 26px; text-align: ; } span.widthpictotitle { font-size: 1.7em; } diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index c325e672043..768ddbdb19c 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -290,6 +290,7 @@ class Website extends CommonObject $sql .= ' t.rowid,'; $sql .= " t.entity,"; $sql .= " t.ref,"; + $sql .= " t.position,"; $sql .= " t.description,"; $sql .= " t.lang,"; $sql .= " t.otherlang,"; @@ -319,6 +320,7 @@ class Website extends CommonObject $this->entity = $obj->entity; $this->ref = $obj->ref; + $this->position = $obj->position; $this->description = $obj->description; $this->lang = $obj->lang; $this->otherlang = $obj->otherlang; @@ -670,7 +672,8 @@ class Website extends CommonObject $object->virtualhost = ''; $object->date_creation = $now; $object->fk_user_creat = $user->id; - $object->position = $object->position + 1; + $object->position = ((int) $object->position) + 1; + $object->status = self::STATUS_DRAFT; if (empty($object->lang)) $object->lang = substr($langs->defaultlang, 0, 2); // Should not happen. Protection for corrupted site with no languages // Create clone diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 539e7533af6..e0afd583ea2 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2594,11 +2594,11 @@ if (!GETPOST('hide_websitemenu')) $textifempty = 1; $formquestion = array( array('type' => 'hidden', 'name' => 'sourcepageurl', 'value'=> $objectpage->pageurl), - array('type' => 'checkbox', 'tdclass'=>'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0), - array('type' => 'other', 'name' => 'newlang', 'label' => $form->textwithpicto($langs->trans("Language"), $langs->trans("DefineListOfAltLanguagesInWebsiteProperties")), 'value' => $formadmin->select_language($preselectedlanguage, 'newlang', 0, null, $textifempty, 0, 0, 'minwidth200', 0, 1, 0, $onlylang, 1)), - array('type' => 'other', 'name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)), + array('type' => 'other', 'tdclass'=>'fieldrequired', 'name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)), array('type' => 'text', 'tdclass'=>'maxwidth200 fieldrequired', 'name' => 'newtitle', 'label'=> $langs->trans("WEBSITE_TITLE"), 'value'=> $langs->trans("CopyOf").' '.$objectpage->title), array('type' => 'text', 'tdclass'=>'maxwidth200', 'name' => 'newpageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME"), 'value'=> ''), + array('type' => 'checkbox', 'tdclass'=>'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0, 'morecss'=>'margintoponly'), + array('type' => 'other', 'name' => 'newlang', 'label' => $form->textwithpicto($langs->trans("Language"), $langs->trans("DefineListOfAltLanguagesInWebsiteProperties")), 'value' => $formadmin->select_language($preselectedlanguage, 'newlang', 0, null, $textifempty, 0, 0, 'minwidth200', 0, 1, 0, $onlylang, 1)), ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 300, 550); @@ -2972,6 +2972,15 @@ if ($action == 'editcss') print $websitekey; print ''; + // Status of web site + print ''."\n"; + print ''; + print $langs->trans('Status'); + print ''; + print ajax_object_onoff($object, 'status', 'status', 'Enabled', 'Disabled'); + //print dol_print_date($pagedatecreation, 'dayhour'); + print ''; + // Main language print ''; $htmltext = ''; @@ -3288,15 +3297,16 @@ if ($action == 'editmeta' || $action == 'createcontainer') if ($action != 'createcontainer') { - print ''; - print $langs->trans('IDOfPage'); + print ''; + print $langs->trans('IDOfPage').' - '.$langs->trans('InternalURLOfPage'); print ''; print $pageid; - print ''; + //print ''; - print ''; - print $langs->trans('InternalURLOfPage'); - print ''; + //print ''; + //print $langs->trans('InternalURLOfPage'); + //print ''; + print '   -   '; print '/public/website/index.php?website='.urlencode($websitekey).'&pageid='.urlencode($pageid); //if ($objectpage->grabbed_from) print ' - '.$langs->trans('InitiallyGrabbedFrom').' '.$objectpage->grabbed_from.''; print ''; @@ -3334,6 +3344,17 @@ if ($action == 'editmeta' || $action == 'createcontainer') if (GETPOST('WEBSITE_LANG', 'aZ09')) $pagelang = GETPOST('WEBSITE_LANG', 'aZ09'); if (GETPOST('htmlheader', 'none')) $pagehtmlheader = GETPOST('htmlheader', 'none'); + if ($action != 'createcontainer') + { + print ''."\n"; + print ''; + print $langs->trans('Status'); + print ''; + print ajax_object_onoff($objectpage, 'status', 'status', 'Enabled', 'Disabled'); + //print dol_print_date($pagedatecreation, 'dayhour'); + print ''; + } + // Type of container print ''; print $langs->trans('WEBSITE_TYPE_CONTAINER'); @@ -3555,17 +3576,6 @@ if ($action == 'editmeta' || $action == 'createcontainer') print $doleditor->Create(1, '', true, 'HTML Header', 'html'); print ''; - if ($action != 'createcontainer') - { - print ''."\n"; - print ''; - print $langs->trans('Status'); - print ''; - print ajax_object_onoff($objectpage, 'status', 'status', 'Enabled', 'Disabled'); - //print dol_print_date($pagedatecreation, 'dayhour'); - print ''; - } - print ''; if ($action == 'createcontainer') { From 6d957c276c3df287f835bc414329c6808360c98f Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Tue, 4 Aug 2020 08:11:44 +0200 Subject: [PATCH 185/434] Improving TakePOS search informing the user if there is no record or clearing the box if it exists avoiding manually clear every scan --- htdocs/takepos/index.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index ab5acc1ac50..36dcbbe3d55 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -529,8 +529,19 @@ function Search2(keyCodeForEnter) { ClickProduct(0); } } + if (eventKeyCode == keyCodeForEnter){ + ClearSearch(); + if (data.length == 0) { + $('#search').val('load('errors'); + echo dol_escape_js($langs->trans("ErrorRecordNotFound")); + ?>'); + $('#search').select(); + } + } }); } + } function Edit(number) { From 0347f2a46beac5286af06264bafe8ddc07b92064 Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Tue, 4 Aug 2020 08:19:27 +0200 Subject: [PATCH 186/434] More elegant --- htdocs/takepos/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 36dcbbe3d55..96608ed4fdf 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -530,7 +530,6 @@ function Search2(keyCodeForEnter) { } } if (eventKeyCode == keyCodeForEnter){ - ClearSearch(); if (data.length == 0) { $('#search').val('load('errors'); @@ -538,6 +537,7 @@ function Search2(keyCodeForEnter) { ?>'); $('#search').select(); } + else ClearSearch(); } }); } From 360afccecc6c397e592e2497db5268e0b71d997a Mon Sep 17 00:00:00 2001 From: Tim Otte Date: Tue, 4 Aug 2020 11:02:16 +0200 Subject: [PATCH 187/434] Fixed translation of product units in documents --- htdocs/bom/class/bom.class.php | 1 + htdocs/comm/propal/class/propal.class.php | 1 + htdocs/commande/class/commande.class.php | 1 + htdocs/compta/facture/class/facture.class.php | 1 + htdocs/contrat/class/contrat.class.php | 1 + htdocs/core/class/commonobjectline.class.php | 4 ++-- htdocs/expedition/class/expedition.class.php | 1 + htdocs/fourn/class/fournisseur.commande.class.php | 1 + htdocs/fourn/class/fournisseur.facture.class.php | 1 + htdocs/livraison/class/livraison.class.php | 1 + htdocs/product/class/product.class.php | 1 + htdocs/product/stock/class/entrepot.class.php | 1 + htdocs/product/stock/class/mouvementstock.class.php | 1 + htdocs/supplier_proposal/class/supplier_proposal.class.php | 1 + 14 files changed, 15 insertions(+), 2 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 9ec55ae2f4a..847cf676054 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -927,6 +927,7 @@ class BOM extends CommonObject global $conf, $langs; $langs->load("mrp"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index cef7e3ee48e..d2e2864eef0 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3662,6 +3662,7 @@ class Propal extends CommonObject global $conf, $langs; $langs->load("propale"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'azur'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 28d2170e49a..a30d04fd761 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3859,6 +3859,7 @@ class Commande extends CommonOrder global $conf, $langs; $langs->load("orders"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'einstein'; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 843b3dd32ea..1eccddbc9ae 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4296,6 +4296,7 @@ class Facture extends CommonInvoice global $conf, $langs; $langs->load("bills"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index c2200a411c2..c1a652a19ba 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2393,6 +2393,7 @@ class Contrat extends CommonObject global $conf, $langs; $langs->load("contracts"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'strato'; diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index f92004120ff..59b0acee232 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -74,12 +74,12 @@ abstract class CommonObjectLine extends CommonObject $label_type = 'short_label'; } - $sql = 'select '.$label_type.' from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; + $sql = 'select '.$label_type.',code from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { $res = $this->db->fetch_array($resql); - $label = $res[$label_type]; + $label = ($label_type == 'short' ? $res[$label_type] : 'unit'.$res['code']); $this->db->free($resql); return $label; } else { diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 6b08d4db5e6..d05d0c63d37 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2462,6 +2462,7 @@ class Expedition extends CommonObject global $conf, $langs; $langs->load("sendings"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'rouget'; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index c544658a921..e6098cba01e 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2959,6 +2959,7 @@ class CommandeFournisseur extends CommonOrder global $conf, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'muscadet'; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 9949c4d3253..d7e8908312e 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2637,6 +2637,7 @@ class FactureFournisseur extends CommonInvoice global $conf, $user, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); // Set the model on the model name to use if (empty($modele)) diff --git a/htdocs/livraison/class/livraison.class.php b/htdocs/livraison/class/livraison.class.php index 6199bc4ec88..1429e39be8e 100644 --- a/htdocs/livraison/class/livraison.class.php +++ b/htdocs/livraison/class/livraison.class.php @@ -1035,6 +1035,7 @@ class Livraison extends CommonObject global $conf, $user, $langs; $langs->load("deliveries"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'typhon'; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 5de1ee5ad99..5c6f1f3955b 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4426,6 +4426,7 @@ class Product extends CommonObject global $conf, $user, $langs; $langs->load("products"); + $outputlangs->load("products"); // Positionne le modele sur le nom du modele a utiliser if (!dol_strlen($modele)) { diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 068ea05dbab..62a7b5835d4 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -856,6 +856,7 @@ class Entrepot extends CommonObject global $conf, $user, $langs; $langs->load("stocks"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 509379860c3..d1c703924d4 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -1167,6 +1167,7 @@ class MouvementStock extends CommonObject global $conf, $user, $langs; $langs->load("stocks"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'stdmovement'; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 907a741c288..871d94b87a4 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2630,6 +2630,7 @@ class SupplierProposal extends CommonObject global $conf, $langs; $langs->load("supplier_proposal"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'aurore'; From 81467e1d0996041e25d26ab769146d0003314861 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Tue, 4 Aug 2020 11:05:12 +0200 Subject: [PATCH 188/434] FIX search warehouse list --- htdocs/product/stock/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index f5121ea0089..f0b94f99bdb 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -232,7 +232,7 @@ foreach ($search as $key => $val) if ($search[$key] == '-1') $search[$key] = ''; $mode_search = 2; } - if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : $key), $search[$key], (($key == 'status') ? 2 : $mode_search)); + if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : 't.' . $key), $search[$key], (($key == 'status') ? 2 : $mode_search)); } if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all); // Add where from extra fields From 0e03578e913120f963cbbf9bd4f5961ca15b304c Mon Sep 17 00:00:00 2001 From: Tim Otte Date: Tue, 4 Aug 2020 11:02:16 +0200 Subject: [PATCH 189/434] Fixed translation of product units in documents --- htdocs/bom/class/bom.class.php | 1 + htdocs/comm/propal/class/propal.class.php | 1 + htdocs/commande/class/commande.class.php | 1 + htdocs/compta/facture/class/facture.class.php | 1 + htdocs/contrat/class/contrat.class.php | 1 + htdocs/core/class/commonobjectline.class.php | 4 ++-- htdocs/expedition/class/expedition.class.php | 1 + htdocs/fourn/class/fournisseur.commande.class.php | 1 + htdocs/fourn/class/fournisseur.facture.class.php | 1 + htdocs/livraison/class/livraison.class.php | 1 + htdocs/product/class/product.class.php | 1 + htdocs/product/stock/class/entrepot.class.php | 1 + htdocs/product/stock/class/mouvementstock.class.php | 1 + htdocs/supplier_proposal/class/supplier_proposal.class.php | 1 + 14 files changed, 15 insertions(+), 2 deletions(-) diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index b23a96372c6..aea05d59a15 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -945,6 +945,7 @@ class BOM extends CommonObject global $conf, $langs; $langs->load("mrp"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 3fd122c0103..0be35671738 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3787,6 +3787,7 @@ class Propal extends CommonObject global $conf, $langs; $langs->load("propale"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'azur'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index b911a03e3ad..b1c0aac6d15 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3990,6 +3990,7 @@ class Commande extends CommonOrder global $conf, $langs; $langs->load("orders"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'einstein'; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 193be9d5575..f0d67f309f2 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4402,6 +4402,7 @@ class Facture extends CommonInvoice global $conf, $langs; $langs->load("bills"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 1dec473edac..1153f89689d 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2468,6 +2468,7 @@ class Contrat extends CommonObject global $conf, $langs; $langs->load("contracts"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'strato'; diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index f04e2da11ee..4874dded08d 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -74,12 +74,12 @@ abstract class CommonObjectLine extends CommonObject $label_type = 'short_label'; } - $sql = 'select '.$label_type.' from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; + $sql = 'select '.$label_type.',code from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { $res = $this->db->fetch_array($resql); - $label = $res[$label_type]; + $label = ($label_type == 'short' ? $res[$label_type] : 'unit'.$res['code']); $this->db->free($resql); return $label; } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 8e17403635a..ab77e95983f 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2567,6 +2567,7 @@ class Expedition extends CommonObject global $conf, $langs; $langs->load("sendings"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'rouget'; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 5ca0a154312..6456d3ec07b 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3084,6 +3084,7 @@ class CommandeFournisseur extends CommonOrder global $conf, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'muscadet'; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index bbc8a3e6e28..093be1d9de8 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -2721,6 +2721,7 @@ class FactureFournisseur extends CommonInvoice global $conf, $user, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); // Set the model on the model name to use if (empty($modele)) diff --git a/htdocs/livraison/class/livraison.class.php b/htdocs/livraison/class/livraison.class.php index acfe8b29d05..6c5c6e49611 100644 --- a/htdocs/livraison/class/livraison.class.php +++ b/htdocs/livraison/class/livraison.class.php @@ -1068,6 +1068,7 @@ class Livraison extends CommonObject global $conf, $user, $langs; $langs->load("deliveries"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'typhon'; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 4dd4c7b3420..6a832eced1e 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4568,6 +4568,7 @@ class Product extends CommonObject global $conf, $user, $langs; $langs->load("products"); + $outputlangs->load("products"); // Positionne le modele sur le nom du modele a utiliser if (!dol_strlen($modele)) { diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index ea5feaa170c..76e828dda91 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -878,6 +878,7 @@ class Entrepot extends CommonObject global $conf, $user, $langs; $langs->load("stocks"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index c2599faf942..ffc84f41e92 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -1164,6 +1164,7 @@ class MouvementStock extends CommonObject global $conf, $user, $langs; $langs->load("stocks"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'stdmovement'; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index fa87111c2e8..dd63a20d40a 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2722,6 +2722,7 @@ class SupplierProposal extends CommonObject global $conf, $langs; $langs->load("supplier_proposal"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'aurore'; From dbb2e8b1ba909f2373d497d2ad9e4de1cad983a9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 11:56:01 +0200 Subject: [PATCH 190/434] Update dispatch.php --- htdocs/fourn/commande/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 3bc69e6770b..46166cb31e0 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -744,7 +744,7 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; print ' '.$langs->trans("QtyToDispatchShort"); - print ' ('.$langs->trans("Reset").')'.''; + print ' ('.$langs->trans("Reset").')'; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { From fd551261bbd7b1b1573b4db2444400bc2c080c9c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 11:58:29 +0200 Subject: [PATCH 191/434] Update dispatch.php --- htdocs/fourn/commande/dispatch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 46166cb31e0..2293fd8aff0 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -744,7 +744,7 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; print ' '.$langs->trans("QtyToDispatchShort"); - print ' ('.$langs->trans("Reset").')'; + print '
'.$langs->trans("Reset").')'; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { From 4bacb7d48ebbe34d3aa7256fa8aabf339601832e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:00:24 +0200 Subject: [PATCH 192/434] Update dispatch.php --- htdocs/fourn/commande/dispatch.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 2293fd8aff0..c64d158ac2c 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -744,7 +744,7 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; print ' '.$langs->trans("QtyToDispatchShort"); - print '
'.$langs->trans("Reset").')'; + print '
'.$langs->trans("Reset").''; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { @@ -1069,20 +1069,16 @@ if ($id > 0 || !empty($ref)) { $("select[name=fk_default_warehouse]").change(function() { var fk_default_warehouse = $("option:selected", this).val(); $("select[name^=entrepot_]").val(fk_default_warehouse).change(); - });'; - $i = 0; - print ' + }); + jQuery("#autoreset").click(function() {'; $i = 0; - while ($i < $nbproduct) - { - print ' - jQuery("#qty_0_'.$i.'").val("");'; + while ($i < $nbproduct) { + print ' jQuery("#qty_0_'.$i.'").val("");'; $i++; } print ' - });'; - print ' + }); }); '; From fa96fd8a8b0dab7ac14342fb27ee952f04c56d2e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:19:44 +0200 Subject: [PATCH 193/434] Update actions_addupdatedelete.inc.php --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 08b3e037499..b4bcaff370a 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -156,7 +156,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == '1' ? 1 : 0); + $value = ((GETPOST($key, 'aZ09) == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 0d17682773bb29b22cc92a809dbc2e7abbb7a1aa Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:20:10 +0200 Subject: [PATCH 194/434] Update actions_addupdatedelete.inc.php --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index b4bcaff370a..82a76cf8718 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -156,7 +156,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = ((GETPOST($key, 'aZ09) == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); + $value = ((GETPOST($key, 'aZ09') == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 13202dfc7c550c03b10be45f212b35d08e05f6c1 Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Mon, 3 Aug 2020 14:31:33 +0100 Subject: [PATCH 195/434] fix:value of checked option must be the same as in showInputfield function --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 37a39e7d1f0..c3a93639a05 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -165,7 +165,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == 'on' ? 1 : 0); + $value = (GETPOST($key) == '1' ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 2aaae47aeffcc9c4f0904546aa1a342f49fb3af2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:19:44 +0200 Subject: [PATCH 196/434] Update actions_addupdatedelete.inc.php --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index c3a93639a05..b30c1c33731 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -165,7 +165,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == '1' ? 1 : 0); + $value = ((GETPOST($key, 'aZ09) == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 08167b959cc5e7daa91614861681275c6d18a037 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:20:10 +0200 Subject: [PATCH 197/434] Update actions_addupdatedelete.inc.php --- htdocs/core/actions_addupdatedelete.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index b30c1c33731..ec35ec4061d 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -165,7 +165,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = ((GETPOST($key, 'aZ09) == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); + $value = ((GETPOST($key, 'aZ09') == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } From 2076d18825817a4ac90f70bd273f7479465d5d90 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 12:47:09 +0200 Subject: [PATCH 198/434] FIX Param of fetch_name_optionals_label must be object->table_element --- htdocs/commande/list.php | 2 +- htdocs/compta/facture/invoicetemplate_list.php | 2 +- htdocs/compta/facture/list.php | 2 +- htdocs/contact/list.php | 2 +- htdocs/contrat/list.php | 2 +- htdocs/contrat/services_list.php | 2 +- htdocs/core/class/extrafields.class.php | 3 ++- htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php | 2 +- htdocs/expensereport/list.php | 2 +- htdocs/fichinter/list.php | 2 +- htdocs/fourn/commande/list.php | 2 +- htdocs/modulebuilder/template/class/myobject.class.php | 2 +- htdocs/product/list.php | 2 +- htdocs/projet/activity/perweek.php | 3 +-- htdocs/public/ticket/list.php | 2 +- htdocs/zapier/class/hook.class.php | 4 ++-- 16 files changed, 18 insertions(+), 18 deletions(-) diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 3b83e04fe3c..0cc9fa6634b 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -116,7 +116,7 @@ $hookmanager->initHooks(array('orderlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('commande'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); // List of fields to search into when doing a "search in all" diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php index d8f51290872..5c353d6f2cd 100644 --- a/htdocs/compta/facture/invoicetemplate_list.php +++ b/htdocs/compta/facture/invoicetemplate_list.php @@ -108,7 +108,7 @@ $hookmanager->initHooks(array('invoicereclist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('facture_rec'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 128e0502344..6d12483e303 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -150,7 +150,7 @@ $hookmanager->initHooks(array('invoicelist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('facture'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index f766c8beeb8..39c588ace15 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -143,7 +143,7 @@ $hookmanager->initHooks(array('contactlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contact'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index a7205730817..37fd99a771e 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -100,7 +100,7 @@ $hookmanager->initHooks(array('contractlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contrat'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); // List of fields to search into when doing a "search in all" diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 2b81ceff5fa..90f6516a499 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -84,7 +84,7 @@ $hookmanager->initHooks(array('contractservicelist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contratdet'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index eecb5b54330..5ac47f1a478 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -842,7 +842,7 @@ class ExtraFields /** * Load array this->attributes, or old this->attribute_xxx like attribute_label, attribute_type, ... * - * @param string $elementtype Type of element ('' = all, 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). + * @param string $elementtype Type of element ('' = all or $object->table_element like 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). * @param boolean $forceload Force load of extra fields whatever is status of cache. * @return array Array of attributes keys+label for all extra fields. */ @@ -856,6 +856,7 @@ class ExtraFields if ($elementtype == 'thirdparty') $elementtype = 'societe'; if ($elementtype == 'contact') $elementtype = 'socpeople'; if ($elementtype == 'order_supplier') $elementtype = 'commande_fournisseur'; + if ($elementtype == 'stock_mouvement') $elementtype = 'movement'; $array_name_label = array(); diff --git a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php index d0e9ba9d1e4..69af56d1e17 100644 --- a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php +++ b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php @@ -183,7 +183,7 @@ class pdf_stdmovement extends ModelePDFMovement /** * Function to build a document on disk using the generic odt module. * - * @param StockMovements $object Object source to build document + * @param MouvementStock $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 07f0e332276..ec54b88a31b 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -109,7 +109,7 @@ $hookmanager->initHooks(array('expensereportlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('expensereport'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 3ecf9a076dc..42031e25ce5 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -85,7 +85,7 @@ $hookmanager->initHooks(array('interventionlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('fichinter'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index acd79212052..417e78023a8 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -120,7 +120,7 @@ $hookmanager->initHooks(array('supplierorderlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('commande_fournisseur'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index bfd1cd46fb5..8fe0b67a233 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -310,7 +310,7 @@ class MyObject extends CommonObject foreach ($object->array_options as $key => $option) { $shortkey = preg_replace('/options_/', '', $key); - if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; unset($object->array_options[$key]); diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 57eacb75ed4..19b5c48df8f 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -107,7 +107,7 @@ $extrafields = new ExtraFields($db); $form = new Form($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('product'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); if (empty($action)) $action = 'list'; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index 3a5ae388f9f..484a93e8631 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -122,8 +122,7 @@ $object = new Task($db); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -//$extrafields->fetch_name_optionals_label('projet'); -$extrafields->fetch_name_optionals_label('projet_task'); +$extrafields->fetch_name_optionals_label($object->table_element); $arrayfields = array(); /*$arrayfields=array( diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index 40e6e55cb33..7d794e99a74 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -201,7 +201,7 @@ if ($action == "view_ticketlist") // fetch optionals attributes and labels $extrafields = new ExtraFields($db); - $extrafields->fetch_name_optionals_label('ticket'); + $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/zapier/class/hook.class.php b/htdocs/zapier/class/hook.class.php index b985c77434e..4d3d7296b2f 100644 --- a/htdocs/zapier/class/hook.class.php +++ b/htdocs/zapier/class/hook.class.php @@ -354,10 +354,10 @@ class Hook extends CommonObject // ... // Clear extrafields that are unique if (is_array($object->array_options) && count($object->array_options) > 0) { - $extrafields->fetch_name_optionals_label($this->element); + $extrafields->fetch_name_optionals_label($this->table_element); foreach ($object->array_options as $key => $option) { $shortkey = preg_replace('/options_/', '', $key); - if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) { + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { // var_dump($key); // var_dump($clonedObj->array_options[$key]); // exit; From 4587031481f4d15c0897e621e44d16360163beca Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 13:31:29 +0200 Subject: [PATCH 199/434] FIX #14336 --- htdocs/core/tpl/extrafields_list_search_title.tpl.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/tpl/extrafields_list_search_title.tpl.php b/htdocs/core/tpl/extrafields_list_search_title.tpl.php index 9a83cbb42aa..6c0e6b0a559 100644 --- a/htdocs/core/tpl/extrafields_list_search_title.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_title.tpl.php @@ -29,6 +29,10 @@ if (!empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_e } else { + if (! empty($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]) && is_object($langs)) { + $langs->load($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]); + } + $tooltip = empty($extrafields->attributes[$extrafieldsobjectkey]['help'][$key]) ? '' : $extrafields->attributes[$extrafieldsobjectkey]['help'][$key]; print getTitleFieldOfList($extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align ? 'align="'.$align.'" data-titlekey="'.$key.'"' : 'data-titlekey="'.$key.'"'), $sortfield, $sortorder, '', $disablesortlink, $tooltip)."\n"; From 39a55839301dae3a33eeecfc86177b8b898904b7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 13:31:29 +0200 Subject: [PATCH 200/434] FIX #14146 --- htdocs/core/tpl/extrafields_list_search_title.tpl.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/tpl/extrafields_list_search_title.tpl.php b/htdocs/core/tpl/extrafields_list_search_title.tpl.php index 9a83cbb42aa..6c0e6b0a559 100644 --- a/htdocs/core/tpl/extrafields_list_search_title.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_title.tpl.php @@ -29,6 +29,10 @@ if (!empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_e } else { + if (! empty($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]) && is_object($langs)) { + $langs->load($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]); + } + $tooltip = empty($extrafields->attributes[$extrafieldsobjectkey]['help'][$key]) ? '' : $extrafields->attributes[$extrafieldsobjectkey]['help'][$key]; print getTitleFieldOfList($extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align ? 'align="'.$align.'" data-titlekey="'.$key.'"' : 'data-titlekey="'.$key.'"'), $sortfield, $sortorder, '', $disablesortlink, $tooltip)."\n"; From 9a5d0ab0a293aa859f5fe79232bcbc7d6289c68f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 4 Aug 2020 13:48:11 +0200 Subject: [PATCH 201/434] FIX #14236 --- htdocs/adherents/admin/adherent_emails.php | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/htdocs/adherents/admin/adherent_emails.php b/htdocs/adherents/admin/adherent_emails.php index e0675a6124a..c58dea54a93 100644 --- a/htdocs/adherents/admin/adherent_emails.php +++ b/htdocs/adherents/admin/adherent_emails.php @@ -93,6 +93,7 @@ if ($action == 'update' || $action == 'add') $constnote = (GETPOSTISSET('constnote_'.$constname) ? GETPOST('constnote_'.$constname, 'none') : GETPOST('constnote')); $typetouse = empty($oldtypetonewone[$consttype]) ? $consttype : $oldtypetonewone[$consttype]; + $constvalue = preg_replace('/:member$/', '', $constvalue); $res = dolibarr_set_const($db, $constname, $constvalue, $typetouse, 0, $constnote, $conf->entity); @@ -108,26 +109,6 @@ if ($action == 'update' || $action == 'add') } } -// Action to enable a submodule of the adherent module -if ($action == 'set') -{ - $result = dolibarr_set_const($db, GETPOST('name', 'alpha'), GETPOST('value'), '', 0, '', $conf->entity); - if ($result < 0) - { - print $db->error(); - } -} - -// Action to disable a submodule of the adherent module -if ($action == 'unset') -{ - $result = dolibarr_del_const($db, GETPOST('name', 'alpha'), $conf->entity); - if ($result < 0) - { - print $db->error(); - } -} - /* From 11f14b8fe5c155dbb706a54e21a4933d8d02000c Mon Sep 17 00:00:00 2001 From: John Botella Date: Tue, 4 Aug 2020 14:13:52 +0200 Subject: [PATCH 202/434] Fix bad usage of moreparam --- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/lib/ajax.lib.php | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 1e1bbdf58d2..718b9fecdfc 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5953,7 +5953,7 @@ class Form $urlforajaxcall = DOL_URL_ROOT.'/core/ajax/selectobject.php'; // No immediate load of all database - $urloption = 'htmlname='.$htmlname.'&outjson=1&objectdesc='.$objectdesc.'&filter='.urlencode($objecttmp->filter).($moreparams ? $moreparams : ''); + $urloption = 'htmlname='.$htmlname.'&outjson=1&objectdesc='.$objectdesc.'&filter='.urlencode($objecttmp->filter); // Activate the auto complete using ajax call. $out .= ajax_autocompleter($preselectedvalue, $htmlname, $urlforajaxcall, $urloption, $conf->global->$confkeyforautocompletemode, 0, array()); $out .= ''; diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index a430a1612af..72bdc413795 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -25,25 +25,26 @@ /** - * Generic function that return javascript to add to a page to transform a common input field into an autocomplete field by calling an Ajax page (ex: /societe/ajaxcompanies.php). + * Generic function that return javascript to add to a page to transform a common input field into an autocomplete field by calling an Ajax page (ex: /societe/ajaxcompanies.php). * The HTML field must be an input text with id=search_$htmlname. * This use the jQuery "autocomplete" function. If we want to use the select2, we must also convert the input into select on funcntions that call this method. * - * @param string $selected Preselected value - * @param string $htmlname HTML name of input field - * @param string $url Ajax Url to call for request: /path/page.php. Must return a json array ('key'=>id, 'value'=>String shown into input field once selected, 'label'=>String shown into combo list) - * @param string $urloption More parameters on URL request - * @param int $minLength Minimum number of chars to trigger that Ajax search - * @param int $autoselect Automatic selection if just one value - * @param array $ajaxoptions Multiple options array + * @param string $selected Preselected value + * @param string $htmlname HTML name of input field + * @param string $url Ajax Url to call for request: /path/page.php. Must return a json array ('key'=>id, 'value'=>String shown into input field once selected, 'label'=>String shown into combo list) + * @param string $urloption More parameters on URL request + * @param int $minLength Minimum number of chars to trigger that Ajax search + * @param int $autoselect Automatic selection if just one value + * @param array $ajaxoptions Multiple options array * - Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done * - Ex: array('disabled'=> ) * - Ex: array('show'=> ) * - Ex: array('update_textarea'=> ) * - Ex: array('option_disabled'=> id to disable and warning to show if we select a disabled value (this is possible when using autocomplete ajax) - * @return string Script + * @param string $moreparams More params provided to ajax call + * @return string Script */ -function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array()) +function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams = '') { if (empty($minLength)) $minLength=1; @@ -55,7 +56,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen // Input search_htmlname is original field // Input htmlname is a second input field used when using ajax autocomplete. - $script = ''; + $script = ''; $script.= ''."\n"; $script.= ''; - print load_fiche_titre($langs->trans("StockCorrection"), '', 'generic'); +print load_fiche_titre($langs->trans("StockCorrection"), '', 'generic'); - print ''."\n"; +print ''."\n"; - dol_fiche_head(); +dol_fiche_head(); - print ''; - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; +print '
'; - // Warehouse or product - print ''; - if ($object->element == 'product') - { - print ''; - print ''; - } - if ($object->element == 'stock') - { - print ''; - print ''; - } - print ''; - print ''; - print ''; +// Warehouse or product +print ''; +if ($object->element == 'product') { + print ''; + print ''; +} +if ($object->element == 'stock') { + print ''; + print ''; +} +print ''; +print ''; +print ''; - // Serial / Eat-by date - if (!empty($conf->productbatch->enabled) && - (($object->element == 'product' && $object->hasbatch()) - || ($object->element == 'stock')) - ) - { - print ''; - print 'element == 'stock' ? '' : ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; - print ''; - print ''; - print ''; - print ''; - print ''; - } +// Serial / Eat-by date +if (!empty($conf->productbatch->enabled) && +(($object->element == 'product' && $object->hasbatch()) +|| ($object->element == 'stock')) +) +{ + print ''; + print 'element == 'stock' ? '' : ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; + print ''; + print ''; + print ''; + print ''; + print ''; +} - // Purchase price and project - print ''; - print ''; - print ''; - if (!empty($conf->projet->enabled)) - { - print ''; - print ''; - } - print ''; +// Purchase price and project +print ''; +print ''; +print ''; +if (!empty($conf->projet->enabled)) +{ + print ''; + print ''; +} +print ''; - // Label of mouvement of id of inventory - $valformovementlabel = ((GETPOST("label") && (GETPOST('label') != $langs->trans("MovementCorrectStock", ''))) ? GETPOST("label") : $langs->trans("MovementCorrectStock", $productref)); - print ''; - print ''; - print ''; - print ''; - print ''; +// Label of mouvement of id of inventory +$valformovementlabel = ((GETPOST("label") && (GETPOST('label') != $langs->trans("MovementCorrectStock", ''))) ? GETPOST("label") : $langs->trans("MovementCorrectStock", $productref)); +print ''; +print ''; +print ''; +print ''; +print ''; - print '
'.$langs->trans("Warehouse").''; - print $formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100'); - print '   '; - print ''.$langs->trans("Product").''; - $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); - print '   '; - print ''.$langs->trans("NumberOfUnit").'
'.$langs->trans("Warehouse").''; + print $formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100'); + print '   '; + print ''.$langs->trans("Product").''; + $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); + print '   '; + print ''.$langs->trans("NumberOfUnit").'
'; - print ''; - print '
'.$langs->trans("EatByDate").''; - $eatbyselected = dol_mktime(0, 0, 0, GETPOST('eatbymonth'), GETPOST('eatbyday'), GETPOST('eatbyyear')); - print $form->selectDate($eatbyselected, 'eatby', '', '', 1, ""); - print ''.$langs->trans("SellByDate").''; - $sellbyselected = dol_mktime(0, 0, 0, GETPOST('sellbymonth'), GETPOST('sellbyday'), GETPOST('sellbyyear')); - print $form->selectDate($sellbyselected, 'sellby', '', '', 1, ""); - print '
'; + print ''; + print '
'.$langs->trans("EatByDate").''; + $eatbyselected = dol_mktime(0, 0, 0, GETPOST('eatbymonth'), GETPOST('eatbyday'), GETPOST('eatbyyear')); + print $form->selectDate($eatbyselected, 'eatby', '', '', 1, ""); + print ''.$langs->trans("SellByDate").''; + $sellbyselected = dol_mktime(0, 0, 0, GETPOST('sellbymonth'), GETPOST('sellbyday'), GETPOST('sellbyyear')); + print $form->selectDate($sellbyselected, 'sellby', '', '', 1, ""); + print '
'.$langs->trans("UnitPurchaseValue").''.$langs->trans('Project').''; - $formproject->select_projects(-1, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); - print '
'.$langs->trans("UnitPurchaseValue").''.$langs->trans('Project').''; + $formproject->select_projects(-1, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); + print '
'.$langs->trans("MovementLabel").''; - print ''; - print ''.$langs->trans("InventoryCode").'
'.$langs->trans("MovementLabel").''; +print ''; +print ''.$langs->trans("InventoryCode").'
'; +print ''; - dol_fiche_end(); +dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; - print '
'; +print '
'; +print ''; +print '     '; +print ''; +print '
'; - print ''; +print ''; ?> diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php index dffd18e0176..9bea4a65070 100644 --- a/htdocs/product/stock/tpl/stocktransfer.tpl.php +++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php @@ -29,16 +29,16 @@ if (empty($conf) || !is_object($conf)) { element == 'product') $productref = $object->ref; +$productref = ''; +if ($object->element == 'product') $productref = $object->ref; - $langs->load("productbatch"); +$langs->load("productbatch"); - if (empty($id)) $id = $object->id; +if (empty($id)) $id = $object->id; - $pdluoid = GETPOST('pdluoid', 'int'); +$pdluoid = GETPOST('pdluoid', 'int'); - $pdluo = new Productbatch($db); +$pdluo = new Productbatch($db); if ($pdluoid > 0) { @@ -53,49 +53,47 @@ if ($pdluoid > 0) } } - print load_fiche_titre($langs->trans("StockTransfer"), '', 'generic'); +print load_fiche_titre($langs->trans("StockTransfer"), '', 'generic'); - print '
'."\n"; +print ''."\n"; - dol_fiche_head(); +dol_fiche_head(); - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; if ($pdluoid) { print ''; } - print ''; +print '
'; - // Source warehouse or product - print ''; -if ($object->element == 'product') -{ +// Source warehouse or product +print ''; +if ($object->element == 'product') { print ''; print ''; } -if ($object->element == 'stock') -{ +if ($object->element == 'stock') { print ''; print ''; } - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; - // Serial / Eat-by date +// Serial / Eat-by date if (!empty($conf->productbatch->enabled) && - (($object->element == 'product' && $object->hasbatch()) - || ($object->element == 'stock')) - ) +(($object->element == 'product' && $object->hasbatch()) +|| ($object->element == 'stock')) +) { print ''; print 'element == 'stock' ? '' : ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; } - // Label - $valformovementlabel = (GETPOST("label") ?GETPOST("label") : $langs->trans("MovementTransferStock", $productref)); - print ''; - print ''; - print ''; - print ''; - print ''; +// Label +$valformovementlabel = (GETPOST("label") ?GETPOST("label") : $langs->trans("MovementTransferStock", $productref)); +print ''; +print ''; +print ''; +print ''; +print ''; - print '
'.$langs->trans("WarehouseSource").''; print $formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1); print ''.$langs->trans("Product").''; $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); print ''.$langs->trans("WarehouseTarget").''; - print $formproduct->selectWarehouses(GETPOST('id_entrepot_destination'), 'id_entrepot_destination', 'warehouseopen,warehouseinternal', 1); - print '
'.$langs->trans("NumberOfUnit").'
'.$langs->trans("WarehouseTarget").''; +print $formproduct->selectWarehouses(GETPOST('id_entrepot_destination'), 'id_entrepot_destination', 'warehouseopen,warehouseinternal', 1); +print '
'.$langs->trans("NumberOfUnit").'
'; @@ -122,26 +120,26 @@ if (!empty($conf->productbatch->enabled) && print '
'.$langs->trans("MovementLabel").''; - print ''; - print ''.$langs->trans("InventoryCode").'
'.$langs->trans("MovementLabel").''; +print ''; +print ''.$langs->trans("InventoryCode").'
'; +print ''; - dol_fiche_end(); +dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; - print '
'; +print '
'; +print ''; +print '     '; +print ''; +print '
'; - print '
'; +print ''; ?> From 73ea5b0e2d9dda65d3c57e7c273349d58bfc2d8a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 02:48:16 +0200 Subject: [PATCH 267/434] Fix function to convert price to string --- htdocs/core/lib/functionsnumtoword.lib.php | 409 +++++++++++---------- 1 file changed, 213 insertions(+), 196 deletions(-) diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 9f04a81fa5f..c0636673a14 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -13,125 +13,142 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * or see http://www.gnu.org/ + * along with this program. If not, see . + * or see https://www.gnu.org/ */ /** - * \file htdocs/core/lib/functionsnumbertoword.lib.php + * \file htdocs/core/lib/functionsnumtoword.lib.php * \brief A set of functions for Dolibarr * This file contains all frequently used functions. */ /** - * Function to return number in text. + * Function to return a number into a text. + * May use module NUMBERWORDS if found. * - * - * @param float $num Number to convert - * @param Lang $langs Language - * @param boolean $currency 0=number to translate | 1=currency to translate - * @param boolean $centimes 0=no centimes | 1=centimes to translate - * @return string Text of the number + * @param float $num Number to convert (must be a numeric value, like reported by price2num()) + * @param Translate $langs Language + * @param boolean $currency 0=number to translate | 1=currency to translate + * @param boolean $centimes 0=no cents/centimes | 1=there is cents/centimes to translate + * @return string|false Text of the number */ -function dol_convertToWord($num, $langs, $currency=false, $centimes=false) +function dol_convertToWord($num, $langs, $currency = false, $centimes = false) { global $conf; - $num = str_replace(array(',', ' '), '', trim($num)); - if(! $num) { - return false; - } - if($centimes && strlen($num) == 1) { - $num = $num*10; - } - $TNum = explode('.',$num); - $num = (int) $TNum[0]; - $words = array(); - $list1 = array( - '', - $langs->transnoentitiesnoconv('one'), - $langs->transnoentitiesnoconv('two'), - $langs->transnoentitiesnoconv('three'), - $langs->transnoentitiesnoconv('four'), - $langs->transnoentitiesnoconv('five'), - $langs->transnoentitiesnoconv('six'), - $langs->transnoentitiesnoconv('seven'), - $langs->transnoentitiesnoconv('eight'), - $langs->transnoentitiesnoconv('nine'), - $langs->transnoentitiesnoconv('ten'), - $langs->transnoentitiesnoconv('eleven'), - $langs->transnoentitiesnoconv('twelve'), - $langs->transnoentitiesnoconv('thirteen'), - $langs->transnoentitiesnoconv('fourteen'), - $langs->transnoentitiesnoconv('fifteen'), - $langs->transnoentitiesnoconv('sixteen'), - $langs->transnoentitiesnoconv('seventeen'), - $langs->transnoentitiesnoconv('eighteen'), - $langs->transnoentitiesnoconv('nineteen') - ); - $list2 = array( - '', - $langs->transnoentitiesnoconv('ten'), - $langs->transnoentitiesnoconv('twenty'), - $langs->transnoentitiesnoconv('thirty'), - $langs->transnoentitiesnoconv('forty'), - $langs->transnoentitiesnoconv('fifty'), - $langs->transnoentitiesnoconv('sixty'), - $langs->transnoentitiesnoconv('seventy'), - $langs->transnoentitiesnoconv('eighty'), - $langs->transnoentitiesnoconv('ninety'), - $langs->transnoentitiesnoconv('hundred') - ); - $list3 = array( - '', - $langs->transnoentitiesnoconv('thousand'), - $langs->transnoentitiesnoconv('million'), - $langs->transnoentitiesnoconv('billion'), - $langs->transnoentitiesnoconv('trillion'), - $langs->transnoentitiesnoconv('quadrillion') - ); - - $num_length = strlen($num); - $levels = (int) (($num_length + 2) / 3); - $max_length = $levels * 3; - $num = substr('00' . $num, -$max_length); - $num_levels = str_split($num, 3); - $nboflevels = count($num_levels); - for ($i = 0; $i < $nboflevels; $i++) { - $levels--; - $hundreds = (int) ($num_levels[$i] / 100); - $hundreds = ($hundreds ? ' ' . $list1[$hundreds] . ' '.$langs->transnoentities('hundred') . ( $hundreds == 1 ? '' : 's' ) . ' ': ''); - $tens = (int) ($num_levels[$i] % 100); - $singles = ''; - if ( $tens < 20 ) { - $tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' ); - } else { - $tens = (int) ($tens / 10); - $tens = ' ' . $list2[$tens] . ' '; - $singles = (int) ($num_levels[$i] % 10); - $singles = ' ' . $list1[$singles] . ' '; - } - $words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_levels[$i] ) ) ? ' ' . $list3[$levels] . ' ' : '' ); - } //end for loop - $commas = count($words); - if ($commas > 1) { - $commas = $commas - 1; - } - $concatWords = implode(' ', $words); - // Delete multi whitespaces - $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords)); - - if(!empty($currency)) { - $concatWords .= ' '.$currency; + //$num = str_replace(array(',', ' '), '', trim($num)); This should be useless since $num MUST be a php numeric value + if (!$num) { + return false; } - // If we need to write cents call again this function for cents - if(!empty($TNum[1])) { - if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and'); - $concatWords .= ' '.dol_convertToWord($TNum[1], $langs, $currency, true); - if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes'); + if ($centimes && strlen($num) == 1) { + $num = $num * 10; + } + + if (!empty($conf->global->MAIN_MODULE_NUMBERWORDS)) { + if ($currency) { + $type = 1; + } else { + $type = 0; + } + + $concatWords = $langs->getLabelFromNumber($num, $type); + return $concatWords; + } else { + $TNum = explode('.', $num); + $num = (int) $TNum[0]; + $words = array(); + $list1 = array( + '', + $langs->transnoentitiesnoconv('one'), + $langs->transnoentitiesnoconv('two'), + $langs->transnoentitiesnoconv('three'), + $langs->transnoentitiesnoconv('four'), + $langs->transnoentitiesnoconv('five'), + $langs->transnoentitiesnoconv('six'), + $langs->transnoentitiesnoconv('seven'), + $langs->transnoentitiesnoconv('eight'), + $langs->transnoentitiesnoconv('nine'), + $langs->transnoentitiesnoconv('ten'), + $langs->transnoentitiesnoconv('eleven'), + $langs->transnoentitiesnoconv('twelve'), + $langs->transnoentitiesnoconv('thirteen'), + $langs->transnoentitiesnoconv('fourteen'), + $langs->transnoentitiesnoconv('fifteen'), + $langs->transnoentitiesnoconv('sixteen'), + $langs->transnoentitiesnoconv('seventeen'), + $langs->transnoentitiesnoconv('eighteen'), + $langs->transnoentitiesnoconv('nineteen') + ); + $list2 = array( + '', + $langs->transnoentitiesnoconv('ten'), + $langs->transnoentitiesnoconv('twenty'), + $langs->transnoentitiesnoconv('thirty'), + $langs->transnoentitiesnoconv('forty'), + $langs->transnoentitiesnoconv('fifty'), + $langs->transnoentitiesnoconv('sixty'), + $langs->transnoentitiesnoconv('seventy'), + $langs->transnoentitiesnoconv('eighty'), + $langs->transnoentitiesnoconv('ninety'), + $langs->transnoentitiesnoconv('hundred') + ); + $list3 = array( + '', + $langs->transnoentitiesnoconv('thousand'), + $langs->transnoentitiesnoconv('million'), + $langs->transnoentitiesnoconv('billion'), + $langs->transnoentitiesnoconv('trillion'), + $langs->transnoentitiesnoconv('quadrillion') + ); + + $num_length = strlen($num); + $levels = (int) (($num_length + 2) / 3); + $max_length = $levels * 3; + $num = substr('00'.$num, -$max_length); + $num_levels = str_split($num, 3); + $nboflevels = count($num_levels); + for ($i = 0; $i < $nboflevels; $i++) { + $levels--; + $hundreds = (int) ($num_levels[$i] / 100); + $hundreds = ($hundreds ? ' '.$list1[$hundreds].' '.$langs->transnoentities('hundred').($hundreds == 1 ? '' : 's').' ' : ''); + $tens = (int) ($num_levels[$i] % 100); + $singles = ''; + if ($tens < 20) { + $tens = ($tens ? ' '.$list1[$tens].' ' : ''); + } else { + $tens = (int) ($tens / 10); + $tens = ' '.$list2[$tens].' '; + $singles = (int) ($num_levels[$i] % 10); + $singles = ' '.$list1[$singles].' '; + } + $words[] = $hundreds.$tens.$singles.(($levels && (int) ($num_levels[$i])) ? ' '.$list3[$levels].' ' : ''); + } //end for loop + $commas = count($words); + if ($commas > 1) { + $commas = $commas - 1; + } + $concatWords = implode(' ', $words); + // Delete multi whitespaces + $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords)); + + if (!empty($currency)) { + $concatWords .= ' '.$currency; + } + + // If we need to write cents call again this function for cents + $decimalpart = $TNum[1]; + $decimalpart = preg_replace('/0+$/', '', $decimalpart); + + if ($decimalpart) { + if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and'); + + $concatWords .= ' '.dol_convertToWord($decimalpart, $langs, '', true); + if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes'); + } + return $concatWords; } - return $concatWords; } @@ -139,92 +156,92 @@ function dol_convertToWord($num, $langs, $currency=false, $centimes=false) * Function to return number or amount in text. * * @deprecated - * @param float $numero Number to convert - * @param Lang $langs Language - * @param string $numorcurrency 'number' or 'amount' - * @return string Text of the number or -1 in case TOO LONG (more than 1000000000000.99) + * @param float $numero Number to convert + * @param Translate $langs Language + * @param string $numorcurrency 'number' or 'amount' + * @return string Text of the number or -1 in case TOO LONG (more than 1000000000000.99) */ -function dolNumberToWord($numero, $langs, $numorcurrency='number') +function dolNumberToWord($numero, $langs, $numorcurrency = 'number') { // If the number is negative convert to positive and return -1 if is too long if ($numero < 0) $numero *= -1; if ($numero >= 1000000000001) return -1; - // Get 2 decimals to cents, another functions round or truncate - $strnumber = number_format ($numero,10); - $len=strlen($strnumber); - for ($i=0; $i<$len; $i++) - { - if ($strnumber[$i]=='.') { - $parte_decimal = $strnumber[$i+1].$strnumber[$i+2]; - break; + // Get 2 decimals to cents, another functions round or truncate + $strnumber = number_format($numero, 10); + $len = strlen($strnumber); + for ($i = 0; $i < $len; $i++) + { + if ($strnumber[$i] == '.') { + $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2]; + break; + } } - } - /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and - in case exist why ask $lang like a parameter?*/ - if (((is_object($langs) && $langs->default == 'es_MX') || (! is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') - { - if ($numero>=1 && $numero<2) { - return ("UN PESO ".$parte_decimal." / 100 M.N."); - } - elseif ($numero>=0 && $numero<1){ - return ("CERO PESOS ".$parte_decimal." / 100 M.N."); - } - elseif ($numero>=1000000 && $numero<1000001){ - return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); - } - elseif ($numero>=1000000000000 && $numero<1000000000001){ - return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); - } - else { - $entexto =""; - $number = $numero; - if ($number >= 1000000000){ - $CdMMillon = (int) ($numero / 100000000000); - $numero = $numero - $CdMMillon * 100000000000; - $DdMMillon = (int) ($numero / 10000000000); - $numero = $numero - $DdMMillon * 10000000000; - $UdMMillon = (int) ($numero / 1000000000); - $numero = $numero - $UdMMillon * 1000000000; - $entexto .= hundreds2text ($CdMMillon, $DdMMillon, $UdMMillon); - $entexto .= " MIL "; + /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and + in case exist why ask $lang like a parameter?*/ + if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') + { + if ($numero >= 1 && $numero < 2) { + return ("UN PESO ".$parte_decimal." / 100 M.N."); } - if ($number >= 1000000){ - $CdMILLON = (int) ($numero / 100000000); - $numero = $numero - $CdMILLON * 100000000; - $DdMILLON = (int) ($numero / 10000000); - $numero = $numero - $DdMILLON * 10000000; - $udMILLON = (int) ($numero / 1000000); - $numero = $numero - $udMILLON * 1000000; - $entexto .= hundreds2text ($CdMILLON, $DdMILLON, $udMILLON); - if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON==1) - $entexto .= " MILLÓN "; - else - $entexto .= " MILLONES "; + elseif ($numero >= 0 && $numero < 1) { + return ("CERO PESOS ".$parte_decimal." / 100 M.N."); } - if ($number >= 1000) { - $cdm = (int) ($numero / 100000); - $numero = $numero - $cdm * 100000; - $ddm = (int) ($numero / 10000); - $numero = $numero - $ddm * 10000; - $udm = (int) ($numero / 1000); - $numero = $numero - $udm * 1000; - $entexto .= hundreds2text ($cdm, $ddm, $udm); - if ($cdm || $ddm || $udm) + elseif ($numero >= 1000000 && $numero < 1000001) { + return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); + } + elseif ($numero >= 1000000000000 && $numero < 1000000000001) { + return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); + } + else { + $entexto = ""; + $number = $numero; + if ($number >= 1000000000) { + $CdMMillon = (int) ($numero / 100000000000); + $numero = $numero - $CdMMillon * 100000000000; + $DdMMillon = (int) ($numero / 10000000000); + $numero = $numero - $DdMMillon * 10000000000; + $UdMMillon = (int) ($numero / 1000000000); + $numero = $numero - $UdMMillon * 1000000000; + $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon); $entexto .= " MIL "; + } + if ($number >= 1000000) { + $CdMILLON = (int) ($numero / 100000000); + $numero = $numero - $CdMILLON * 100000000; + $DdMILLON = (int) ($numero / 10000000); + $numero = $numero - $DdMILLON * 10000000; + $udMILLON = (int) ($numero / 1000000); + $numero = $numero - $udMILLON * 1000000; + $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); + if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) + $entexto .= " MILLÓN "; + else + $entexto .= " MILLONES "; + } + if ($number >= 1000) { + $cdm = (int) ($numero / 100000); + $numero = $numero - $cdm * 100000; + $ddm = (int) ($numero / 10000); + $numero = $numero - $ddm * 10000; + $udm = (int) ($numero / 1000); + $numero = $numero - $udm * 1000; + $entexto .= hundreds2text($cdm, $ddm, $udm); + if ($cdm || $ddm || $udm) + $entexto .= " MIL "; + } + $c = (int) ($numero / 100); + $numero = $numero - $c * 100; + $d = (int) ($numero / 10); + $u = (int) $numero - $d * 10; + $entexto .= hundreds2text($c, $d, $u); + if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) + $entexto .= " DE"; + $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } - $c = (int) ($numero / 100); - $numero = $numero - $c * 100; - $d = (int) ($numero / 10); - $u = (int) $numero - $d * 10; - $entexto .= hundreds2text ($c, $d, $u); - if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number>1000000) - $entexto .= " DE"; - $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; + return $entexto; } - return $entexto; - } } /** @@ -237,40 +254,40 @@ function dolNumberToWord($numero, $langs, $numorcurrency='number') */ function hundreds2text($hundreds, $tens, $units) { - if ($hundreds==1 && $tens==0 && $units==0){ + if ($hundreds == 1 && $tens == 0 && $units == 0) { return "CIEN"; } - $centenas = array("CIENTO","DOSCIENTOS","TRESCIENTOS","CUATROCIENTOS","QUINIENTOS","SEISCIENTOS","SETECIENTOS","OCHOCIENTOS","NOVECIENTOS"); - $decenas = array("","","TREINTA ","CUARENTA ","CINCUENTA ","SESENTA ","SETENTA ","OCHENTA ","NOVENTA "); - $veintis = array("VEINTE","VEINTIUN","VEINTIDÓS","VEINTITRÉS","VEINTICUATRO","VEINTICINCO","VEINTISÉIS","VEINTISIETE","VEINTIOCHO","VEINTINUEVE"); - $diecis = array("DIEZ","ONCE","DOCE","TRECE","CATORCE","QUINCE","DIECISÉIS","DIECISIETE","DIECIOCHO","DIECINUEVE"); - $unidades = array("UN","DOS","TRES","CUATRO","CINCO","SEIS","SIETE","OCHO","NUEVE"); + $centenas = array("CIENTO", "DOSCIENTOS", "TRESCIENTOS", "CUATROCIENTOS", "QUINIENTOS", "SEISCIENTOS", "SETECIENTOS", "OCHOCIENTOS", "NOVECIENTOS"); + $decenas = array("", "", "TREINTA ", "CUARENTA ", "CINCUENTA ", "SESENTA ", "SETENTA ", "OCHENTA ", "NOVENTA "); + $veintis = array("VEINTE", "VEINTIUN", "VEINTIDÓS", "VEINTITRÉS", "VEINTICUATRO", "VEINTICINCO", "VEINTISÉIS", "VEINTISIETE", "VEINTIOCHO", "VEINTINUEVE"); + $diecis = array("DIEZ", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECISÉIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE"); + $unidades = array("UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE"); $entexto = ""; - if ($hundreds!=0){ - $entexto .= $centenas[$hundreds-1]; + if ($hundreds != 0) { + $entexto .= $centenas[$hundreds - 1]; } - if ($tens>2){ - if ($hundreds!=0) $entexto .= " "; - $entexto .= $decenas[$tens-1]; - if ($units!=0){ + if ($tens > 2) { + if ($hundreds != 0) $entexto .= " "; + $entexto .= $decenas[$tens - 1]; + if ($units != 0) { $entexto .= " Y "; - $entexto .= $unidades[$units-1]; + $entexto .= $unidades[$units - 1]; } return $entexto; } - elseif ($tens==2){ - if ($hundreds!=0) $entexto .= " "; + elseif ($tens == 2) { + if ($hundreds != 0) $entexto .= " "; $entexto .= " ".$veintis[$units]; return $entexto; } - elseif ($tens==1){ - if ($hundreds!=0) $entexto .= " "; + elseif ($tens == 1) { + if ($hundreds != 0) $entexto .= " "; $entexto .= $diecis[$units]; return $entexto; } - if ($units!=0) { - if ($hundreds!=0 || $tens!=0) $entexto .= " "; - $entexto .= $unidades[$units-1]; + if ($units != 0) { + if ($hundreds != 0 || $tens != 0) $entexto .= " "; + $entexto .= $unidades[$units - 1]; } return $entexto; } From 641d9a656548ce601bb42e4d11739f8421cd0b59 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 02:58:07 +0200 Subject: [PATCH 268/434] Fix number to string --- htdocs/core/lib/functionsnumtoword.lib.php | 141 +++++++++++---------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 77a2e6d32b6..6479612de1a 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -163,86 +163,87 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) */ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') { - // If the number is negative convert to positive and return -1 if is too long + // If the number is negative convert to positive and return -1 if it is too long if ($numero < 0) $numero *= -1; - if ($numero >= 1000000000001) + if ($numero >= 1000000000001) { return -1; + } - // Get 2 decimals to cents, another functions round or truncate - $strnumber = number_format($numero, 10); - $len = strlen($strnumber); - for ($i = 0; $i < $len; $i++) - { - if ($strnumber[$i] == '.') { - $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2]; - break; - } + // Get 2 decimals to cents, another functions round or truncate + $strnumber = number_format($numero, 10); + $len = strlen($strnumber); + for ($i = 0; $i < $len; $i++) + { + if ($strnumber[$i] == '.') { + $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2]; + break; } + } - /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and - in case exist why ask $lang like a parameter?*/ - if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') - { - if ($numero >= 1 && $numero < 2) { - return ("UN PESO ".$parte_decimal." / 100 M.N."); + /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and + in case exist why ask $lang like a parameter?*/ + if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') + { + if ($numero >= 1 && $numero < 2) { + return ("UN PESO ".$parte_decimal." / 100 M.N."); + } + elseif ($numero >= 0 && $numero < 1) { + return ("CERO PESOS ".$parte_decimal." / 100 M.N."); + } + elseif ($numero >= 1000000 && $numero < 1000001) { + return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); + } + elseif ($numero >= 1000000000000 && $numero < 1000000000001) { + return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); + } + else { + $entexto = ""; + $number = $numero; + if ($number >= 1000000000) { + $CdMMillon = (int) ($numero / 100000000000); + $numero = $numero - $CdMMillon * 100000000000; + $DdMMillon = (int) ($numero / 10000000000); + $numero = $numero - $DdMMillon * 10000000000; + $UdMMillon = (int) ($numero / 1000000000); + $numero = $numero - $UdMMillon * 1000000000; + $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon); + $entexto .= " MIL "; } - elseif ($numero >= 0 && $numero < 1) { - return ("CERO PESOS ".$parte_decimal." / 100 M.N."); + if ($number >= 1000000) { + $CdMILLON = (int) ($numero / 100000000); + $numero = $numero - $CdMILLON * 100000000; + $DdMILLON = (int) ($numero / 10000000); + $numero = $numero - $DdMILLON * 10000000; + $udMILLON = (int) ($numero / 1000000); + $numero = $numero - $udMILLON * 1000000; + $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); + if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) + $entexto .= " MILLÓN "; + else + $entexto .= " MILLONES "; } - elseif ($numero >= 1000000 && $numero < 1000001) { - return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); - } - elseif ($numero >= 1000000000000 && $numero < 1000000000001) { - return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); - } - else { - $entexto = ""; - $number = $numero; - if ($number >= 1000000000) { - $CdMMillon = (int) ($numero / 100000000000); - $numero = $numero - $CdMMillon * 100000000000; - $DdMMillon = (int) ($numero / 10000000000); - $numero = $numero - $DdMMillon * 10000000000; - $UdMMillon = (int) ($numero / 1000000000); - $numero = $numero - $UdMMillon * 1000000000; - $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon); + if ($number >= 1000) { + $cdm = (int) ($numero / 100000); + $numero = $numero - $cdm * 100000; + $ddm = (int) ($numero / 10000); + $numero = $numero - $ddm * 10000; + $udm = (int) ($numero / 1000); + $numero = $numero - $udm * 1000; + $entexto .= hundreds2text($cdm, $ddm, $udm); + if ($cdm || $ddm || $udm) $entexto .= " MIL "; - } - if ($number >= 1000000) { - $CdMILLON = (int) ($numero / 100000000); - $numero = $numero - $CdMILLON * 100000000; - $DdMILLON = (int) ($numero / 10000000); - $numero = $numero - $DdMILLON * 10000000; - $udMILLON = (int) ($numero / 1000000); - $numero = $numero - $udMILLON * 1000000; - $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); - if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) - $entexto .= " MILLÓN "; - else - $entexto .= " MILLONES "; - } - if ($number >= 1000) { - $cdm = (int) ($numero / 100000); - $numero = $numero - $cdm * 100000; - $ddm = (int) ($numero / 10000); - $numero = $numero - $ddm * 10000; - $udm = (int) ($numero / 1000); - $numero = $numero - $udm * 1000; - $entexto .= hundreds2text($cdm, $ddm, $udm); - if ($cdm || $ddm || $udm) - $entexto .= " MIL "; - } - $c = (int) ($numero / 100); - $numero = $numero - $c * 100; - $d = (int) ($numero / 10); - $u = (int) $numero - $d * 10; - $entexto .= hundreds2text($c, $d, $u); - if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) - $entexto .= " DE"; - $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } - return $entexto; + $c = (int) ($numero / 100); + $numero = $numero - $c * 100; + $d = (int) ($numero / 10); + $u = (int) $numero - $d * 10; + $entexto .= hundreds2text($c, $d, $u); + if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) + $entexto .= " DE"; + $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } + return $entexto; + } } /** From 01babc452ca7c711ad53b0c40e76afcaaf9bb8b2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 03:52:49 +0200 Subject: [PATCH 269/434] More logs --- htdocs/takepos/index.php | 4 ++-- htdocs/takepos/invoice.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index af9c3062ba3..d3fc6b7416a 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -632,7 +632,7 @@ function TakeposPrintingTemp(){ } function OpenDrawer(){ - console.log("OpenDrawer"); + console.log("OpenDrawer call ajax url http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print"); $.ajax({ type: "POST", url: 'http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print', @@ -641,7 +641,7 @@ function OpenDrawer(){ } function DolibarrOpenDrawer() { - console.log("DolibarrOpenDrawer"); + console.log("DolibarrOpenDrawer call ajax url /takepos/ajax/ajax.php?action=opendrawer&term="); $.ajax({ type: "GET", url: "", diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index af4d5aeaf19..a3ef12c92cb 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -717,6 +717,7 @@ function TakeposPrinting(id){ } function TakeposConnector(id){ + console.log("TakeposConnector" + id); var invoice='" + id, From 37f1b27bd29370240f55e29bec260438307d60cc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 03:55:47 +0200 Subject: [PATCH 270/434] Fix phpcs --- htdocs/core/lib/functionsnumtoword.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 6479612de1a..74b585e8b50 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -219,8 +219,8 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) $entexto .= " MILLÓN "; - else - $entexto .= " MILLONES "; + else + $entexto .= " MILLONES "; } if ($number >= 1000) { $cdm = (int) ($numero / 100000); @@ -240,7 +240,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') $entexto .= hundreds2text($c, $d, $u); if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) $entexto .= " DE"; - $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; + $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } return $entexto; } From 25c37d9bca4d467e12615ea6035a5ddb16bbbd17 Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Thu, 6 Aug 2020 07:32:28 +0200 Subject: [PATCH 271/434] FIX: Get some taxes in TakePOS --- htdocs/takepos/invoice.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index aee36f9ddfc..7e771a8d4b7 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -348,6 +348,7 @@ if ($action == "addline") } } if ($idoflineadded <= 0) { + $invoice->fetch_thirdparty(); $idoflineadded = $invoice->addline($prod->description, $price, 1, $tva_tx, $localtax1_tx, $localtax2_tx, $idproduct, $customer->remise_percent, '', 0, 0, 0, '', $price_base_type, $price_ttc, $prod->type, -1, 0, '', 0, $parent_line, null, '', '', 0, 100, '', null, 0); } From da59bb811f6bad41a2c9eff3862884e25ecaa0ce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 12:29:57 +0200 Subject: [PATCH 272/434] Fix backtopage after creating a bookmark --- htdocs/bookmarks/card.php | 1 + htdocs/bookmarks/list.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 385dd506031..411c2c8175f 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -151,6 +151,7 @@ if ($action == 'create') print '
'."\n"; print ''; print ''; + print ''; print load_fiche_titre($langs->trans("NewBookmark")); diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index 5dd1718b263..1cc6029dbc9 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -158,7 +158,7 @@ print ''; print ''; $newcardbutton = ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create', '', !empty($user->rights->bookmark->creer)); +$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create&backtopage='.urlencode(DOL_URL_ROOT.'/bookmarks/list.php'), '', !empty($user->rights->bookmark->creer)); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bookmark', 0, $newcardbutton, '', $limit, 0, 0, 1); From e830e7f3d36a6a7000a75122bc5862b212c7eb29 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 13:14:43 +0200 Subject: [PATCH 273/434] Work on recruitment module --- .../install/mysql/migration/12.0.0-13.0.0.sql | 4 + ...llx_recruitment_recruitmentjobposition.sql | 6 +- htdocs/langs/en_US/boxes.lang | 1 + .../modulebuilder/template/mymoduleindex.php | 60 +++---- .../class/recruitmentjobposition.class.php | 9 +- htdocs/recruitment/recruitmentindex.php | 146 +++++++++++++----- .../recruitmentjobposition_card.php | 7 +- 7 files changed, 150 insertions(+), 83 deletions(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index e6797717711..58d85e80526 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -81,6 +81,7 @@ ALTER TABLE llx_c_incoterms ADD COLUMN label varchar(100) NULL; CREATE TABLE llx_recruitment_recruitmentjobposition( rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, ref varchar(128) DEFAULT '(PROV)' NOT NULL, + entity INTEGER DEFAULT 1 NOT NULL, label varchar(255) NOT NULL, qty integer DEFAULT 1 NOT NULL, fk_soc integer, @@ -89,6 +90,7 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( fk_user_supervisor integer, fk_establishment integer, date_planned date, + remuneration_suggested varchar(255), description text, note_public text, note_private text, @@ -113,6 +115,8 @@ ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitmen ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_status (status); ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN email_recruiter varchar(255); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN entity INTEGER DEFAULT 1 NOT NULL; +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN remuneration_suggested varchar(255); create table llx_recruitment_recruitmentjobposition_extrafields ( diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql index 88ad12acef1..b342156ccd1 100644 --- a/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql @@ -17,7 +17,8 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( -- BEGIN MODULEBUILDER FIELDS rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - ref varchar(128) DEFAULT '(PROV)' NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + entity INTEGER DEFAULT 1 NOT NULL, label varchar(255) NOT NULL, qty integer DEFAULT 1 NOT NULL, fk_soc integer, @@ -26,7 +27,8 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( email_recruiter varchar(255), fk_user_supervisor integer, fk_establishment integer, - date_planned date, + date_planned date, + remuneration_suggested varchar(255), description text, note_public text, note_private text, diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index bd62684421a..69025458630 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -83,6 +83,7 @@ BoxTitleLatestModifiedSupplierOrders=Vendor Orders: last %s modified BoxTitleLastModifiedCustomerBills=Customer Invoices: last %s modified BoxTitleLastModifiedCustomerOrders=Sales Orders: last %s modified BoxTitleLastModifiedPropals=Latest %s modified proposals +BoxTitleLatestModifiedJobPositions=Latest %s modified jobs ForCustomersInvoices=Customers invoices ForCustomersOrders=Customers orders ForProposals=Proposals diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php index 4a3356f1d7e..9050b5319e0 100644 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ b/htdocs/modulebuilder/template/mymoduleindex.php @@ -106,7 +106,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print ''; print ''; - print ''; + print ''; $var = true; if ($num > 0) @@ -117,22 +117,17 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) $obj = $db->fetch_object($resql); print ''; print ''; print ''; $i++; @@ -171,14 +166,12 @@ $max = 3; // Last modified myobject if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) { - $sql = "SELECT s.rowid, s.nom as name, s.client, s.datec, s.tms, s.canvas"; - $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.client IN (1, 2, 3)"; - $sql.= " AND s.entity IN (".getEntity($companystatic->element).")"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND s.rowid = $socid"; + $sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms"; + $sql.= " FROM ".MAIN_DB_PREFIX."mymodule_myobject as s"; + //if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE s.entity IN (".getEntity($myobjectstatic->element).")"; + //if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + //if ($socid) $sql.= " AND s.rowid = $socid"; $sql .= " ORDER BY s.tms DESC"; $sql .= $db->plimit($max, 0); @@ -191,9 +184,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print '
'.$langs->trans("DraftOrders").($num?''.$num.'':'').'
'.$langs->trans("DraftMyObjects").($num?''.$num.'':'').'
'; - $orderstatic->id=$obj->rowid; - $orderstatic->ref=$obj->ref; - $orderstatic->ref_client=$obj->ref_client; - $orderstatic->total_ht = $obj->total_ht; - $orderstatic->total_tva = $obj->total_tva; - $orderstatic->total_ttc = $obj->total_ttc; - print $orderstatic->getNomUrl(1); + + $myobjectstatic->id=$obj->rowid; + $myobjectstatic->ref=$obj->ref; + $myobjectstatic->ref_client=$obj->ref_client; + $myobjectstatic->total_ht = $obj->total_ht; + $myobjectstatic->total_tva = $obj->total_tva; + $myobjectstatic->total_ttc = $obj->total_ttc; + + print $myobjectstatic->getNomUrl(1); print ''; - $companystatic->id=$obj->socid; - $companystatic->name=$obj->name; - $companystatic->client=$obj->client; - $companystatic->code_client = $obj->code_client; - $companystatic->code_fournisseur = $obj->code_fournisseur; - $companystatic->canvas=$obj->canvas; - print $companystatic->getNomUrl(1,'customer',16); print ''.price($obj->total_ttc).'
'; print ''; print ''; print ''; print ''; @@ -202,22 +193,19 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) while ($i < $num) { $objp = $db->fetch_object($resql); - $companystatic->id=$objp->rowid; - $companystatic->name=$objp->name; - $companystatic->client=$objp->client; - $companystatic->code_client = $objp->code_client; - $companystatic->code_fournisseur = $objp->code_fournisseur; - $companystatic->canvas=$objp->canvas; + + $myobjectstatic->id=$objp->rowid; + $myobjectstatic->ref=$objp->ref; + $myobjectstatic->label=$objp->label; + $myobjectstatic->status = $objp->status; + print ''; - print ''; + print ''; print '"; print '"; print ''; $i++; - - } $db->free($resql); diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 048c0d4ee3a..c1ad8c3346d 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -96,15 +96,17 @@ class RecruitmentJobPosition extends CommonObject public $fields=array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1), 'label' => array('type'=>'varchar(255)', 'label'=>'JobLabel', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth500', 'showoncombobox'=>'1', 'autofocusoncreate'=>1), 'qty' => array('type'=>'integer', 'label'=>'NbOfEmployeesExpected', 'enabled'=>'1', 'position'=>45, 'notnull'=>1, 'visible'=>1, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp',), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'1', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), - 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>-1, 'foreignkey'=>'user.rowid',), + 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>1, 'foreignkey'=>'user.rowid',), 'email_recruiter' => array('type'=>'varchar(255)', 'label'=>'EmailRecruiter', 'enabled'=>'1', 'position'=>54, 'notnull'=>0, 'visible'=>-1, 'help'=>'ToUseAGenericEmail'), 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid',), 'fk_establishment' => array('type'=>'integer:Establishment:hrm/class/establishment.class.php', 'label'=>'Establishment', 'enabled'=>'$conf->hrm->enabled', 'position'=>56, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'establishment.rowid',), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'WorkPlace', 'enabled'=>'1', 'position'=>57, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'help'=>"IfJobIsLocatedAtAPartner",), 'date_planned' => array('type'=>'date', 'label'=>'DateExpected', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>1,), + 'remuneration_suggested' => array('type'=>'varchar(255)', 'label'=>'Remuneration', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>1,), 'description' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>65, 'notnull'=>0, 'visible'=>3,), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>101, 'notnull'=>0, 'visible'=>0,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>0,), @@ -119,6 +121,7 @@ class RecruitmentJobPosition extends CommonObject ); public $rowid; public $ref; + public $entity; public $label; public $qty; public $fk_soc; @@ -801,11 +804,11 @@ class RecruitmentJobPosition extends CommonObject $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated'); $this->labelStatus[self::STATUS_RECRUITED] = $langs->trans('Recruited'); - $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Canceled'); $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated'); $this->labelStatusShort[self::STATUS_RECRUITED] = $langs->trans('Recruited'); - $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Canceled'); } $statusType = 'status'.$status; diff --git a/htdocs/recruitment/recruitmentindex.php b/htdocs/recruitment/recruitmentindex.php index 71a4cedcc69..dc0b0eac8cf 100644 --- a/htdocs/recruitment/recruitmentindex.php +++ b/htdocs/recruitment/recruitmentindex.php @@ -24,25 +24,12 @@ * \brief Home page of recruitment top menu */ -// Load Dolibarr environment -$res = 0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; -// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME -$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; -while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } -if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; -if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; -// Try main.inc.php using relative path -if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; -if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; -if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; -if (!$res) die("Include of main fails"); - +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page -$langs->loadLangs(array("recruitment")); +$langs->loadLangs(array("recruitment", "boxes")); $action = GETPOST('action', 'alpha'); @@ -73,6 +60,7 @@ $now = dol_now(); $form = new Form($db); $formfile = new FormFile($db); +$staticrecruitmentjobposition = new RecruitmentJobPosition($db); llxHeader("", $langs->trans("RecruitmentArea")); @@ -81,6 +69,91 @@ print load_fiche_titre($langs->trans("RecruitmentArea"), '', 'object_recruitment print '
'; +/* + * Statistics + */ + +if ($conf->use_javascript_ajax) +{ + $sql = "SELECT COUNT(t.rowid) as nb, status"; + $sql .= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as t"; + $sql .= " GROUP BY t.status"; + $sql .= " ORDER BY t.status ASC"; + $resql = $db->query($sql); + + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + $totalnb = 0; + $dataseries = array(); + $colorseries = array(); + $vals = array(); + + include_once DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; + + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + $vals[$obj->status] = $obj->nb; + + $totalnb += $obj->nb; + } + $i++; + } + $db->free($resql); + + print '
'; + print '
'; - if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastCustomersOrProspects",$max); - else if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastModifiedProspects",$max); - else print $langs->trans("BoxTitleLastModifiedCustomers",$max); + print $langs->trans("BoxTitleLatestModifiedMyObjects",$max); print ''.$langs->trans("DateModificationShort").'
'.$companystatic->getNomUrl(1,'customer',48).''.$myobjectstatic->getNomUrl(1).''; - print $companystatic->getLibCustProspStatut(); print "'.dol_print_date($db->jdate($objp->tms),'day')."
'; + print ''."\n"; + $listofstatus = array(0, 1, 3, 9); + foreach ($listofstatus as $status) + { + $dataseries[] = array($staticrecruitmentjobposition->LibStatut($status, 1), (isset($vals[$status]) ? (int) $vals[$status] : 0)); + if ($status == RecruitmentJobPosition::STATUS_DRAFT) $colorseries[$status] = '-'.$badgeStatus0; + if ($status == RecruitmentJobPosition::STATUS_VALIDATED) $colorseries[$status] = $badgeStatus1; + if ($status == RecruitmentJobPosition::STATUS_RECRUITED) $colorseries[$status] = $badgeStatus4; + if ($status == RecruitmentJobPosition::STATUS_CANCELED) $colorseries[$status] = $badgeStatus9; + + if (empty($conf->use_javascript_ajax)) + { + print ''; + print ''; + print ''; + print "\n"; + } + } + if ($conf->use_javascript_ajax) + { + print ''; + } + print "
'.$langs->trans("Statistics").' - '.$langs->trans("Recruitment").'
'.$staticrecruitmentjobposition->LibStatut($status, 0).''.(isset($vals[$status]) ? $vals[$status] : 0).'
'; + + include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + $dolgraph = new DolGraph(); + $dolgraph->SetData($dataseries); + $dolgraph->SetDataColor(array_values($colorseries)); + $dolgraph->setShowLegend(2); + $dolgraph->setShowPercent(1); + $dolgraph->SetType(array('pie')); + $dolgraph->SetHeight('200'); + $dolgraph->draw('idgraphstatus'); + print $dolgraph->show($totalnb ? 0 : 1); + + print '
"; + print ""; + + print "
"; + } else { + dol_print_error($db); + } +} + +print '
'; + /* BEGIN MODULEBUILDER DRAFT MYOBJECT // Draft MyObject if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) @@ -89,7 +162,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) $sql = "SELECT c.rowid, c.ref, c.ref_client, c.total_ht, c.tva as total_tva, c.total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas"; $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."commande as c"; + $sql.= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as c"; $sql.= ", ".MAIN_DB_PREFIX."societe as s"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE c.fk_soc = s.rowid"; @@ -167,18 +240,16 @@ print '
'; $NBMAX = 3; $max = 3; -/* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT +/* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT */ // Last modified myobject -if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) +if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitmentjobposition->read) { - $sql = "SELECT s.rowid, s.nom as name, s.client, s.datec, s.tms, s.canvas"; - $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms"; + $sql.= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as s"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.client IN (1, 2, 3)"; - $sql.= " AND s.entity IN (".getEntity($companystatic->element).")"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND s.rowid = $socid"; + $sql.= " WHERE s.entity IN (".getEntity($staticrecruitmentjobposition->element).")"; + if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; + if ($socid) $sql.= " AND s.fk_soc = $socid"; $sql .= " ORDER BY s.tms DESC"; $sql .= $db->plimit($max, 0); @@ -191,9 +262,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) print ''; print ''; print ''; print ''; print ''; @@ -202,16 +271,15 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) while ($i < $num) { $objp = $db->fetch_object($resql); - $companystatic->id=$objp->rowid; - $companystatic->name=$objp->name; - $companystatic->client=$objp->client; - $companystatic->code_client = $objp->code_client; - $companystatic->code_fournisseur = $objp->code_fournisseur; - $companystatic->canvas=$objp->canvas; + $staticrecruitmentjobposition->id=$objp->rowid; + $staticrecruitmentjobposition->ref=$objp->ref; + $staticrecruitmentjobposition->label=$objp->label; + $staticrecruitmentjobposition->status = $objp->status; + $staticrecruitmentjobposition->date_creation = $objp->date_creation; + print ''; - print ''; + print ''; print '"; print '"; print ''; @@ -227,9 +295,11 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) print ''; } print "
'; - if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastCustomersOrProspects",$max); - else if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastModifiedProspects",$max); - else print $langs->trans("BoxTitleLastModifiedCustomers",$max); + print $langs->trans("BoxTitleLatestModifiedJobPositions",$max); print ''.$langs->trans("DateModificationShort").'
'.$companystatic->getNomUrl(1,'customer',48).''.$staticrecruitmentjobposition->getNomUrl(1, '').''; - print $companystatic->getLibCustProspStatut(); print "'.dol_print_date($db->jdate($objp->tms),'day')."
'.$langs->trans("None").'

"; + } else { + dol_print_error($db); } } -*/ + print '
'; diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index 137afdd597f..4037147e367 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -503,19 +503,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea { print ''.$langs->trans("Enable").''."\n"; } - } + }*/ if ($permissiontoadd) { if ($object->status == $object::STATUS_VALIDATED) { - print ''.$langs->trans("Cancel").''."\n"; + print ''.$langs->trans("Cancel").''."\n"; } else { - print ''.$langs->trans("Re-Open").''."\n"; + print ''.$langs->trans("Re-Open").''."\n"; } } - */ // Delete (need delete permission, or if draft, just need create/modify permission) if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) From 215242a4a1dc63809ffa0dd3de3d246ad49f3ce0 Mon Sep 17 00:00:00 2001 From: quentin Date: Thu, 6 Aug 2020 14:11:26 +0200 Subject: [PATCH 274/434] fix right project info.php --- htdocs/projet/info.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index d2b95726aea..b08f3ab737a 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -63,7 +63,7 @@ $search_agenda_label=GETPOST('search_agenda_label'); $id = GETPOST("id", 'int'); $socid=0; //if ($user->societe_id > 0) $socid = $user->societe_id; // For external user, no check is done on company because readability is managed by public status of project and assignement. -$result=restrictedArea($user, 'projet', $id, ''); +$result=restrictedArea($user, 'projet', $id, 'projet&project'); if (!$user->rights->projet->lire) accessforbidden(); From 43b23994e437d29417c862921c7fe600486a57a7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 15:55:04 +0200 Subject: [PATCH 275/434] WIP Recruitment module --- htdocs/core/lib/modulebuilder.lib.php | 24 +- ...recruitment_recruitmentcandidature.key.sql | 27 + ...llx_recruitment_recruitmentcandidature.sql | 36 + ...recruitmentcandidature_extrafields.key.sql | 19 + ...ent_recruitmentcandidature_extrafields.sql | 23 + htdocs/modulebuilder/index.php | 212 ++-- .../modulebuilder/template/modulebuilder.txt | 2 +- htdocs/public/recruitment/view.php | 6 + .../class/recruitmentcandidature.class.php | 1040 +++++++++++++++++ .../class/recruitmentjobposition.class.php | 2 +- ...tandard_recruitmentjobposition.modules.php | 10 +- htdocs/recruitment/modulebuilder.txt | 2 +- .../recruitmentjobposition_candidature.php | 43 - 13 files changed, 1293 insertions(+), 153 deletions(-) create mode 100644 htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql create mode 100644 htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql create mode 100644 htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql create mode 100644 htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql create mode 100644 htdocs/recruitment/class/recruitmentcandidature.class.php diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index 3232bae291a..ff14ec56e18 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -207,11 +207,12 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = * @param string $objectname Name of object * @param string $newmask New mask * @param string $readdir Directory source (use $destdir when not defined) - * @param Object $object If object was already loaded/known, it is pass to avaoid another include and new. + * @param Object $object If object was already loaded/known, it is pass to avoid another include and new. + * @param string $moduletype 'external' or 'internal' * @return int <=0 if KO, >0 if OK * @see rebuildObjectClass() */ -function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null) +function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external') { global $db, $langs; @@ -223,8 +224,14 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = ' $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php'; // Edit .sql file - $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; - $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + if ($moduletype == 'internal') { + $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; + $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + } else { + $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; + $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + } + if (!dol_is_file($pathoffiletoeditsrc)) { $langs->load("errors"); @@ -293,8 +300,13 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = ' } // Edit .key.sql file - $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; - $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + if ($moduletype == 'internal') { + $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; + $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + } else { + $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; + $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + } $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r'); diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql new file mode 100644 index 00000000000..8f92832c2a3 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql @@ -0,0 +1,27 @@ +-- Copyright (C) 2020 Laurent Destailleur +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_rowid (rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_ref (ref); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD CONSTRAINT llx_recruitment_recruitmentcandidature_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_status (status); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_mymodule_myobject ADD UNIQUE INDEX uk_mymodule_myobject_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_mymodule_myobject ADD CONSTRAINT llx_mymodule_myobject_fk_field FOREIGN KEY (fk_field) REFERENCES llx_mymodule_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql new file mode 100644 index 00000000000..c1905f46b63 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql @@ -0,0 +1,36 @@ +-- Copyright (C) 2020 Laurent Destailleur +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +CREATE TABLE llx_recruitment_recruitmentcandidature( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + description text, + note_public text, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + model_pdf varchar(255), + status smallint NOT NULL, + firstname varchar(128), + lastname varchar(128), + remuneration_requested integer, + remuneration_proposed integer + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql new file mode 100644 index 00000000000..fb1522bf6f1 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql @@ -0,0 +1,19 @@ +-- Copyright (C) 2020 Laurent Destailleur +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql new file mode 100644 index 00000000000..d0fb92fead9 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql @@ -0,0 +1,23 @@ +-- Copyright (C) 2020 Laurent Destailleur +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +create table llx_recruitment_recruitmentcandidature_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index df9e58e9b31..c8274a8f8dd 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -95,6 +95,85 @@ $result = restrictedArea($user, 'modulebuilder', null); $error = 0; +// Define $listofmodules +$dirsrootforscan = array($dirread); +// Add also the core modules into the list of modules to show/edit +if ($dirread != DOL_DOCUMENT_ROOT && ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->MODULEBUILDER_ADD_DOCUMENT_ROOT))) { $dirsrootforscan[] = DOL_DOCUMENT_ROOT; } + +// Search modules to edit +$textforlistofdirs = ''."\n"; +$listofmodules = array(); +$i = 0; +foreach ($dirsrootforscan as $dirread) +{ + $moduletype = 'external'; + if ($dirread == DOL_DOCUMENT_ROOT) { + $moduletype = 'internal'; + } + + $dirsincustom = dol_dir_list($dirread, 'directories'); + if (is_array($dirsincustom) && count($dirsincustom) > 0) { + foreach ($dirsincustom as $dircustomcursor) { + $fullname = $dircustomcursor['fullname']; + if (dol_is_file($fullname.'/'.$FILEFLAG)) + { + // Get real name of module (MyModule instead of mymodule) + $dirtoscanrel = basename($fullname).'/core/modules/'; + + $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$'); + if (empty($descriptorfiles)) // If descriptor not found into module dir, we look into main module dir. + { + $dirtoscanrel = 'core/modules/'; + $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$'); + } + $modulenamewithcase = ''; + $moduledescriptorrelpath = ''; + $moduledescriptorfullpath = ''; + + foreach ($descriptorfiles as $descriptorcursor) { + $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']); + $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase); + $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name']; + $moduledescriptorfullpath = $descriptorcursor['fullname']; + //var_dump($descriptorcursor); + } + if ($modulenamewithcase) + { + $listofmodules[$dircustomcursor['name']] = array( + 'modulenamewithcase'=>$modulenamewithcase, + 'moduledescriptorrelpath'=> $moduledescriptorrelpath, + 'moduledescriptorfullpath'=>$moduledescriptorfullpath, + 'moduledescriptorrootpath'=>$dirread, + 'moduletype'=>$moduletype + ); + } + //var_dump($listofmodules); + } + } + } + + if ($forceddirread && empty($listofmodules)) // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir + { + $listofmodules[strtolower($module)] = array( + 'modulenamewithcase'=>$module, + 'moduledescriptorrelpath'=> 'notyetimplemented', + 'moduledescriptorfullpath'=> 'notyetimplemented', + 'moduledescriptorrootpath'=> 'notyetimplemented', + ); + } + + // Show description of content + $newdircustom = $dirins; + if (empty($newdircustom)) $newdircustom = img_warning(); + // If dirread was forced to somewhere else, by using URL + // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product + if (empty($i)) $textforlistofdirs .= $langs->trans("DirScanned").' : '; + else $textforlistofdirs .= ', '; + $textforlistofdirs .= ''.$dirread.''; + $i++; +} + + /* * Actions */ @@ -214,7 +293,6 @@ if ($dirins && $action == 'initmodule' && $modulename) } $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement); - //var_dump($result); if ($result < 0) { @@ -769,6 +847,9 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { $objectname = ucfirst($objectname); + $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $moduletype = $listofmodules[strtolower($module)]['moduletype']; + if (preg_match('/[^a-z0-9_]/i', $objectname)) { $error++; @@ -1076,6 +1157,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) $objectname = $tabobj; + $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $moduletype = $listofmodules[strtolower($module)]['moduletype']; + $srcdir = $dirread.'/'.strtolower($module); $destdir = $dirins.'/'.strtolower($module); dol_mkdir($destdir); @@ -1125,7 +1209,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) // Edit the class file to write properties if (!$error) { - $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry); + $moduletype = 'external'; + + $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry, $moduletype); if (is_numeric($object) && $object <= 0) { $error++; @@ -1135,7 +1221,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) // Edit sql with new properties if (!$error) { - $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object); + $moduletype = 'external'; + + $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object, $moduletype); if ($result <= 0) { $error++; @@ -1477,79 +1565,11 @@ print load_fiche_titre($text, '', 'title_setup'); print ''.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'
'; -$dirsrootforscan = array($dirread); -// Add also the core modules into the list of modules to show/edit -if ($dirread != DOL_DOCUMENT_ROOT && ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->MODULEBUILDER_ADD_DOCUMENT_ROOT))) { $dirsrootforscan[] = DOL_DOCUMENT_ROOT; } - -// Search modules to edit -print ''."\n"; -$listofmodules = array(); -$i = 0; -foreach ($dirsrootforscan as $dirread) -{ - $dirsincustom = dol_dir_list($dirread, 'directories'); - if (is_array($dirsincustom) && count($dirsincustom) > 0) { - foreach ($dirsincustom as $dircustomcursor) { - $fullname = $dircustomcursor['fullname']; - if (dol_is_file($fullname.'/'.$FILEFLAG)) - { - // Get real name of module (MyModule instead of mymodule) - $dirtoscanrel = basename($fullname).'/core/modules/'; - - $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$'); - if (empty($descriptorfiles)) // If descriptor not found into module dir, we look into main module dir. - { - $dirtoscanrel = 'core/modules/'; - $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$'); - } - $modulenamewithcase = ''; - $moduledescriptorrelpath = ''; - $moduledescriptorfullpath = ''; - - foreach ($descriptorfiles as $descriptorcursor) { - $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']); - $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase); - $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name']; - $moduledescriptorfullpath = $descriptorcursor['fullname']; - //var_dump($descriptorcursor); - } - if ($modulenamewithcase) - { - $listofmodules[$dircustomcursor['name']] = array( - 'modulenamewithcase'=>$modulenamewithcase, - 'moduledescriptorrelpath'=> $moduledescriptorrelpath, - 'moduledescriptorfullpath'=>$moduledescriptorfullpath, - 'moduledescriptorrootpath'=>$dirread - ); - } - //var_dump($listofmodules); - } - } - } - - if ($forceddirread && empty($listofmodules)) // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir - { - $listofmodules[strtolower($module)] = array( - 'modulenamewithcase'=>$module, - 'moduledescriptorrelpath'=> 'notyetimplemented', - 'moduledescriptorfullpath'=> 'notyetimplemented', - 'moduledescriptorrootpath'=> 'notyetimplemented', - ); - } - - // Show description of content - $newdircustom = $dirins; - if (empty($newdircustom)) $newdircustom = img_warning(); - // If dirread was forced to somewhere else, by using URL - // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product - if (empty($i)) print $langs->trans("DirScanned").' : '; - else print ', '; - print ''.$dirread.''; - $i++; -} +print $textforlistofdirs; print '
'; //var_dump($listofmodules); + $message = ''; if (!$dirins) { @@ -1583,7 +1603,6 @@ $error = 0; $moduleobj = null; - if (!empty($module) && $module != 'initmodule' && $module != 'deletemodule') { $modulelowercase = strtolower($module); @@ -1835,6 +1854,8 @@ if ($module == 'initmodule') print '
'; + // Note module is inside $dirread + if ($tab == 'description') { $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; @@ -2315,29 +2336,31 @@ if ($module == 'initmodule') $pathtopicto = strtolower($module).'/img/object_'.strtolower($tabobj).'.png'; $pathtoscript = strtolower($module).'/scripts/'.strtolower($tabobj).'.php'; - //var_dump($pathtolib); - $realpathtoclass = dol_buildpath($pathtoclass, 0, 2); - $realpathtoapi = dol_buildpath($pathtoapi, 0, 2); - $realpathtoagenda = dol_buildpath($pathtoagenda, 0, 2); - $realpathtocard = dol_buildpath($pathtocard, 0, 2); - $realpathtodocument = dol_buildpath($pathtodocument, 0, 2); - $realpathtolist = dol_buildpath($pathtolist, 0, 2); - $realpathtonote = dol_buildpath($pathtonote, 0, 2); - $realpathtophpunit = dol_buildpath($pathtophpunit, 0, 2); - $realpathtosql = dol_buildpath($pathtosql, 0, 2); - $realpathtosqlextra = dol_buildpath($pathtosqlextra, 0, 2); - $realpathtosqlkey = dol_buildpath($pathtosqlkey, 0, 2); - $realpathtosqlextrakey = dol_buildpath($pathtosqlextrakey, 0, 2); - $realpathtolib = dol_buildpath($pathtolib, 0, 2); - $realpathtoobjlib = dol_buildpath($pathtoobjlib, 0, 2); - $realpathtopicto = dol_buildpath($pathtopicto, 0, 2); - $realpathtoscript = dol_buildpath($pathtoscript, 0, 2); + //var_dump($pathtoclass); var_dump($dirread); + $realpathtoclass = $dirread.'/'.$pathtoclass; + $realpathtoapi = $dirread.'/'.$pathtoapi; + $realpathtoagenda = $dirread.'/'.$pathtoagenda; + $realpathtocard = $dirread.'/'.$pathtocard; + $realpathtodocument = $dirread.'/'.$pathtodocument; + $realpathtolist = $dirread.'/'.$pathtolist; + $realpathtonote = $dirread.'/'.$pathtonote; + $realpathtophpunit = $dirread.'/'.$pathtophpunit; + $realpathtosql = $dirread.'/'.$pathtosql; + $realpathtosqlextra = $dirread.'/'.$pathtosqlextra; + $realpathtosqlkey = $dirread.'/'.$pathtosqlkey; + $realpathtosqlextrakey = $dirread.'/'.$pathtosqlextrakey; + $realpathtolib = $dirread.'/'.$pathtolib; + $realpathtoobjlib = $dirread.'/'.$pathtoobjlib; + $realpathtopicto = $dirread.'/'.$pathtopicto; + $realpathtoscript = $dirread.'/'.$pathtoscript; if (empty($realpathtoapi)) // For compatibility with some old modules { $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'s.class.php'; - $realpathtoapi = dol_buildpath($pathtoapi, 0, 2); + $realpathtoapi = $dirread.'/'.$pathtoapi; } + $urloflist = $dirread.'/'.$pathtolist; + $urlofcard = $dirread.'/'.$pathtocard; print '
'; print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass ? '' : '').$pathtoclass.($realpathtoclass ? '' : '').''; @@ -2423,9 +2446,6 @@ if ($module == 'initmodule') print '
'; print '
'; - $urloflist = dol_buildpath($pathtolist, 1); - $urlofcard = dol_buildpath($pathtocard, 1); - print '
'; print ' '.$langs->trans("PageForList").' : '.($realpathtolist ? '' : '').$pathtolist.($realpathtolist ? '' : '').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; @@ -2472,7 +2492,7 @@ if ($module == 'initmodule') if (function_exists('opcache_invalidate')) opcache_invalidate($dirread.'/'.$pathtoclass, true); // remove the include cache hell ! - if (empty($forceddirread)) + if (empty($forceddirread) && empty($dirread)) { $result = dol_include_once($pathtoclass); } else { diff --git a/htdocs/modulebuilder/template/modulebuilder.txt b/htdocs/modulebuilder/template/modulebuilder.txt index 24ea0d6eac5..670a1774929 100644 --- a/htdocs/modulebuilder/template/modulebuilder.txt +++ b/htdocs/modulebuilder/template/modulebuilder.txt @@ -1,3 +1,3 @@ # DO NOT DELETE THIS FILE MANUALLY # File to flag module built using official module template. -# When this file is present into a module directory, you can edit it with the module builder tool. Use ModuleBuilder if you want to delete module. \ No newline at end of file +# When this file is present into a module directory, you can edit it with the module builder tool. \ No newline at end of file diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index 3afc6825c43..2b07d303aa9 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -264,6 +264,12 @@ if ($object->date_planned > $now) { } print '
'; +// Remuneration +print $langs->trans("Remuneration").' : '; +print ''; +print $object->remuneration_suggested; +print '
'; + // Contact $tmpuser = new User($db); $tmpuser->fetch($object->fk_user_recruiter); diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php new file mode 100644 index 00000000000..cacda6674c2 --- /dev/null +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -0,0 +1,1040 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file class/recruitmentcandidature.class.php + * \ingroup recruitment + * \brief This file is a CRUD class file for RecruitmentCandidature (Create/Read/Update/Delete) + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class for RecruitmentCandidature + */ +class RecruitmentCandidature extends CommonObject +{ + /** + * @var string ID to identify managed object. + */ + public $element = 'recruitmentcandidature'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'recruitment_recruitmentcandidature'; + + /** + * @var int Does this object support multicompany module ? + * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table + */ + public $ismultientitymanaged = 0; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for recruitmentcandidature. Must be the part after the 'object_' into object_recruitmentcandidature.png + */ + public $picto = 'recruitmentcandidature@recruitment'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '9'=>'Canceled'),), + 'firstname' => array('type'=>'varchar(128)', 'label'=>'Firstname', 'enabled'=>'1', 'position'=>20, 'notnull'=>0, 'visible'=>1,), + 'lastname' => array('type'=>'varchar(128)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1,), + 'remuneration_requested' => array('type'=>'integer', 'label'=>'RequestedRemuneration', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1,), + 'remuneration_proposed' => array('type'=>'integer', 'label'=>'ProposedRemuneration', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1,), + ); + public $rowid; + public $ref; + public $description; + public $note_public; + public $note_private; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $import_key; + public $model_pdf; + public $status; + public $firstname; + public $lastname; + public $remuneration_requested; + public $remuneration_proposed; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + /** + * @var int Name of subtable line + */ + //public $table_element_line = 'recruitment_recruitmentcandidatureline'; + + /** + * @var int Field with ID of parent key if this object has a parent + */ + //public $fk_element = 'fk_recruitmentcandidature'; + + /** + * @var int Name of subtable class that manage subtable lines + */ + //public $class_element_line = 'RecruitmentCandidatureline'; + + /** + * @var array List of child tables. To test if we can delete object. + */ + //protected $childtables = array(); + + /** + * @var array List of child tables. To know object to delete on cascade. + * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + */ + //protected $childtablesoncascade = array('recruitment_recruitmentcandidaturedet'); + + /** + * @var RecruitmentCandidatureLine[] Array of subtable lines + */ + //public $lines = array(); + + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $conf, $langs; + + $this->db = $db; + + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0; + if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) $this->fields['entity']['enabled'] = 0; + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->recruitment->recruitmentcandidature->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 0; + }*/ + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) + { + if (isset($val['enabled']) && empty($val['enabled'])) + { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) + { + foreach ($this->fields as $key => $val) + { + if (is_array($val['arrayofkeyval'])) + { + foreach ($val['arrayofkeyval'] as $key2 => $val2) + { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + return $this->createCommon($user, $notrigger); + } + + /** + * Clone an object into another one + * + * @param User $user User that creates + * @param int $fromid Id of object to clone + * @return mixed New object created, <0 if KO + */ + public function createFromClone(User $user, $fromid) + { + global $langs, $extrafields; + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $object = new self($this->db); + + $this->db->begin(); + + // Load source object + $result = $object->fetchCommon($fromid); + if ($result > 0 && !empty($object->table_element_line)) $object->fetchLines(); + + // get lines so they will be clone + //foreach($this->lines as $line) + // $line->fetch_optionals(); + + // Reset some properties + unset($object->id); + unset($object->fk_user_creat); + unset($object->import_key); + + + // Clear fields + $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default']; + $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + $object->status = self::STATUS_DRAFT; + // ... + // Clear extrafields that are unique + if (is_array($object->array_options) && count($object->array_options) > 0) + { + $extrafields->fetch_name_optionals_label($this->table_element); + foreach ($object->array_options as $key => $option) + { + $shortkey = preg_replace('/options_/', '', $key); + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) + { + //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; + unset($object->array_options[$key]); + } + } + } + + // Create clone + $object->context['createfromclone'] = 'createfromclone'; + $result = $object->createCommon($user); + if ($result < 0) { + $error++; + $this->error = $object->error; + $this->errors = $object->errors; + } + + if (!$error) + { + // copy internal contacts + if ($this->copy_linked_contact($object, 'internal') < 0) + { + $error++; + } + } + + if (!$error) + { + // copy external contacts if same company + if (property_exists($this, 'socid') && $this->socid == $object->socid) + { + if ($this->copy_linked_contact($object, 'external') < 0) + $error++; + } + } + + unset($object->context['createfromclone']); + + // End + if (!$error) { + $this->db->commit(); + return $object; + } else { + $this->db->rollback(); + return -1; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + $result = $this->fetchCommon($id, $ref); + if ($result > 0 && !empty($this->table_element_line)) $this->fetchLines(); + return $result; + } + + /** + * Load object lines in memory from the database + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetchLines() + { + $this->lines = array(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * Load list of objects in memory from the database. + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit limit + * @param int $offset Offset + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) + * @param string $filtermode Filter mode (AND or OR) + * @return array|int int <0 if KO, array of pages if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $records = array(); + + $sql = 'SELECT '; + $sql .= $this->getFieldList(); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')'; + else $sql .= ' WHERE 1 = 1'; + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid') { + $sqlwhere[] = $key.'='.$value; + } elseif (strpos($key, 'date') !== false) { + $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } else { + $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= ' '.$this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < ($limit ? min($limit, $num) : $num)) + { + $obj = $this->db->fetch_object($resql); + + $record = new self($this->db); + $record->setVarsFromFetchObj($obj); + + $records[$record->id] = $record; + + $i++; + } + $this->db->free($resql); + + return $records; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + return $this->updateCommon($user, $notrigger); + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) + { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * Validate object + * + * @param User $user User making status change + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <=0 if OK, 0=Nothing done, >0 if KO + */ + public function validate($user, $notrigger = 0) + { + global $conf, $langs; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) + { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitmentcandidature->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitmentcandidature->recruitmentcandidature_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life + { + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " status = ".self::STATUS_VALIDATED; + if (!empty($this->fields['date_validation'])) $sql .= ", date_validation = '".$this->db->idate($now)."',"; + if (!empty($this->fields['fk_user_valid'])) $sql .= ", fk_user_valid = ".$user->id; + $sql .= " WHERE rowid = ".$this->id; + + dol_syslog(get_class($this)."::validate()", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) + { + dol_print_error($this->db); + $this->error = $this->db->lasterror(); + $error++; + } + + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('RECRUITMENTCANDIDATURE_VALIDATE', $user); + if ($result < 0) $error++; + // End call triggers + } + } + + if (!$error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'recruitmentcandidature/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentcandidature/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { $error++; $this->error = $this->db->lasterror(); } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$oldref; + $dirdest = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref; + if (!$error && file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->recruitment->dir_output.'/recruitmentcandidature/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) + { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) + { + $this->ref = $num; + $this->status = self::STATUS_VALIDATED; + } + + if (!$error) + { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, >0 if OK + */ + public function setDraft($user, $notrigger = 0) + { + // Protection + if ($this->status <= self::STATUS_DRAFT) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTCANDIDATURE_UNVALIDATE'); + } + + /** + * Set cancel status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function cancel($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_VALIDATED) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTCANDIDATURE_CLOSE'); + } + + /** + * Set back to validated status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function reopen($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_CANCELED) + { + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTCANDIDATURE_REOPEN'); + } + + /** + * Return a link to the object card (with optionaly the picto) + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) + { + global $conf, $langs, $hookmanager; + + if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips + + $result = ''; + + $label = ''.$langs->trans("RecruitmentCandidature").''; + $label .= '
'; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + + $url = dol_buildpath('/recruitment/recruitmentcandidature_card.php', 1).'?id='.$this->id; + + if ($option != 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; + if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + } + + $linkclose = ''; + if (empty($notooltip)) + { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label = $langs->trans("ShowRecruitmentCandidature"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + + $linkstart = ''; + $linkend = ''; + + $result .= $linkstart; + + if (empty($this->showphoto_on_popup)) { + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } else { + if ($withpicto) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + list($class, $module) = explode('@', $this->picto); + $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); + if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { + $result .= '
No photo
'; + } else { + $result .= '
No photo
'; + } + + $result .= '
'; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } + } + + if ($withpicto != 2) $result .= $this->ref; + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('recruitmentcandidaturedao')); + $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) $result = $hookmanager->resPrint; + else $result .= $hookmanager->resPrint; + + return $result; + } + + /** + * Return label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLibStatut($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function LibStatut($status, $mode = 0) + { + // phpcs:enable + if (empty($this->labelStatus) || empty($this->labelStatusShort)) + { + global $langs; + //$langs->load("recruitment@recruitment"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + } + + $statusType = 'status'.$status; + //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; + if ($status == self::STATUS_CANCELED) $statusType = 'status6'; + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); + } + + /** + * Load the info information in the object + * + * @param int $id Id of object + * @return void + */ + public function info($id) + { + $sql = 'SELECT rowid, date_creation as datec, tms as datem,'; + $sql .= ' fk_user_creat, fk_user_modif'; + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + $sql .= ' WHERE t.rowid = '.$id; + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + + if ($obj->fk_user_valid) + { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) + { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_cloture); + $this->user_cloture = $cluser; + } + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_validation = $this->db->jdate($obj->datev); + } + + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + $this->initAsSpecimenCommon(); + } + + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + $objectline = new RecruitmentCandidatureLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_recruitmentcandidature = '.$this->id)); + + if (is_numeric($result)) + { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("recruitment@recruitment"); + + if (empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) { + $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard'; + } + + if (!empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) + { + $mybool = false; + + $file = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON.".php"; + $classname = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/recruitment/"); + + // Load file with numbering class (if found) + $mybool |= @include_once $dir.$file; + } + + if ($mybool === false) + { + dol_print_error('', "Failed to include file ".$file); + return ''; + } + + if (class_exists($classname)) { + $obj = new $classname(); + $numref = $obj->getNextValue($this); + + if ($numref != '' && $numref != '-1') + { + return $numref; + } else { + $this->error = $obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } else { + print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; + return ""; + } + } else { + print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); + return ""; + } + } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param null|array $moreparams Array to provide more information + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) + { + global $conf, $langs; + + $result = 0; + $includedocgeneration = 1; + + $langs->load("recruitment@recruitment"); + + if (!dol_strlen($modele)) { + $modele = 'standard_recruitmentcandidature'; + + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (!empty($conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF)) { + $modele = $conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF; + } + } + + $modelpath = "core/modules/recruitment/doc/"; + + if ($includedocgeneration) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * Action executed by scheduler + * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' + * Use public function doScheduledJob($param1, $param2, ...) to get parameters + * + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function doScheduledJob() + { + global $conf, $langs; + + //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; + + $error = 0; + $this->output = ''; + $this->error = ''; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $now = dol_now(); + + $this->db->begin(); + + // ... + + $this->db->commit(); + + return $error; + } +} + + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; + +/** + * Class RecruitmentCandidatureLine. You can also remove this and generate a CRUD class for lines objects. + */ +class RecruitmentCandidatureLine extends CommonObjectLine +{ + // To complete with content of an object RecruitmentCandidatureLine + // We should have a field rowid, fk_recruitmentcandidature and position + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } +} diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index c1ad8c3346d..aab39e4e433 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -45,7 +45,7 @@ class RecruitmentJobPosition extends CommonObject * @var int Does this object support multicompany module ? * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table */ - public $ismultientitymanaged = 0; + public $ismultientitymanaged = 1; /** * @var int Does object support extrafields ? 0=No, 1=Yes diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index 580b3141d5c..cc28ea8978b 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -358,10 +358,10 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio $pdf->SetDrawColor(128, 128, 128); $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); - $pdf->SetSubject($outputlangs->transnoentities("JobPosition")); + $pdf->SetSubject($object->label); $pdf->SetCreator("Dolibarr ".DOL_VERSION); $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); - $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("JobPosition")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$object->label." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); // Set certificate @@ -872,11 +872,11 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio $pdf->SetFont('', 'B', $default_font_size + 3); $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); - $title = $outputlangs->transnoentities("JobPosition"); - if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title = $object->label; + /*if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { $title .= ' - '; $title .= $outputlangsbis->transnoentities("JobPosition"); - } + }*/ $pdf->MultiCell($w, 3, $title, '', 'R'); $pdf->SetFont('', 'B', $default_font_size); diff --git a/htdocs/recruitment/modulebuilder.txt b/htdocs/recruitment/modulebuilder.txt index 24ea0d6eac5..670a1774929 100644 --- a/htdocs/recruitment/modulebuilder.txt +++ b/htdocs/recruitment/modulebuilder.txt @@ -1,3 +1,3 @@ # DO NOT DELETE THIS FILE MANUALLY # File to flag module built using official module template. -# When this file is present into a module directory, you can edit it with the module builder tool. Use ModuleBuilder if you want to delete module. \ No newline at end of file +# When this file is present into a module directory, you can edit it with the module builder tool. \ No newline at end of file diff --git a/htdocs/recruitment/recruitmentjobposition_candidature.php b/htdocs/recruitment/recruitmentjobposition_candidature.php index bf2c766771f..d0e15827c2e 100644 --- a/htdocs/recruitment/recruitmentjobposition_candidature.php +++ b/htdocs/recruitment/recruitmentjobposition_candidature.php @@ -539,52 +539,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; // ancre - $includedocgeneration = 1; - - // Documents - if ($includedocgeneration) { - $objref = dol_sanitizeFileName($object->ref); - $relativepath = $objref . '/' . $objref . '.pdf'; - $filedir = $conf->recruitment->dir_output.'/'.$object->element.'/'.$objref; - $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->recruitment->recruitmentjobposition->read; // If you can read, you can build the PDF to read content - $delallowed = $user->rights->recruitment->recruitmentjobposition->write; // If you can create/edit, you can remove a file on card - print $formfile->showdocuments('recruitment:RecruitmentJobPosition', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); - } - - // Show links to link elements - $linktoelem = $form->showLinkToObjectBlock($object, null, array('recruitmentjobposition')); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - - // Show link to public job page - if ($object->status != RecruitmentJobPosition::STATUS_DRAFT) - { - print '
'."\n"; - // Load translation files required by the page - $langs->loadLangs(array('recruitment')); - - $out = img_picto('', 'globe').' '.$langs->trans("PublicUrl").'
'; - - $url = getPublicJobPositionUrl(0, $object->ref); - $out .= ''; - $out .= ''.img_picto('', 'globe').''; - $out .= ajax_autoselect("recruitmentjobpositionurl", 0); - - print $out; - } print '
'; - $MAXEVENT = 10; - - $morehtmlright = ''; - $morehtmlright .= $langs->trans("SeeAll"); - $morehtmlright .= ''; - - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, $object->element.'@recruitment', (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); print '
'; } From 561520b44c6102f6dbaa21ec4b5b620bc99ace6d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 16:06:15 +0200 Subject: [PATCH 276/434] WIP Recruitment module --- .../install/mysql/migration/12.0.0-13.0.0.sql | 45 +++++++++++++++++++ ...llx_recruitment_recruitmentcandidature.sql | 3 +- .../class/recruitmentcandidature.class.php | 1 + 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 58d85e80526..dd42297dc3b 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -129,6 +129,51 @@ create table llx_recruitment_recruitmentjobposition_extrafields ALTER TABLE llx_recruitment_recruitmentjobposition_extrafields ADD INDEX idx_fk_object(fk_object); + +CREATE TABLE llx_recruitment_recruitmentcandidature( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + fk_recruitmentjobposition INTEGER NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + description text, + note_public text, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + model_pdf varchar(255), + status smallint NOT NULL, + firstname varchar(128), + lastname varchar(128), + remuneration_requested integer, + remuneration_proposed integer + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_rowid (rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_ref (ref); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD CONSTRAINT llx_recruitment_recruitmentcandidature_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_status (status); + + +create table llx_recruitment_recruitmentcandidature_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_fk_object(fk_object); + + + + + + + -- Add dictionary for prospect level and action commercial on contacts (Using this is not recommanded) create table llx_c_prospectcontactlevel diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql index c1905f46b63..fb9cf56c8b2 100644 --- a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql @@ -17,7 +17,8 @@ CREATE TABLE llx_recruitment_recruitmentcandidature( -- BEGIN MODULEBUILDER FIELDS rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - ref varchar(128) DEFAULT '(PROV)' NOT NULL, + fk_recruitmentjobposition INTEGER NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, description text, note_public text, note_private text, diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php index cacda6674c2..4ee4bccbb7a 100644 --- a/htdocs/recruitment/class/recruitmentcandidature.class.php +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -96,6 +96,7 @@ class RecruitmentCandidature extends CommonObject public $fields=array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'comment'=>"Id"), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'fk_recruitmentjobposition' => array('type'=>'integer:RecruitmentJobPosition:recruitment/class/recruitment_recruitmentjobposition.class.php', 'label'=>'Job', 'enabled'=>'1', 'position'=>15, 'notnull'=>1, 'visible'=>1, 'index'=>1), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), From e6c4c8082ea5bc700c7532eef1d3a7feefe359b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 16:10:40 +0200 Subject: [PATCH 277/434] Fix phpcs --- .../modulebuilder/template/mymoduleindex.php | 8 ++--- .../modulebuilder/template/myobject_card.php | 32 ++++++----------- htdocs/recruitment/recruitmentindex.php | 10 ++---- .../recruitmentjobposition_card.php | 35 ++++++------------- 4 files changed, 27 insertions(+), 58 deletions(-) diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php index 9050b5319e0..91eb5eca8da 100644 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ b/htdocs/modulebuilder/template/mymoduleindex.php @@ -184,7 +184,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print ''; print ''; print ''; print ''; print ''; @@ -203,15 +203,13 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print ''; print '"; - print '"; + print '"; print ''; $i++; } $db->free($resql); - } - else - { + } else { print ''; } print "
'; - print $langs->trans("BoxTitleLatestModifiedMyObjects",$max); + print $langs->trans("BoxTitleLatestModifiedMyObjects", $max); print ''.$langs->trans("DateModificationShort").'
'.$myobjectstatic->getNomUrl(1).''; print "'.dol_print_date($db->jdate($objp->tms),'day')."'.dol_print_date($db->jdate($objp->tms), 'day')."
'.$langs->trans("None").'

"; diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index fd17bfe2d6d..a85f84a50ba 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -468,27 +468,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_VALIDATED) { + if ($permissiontoadd) { print ''.$langs->trans("SetToDraft").''; } } // Modify - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } // Validate - if ($object->status == $object::STATUS_DRAFT) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_DRAFT) { + if ($permissiontoadd) { if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { print ''.$langs->trans("Validate").''; @@ -500,31 +495,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Clone - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("ToClone").''."\n"; } /* if ($permissiontoadd) { - if ($object->status == $object::STATUS_ENABLED) - { + if ($object->status == $object::STATUS_ENABLED) { print ''.$langs->trans("Disable").''."\n"; - } - else - { + } else { print ''.$langs->trans("Enable").''."\n"; } } if ($permissiontoadd) { - if ($object->status == $object::STATUS_VALIDATED) - { + if ($object->status == $object::STATUS_VALIDATED) { print ''.$langs->trans("Cancel").''."\n"; - } - else - { + } else { print ''.$langs->trans("Re-Open").''."\n"; } } diff --git a/htdocs/recruitment/recruitmentindex.php b/htdocs/recruitment/recruitmentindex.php index dc0b0eac8cf..cf1f0e7dee4 100644 --- a/htdocs/recruitment/recruitmentindex.php +++ b/htdocs/recruitment/recruitmentindex.php @@ -262,7 +262,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm print ''; print ''; print ''; print ''; print ''; @@ -281,17 +281,13 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitm print ''; print '"; - print '"; + print '"; print ''; $i++; - - } $db->free($resql); - } - else - { + } else { print ''; } print "
'; - print $langs->trans("BoxTitleLatestModifiedJobPositions",$max); + print $langs->trans("BoxTitleLatestModifiedJobPositions", $max); print ''.$langs->trans("DateModificationShort").'
'.$staticrecruitmentjobposition->getNomUrl(1, '').''; print "'.dol_print_date($db->jdate($objp->tms),'day')."'.dol_print_date($db->jdate($objp->tms), 'day')."
'.$langs->trans("None").'

"; diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index 4037147e367..0763b5ca749 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -455,8 +455,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) - { + if ($object->status == $object::STATUS_VALIDATED) { if ($permissiontoadd) { print ''.$langs->trans("SetToDraft").''; @@ -464,18 +463,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Modify - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } // Validate - if ($object->status == $object::STATUS_DRAFT) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_DRAFT) { + if ($permissiontoadd) { if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { print ''.$langs->trans("Validate").''; @@ -487,38 +483,29 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Clone - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("ToClone").''."\n"; } /* - if ($permissiontoadd) - { - if ($object->status == $object::STATUS_ENABLED) - { + if ($permissiontoadd) { + if ($object->status == $object::STATUS_ENABLED) { print ''.$langs->trans("Disable").''."\n"; - } - else - { + } else { print ''.$langs->trans("Enable").''."\n"; } }*/ if ($permissiontoadd) { - if ($object->status == $object::STATUS_VALIDATED) - { + if ($object->status == $object::STATUS_VALIDATED) { print ''.$langs->trans("Cancel").''."\n"; - } - else - { + } else { print ''.$langs->trans("Re-Open").''."\n"; } } // Delete (need delete permission, or if draft, just need create/modify permission) - if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) - { + if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) { print ''.$langs->trans('Delete').''."\n"; } else { print ''.$langs->trans('Delete').''."\n"; From 53acd8cffd88c4d3d3d19b72dfc0ae623fe95ec2 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 6 Aug 2020 16:28:17 +0200 Subject: [PATCH 278/434] FIX: MAIN_MAIL_FORCE_SENDTO work now for all mail sending method --- htdocs/core/class/CMailFile.class.php | 76 +++++++++++++-------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 853f2f98b05..32545465f45 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -242,6 +242,23 @@ class CMailFile // Add autocopy to (Note: Adding bcc for specific modules are also done from pages) if (! empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc.=($addr_bcc?', ':'').$conf->global->MAIN_MAIL_AUTOCOPY_TO; + $this->addr_to = $to; + $this->addr_cc = $addr_cc; + $this->addr_bcc = $addr_bcc; + $this->reply_to = $replyto; + $this->addr_from = $from; + $this->subject = $subject; + $this->errors_to = $errors_to; + $this->deliveryreceipt = $deliveryreceipt; + $this->trackid = $trackid; + + if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) + { + $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; + $this->addr_cc = ''; + $this->addr_bcc = ''; + } + // Action according to choosed sending method if ($this->sendmode == 'mail') { @@ -254,16 +271,6 @@ class CMailFile $files_encoded = ""; // Define smtp_headers - $this->subject = $subject; - $this->addr_from = $from; - $this->reply_to = $replyto; - $this->errors_to = $errors_to; - $this->addr_to = $to; - $this->addr_cc = $addr_cc; - $this->addr_bcc = $addr_bcc; - $this->deliveryreceipt = $deliveryreceipt; - $this->trackid = $trackid; - $smtp_headers = $this->write_smtpheaders(); if (! empty($moreinheader)) $smtp_headers.=$moreinheader; // $moreinheader contains the \r\n @@ -311,11 +318,11 @@ class CMailFile $smtps = new SMTPs(); $smtps->setCharSet($conf->file->character_set_client); - $smtps->setSubject($this->encodetorfc2822($subject)); - $smtps->setTO($this->getValidAddress($to, 0, 1)); - $smtps->setFrom($this->getValidAddress($from, 0, 1)); - $smtps->setTrackId($trackid); - $smtps->setReplyTo($this->getValidAddress($replyto, 0, 1)); + $smtps->setSubject($this->encodetorfc2822($this->subject)); + $smtps->setTO($this->getValidAddress($this->addr_to, 0, 1)); + $smtps->setFrom($this->getValidAddress($this->addr_from, 0, 1)); + $smtps->setTrackId($this->trackid); + $smtps->setReplyTo($this->getValidAddress($this->reply_to, 0, 1)); if (! empty($moreinheader)) $smtps->setMoreInHeader($moreinheader); @@ -353,10 +360,10 @@ class CMailFile } } - $smtps->setCC($addr_cc); - $smtps->setBCC($addr_bcc); - $smtps->setErrorsTo($errors_to); - $smtps->setDeliveryReceipt($deliveryreceipt); + $smtps->setCC($this->addr_cc); + $smtps->setBCC($this->addr_bcc); + $smtps->setErrorsTo($this->errors_to); + $smtps->setDeliveryReceipt($this->deliveryreceipt); $this->smtps=$smtps; } @@ -378,8 +385,8 @@ class CMailFile //$this->message = new Swift_SignedMessage(); // Adding a trackid header to a message $headers = $this->message->getHeaders(); - $headers->addTextHeader('X-Dolibarr-TRACKID', $trackid . '@' . $host); - $headerID = time() . '.swiftmailer-dolibarr-' . $trackid . '@' . $host; + $headers->addTextHeader('X-Dolibarr-TRACKID', $this->trackid . '@' . $host); + $headerID = time() . '.swiftmailer-dolibarr-' . $this->trackid . '@' . $host; $msgid = $headers->get('Message-ID'); $msgid->setId($headerID); $headers->addIdHeader('References', $headerID); @@ -387,33 +394,33 @@ class CMailFile // Give the message a subject try { - $result = $this->message->setSubject($subject); + $result = $this->message->setSubject($this->subject); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } // Set the From address with an associative array //$this->message->setFrom(array('john@doe.com' => 'John Doe')); - if (! empty($from)) { + if (! empty($this->addr_from)) { try { - $result = $this->message->setFrom($this->getArrayAddress($from)); + $result = $this->message->setFrom($this->getArrayAddress($this->addr_from)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } } // Set the To addresses with an associative array - if (! empty($to)) { + if (! empty($this->addr_to)) { try { - $result = $this->message->setTo($this->getArrayAddress($to)); + $result = $this->message->setTo($this->getArrayAddress($this->addr_to)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } } - if (! empty($replyto)) { + if (! empty($this->reply_to)) { try { - $result = $this->message->SetReplyTo($this->getArrayAddress($replyto)); + $result = $this->message->SetReplyTo($this->getArrayAddress($this->reply_to)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } @@ -467,10 +474,10 @@ class CMailFile } } - if (! empty($addr_cc)) $this->message->setCc($this->getArrayAddress($addr_cc)); - if (! empty($addr_bcc)) $this->message->setBcc($this->getArrayAddress($addr_bcc)); + if (! empty($this->addr_cc)) $this->message->setCc($this->getArrayAddress($this->addr_cc)); + if (! empty($this->addr_bcc)) $this->message->setBcc($this->getArrayAddress($this->addr_bcc)); //if (! empty($errors_to)) $this->message->setErrorsTo($this->getArrayAddress($errors_to); - if (isset($deliveryreceipt) && $deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($from)); + if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($this->addr_from)); } else { @@ -589,13 +596,6 @@ class CMailFile $keyforstarttls ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING'; } - if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) - { - $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; - $this->addr_cc = ''; - $this->addr_bcc = ''; - } - // Action according to choosed sending method if ($this->sendmode == 'mail') { From c6ee80eefd2f85e34b66432e8f2869ffb2dd4380 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 12:29:57 +0200 Subject: [PATCH 279/434] FIX Disable svg as supported image by default. Set MAIN_ALLOW_SVG_FILES_AS_IMAGES to 1 to have svg working. --- htdocs/bookmarks/card.php | 1 + htdocs/bookmarks/list.php | 2 +- htdocs/core/lib/images.lib.php | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 385dd506031..411c2c8175f 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -151,6 +151,7 @@ if ($action == 'create') print ''."\n"; print ''; print ''; + print ''; print load_fiche_titre($langs->trans("NewBookmark")); diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index 5dd1718b263..1cc6029dbc9 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -158,7 +158,7 @@ print ''; print ''; $newcardbutton = ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create', '', !empty($user->rights->bookmark->creer)); +$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create&backtopage='.urlencode(DOL_URL_ROOT.'/bookmarks/list.php'), '', !empty($user->rights->bookmark->creer)); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bookmark', 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index b65ad51db86..13918b908ad 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -37,7 +37,12 @@ $quality = 80; */ function image_format_supported($file) { - $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm|\.svg'; // See also into product.class.php + global $conf; + + $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php + if (! empty($conf->global->MAIN_ALLOW_PREVIEW_OF_UPLOADED_SVG_FILES)) { + $regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript + } // Case filename is not a format image $reg = array(); From c2b03e49e13849f1fa7ba9e7749d893d39da09e6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 17:28:57 +0200 Subject: [PATCH 280/434] Fix logo not visible in setup page --- htdocs/admin/company.php | 31 +++++++++++++++++++++++-------- htdocs/core/lib/images.lib.php | 5 +++-- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index d7761557f22..6268148fdb5 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -494,10 +494,17 @@ if (!empty($mysoc->logo_mini)) { print ''; } print ''; -} else { - print '
'; - print ''; - print '
'; +} elseif (!empty($mysoc->logo)) { + if (file_exists($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) { + print '
'; + print ''; + print '
'; + print ''; + } else { + print '
'; + print ''; + print '
'; + } } print ''; print ''; @@ -514,10 +521,18 @@ if (!empty($mysoc->logo_squarred_mini)) { print ''; } print ''; -} else { - print '
'; - print ''; - print '
'; +} elseif (!empty($mysoc->logo_squarred)) { + if (file_exists($conf->mycompany->dir_output.'/logos/'.$mysoc->logo_squarred)) { + print '
'; + print ''; + print '
'; + print ''; + } + else { + print '
'; + print ''; + print '
'; + } } print ''; print ''; diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index 13918b908ad..0822d3edd4b 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -33,14 +33,15 @@ $quality = 80; * Return if a filename is file name of a supported image format * * @param string $file Filename + * @param int $acceptsvg 0=Default (depends on setup), 1=Always accept SVG as image files * @return int -1=Not image filename, 0=Image filename but format not supported for conversion by PHP, 1=Image filename with format supported by this PHP */ -function image_format_supported($file) +function image_format_supported($file, $acceptsvg = 0) { global $conf; $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php - if (! empty($conf->global->MAIN_ALLOW_PREVIEW_OF_UPLOADED_SVG_FILES)) { + if ($acceptsvg || ! empty($conf->global->MAIN_ALLOW_SVG_FILES_AS_IMAGES)) { $regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript } From 582ae36e6cbe925b8467ccabc09f752a2d68d6b6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 17:30:13 +0200 Subject: [PATCH 281/434] Doc --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 1144f11726f..6ee67b86faa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,6 +50,7 @@ FIX: Warning if no bank account defined FIX: We need to see unit line on PDF even though it's an option FIX: wrong element var for fetch_name_optionals_label function with expeditions FIX: wrong link to third invoice templates +FIX: Disable svg as supported image by default (can contains javascript). Set MAIN_ALLOW_SVG_FILES_AS_IMAGES to 1 to have svg accepted FIX: #14076 FIX: #14146 FIX: #14209 From 61e194bb6dffd73182f79b845a228d24aac44d89 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 17:37:00 +0200 Subject: [PATCH 282/434] Add protection to allow only jpg and png as image file --- htdocs/admin/company.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 6268148fdb5..6330909f2c0 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -111,6 +111,12 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha')) foreach ($arrayofimages as $varforimage) { + if (! preg_match('/(\.jpeg|\.jpg|\.png)$/i', $_FILES[$varforimage]["tmp_name"])) { // Logo can be used on a lot of different places. Only jpg and png can be supported. + $langs->load("errors"); + setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); + break; + } + if ($_FILES[$varforimage]["tmp_name"]) { $reg = array(); From edd19419ad73dc5e82407c3da6df83c8633bfe2c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 6 Aug 2020 17:39:36 +0200 Subject: [PATCH 283/434] Add protection to allow only jpg and png as image file --- htdocs/admin/company.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 6330909f2c0..88f6034a3b6 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -111,7 +111,7 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha')) foreach ($arrayofimages as $varforimage) { - if (! preg_match('/(\.jpeg|\.jpg|\.png)$/i', $_FILES[$varforimage]["tmp_name"])) { // Logo can be used on a lot of different places. Only jpg and png can be supported. + if ($_FILES[$varforimage]["name"] && ! preg_match('/(\.jpeg|\.jpg|\.png)$/i', $_FILES[$varforimage]["name"])) { // Logo can be used on a lot of different places. Only jpg and png can be supported. $langs->load("errors"); setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); break; From 20ea6d86d81494c4a251f05bf8da470f1ff2eb46 Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Thu, 6 Aug 2020 19:57:31 +0200 Subject: [PATCH 284/434] Update api_supplier_orders.class.php Added example of creating a supplier order --- htdocs/fourn/class/api_supplier_orders.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index bee6346386b..b180016bdd9 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -187,6 +187,8 @@ class SupplierOrders extends DolibarrApi /** * Create supplier order object * + * Example: {"ref": "auto", "ref_supplier": "1234", "socid": "1", "multicurrency_code": "SEK", "multicurrency_tx": 1, "tva_tx": 25, "note": "Imported via the REST API"} + * * @param array $request_data Request datas * @return int ID of supplier order */ From 9c254159ab8dad8477c1814beaaf2f6c54d30c4b Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Fri, 7 Aug 2020 00:06:48 +0200 Subject: [PATCH 285/434] Update api_products.class.php fixes #14309 Throw 400 and add hint to user about using the right endpoint. --- htdocs/product/class/api_products.class.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 1f4bbf870f3..89c9a78ddaa 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -286,6 +286,9 @@ class Products extends DolibarrApi foreach ($request_data as $field => $value) { if ($field == 'id') { continue; + } + if ($field == 'stock_reel') { + throw new RestException(400, 'Stock reel cannot be updated here. Use the /stockmovements endpoint instead'); } $this->product->$field = $value; } From 8b69dd1384f9e82a5aecb61730d1f080f8c14b21 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 09:50:15 +0200 Subject: [PATCH 286/434] Increase length of default password. --- .../modules/security/generate/modGeneratePassStandard.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php index 3a1cf3667aa..23b71244cbd 100644 --- a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php +++ b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php @@ -59,7 +59,7 @@ class modGeneratePassStandard extends ModeleGenPassword public function __construct($db, $conf, $langs, $user) { $this->id = "standard"; - $this->length = 8; + $this->length = 10; $this->db = $db; $this->conf = $conf; From 022fb23cee5806d0426fcdc1bae4531c999a3604 Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Thu, 6 Aug 2020 07:32:28 +0200 Subject: [PATCH 287/434] FIX: Get some taxes in TakePOS --- htdocs/takepos/invoice.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index a3ef12c92cb..d22d2702571 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -341,6 +341,7 @@ if ($action == "addline") } } if ($idoflineadded <= 0) { + $invoice->fetch_thirdparty(); $idoflineadded = $invoice->addline($prod->description, $price, 1, $tva_tx, $localtax1_tx, $localtax2_tx, $idproduct, $customer->remise_percent, '', 0, 0, 0, '', $price_base_type, $price_ttc, $prod->type, -1, 0, '', 0, $parent_line, null, '', '', 0, 100, '', null, 0); } From c52c4229c563f69acfc9936aa087abb51765fcfc Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Tue, 4 Aug 2020 22:02:15 +0200 Subject: [PATCH 288/434] Update api_supplier_invoices.class.php fixes #14831 --- htdocs/fourn/class/api_supplier_invoices.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 1f20965fab3..f5b3afa4b18 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -454,7 +454,7 @@ class SupplierInvoices extends DolibarrApi $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching $paiement->paiementid = $paiementid; - $paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->oper = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); $paiement->num_payment = $num_payment; $paiement->note_public = $comment; From ed6acfa1e76307c6a30ac7188326b89f269caa02 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 11:45:15 +0200 Subject: [PATCH 289/434] Better compatibility --- htdocs/fourn/class/api_supplier_invoices.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index f5b3afa4b18..b42c578a783 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -454,7 +454,8 @@ class SupplierInvoices extends DolibarrApi $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching $paiement->paiementid = $paiementid; - $paiement->oper = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->oper = $paiement->paiementcode; // For backward compatibility $paiement->num_payment = $num_payment; $paiement->note_public = $comment; From 7a03521664e79154a026c1847af611b882fbf228 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 12:07:34 +0200 Subject: [PATCH 290/434] Doc --- htdocs/install/repair.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index d427e529a8d..ef4e3b82a9d 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -996,7 +996,7 @@ if ($ok && GETPOST('clean_product_stock_batch', 'alpha')) $resql2 = $db->query($sql2); if ($resql2) { - // We update product_stock, so we must field stock into product too. + // We update product_stock, so we must fill p.stock into product too. $sql3 = 'UPDATE '.MAIN_DB_PREFIX.'product p SET p.stock= (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.'product_stock ps WHERE ps.fk_product = p.rowid)'; $resql3 = $db->query($sql3); if (!$resql3) From 2cdb17a1106d6faebff73d83d531ffd2bb8fc1c4 Mon Sep 17 00:00:00 2001 From: bahfir abbes Date: Wed, 5 Aug 2020 08:35:49 +0100 Subject: [PATCH 291/434] fix: fetch reception on supplier order dispatch fetch --- htdocs/fourn/class/fournisseur.commande.dispatch.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index 19ea5880346..808b217caed 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -292,7 +292,9 @@ class CommandeFournisseurDispatch extends CommonObject $this->batch = $obj->batch; $this->eatby = $this->db->jdate($obj->eatby); $this->sellby = $this->db->jdate($obj->sellby); - $this->fetch_optionals(); + $this->fk_reception = $obj->fk_reception; + + $this->fetch_optionals(); } $this->db->free($resql); From 940b4e7bea7d3af07042efa1fe165230112b9d56 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 12:49:21 +0200 Subject: [PATCH 292/434] Fix #14413 --- htdocs/contact/list.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index ca427fb2794..7dad73cdb1c 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -307,8 +307,10 @@ $form = new Form($db); $formother = new FormOther($db); $formcompany = new FormCompany($db); $contactstatic = new Contact($db); -$contactstatic->thirdparty->client=2; -$contactstatic->loadCacheOfProspStatus(); + +if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { + $contactstatic->loadCacheOfProspStatus(); +} $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); From e72e05d5f50466833409d59e1e4fabcbb217f376 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 13:31:23 +0200 Subject: [PATCH 293/434] Add field default_lang for users --- .../install/mysql/migration/12.0.0-13.0.0.sql | 1 + htdocs/install/mysql/tables/llx_user.sql | 3 +- htdocs/langs/en_US/admin.lang | 2 +- htdocs/user/param_ihm.php | 96 +++++++++---------- 4 files changed, 52 insertions(+), 50 deletions(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index dd42297dc3b..b8f41e63878 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -208,4 +208,5 @@ insert into llx_c_stcommcontact (id,code,libelle) values ( 3, 'ST_DONE', 'Conta ALTER TABLE llx_socpeople ADD COLUMN fk_prospectcontactlevel varchar(12) AFTER priv; ALTER TABLE llx_socpeople ADD COLUMN fk_stcommcontact integer DEFAULT 0 NOT NULL AFTER fk_prospectcontactlevel; +ALTER TABLE llx_user ADD COLUMN default_lang varchar(6); diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index e27ac19c15a..cb57c901400 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -55,6 +55,7 @@ create table llx_user personal_mobile varchar(20), email varchar(255), personal_email varchar(255), + default_lang varchar(6), -- default language for communication. see also lang parameter socialnetworks text DEFAULT NULL, -- json with socialnetworks @@ -85,7 +86,7 @@ create table llx_user openid varchar(255), statut tinyint DEFAULT 1, photo varchar(255), -- filename or url of photo - lang varchar(6), + lang varchar(6), -- language selected by user as interface language. see also default_lang parameter color varchar(6), barcode varchar(255) DEFAULT NULL, fk_barcode_type integer DEFAULT 0, diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index ac552faff5c..5316f49a2b1 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1684,7 +1684,7 @@ AGENDA_USE_EVENT_TYPE=Use events types (managed in menu Setup -> Dictionaries -> AGENDA_USE_EVENT_TYPE_DEFAULT=Automatically set this default value for type of event in event create form AGENDA_DEFAULT_FILTER_TYPE=Automatically set this type of event in search filter of agenda view AGENDA_DEFAULT_FILTER_STATUS=Automatically set this status for events in search filter of agenda view -AGENDA_DEFAULT_VIEW=Which tab do you want to open by default when selecting menu Agenda +AGENDA_DEFAULT_VIEW=Which view do you want to open by default when selecting menu Agenda AGENDA_REMINDER_EMAIL=Enable event reminder by emails (remind option/delay can be defined on each event). Note: Module %s must be enabled and correctly setup to have reminder sent at the correct frequency. AGENDA_REMINDER_BROWSER=Enable event reminder on user's browser (when event date is reached, each user is able to refuse this from the browser confirmation question) AGENDA_REMINDER_BROWSER_SOUND=Enable sound notification diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php index 1f0880b0fb3..2cb4f174b23 100644 --- a/htdocs/user/param_ihm.php +++ b/htdocs/user/param_ihm.php @@ -264,19 +264,6 @@ if ($action == 'edit') print ''; print ''; - // Landing page - print ''; - print ''; - print ''; - print ''; - // Language by default print ''; print ''; print ''; + print '> '; print ''; + // Landing page + print ''; + print ''; + print ''; + print ''; + + // Landing page for Agenda - AGENDA_DEFAULT_VIEW + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''; + print ''."\n"; + // Max size of lists print ''; print ''; print ''; + print '> '; print ''; - // AGENDA_DEFAULT_VIEW - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''; - print ''."\n"; - print '
'.$langs->trans("Parameter").''.$langs->trans("DefaultValue").' '.$langs->trans("PersonalValue").'
'.$langs->trans("LandingPage").''; - print (empty($conf->global->MAIN_LANDING_PAGE) ? '' : $conf->global->MAIN_LANDING_PAGE); - print 'conf->MAIN_LANDING_PAGE) ? " checked" : ""); - print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo - print '> '.$langs->trans("UsePersonalValue").''; - print $form->selectarray('MAIN_LANDING_PAGE', $tmparray, (!empty($object->conf->MAIN_LANDING_PAGE) ? $object->conf->MAIN_LANDING_PAGE : ''), 0, 0, 0, '', 1); - //print info_admin($langs->trans("WarningYouMayLooseAccess"), 0, 0, 0); - print '
'.$langs->trans("Language").''; @@ -286,31 +273,44 @@ if ($action == 'edit') print 'conf->MAIN_LANG_DEFAULT) ? " checked" : ""); print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo - print '> '.$langs->trans("UsePersonalValue").''; print $formadmin->select_language((!empty($object->conf->MAIN_LANG_DEFAULT) ? $object->conf->MAIN_LANG_DEFAULT : ''), 'main_lang_default', 1, null, 0, 0, (!empty($dolibarr_main_demo))); print '
'.$langs->trans("LandingPage").''; + print (empty($conf->global->MAIN_LANDING_PAGE) ? '' : $conf->global->MAIN_LANDING_PAGE); + print 'conf->MAIN_LANDING_PAGE) ? " checked" : ""); + print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo + print '> '; + print $form->selectarray('MAIN_LANDING_PAGE', $tmparray, (!empty($object->conf->MAIN_LANDING_PAGE) ? $object->conf->MAIN_LANDING_PAGE : ''), 0, 0, 0, '', 1); + //print info_admin($langs->trans("WarningYouMayLooseAccess"), 0, 0, 0); + print '
'.$langs->trans("AGENDA_DEFAULT_VIEW").' conf->AGENDA_DEFAULT_VIEW) ? " checked" : ""); + print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo + print '> '."\n"; + $tmplist = array(''=>' ', 'show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser")); + print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $object->conf->AGENDA_DEFAULT_VIEW, 0, 0, 0, ''); + print '
'.$langs->trans("MaxSizeList").''.$conf->global->MAIN_SIZE_LISTE_LIMIT.'conf->MAIN_SIZE_LISTE_LIMIT) ? " checked" : ""); print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo - print '> '.$langs->trans("UsePersonalValue").'
'.$langs->trans("AGENDA_DEFAULT_VIEW").' conf->AGENDA_DEFAULT_VIEW) ? " checked" : ""); - print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo - print '> '.$langs->trans("UsePersonalValue").''."\n"; - $tmplist = array(''=>' ', 'show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser")); - print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $object->conf->AGENDA_DEFAULT_VIEW, 0, 0, 0, ''); - print '

'; // Theme @@ -334,6 +334,20 @@ if ($action == 'edit') print ''; print ''; + // Language + print ''; + print ''; + print ''; + print ''; + // Landing page print ''; print ''; - // Language - print ''; - print ''; - print ''; - print ''; - - // Max size for lists - print ''; - print ''; - print ''; - print ''; - - // AGENDA_DEFAULT_VIEW + // Landing page for Agenda - AGENDA_DEFAULT_VIEW print ''."\n"; print ''."\n"; print ''."\n"; @@ -380,6 +374,12 @@ if ($action == 'edit') if (!empty($object->conf->AGENDA_DEFAULT_VIEW)) print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $object->conf->AGENDA_DEFAULT_VIEW, 0, 0, 0, '', 0, 0, 1); print ''."\n"; + // Max size for lists + print ''; + print ''; + print ''; + print ''; + print '
'.$langs->trans("Parameter").''.$langs->trans("DefaultValue").' '.$langs->trans("PersonalValue").'
'.$langs->trans("Language").''; + $s = picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); + print ($s ? $s.' ' : ''); + print (isset($conf->global->MAIN_LANG_DEFAULT) && $conf->global->MAIN_LANG_DEFAULT == 'auto' ? $langs->trans("AutoDetectLang") : $langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); + print 'conf->MAIN_LANG_DEFAULT) ? " checked" : "").'> '.$langs->trans("UsePersonalValue").''; + $s = (isset($object->conf->MAIN_LANG_DEFAULT) ? picto_from_langcode($object->conf->MAIN_LANG_DEFAULT) : ''); + print ($s ? $s.' ' : ''); + print (isset($object->conf->MAIN_LANG_DEFAULT) && $object->conf->MAIN_LANG_DEFAULT == 'auto' ? $langs->trans("AutoDetectLang") : (!empty($object->conf->MAIN_LANG_DEFAULT) ? $langs->trans("Language_".$object->conf->MAIN_LANG_DEFAULT) : '')); + print '
'.$langs->trans("LandingPage").''; @@ -350,27 +364,7 @@ if ($action == 'edit') //print $form->selectarray('MAIN_LANDING_PAGE', $tmparray, (! empty($object->conf->MAIN_LANDING_PAGE)?$object->conf->MAIN_LANDING_PAGE:''), 0, 0, 0, '', 1); print '
'.$langs->trans("Language").''; - $s = picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); - print ($s ? $s.' ' : ''); - print (isset($conf->global->MAIN_LANG_DEFAULT) && $conf->global->MAIN_LANG_DEFAULT == 'auto' ? $langs->trans("AutoDetectLang") : $langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); - print 'conf->MAIN_LANG_DEFAULT) ? " checked" : "").'> '.$langs->trans("UsePersonalValue").''; - $s = (isset($object->conf->MAIN_LANG_DEFAULT) ? picto_from_langcode($object->conf->MAIN_LANG_DEFAULT) : ''); - print ($s ? $s.' ' : ''); - print (isset($object->conf->MAIN_LANG_DEFAULT) && $object->conf->MAIN_LANG_DEFAULT == 'auto' ? $langs->trans("AutoDetectLang") : (!empty($object->conf->MAIN_LANG_DEFAULT) ? $langs->trans("Language_".$object->conf->MAIN_LANG_DEFAULT) : '')); - print '
'.$langs->trans("MaxSizeList").''.(!empty($conf->global->MAIN_SIZE_LISTE_LIMIT) ? $conf->global->MAIN_SIZE_LISTE_LIMIT : ' ').'conf->MAIN_SIZE_LISTE_LIMIT) ? " checked" : "").'> '.$langs->trans("UsePersonalValue").''.(!empty($object->conf->MAIN_SIZE_LISTE_LIMIT) ? $object->conf->MAIN_SIZE_LISTE_LIMIT : ' ').'
'.$langs->trans("AGENDA_DEFAULT_VIEW").' 
'.$langs->trans("MaxSizeList").''.(!empty($conf->global->MAIN_SIZE_LISTE_LIMIT) ? $conf->global->MAIN_SIZE_LISTE_LIMIT : ' ').'conf->MAIN_SIZE_LISTE_LIMIT) ? " checked" : "").'> '.$langs->trans("UsePersonalValue").''.(!empty($object->conf->MAIN_SIZE_LISTE_LIMIT) ? $object->conf->MAIN_SIZE_LISTE_LIMIT : ' ').'

'; From aaaf690006e77d0d10360244028b78afcaf54c8d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:05:05 +0200 Subject: [PATCH 294/434] FIX Language visible just after login does not match user choice. --- htdocs/main.inc.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index e9caccf436b..90db6718a3b 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -644,6 +644,11 @@ if (!defined('NOLOGIN')) if (GETPOST('lang', 'aZ09')) $paramsurl[] = 'lang='.GETPOST('lang', 'aZ09'); header('Location: '.DOL_URL_ROOT.'/index.php'.(count($paramsurl) ? '?'.implode('&', $paramsurl) : '')); exit; + } else { + // User is loaded, we may need to change language for him according to its choice + if (! empty($user->conf->MAIN_LANG_DEFAULT)) { + $langs->setDefaultLang($user->conf->MAIN_LANG_DEFAULT); + } } } else { // We are already into an authenticated session From dd510901a4c6fdb19d518989ce6d11e354bf01e7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:05:15 +0200 Subject: [PATCH 295/434] Fix duplicate field --- htdocs/install/mysql/migration/12.0.0-13.0.0.sql | 2 -- htdocs/install/mysql/tables/llx_user.sql | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index b8f41e63878..347985aad2b 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -208,5 +208,3 @@ insert into llx_c_stcommcontact (id,code,libelle) values ( 3, 'ST_DONE', 'Conta ALTER TABLE llx_socpeople ADD COLUMN fk_prospectcontactlevel varchar(12) AFTER priv; ALTER TABLE llx_socpeople ADD COLUMN fk_stcommcontact integer DEFAULT 0 NOT NULL AFTER fk_prospectcontactlevel; -ALTER TABLE llx_user ADD COLUMN default_lang varchar(6); - diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index cb57c901400..b49feba85d6 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -55,7 +55,6 @@ create table llx_user personal_mobile varchar(20), email varchar(255), personal_email varchar(255), - default_lang varchar(6), -- default language for communication. see also lang parameter socialnetworks text DEFAULT NULL, -- json with socialnetworks @@ -86,7 +85,7 @@ create table llx_user openid varchar(255), statut tinyint DEFAULT 1, photo varchar(255), -- filename or url of photo - lang varchar(6), -- language selected by user as interface language. see also default_lang parameter + lang varchar(6), -- default language for communication. Note that language selected by user as interface language is savec into llx_user_param. color varchar(6), barcode varchar(255) DEFAULT NULL, fk_barcode_type integer DEFAULT 0, From 4376ca4c94830a44ba481dbe58c305388a85f5e5 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Fri, 7 Aug 2020 14:16:49 +0200 Subject: [PATCH 296/434] Revert "Fix filter warehouse list on status" This reverts commit 587ca48312f709275fd495504700bed2f76e2672. --- htdocs/product/stock/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 820572dc601..f0b94f99bdb 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -50,7 +50,7 @@ $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always ' $search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); $search_ref = GETPOST("sref", "alpha") ?GETPOST("sref", "alpha") : GETPOST("search_ref", "alpha"); $search_label = GETPOST("snom", "alpha") ?GETPOST("snom", "alpha") : GETPOST("search_label", "alpha"); -$search_status = GETPOST("search_statut", "int"); +$search_status = GETPOST("search_status", "int"); if (!empty($conf->categorie->enabled)) { @@ -232,7 +232,7 @@ foreach ($search as $key => $val) if ($search[$key] == '-1') $search[$key] = ''; $mode_search = 2; } - if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : 't.' . $key), $search[$key], (($key == 'statut') ? 2 : $mode_search)); + if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : 't.' . $key), $search[$key], (($key == 'status') ? 2 : $mode_search)); } if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all); // Add where from extra fields @@ -449,7 +449,7 @@ print $hookmanager->resPrint; // Status if (!empty($arrayfields['t.statut']['checked'])) { print ''; - print $form->selectarray('search_statut', $warehouse->statuts, $search_status, 1, 0, 0, '', 1); + print $form->selectarray('search_status', $warehouse->statuts, $search_status, 1, 0, 0, '', 1); print ''; } From 1bb24de555b2f907c73fd086fbd18580c9275a44 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:22:43 +0200 Subject: [PATCH 297/434] Can set the language of a user. --- htdocs/langs/en_US/users.lang | 1 + htdocs/user/card.php | 36 ++++++++++++++++++++++++++++++++ htdocs/user/class/user.class.php | 1 + 3 files changed, 38 insertions(+) diff --git a/htdocs/langs/en_US/users.lang b/htdocs/langs/en_US/users.lang index aea757e4a15..37ad1c0fc0d 100644 --- a/htdocs/langs/en_US/users.lang +++ b/htdocs/langs/en_US/users.lang @@ -117,3 +117,4 @@ ForceUserHolidayValidator=Force leave request validator ValidatorIsSupervisorByDefault=By default, the validator is the supervisor of the user. Keep empty to keep this behaviour. UserPersonalEmail=Personal email UserPersonalMobile=Personal mobile phone +WarningNotLangOfInterface=Warning, this is the main language the user speak, not the language of the interface he choosed to see. To change the interface language visible by this user, go on tab %s \ No newline at end of file diff --git a/htdocs/user/card.php b/htdocs/user/card.php index d74467a14b7..eb3cd67cf50 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -44,6 +44,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; @@ -253,6 +254,8 @@ if (empty($reshook)) { $object->fk_warehouse = GETPOST('fk_warehouse', 'int'); + $object->lang = GETPOST('default_lang', 'aZ09'); + // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost(null, $object); if ($ret < 0) { @@ -415,6 +418,8 @@ if (empty($reshook)) { $object->fk_warehouse = GETPOST('fk_warehouse', 'int'); } + $object->lang = GETPOST('default_lang', 'aZ09'); + if (!empty($conf->multicompany->enabled)) { if (!empty($_POST["superadmin"])) @@ -671,6 +676,7 @@ if (empty($reshook)) { $form = new Form($db); $formother = new FormOther($db); $formcompany = new FormCompany($db); +$formadmin = new FormAdmin($db); $formfile = new FormFile($db); if (!empty($conf->stock->enabled)) $formproduct = new FormProduct($db); @@ -1113,6 +1119,14 @@ if ($action == 'create' || $action == 'adduserldap') print ""; } + if (!empty($conf->global->MAIN_MULTILANGS)) + { + print ''.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print $formadmin->select_language(GETPOST('default_lang', 'alpha') ?GETPOST('default_lang', 'alpha') : ($object->lang ? $object->lang : ''), 'default_lang', 0, 0, 1, 0, 0, 'maxwidth200onsmartphone'); + print ''; + print ''; + } + // Multicompany if (!empty($conf->multicompany->enabled) && is_object($mc)) { @@ -1654,6 +1668,19 @@ if ($action == 'create' || $action == 'adduserldap') print ''; } + // Default language + if (!empty($conf->global->MAIN_MULTILANGS)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + print ''.$langs->trans("DefaultLang").''; + //$s=picto_from_langcode($object->default_lang); + //print ($s?$s.' ':''); + $langs->load("languages"); + $labellang = ($object->lang ? $langs->trans('Language_'.$object->lang) : ''); + print $form->textwithpicto($labellang, $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))); + print ''; + } + if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->file->main_authentication) && !empty($conf->global->MAIN_OPENIDURL_PERUSER)) { print ''.$langs->trans("OpenIDURL").''; @@ -2446,6 +2473,15 @@ if ($action == 'create' || $action == 'adduserldap') print ""; } + // Default language + if (!empty($conf->global->MAIN_MULTILANGS)) + { + print ''.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print $formadmin->select_language($object->lang, 'default_lang', 0, 0, 1); + print ''; + print ''; + } + // Status print ''.$langs->trans("Status").''; print ''; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index cc794db045b..75c6a0a4d60 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1549,6 +1549,7 @@ class User extends CommonObject $sql .= ", default_range = ".($this->default_range > 0 ? $this->default_range : 'null'); $sql .= ", default_c_exp_tax_cat = ".($this->default_c_exp_tax_cat > 0 ? $this->default_c_exp_tax_cat : 'null'); $sql .= ", fk_warehouse = ".($this->fk_warehouse ? "'".$this->db->escape($this->fk_warehouse)."'" : "null"); + $sql .= ", lang = ".($this->lang ? "'".$this->db->escape($this->lang)."'" : "null"); $sql .= " WHERE rowid = ".$this->id; From 7e15abc9724ea8071e753a9c7631065e90f2caf7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:34:21 +0200 Subject: [PATCH 298/434] Fix missing translation --- htdocs/langs/en_US/admin.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 5316f49a2b1..07961cadde4 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1850,6 +1850,7 @@ MailToSendSupplierRequestForQuotation=Quotation request MailToSendSupplierOrder=Purchase orders MailToSendSupplierInvoice=Vendor invoices MailToSendContract=Contracts +MailToSendReception=Receptions MailToThirdparty=Third parties MailToMember=Members MailToUser=Users From 5e90286a2e0e3f336d9d555d8463aa50b71604d4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:38:03 +0200 Subject: [PATCH 299/434] Fix permission on type of email templates must depends on user perms. --- htdocs/admin/mails_templates.php | 42 ++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 4334236f813..0f490bb828a 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -153,20 +153,20 @@ $sourceList = array(); // We save list of template email Dolibarr can manage. This list can found by a grep into code on "->param['models']" $elementList = array(); -if ($conf->propal->enabled) $elementList['propal_send'] = $langs->trans('MailToSendProposal'); -if ($conf->commande->enabled) $elementList['order_send'] = $langs->trans('MailToSendOrder'); -if ($conf->facture->enabled) $elementList['facture_send'] = $langs->trans('MailToSendInvoice'); +if ($conf->propal->enabled && $user->rights->propal->lire) $elementList['propal_send'] = $langs->trans('MailToSendProposal'); +if ($conf->commande->enabled && $user->rights->commande->lire) $elementList['order_send'] = $langs->trans('MailToSendOrder'); +if ($conf->facture->enabled && $user->rights->facture->lire) $elementList['facture_send'] = $langs->trans('MailToSendInvoice'); if ($conf->expedition->enabled) $elementList['shipping_send'] = $langs->trans('MailToSendShipment'); if ($conf->reception->enabled) $elementList['reception_send'] = $langs->trans('MailToSendReception'); if ($conf->ficheinter->enabled) $elementList['fichinter_send'] = $langs->trans('MailToSendIntervention'); if ($conf->supplier_proposal->enabled) $elementList['supplier_proposal_send'] = $langs->trans('MailToSendSupplierRequestForQuotation'); -if ($conf->fournisseur->enabled && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || $conf->supplier_order->enabled) $elementList['order_supplier_send'] = $langs->trans('MailToSendSupplierOrder'); -if ($conf->fournisseur->enabled && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || $conf->supplier_invoice->enabled) $elementList['invoice_supplier_send'] = $langs->trans('MailToSendSupplierInvoice'); -if ($conf->societe->enabled) $elementList['thirdparty'] = $langs->trans('MailToThirdparty'); -if ($conf->adherent->enabled) $elementList['member'] = $langs->trans('MailToMember'); -if ($conf->contrat->enabled) $elementList['contract'] = $langs->trans('MailToSendContract'); +if (($conf->fournisseur->enabled && $user->rights->fournisseur->commande->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || ($conf->supplier_order->enabled && $user->rights->supplier_order->lire)) $elementList['order_supplier_send'] = $langs->trans('MailToSendSupplierOrder'); +if (($conf->fournisseur->enabled && $user->rights->fournisseur->facture->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || ($conf->supplier_invoice->enabled && $user->rights->supplier_invoice->lire)) $elementList['invoice_supplier_send'] = $langs->trans('MailToSendSupplierInvoice'); +if ($conf->societe->enabled && $user->rights->societe->lire) $elementList['thirdparty'] = $langs->trans('MailToThirdparty'); +if ($conf->adherent->enabled && $user->rights->adherent->lire) $elementList['member'] = $langs->trans('MailToMember'); +if ($conf->contrat->enabled && $user->rights->contrat->lire) $elementList['contract'] = $langs->trans('MailToSendContract'); if ($conf->projet->enabled) $elementList['project'] = $langs->trans('MailToProject'); -if ($conf->ticket->enabled) $elementList['ticket_send'] = $langs->trans('MailToTicket'); +if ($conf->ticket->enabled && $user->rights->ticket->read) $elementList['ticket_send'] = $langs->trans('MailToTicket'); $elementList['user'] = $langs->trans('MailToUser'); $parameters = array('elementList'=>$elementList); @@ -544,6 +544,7 @@ if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $fieldsforco foreach ($fieldsforcontent as $tmpfieldlist) { print ''; + // Label if ($tmpfieldlist == 'topic') { @@ -557,6 +558,7 @@ foreach ($fieldsforcontent as $tmpfieldlist) print $form->textwithpicto($langs->trans("Content"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'
'; if ($tmpfieldlist == 'content_lines') print $form->textwithpicto($langs->trans("ContentForLines"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'
'; + // Input field if ($tmpfieldlist == 'topic') { print ''; @@ -633,30 +635,34 @@ if ($resql) // Title line with search boxes print ''; + $filterfound = 0; foreach ($fieldlist as $field => $value) { - if ($value == 'label') print ''; - elseif ($value == 'lang') - { + if ($value == 'label') { + print ''; + } elseif ($value == 'lang') { print ''; print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1, 0, 0, 'maxwidth100'); print ''; - } elseif ($value == 'fk_user') - { + } elseif ($value == 'fk_user') { print ''; $restrictid = array(); if (!$user->admin) $restrictid = array($user->id); //var_dump($restrictid); print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, 'hierarchyme', null, 0, 0, 1, '', 0, '', 'maxwidth100'); print ''; - } elseif ($value == 'topic') print ''; - elseif ($value == 'type_template') - { + } elseif ($value == 'topic') { + print ''; + } elseif ($value == 'type_template') { print ''.$form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100 maxwidth100onsmartphone').''; - } elseif (!in_array($value, array('content', 'content_lines'))) print ''; + } elseif (!in_array($value, array('content', 'content_lines'))) { + print ''; + } } + if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) print ''; + // Action column print ''; $searchpicto = $form->showFilterButtons(); From f132f272f26c636ae6230748dd65ab7baa6f7be3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:34:21 +0200 Subject: [PATCH 300/434] Fix missing translation --- htdocs/langs/en_US/admin.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index bd957f0ca02..90b95883673 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1846,6 +1846,7 @@ MailToSendSupplierRequestForQuotation=Quotation request MailToSendSupplierOrder=Purchase orders MailToSendSupplierInvoice=Vendor invoices MailToSendContract=Contracts +MailToSendReception=Receptions MailToThirdparty=Third parties MailToMember=Members MailToUser=Users From 71a6cf120747d3d7f4b0f3496e3a0e8ff66bbf24 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:38:03 +0200 Subject: [PATCH 301/434] Fix permission on type of email templates must depends on user perms. Conflicts: htdocs/admin/mails_templates.php --- htdocs/admin/mails_templates.php | 43 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 320d2e1d8a1..a26e0801238 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -155,20 +155,20 @@ $sourceList = array(); // We save list of template email Dolibarr can manage. This list can found by a grep into code on "->param['models']" $elementList = array(); -if ($conf->propal->enabled) $elementList['propal_send'] = $langs->trans('MailToSendProposal'); -if ($conf->commande->enabled) $elementList['order_send'] = $langs->trans('MailToSendOrder'); -if ($conf->facture->enabled) $elementList['facture_send'] = $langs->trans('MailToSendInvoice'); +if ($conf->propal->enabled && $user->rights->propal->lire) $elementList['propal_send'] = $langs->trans('MailToSendProposal'); +if ($conf->commande->enabled && $user->rights->commande->lire) $elementList['order_send'] = $langs->trans('MailToSendOrder'); +if ($conf->facture->enabled && $user->rights->facture->lire) $elementList['facture_send'] = $langs->trans('MailToSendInvoice'); if ($conf->expedition->enabled) $elementList['shipping_send'] = $langs->trans('MailToSendShipment'); if ($conf->reception->enabled) $elementList['reception_send'] = $langs->trans('MailToSendReception'); if ($conf->ficheinter->enabled) $elementList['fichinter_send'] = $langs->trans('MailToSendIntervention'); if ($conf->supplier_proposal->enabled) $elementList['supplier_proposal_send'] = $langs->trans('MailToSendSupplierRequestForQuotation'); -if ($conf->fournisseur->enabled && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || $conf->supplier_order->enabled) $elementList['order_supplier_send'] = $langs->trans('MailToSendSupplierOrder'); -if ($conf->fournisseur->enabled && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || $conf->supplier_invoice->enabled) $elementList['invoice_supplier_send'] = $langs->trans('MailToSendSupplierInvoice'); -if ($conf->societe->enabled) $elementList['thirdparty'] = $langs->trans('MailToThirdparty'); -if ($conf->adherent->enabled) $elementList['member'] = $langs->trans('MailToMember'); -if ($conf->contrat->enabled) $elementList['contract'] = $langs->trans('MailToSendContract'); +if (($conf->fournisseur->enabled && $user->rights->fournisseur->commande->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || ($conf->supplier_order->enabled && $user->rights->supplier_order->lire)) $elementList['order_supplier_send'] = $langs->trans('MailToSendSupplierOrder'); +if (($conf->fournisseur->enabled && $user->rights->fournisseur->facture->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || ($conf->supplier_invoice->enabled && $user->rights->supplier_invoice->lire)) $elementList['invoice_supplier_send'] = $langs->trans('MailToSendSupplierInvoice'); +if ($conf->societe->enabled && $user->rights->societe->lire) $elementList['thirdparty'] = $langs->trans('MailToThirdparty'); +if ($conf->adherent->enabled && $user->rights->adherent->lire) $elementList['member'] = $langs->trans('MailToMember'); +if ($conf->contrat->enabled && $user->rights->contrat->lire) $elementList['contract'] = $langs->trans('MailToSendContract'); if ($conf->projet->enabled) $elementList['project'] = $langs->trans('MailToProject'); -if ($conf->ticket->enabled) $elementList['ticket_send'] = $langs->trans('MailToTicket'); +if ($conf->ticket->enabled && $user->rights->ticket->read) $elementList['ticket_send'] = $langs->trans('MailToTicket'); $elementList['user'] = $langs->trans('MailToUser'); $parameters = array('elementList'=>$elementList); @@ -558,6 +558,7 @@ if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $fieldsforco foreach ($fieldsforcontent as $tmpfieldlist) { print ''; + // Label if ($tmpfieldlist == 'topic') { @@ -571,6 +572,7 @@ foreach ($fieldsforcontent as $tmpfieldlist) print $form->textwithpicto($langs->trans("Content"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'
'; if ($tmpfieldlist == 'content_lines') print $form->textwithpicto($langs->trans("ContentForLines"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'
'; + // Input field if ($tmpfieldlist == 'topic') { print ''; @@ -652,33 +654,34 @@ if ($resql) // Title line with search boxes print ''; + $filterfound = 0; foreach ($fieldlist as $field => $value) { - if ($value == 'label') print ''; - elseif ($value == 'lang') - { + if ($value == 'label') { + print ''; + } elseif ($value == 'lang') { print ''; print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1, 0, 0, 'maxwidth100'); print ''; - } - elseif ($value == 'fk_user') - { + } elseif ($value == 'fk_user') { print ''; $restrictid = array(); if (!$user->admin) $restrictid = array($user->id); //var_dump($restrictid); print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, 'hierarchyme', null, 0, 0, 1, '', 0, '', 'maxwidth100'); print ''; - } - elseif ($value == 'topic') print ''; - elseif ($value == 'type_template') - { + } elseif ($value == 'topic') { + print ''; + } elseif ($value == 'type_template') { print ''.$form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100 maxwidth100onsmartphone').''; + } elseif (!in_array($value, array('content', 'content_lines'))) { + print ''; } - elseif (!in_array($value, array('content', 'content_lines'))) print ''; } + if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) print ''; + // Action column print ''; $searchpicto = $form->showFilterButtons(); From 7e629d7ef4d2d7b27e57f609ad68ef8e19e9ad87 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:05:05 +0200 Subject: [PATCH 302/434] FIX Language visible just after login does not match user choice. --- htdocs/main.inc.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 396e377e7b5..2887b4b1f77 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -655,6 +655,11 @@ if (!defined('NOLOGIN')) if (GETPOST('lang', 'aZ09')) $paramsurl[] = 'lang='.GETPOST('lang', 'aZ09'); header('Location: '.DOL_URL_ROOT.'/index.php'.(count($paramsurl) ? '?'.implode('&', $paramsurl) : '')); exit; + } else { + // User is loaded, we may need to change language for him according to its choice + if (! empty($user->conf->MAIN_LANG_DEFAULT)) { + $langs->setDefaultLang($user->conf->MAIN_LANG_DEFAULT); + } } } else From ac48576b88debf1e243dfa2e12ca75ef324ec3ee Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:49:07 +0200 Subject: [PATCH 303/434] Add missing dependency in debian package #12785 --- build/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/debian/control b/build/debian/control index 970f192f094..0c010b6a478 100755 --- a/build/debian/control +++ b/build/debian/control @@ -14,7 +14,7 @@ Architecture: all Depends: libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm | php5 | libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php, php5-cli | php-cli, # Required PHP extensions - php5-mysql | php5-mysqli | php-mysql | php-mysqli, php5-curl | php-curl, php5-gd | php-gd, php5-ldap | php-gd, + php5-mysql | php5-mysqli | php-mysql | php-mysqli, php5-curl | php-curl, php5-gd | php-gd, php5-ldap | php-gd, php5-zip | php-zip # Required PHP libraries php-pear, php-mail-mime, # php-tcpdf, From ada7b74ba1fd183b8735c8d651eac9b947d20c14 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:56:30 +0200 Subject: [PATCH 304/434] Fix phpcs --- htdocs/core/lib/ajax.lib.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 72bdc413795..4018d20aee5 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -25,24 +25,24 @@ /** - * Generic function that return javascript to add to a page to transform a common input field into an autocomplete field by calling an Ajax page (ex: /societe/ajaxcompanies.php). - * The HTML field must be an input text with id=search_$htmlname. - * This use the jQuery "autocomplete" function. If we want to use the select2, we must also convert the input into select on funcntions that call this method. + * Generic function that return javascript to add to a page to transform a common input field into an autocomplete field by calling an Ajax page (ex: /societe/ajaxcompanies.php). + * The HTML field must be an input text with id=search_$htmlname. + * This use the jQuery "autocomplete" function. If we want to use the select2, we must also convert the input into select on funcntions that call this method. * - * @param string $selected Preselected value - * @param string $htmlname HTML name of input field - * @param string $url Ajax Url to call for request: /path/page.php. Must return a json array ('key'=>id, 'value'=>String shown into input field once selected, 'label'=>String shown into combo list) - * @param string $urloption More parameters on URL request - * @param int $minLength Minimum number of chars to trigger that Ajax search - * @param int $autoselect Automatic selection if just one value - * @param array $ajaxoptions Multiple options array + * @param string $selected Preselected value + * @param string $htmlname HTML name of input field + * @param string $url Ajax Url to call for request: /path/page.php. Must return a json array ('key'=>id, 'value'=>String shown into input field once selected, 'label'=>String shown into combo list) + * @param string $urloption More parameters on URL request + * @param int $minLength Minimum number of chars to trigger that Ajax search + * @param int $autoselect Automatic selection if just one value + * @param array $ajaxoptions Multiple options array * - Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done * - Ex: array('disabled'=> ) * - Ex: array('show'=> ) * - Ex: array('update_textarea'=> ) * - Ex: array('option_disabled'=> id to disable and warning to show if we select a disabled value (this is possible when using autocomplete ajax) * @param string $moreparams More params provided to ajax call - * @return string Script + * @return string Script */ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams = '') { From dd773d33fd41f7dd737618caf2ea6ae85abe43b6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:57:52 +0200 Subject: [PATCH 305/434] Fix phpcs --- htdocs/product/composition/card.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index 1fbbe2ecefa..7693ef9a4de 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -66,12 +66,13 @@ if ($id > 0 || ! empty($ref)) if ($cancel) $action =''; -// Action association d'un sousproduit +// Add subproduct to product if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->service->creer)) { $error=0; - for ($i=0; $i < GETPOST("max_prod", 'int'); $i++) + $maxprod = GETPOST("max_prod", 'int'); + for ($i=0; $i < $maxprod; $i++) { $qty = price2num(GETPOST("prod_qty_".$i, 'alpha'), 'MS'); if ($qty > 0) From 3c6f122a81ff2d8d9f7fc5c2fe2ce419e8f938ae Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 14:59:22 +0200 Subject: [PATCH 306/434] Fix phpunit --- test/phpunit/SecurityTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 5a248006498..50ae74e5031 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -300,9 +300,9 @@ class SecurityTest extends PHPUnit\Framework\TestCase $this->assertEquals($genpass2, ''); $conf->global->USER_PASSWORD_GENERATED='Standard'; - $genpass3=getRandomPassword(false); // Should return a password of 8 chars + $genpass3=getRandomPassword(false); // Should return a password of 10 chars print __METHOD__." genpass3=".$genpass3."\n"; - $this->assertEquals(strlen($genpass3), 8); + $this->assertEquals(strlen($genpass3), 10); return 0; } From dec0e418e32a964273365a678a02301e622b7e32 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Fri, 7 Aug 2020 15:11:36 +0200 Subject: [PATCH 307/434] Convert search key status to class key statut. Add comment to refactor class statut to class status --- htdocs/product/stock/list.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index f0b94f99bdb..036fba2be76 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -101,7 +101,9 @@ $search_all = trim(GETPOST("search_all", 'alpha')); $search = array(); foreach ($object->fields as $key => $val) { - if (GETPOST('search_'.$key, 'alpha') !== '') $search[$key] = GETPOST('search_'.$key, 'alpha'); + $search_key = $key; + if ($search_key == 'statut') $search_key = 'status'; // remove this after refactor entrepot.class property statut to status + if (GETPOST('search_'.$search_key, 'alpha') !== '') $search[$search_key] = GETPOST('search_'.$search_key, 'alpha'); } // Definition of fields for list @@ -226,13 +228,15 @@ if (!empty($conf->categorie->enabled)) } foreach ($search as $key => $val) { + $class_key = $key; + if ($class_key == 'status') $class_key = 'statut'; // remove this after refactor entrepot.class property statut to status if (($key == 'status' && $search[$key] == -1) || $key=='entity') continue; $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); if (strpos($object->fields[$key]['type'], 'integer:') === 0) { if ($search[$key] == '-1') $search[$key] = ''; $mode_search = 2; } - if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : 't.' . $key), $search[$key], (($key == 'status') ? 2 : $mode_search)); + if ($search[$key] != '') $sql .= natural_search((($key == 'ref') ? 't.ref' : 't.' . $class_key), $search[$key], (($key == 'status') ? 2 : $mode_search)); } if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all); // Add where from extra fields From 00804c10204b11987b5dc6fb1570a3d8ec14f13c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 15:19:26 +0200 Subject: [PATCH 308/434] Complete fix for #14146 --- htdocs/contact/list.php | 8 +++++++- htdocs/core/class/html.form.class.php | 6 +++++- htdocs/modulebuilder/template/myobject_list.php | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 39c588ace15..843a894a0fd 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -200,7 +200,13 @@ if (is_array($extrafields->attributes[$object->table_element]['label']) && count foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) - $arrayfields["ef.".$key] = array('label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key])); + $arrayfields["ef.".$key] = array( + 'label'=>$extrafields->attributes[$object->table_element]['label'][$key], + 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), + 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], + 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]), + 'langfile'=>$extrafields->attributes[$object->table_element]['langfile'][$key], + ); } } $object->fields = dol_sort_array($object->fields, 'position'); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 14db0028606..90efe26e1ca 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6744,7 +6744,7 @@ class Form */ public static function multiSelectArrayWithCheckbox($htmlname, &$array, $varpage) { - global $conf, $langs, $user; + global $conf, $langs, $user, $extrafields; if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) return ''; @@ -6776,6 +6776,10 @@ class Form } if ($val['label']) { + if (! empty($val['langfile']) && is_object($langs)) { + $langs->load($val['langfile']); + } + $lis .= '
  • '; $listcheckedstring .= (empty($val['checked']) ? '' : $key.','); } diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 0059570d314..809f7ffb107 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -139,7 +139,8 @@ if (is_array($extrafields->attributes[$object->table_element]['label']) && count 'label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], - 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]) + 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]), + 'langfile'=>$extrafields->attributes[$object->table_element]['langfile'][$key] ); } } From 9876e37309f0c9c4d1ca4d067e02a6533258e1a7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 15:47:02 +0200 Subject: [PATCH 309/434] A little perf and memory enhancement when building category tree --- htdocs/categories/class/categorie.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index d5a2f76ecd5..7d3cdfde518 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1213,7 +1213,8 @@ class Categorie extends CommonObject //print 'Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].'
    '."\n"; // We count number of _ to have level - $this->cats[$id_categ]['level'] = dol_strlen(preg_replace('/[^_]/i', '', $this->cats[$id_categ]['fullpath'])); + $nbunderscore = substr_count($this->cats[$id_categ]['fullpath'], '_'); + $this->cats[$id_categ]['level'] = ($nbunderscore ? $nbunderscore : null); return; } From 0dda5ca4d6df39400d20e2fd959fd8f7c6c61843 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 16:27:09 +0200 Subject: [PATCH 310/434] Fix experimental --- htdocs/core/modules/modPaymentByBankTransfer.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modPaymentByBankTransfer.class.php b/htdocs/core/modules/modPaymentByBankTransfer.class.php index d68274e2dee..2a1686bd1c3 100644 --- a/htdocs/core/modules/modPaymentByBankTransfer.class.php +++ b/htdocs/core/modules/modPaymentByBankTransfer.class.php @@ -54,7 +54,7 @@ class modPaymentByBankTransfer extends DolibarrModules $this->description = "Management of payment by bank transfer"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'development'; + $this->version = 'experimental'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of png file (without png) used for this module From e69616110ddd4055b63b1e45c0d41a23b054a024 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 16:59:27 +0200 Subject: [PATCH 311/434] Fix permission on page --- htdocs/compta/facture/prelevement.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index b24723330a0..cfe6cd51a22 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -38,8 +38,6 @@ require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; -if (!$user->rights->facture->lire) accessforbidden(); - // Load translation files required by the page $langs->loadLangs(array('bills', 'banks', 'withdrawals', 'companies')); @@ -51,7 +49,6 @@ $type = GETPOST('type', 'aZ09'); $fieldid = (!empty($ref) ? 'ref' : 'rowid'); if ($user->socid) $socid = $user->socid; -$result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid); if ($type == 'bank-transfer') { $object = new FactureFournisseur($db); @@ -63,6 +60,7 @@ if ($type == 'bank-transfer') { if ($id > 0 || !empty($ref)) { $ret = $object->fetch($id, $ref); + $isdraft = (($object->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); if ($ret > 0) { $object->fetch_thirdparty(); @@ -71,6 +69,13 @@ if ($id > 0 || !empty($ref)) $hookmanager->initHooks(array('directdebitcard', 'globalcard')); +if ($type == 'bank-transfer') { + $result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture', 'fk_soc', $fieldid, $isdraft); + if (!$user->rights->fournisseur->facture->lire) accessforbidden(); +} else { + $result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid, $isdraft); + if (!$user->rights->facture->lire) accessforbidden(); +} /* From bd5c4603e315bf90d5412dea1b9bd589ed0bbd81 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 17:06:12 +0200 Subject: [PATCH 312/434] Fix regression in sending emails --- htdocs/core/class/CMailFile.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 50418604c07..bc80d48d412 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -357,7 +357,7 @@ class CMailFile $smtps->setSubject($subjecttouse); $smtps->setTO($this->getValidAddress($this->to, 0, 1)); - $smtps->setFrom($this->getValidAddress($this->from, 0, 1)); + $smtps->setFrom($this->getValidAddress($this->addr_from, 0, 1)); $smtps->setTrackId($this->trackid); $smtps->setReplyTo($this->getValidAddress($this->replyto, 0, 1)); @@ -781,14 +781,14 @@ class CMailFile $from = $this->smtps->getFrom('org'); if ($res && !$from) { - $this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."
    Sender address '$from' invalid"; + $this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport." - Sender address '$from' invalid"; dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); $res = false; } $dest = $this->smtps->getTo(); if ($res && !$dest) { - $this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."
    Recipient address '$dest' invalid"; + $this->error = "Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport." - Recipient address '$dest' invalid"; dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); $res = false; } @@ -811,7 +811,7 @@ class CMailFile else { if (empty($this->error)) $this->error = $result; - dol_syslog("CMailFile::sendfile: mail end error with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport."
    ".$this->error, LOG_ERR); + dol_syslog("CMailFile::sendfile: mail end error with smtps lib to HOST=".$server.", PORT=".$conf->global->$keyforsmtpport." - ".$this->error, LOG_ERR); $res = false; } } From 795754273e18b5b2e6fbd35eb182908b628570d1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 17:06:57 +0200 Subject: [PATCH 313/434] Fix regression in sending emails --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index bc80d48d412..0b28be50f7e 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -356,7 +356,7 @@ class CMailFile } $smtps->setSubject($subjecttouse); - $smtps->setTO($this->getValidAddress($this->to, 0, 1)); + $smtps->setTO($this->getValidAddress($this->addr_to, 0, 1)); $smtps->setFrom($this->getValidAddress($this->addr_from, 0, 1)); $smtps->setTrackId($this->trackid); $smtps->setReplyTo($this->getValidAddress($this->replyto, 0, 1)); From 030df58fea7ab8a7eac92f17b971c496e2d082e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 17:11:23 +0200 Subject: [PATCH 314/434] Fix regression in sending emails --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 0b28be50f7e..5ac114cfa69 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -403,7 +403,7 @@ class CMailFile $smtps->setDeliveryReceipt($this->deliveryreceipt); $host = dol_getprefix('email'); - $this->msgid = time().'.SMTPs-dolibarr-'.$trackid.'@'.$host; + $this->msgid = time().'.SMTPs-dolibarr-'.$this->trackid.'@'.$host; $this->smtps = $smtps; } From 4855b496983264326ff29ec6db5b87b650c693e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 19:44:49 +0200 Subject: [PATCH 315/434] css --- htdocs/holiday/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index c5554a40fb1..692b9639805 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -1348,7 +1348,7 @@ else print ''; } - // Validator + // Approver if (!$edit && $action != 'editvalidator') { print ''; print ''; @@ -1359,7 +1359,7 @@ else $include_users = $object->fetch_users_approver_holiday(); if (is_array($include_users) && in_array($user->id, $include_users) && $object->statut == Holiday::STATUS_VALIDATED) { - print ''.img_edit($langs->trans("Edit")).''; + print ''.img_edit($langs->trans("Edit")).''; } print ''; print ''; From aa699bacc6b64e0e6f4fe2d363c28782c7aaed8f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 20:10:31 +0200 Subject: [PATCH 316/434] css --- htdocs/product/list.php | 24 +++++++++++++++++------- htdocs/societe/list.php | 1 + htdocs/theme/eldy/info-box.inc.php | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 4b74e6b9a0f..2acdbaa7f56 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -647,7 +647,7 @@ if ($resql) // Type if (!empty($arrayfields['p.fk_product_type']['checked'])) { - print ''; + print ''; $array = array('-1'=>' ', '0'=>$langs->trans('Product'), '1'=>$langs->trans('Service')); print $form->selectarray('search_type', $array, $search_type); print ''; @@ -875,7 +875,7 @@ if ($resql) print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"], "p.label", "", $param, "", $sortfield, $sortorder); } if (!empty($arrayfields['p.fk_product_type']['checked'])) { - print_liste_field_titre($arrayfields['p.fk_product_type']['label'], $_SERVER["PHP_SELF"], "p.fk_product_type", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre($arrayfields['p.fk_product_type']['label'], $_SERVER["PHP_SELF"], "p.fk_product_type", "", $param, "", $sortfield, $sortorder, 'center '); } if (!empty($arrayfields['p.barcode']['checked'])) { print_liste_field_titre($arrayfields['p.barcode']['label'], $_SERVER["PHP_SELF"], "p.barcode", "", $param, "", $sortfield, $sortorder); @@ -1086,9 +1086,19 @@ if ($resql) // Type if (!empty($arrayfields['p.fk_product_type']['checked'])) { - print ''; - if ($obj->fk_product_type == 0) print $langs->trans("Product"); - else print $langs->trans("Service"); + print ''; + $s = ''; + if ($obj->fk_product_type == 0) + { + $s .= ''; + $s .= dol_substr($langs->trans("Product"), 0, 1); + $s .= ''; + } else { + $s .= ''; + $s .= dol_substr($langs->trans("Service"), 0, 1); + $s .= ''; + } + print $s; print ''; if (!$i) $totalarray['nbfield']++; } @@ -1323,7 +1333,7 @@ if ($resql) print ''; } - // Sell Tax Rate + // VAT or Sell Tax Rate if (!empty($arrayfields['p.tva_tx']['checked'])) { print ''; @@ -1339,7 +1349,7 @@ if ($resql) print price($product_static->pmp, 1, $langs); print ''; } - // cost_price + // Cost price if (!empty($arrayfields['p.cost_price']['checked'])) { print ''; diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index cc61e6c3318..71e214af5c0 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -1196,6 +1196,7 @@ while ($i < min($num, $limit)) print "".$obj->idprof6."\n"; if (!$i) $totalarray['nbfield']++; } + // VAT if (!empty($arrayfields['s.tva_intra']['checked'])) { print ""; diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index c1f3be0df41..5d4ae8de59b 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -263,6 +263,24 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) $conf->global->THEME_SATURATE_RATIO = border-radius: 3px; } +.product-type-back { + background-color: #a6c974 !important; + color: #FFF !important; + padding: 2px; + margin: 2px; + border-bottom-left-radius: 5px; + border-top-right-radius: 5px; +} +.service-type-back { + background-color: #979c01 !important; + color: #FFF !important; + padding: 2px; + margin: 2px; + border-bottom-right-radius: 5px; + border-top-left-radius: 5px; +} + + .bg-infobox-project{ color: #6c6aa8 !important; } From 6f7b65d9f2aba720310b19988d1eb7b51d7ec259 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 7 Aug 2020 20:44:49 +0200 Subject: [PATCH 317/434] css --- htdocs/product/list.php | 14 ++++++++------ htdocs/theme/eldy/global.inc.php | 3 +++ htdocs/theme/eldy/info-box.inc.php | 16 ---------------- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 2acdbaa7f56..53a5d993128 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -1090,13 +1090,15 @@ if ($resql) $s = ''; if ($obj->fk_product_type == 0) { - $s .= ''; - $s .= dol_substr($langs->trans("Product"), 0, 1); - $s .= ''; + //$s .= ''; + $s .= img_picto($langs->trans("Product"), 'product', 'class="paddingleftonly paddingrightonly colorgrey"'); + //$s .= dol_substr($langs->trans("Product"), 0, 1); + //$s .= ''; } else { - $s .= ''; - $s .= dol_substr($langs->trans("Service"), 0, 1); - $s .= ''; + //$s .= ''; + $s .= img_picto($langs->trans("Service"), 'service', 'class="paddingleftonly paddingrightonly colorgrey"'); + //$s .= dol_substr($langs->trans("Service"), 0, 1); + //$s .= ''; } print $s; print ''; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index ab7a56ea89d..972221079c9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -385,6 +385,9 @@ input.pageplusone { .colorwhite { color: #fff; } +.colorgrey { + color: #888 !important; +} .colorblack { color: #000; } diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index 5d4ae8de59b..b009d7ef95b 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -263,22 +263,6 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) $conf->global->THEME_SATURATE_RATIO = border-radius: 3px; } -.product-type-back { - background-color: #a6c974 !important; - color: #FFF !important; - padding: 2px; - margin: 2px; - border-bottom-left-radius: 5px; - border-top-right-radius: 5px; -} -.service-type-back { - background-color: #979c01 !important; - color: #FFF !important; - padding: 2px; - margin: 2px; - border-bottom-right-radius: 5px; - border-top-left-radius: 5px; -} .bg-infobox-project{ From 9f130aa2af4ae5c97c261b391f61c47ab5c1ecc4 Mon Sep 17 00:00:00 2001 From: Egils Consulting Date: Fri, 7 Aug 2020 23:17:43 +0200 Subject: [PATCH 318/434] New function count_all_categories This is useful to count the total number of categories e.g. to decide whether to load the full tree or not. It might make most sense to wait with merging until there is code in viewcat.php or index.php using it. --- htdocs/categories/class/categorie.class.php | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 7d3cdfde518..111f3bf8a88 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -2010,4 +2010,29 @@ class Categorie extends CommonObject return ""; } } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Count all categories + * + * @return int Number of categories, -1 on error + */ + public function count_all_categories() + { + dol_syslog(get_class($this)."::count_all_categories", LOG_DEBUG); + $sql = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."categorie"; + $sql .= " WHERE entity IN (".getEntity('category').")"; + + $res = $this->db->query($sql); + if ($res) + { + $obj = $this->db->fetch_object($res); + return $obj->count; + } + else + { + dol_print_error($this->db); + return -1; + } + } } From fc58d92db4312f74d851e2f412deb1d79ca83391 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 7 Aug 2020 21:20:55 +0000 Subject: [PATCH 319/434] Fixing style errors. --- htdocs/categories/class/categorie.class.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 111f3bf8a88..dd1e48b7346 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -2010,7 +2010,7 @@ class Categorie extends CommonObject return ""; } } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Count all categories @@ -2019,20 +2019,19 @@ class Categorie extends CommonObject */ public function count_all_categories() { - dol_syslog(get_class($this)."::count_all_categories", LOG_DEBUG); + dol_syslog(get_class($this)."::count_all_categories", LOG_DEBUG); $sql = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."categorie"; $sql .= " WHERE entity IN (".getEntity('category').")"; $res = $this->db->query($sql); - if ($res) + if ($res) { - $obj = $this->db->fetch_object($res); - return $obj->count; - } - else - { - dol_print_error($this->db); - return -1; - } + $obj = $this->db->fetch_object($res); + return $obj->count; + } + else { + dol_print_error($this->db); + return -1; + } } } From 8f8f7ecf5dce545ee891630054ab389e8fcf01a1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 8 Aug 2020 02:24:01 +0200 Subject: [PATCH 320/434] Update categorie.class.php --- htdocs/categories/class/categorie.class.php | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index dd1e48b7346..6128ab5e2df 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -2011,27 +2011,24 @@ class Categorie extends CommonObject } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Count all categories * * @return int Number of categories, -1 on error */ - public function count_all_categories() + public function countNbOfCategories() { dol_syslog(get_class($this)."::count_all_categories", LOG_DEBUG); - $sql = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."categorie"; - $sql .= " WHERE entity IN (".getEntity('category').")"; + $sql = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."categorie"; + $sql .= " WHERE entity IN (".getEntity('category').")"; - $res = $this->db->query($sql); - if ($res) - { + $res = $this->db->query($sql); + if ($res) { $obj = $this->db->fetch_object($res); - return $obj->count; - } - else { - dol_print_error($this->db); - return -1; + return $obj->count; + } else { + dol_print_error($this->db); + return -1; } } } From 537b58b44659e1a2b87b27601583ceab275e781d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 8 Aug 2020 02:34:22 +0200 Subject: [PATCH 321/434] Introduce workaround to allow integrator to suggest list of modules in old style by default instead of kanban style #14075 --- htdocs/admin/modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 18b9afe31ba..af689b1165d 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -38,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/dolistore.class.php'; // Load translation files required by the page $langs->loadLangs(array("errors", "admin", "modulebuilder")); -$mode = GETPOSTISSET('mode') ? GETPOST('mode', 'alpha') : 'commonkanban'; +$mode = GETPOSTISSET('mode') ? GETPOST('mode', 'alpha') : (empty($conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT) ? 'commonkanban' : 'common'); if (empty($mode)) $mode = 'common'; $action = GETPOST('action', 'alpha'); //var_dump($_POST);exit; From 4e6158d23c6772f13320a721ac02a16da18daf08 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 8 Aug 2020 02:54:14 +0200 Subject: [PATCH 322/434] Work on recruitment module --- .../install/mysql/migration/12.0.0-13.0.0.sql | 13 +++++++- .../mysql/tables/llx_c_recruitment_origin.sql | 33 +++++++++++++++++++ ...llx_recruitment_recruitmentcandidature.sql | 3 +- .../class/recruitmentcandidature.class.php | 3 ++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 htdocs/install/mysql/tables/llx_c_recruitment_origin.sql diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 347985aad2b..3bb62c53e61 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -148,16 +148,20 @@ CREATE TABLE llx_recruitment_recruitmentcandidature( firstname varchar(128), lastname varchar(128), remuneration_requested integer, - remuneration_proposed integer + remuneration_proposed integer, + fk_recruitment_origin INTEGER NULL -- END MODULEBUILDER FIELDS ) ENGINE=innodb; +ALTER TABLE llx_recruitment_recruitmentcandidature ADD COLUMN fk_recruitment_origin INTEGER NULL; + ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_rowid (rowid); ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_ref (ref); ALTER TABLE llx_recruitment_recruitmentcandidature ADD CONSTRAINT llx_recruitment_recruitmentcandidature_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_status (status); + create table llx_recruitment_recruitmentcandidature_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, @@ -208,3 +212,10 @@ insert into llx_c_stcommcontact (id,code,libelle) values ( 3, 'ST_DONE', 'Conta ALTER TABLE llx_socpeople ADD COLUMN fk_prospectcontactlevel varchar(12) AFTER priv; ALTER TABLE llx_socpeople ADD COLUMN fk_stcommcontact integer DEFAULT 0 NOT NULL AFTER fk_prospectcontactlevel; +create table llx_c_recruitment_origin +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(32) NOT NULL, + label varchar(64) NOT NULL, + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_c_recruitment_origin.sql b/htdocs/install/mysql/tables/llx_c_recruitment_origin.sql new file mode 100644 index 00000000000..b18f7eb383c --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_recruitment_origin.sql @@ -0,0 +1,33 @@ +-- ======================================================================== +-- Copyright (C) 2005-2016 Laurent Destailleur +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- Defini les types de contact d'un element sert de reference pour +-- la table llx_element_contact +-- +-- element est le nom de la table utilisant le type de contact. +-- i.e. contact, facture, projet, societe (sans le llx_ devant). +-- Libelle est un texte decrivant le type de contact. +-- active precise si cette valeur est 'active' ou 'archive'. +-- +-- ======================================================================== + +create table llx_c_recruitment_origin +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(32) NOT NULL, + label varchar(64) NOT NULL, + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql index fb9cf56c8b2..43bdb14e7bd 100644 --- a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql @@ -32,6 +32,7 @@ CREATE TABLE llx_recruitment_recruitmentcandidature( firstname varchar(128), lastname varchar(128), remuneration_requested integer, - remuneration_proposed integer + remuneration_proposed integer, + fk_recruitment_origin INTEGER NULL -- END MODULEBUILDER FIELDS ) ENGINE=innodb; diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php index 4ee4bccbb7a..4a18ddf85fb 100644 --- a/htdocs/recruitment/class/recruitmentcandidature.class.php +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -111,9 +111,11 @@ class RecruitmentCandidature extends CommonObject 'lastname' => array('type'=>'varchar(128)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1,), 'remuneration_requested' => array('type'=>'integer', 'label'=>'RequestedRemuneration', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1,), 'remuneration_proposed' => array('type'=>'integer', 'label'=>'ProposedRemuneration', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1,), + 'fk_recruitment_origin' => array('type'=>'integer:CRecruitmentOrigin:recruitment/class/recruitment_crecruitmentorigin.class.php', 'label'=>'Origin', 'enabled'=>'1', 'position'=>45, 'visible'=>1, 'index'=>1), ); public $rowid; public $ref; + public $fk_recruitmentjobposition; public $description; public $note_public; public $note_private; @@ -128,6 +130,7 @@ class RecruitmentCandidature extends CommonObject public $lastname; public $remuneration_requested; public $remuneration_proposed; + public $fk_recruitment_origin; // END MODULEBUILDER PROPERTIES From dde83c8fcc03bbb1f5ee09181197dd7fd88f8010 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 8 Aug 2020 10:17:52 +0200 Subject: [PATCH 323/434] Fix debian package --- build/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/debian/control b/build/debian/control index 0c010b6a478..0ef5367072f 100755 --- a/build/debian/control +++ b/build/debian/control @@ -14,7 +14,7 @@ Architecture: all Depends: libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm | php5 | libapache2-mod-php | libapache2-mod-phpfilter | php-cgi | php-fpm | php, php5-cli | php-cli, # Required PHP extensions - php5-mysql | php5-mysqli | php-mysql | php-mysqli, php5-curl | php-curl, php5-gd | php-gd, php5-ldap | php-gd, php5-zip | php-zip + php5-mysql | php5-mysqli | php-mysql | php-mysqli, php5-curl | php-curl, php5-gd | php-gd, php5-ldap | php-gd, php5-zip | php-zip, # Required PHP libraries php-pear, php-mail-mime, # php-tcpdf, From 6e01ffd5ac0ebfbbf0c47febfbe92bc2f1430592 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 8 Aug 2020 13:00:57 +0200 Subject: [PATCH 324/434] Prepare for 12.0.3 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 9d76057b367..94ecf930724 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (!defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE', 'Dolibarr'); -if (!defined('DOL_VERSION')) define('DOL_VERSION', '12.0.2'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (!defined('DOL_VERSION')) define('DOL_VERSION', '12.0.3'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (!defined('EURO')) define('EURO', chr(128)); From 5291746252e9e0ba9ae841d5f7a291831b9e0f86 Mon Sep 17 00:00:00 2001 From: asolslk <52134143+asolslk@users.noreply.github.com> Date: Sat, 8 Aug 2020 19:04:38 +0800 Subject: [PATCH 325/434] Update listbyaccount.php fixed #14408 --- htdocs/accountancy/bookkeeping/listbyaccount.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 1f4ac513806..8ff9abc52f7 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -543,7 +543,13 @@ while ($i < min($num, $limit)) // Show the break account print ""; - print ''; + if ($totalarray['nbfield']==""){ + print ''; + } + else + { + print ''; + } if ($line->numero_compte != "" && $line->numero_compte != '-1') print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte); else print ''.$langs->trans("Unknown").''; print ''; From d3cb704a0e4709bb293192dfcdfd12e755e1c260 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sat, 8 Aug 2020 11:05:19 +0000 Subject: [PATCH 326/434] Fixing style errors. --- htdocs/accountancy/bookkeeping/listbyaccount.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 8ff9abc52f7..bca2ab3a5a8 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -546,8 +546,7 @@ while ($i < min($num, $limit)) if ($totalarray['nbfield']==""){ print ''; } - else - { + else { print ''; } if ($line->numero_compte != "" && $line->numero_compte != '-1') print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte); From ea829913b0f3b490d599cd2bf33e1e0981b881ca Mon Sep 17 00:00:00 2001 From: asolslk <52134143+asolslk@users.noreply.github.com> Date: Sat, 8 Aug 2020 19:07:55 +0800 Subject: [PATCH 327/434] Update accounting.lib.php --- htdocs/core/lib/accounting.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index 317c639ad91..24ba8ced2e4 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -96,7 +96,7 @@ function length_accountg($account) if ($account < 0 || is_empty($account)) return ''; - if (!is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; + if (is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; $g = $conf->global->ACCOUNTING_LENGTH_GACCOUNT; if (!is_empty($g)) { @@ -131,7 +131,7 @@ function length_accounta($accounta) if ($accounta < 0 || is_empty($accounta)) return ''; - if (!is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $accounta; + if (is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $accounta; $a = $conf->global->ACCOUNTING_LENGTH_AACCOUNT; if (!is_empty($a)) { From 41bb83f10786054545566d309bdef69806ab6f70 Mon Sep 17 00:00:00 2001 From: asolslk <52134143+asolslk@users.noreply.github.com> Date: Sat, 8 Aug 2020 19:10:50 +0800 Subject: [PATCH 328/434] Update listbyaccount.php fixed #14221 --- htdocs/accountancy/bookkeeping/listbyaccount.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 1f4ac513806..763a7c0dd6c 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; // Load translation files required by the page @@ -78,6 +79,7 @@ if ($sortfield == "") $sortfield = "t.doc_date,t.rowid"; // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new BookKeeping($db); +$formfile = new FormFile($db); $hookmanager->initHooks(array('bookkeepingbyaccountlist')); $formaccounting = new FormAccounting($db); From f8557879fb2b882db101de701658283ab3d8cdd4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 8 Aug 2020 13:15:29 +0200 Subject: [PATCH 329/434] Update listbyaccount.php --- htdocs/accountancy/bookkeeping/listbyaccount.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index bca2ab3a5a8..0d8e3836b31 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -543,12 +543,7 @@ while ($i < min($num, $limit)) // Show the break account print ""; - if ($totalarray['nbfield']==""){ - print ''; - } - else { - print ''; - } + print ''; if ($line->numero_compte != "" && $line->numero_compte != '-1') print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte); else print ''.$langs->trans("Unknown").''; print ''; From cab9f6daae1026791f930bdba896b8944ba91aaf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 8 Aug 2020 13:22:55 +0200 Subject: [PATCH 330/434] Comment must be in english --- .../doc/pdf_standard.modules.php | 2 +- htdocs/fichinter/class/fichinterrec.class.php | 28 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php index 6d3bc5e8e65..3c0ae6890e3 100644 --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php @@ -381,7 +381,7 @@ class pdf_standard extends ModeleExpenseReport $pdf->setPage($pageposafter + 1); $showpricebeforepagebreak = 1; $nexY = $tab_top_newpage; - $nexY += ($pdf->getFontSize() * 1.3); // Passe espace entre les lignes + $nexY += ($pdf->getFontSize() * 1.3); // Add space between lines $pdf->SetFont('', '', $default_font_size - 2); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index 679d231d6a8..66475f83edf 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -197,8 +197,6 @@ class FichinterRec extends Fichinter */ $num = count($fichintsrc->lines); for ($i = 0; $i < $num; $i++) { - //$result=$fichintlignesrc->fetch($fichintsrc->lines[$i]->id); - //var_dump($fichintsrc->lines[$i]); $result_insert = $this->addline( $fichintsrc->lines[$i]->desc, @@ -243,7 +241,7 @@ class FichinterRec extends Fichinter /** - * Recupere l'objet facture et ses lignes de factures + * Get the template of intervention object and lines * * @param int $rowid Id of object to load * @param string $ref Reference of fichinter @@ -295,9 +293,7 @@ class FichinterRec extends Fichinter $this->brouillon = 1; - /* - * Lines - */ + // Lines $result = $this->fetch_lines(); if ($result < 0) { $this->error = $this->db->error(); @@ -318,9 +314,9 @@ class FichinterRec extends Fichinter // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Recupere les lignes de factures predefinies dans this->lines - * @param int $sall sall + * Load all lines of template of intervention into this->lines * + * @param int $sall sall * @return int 1 if OK, < 0 if KO */ public function fetch_lines($sall = 0) @@ -441,15 +437,15 @@ class FichinterRec extends Fichinter * @param integer $duration Durée * @param string $datei Date * @param int $rang Position of line - * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) - * @param double $qty Quantite - * @param double $txtva Taux de tva force, sinon -1 - * @param int $fk_product Id du produit/service predefini - * @param double $remise_percent Pourcentage de remise de la ligne + * @param double $pu_ht Unit price without tax (> 0 even for credit note) + * @param double $qty Quantity + * @param double $txtva Forced VAT rate, otherwise -1 + * @param int $fk_product Id of predefined product/service + * @param double $remise_percent Percentage of discount on line * @param string $price_base_type HT or TTC - * @param int $info_bits Bits de type de lignes - * @param int $fk_remise_except Id remise - * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) + * @param int $info_bits Bits for type of lines + * @param int $fk_remise_except Id discount + * @param double $pu_ttc Unit price with tax (> 0 even for credit note) * @param int $type Type of line (0=product, 1=service) * @param int $special_code Special code * @param string $label Label of the line From f35893ceb4f465a474cb4e0b00d7182c35dcefbd Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 8 Aug 2020 15:12:29 +0200 Subject: [PATCH 331/434] fix deprecated --- .../doc/pdf_muscadet.modules.php | 58 +++++++++---------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php index aa6238f84a8..206935e7323 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php @@ -717,13 +717,12 @@ class pdf_muscadet extends ModelePDFSuppliersOrders */ protected function _tableau_info(&$pdf, $object, $posy, $outputlangs) { - // phpcs:enable - global $conf, $mysoc; - $default_font_size = pdf_getPDFFontSize($outputlangs); + // phpcs:enable + global $conf, $mysoc; + $default_font_size = pdf_getPDFFontSize($outputlangs); - // If France, show VAT mention if not applicable - if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) - { + // If France, show VAT mention if not applicable + if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) { $pdf->SetFont('', 'B', $default_font_size - 2); $pdf->SetXY($this->marge_gauche, $posy); $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); @@ -733,39 +732,36 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $posxval = 52; - // Show payments conditions - if (!empty($object->cond_reglement_code) || $object->cond_reglement) - { - $pdf->SetFont('', 'B', $default_font_size - 2); - $pdf->SetXY($this->marge_gauche, $posy); - $titre = $outputlangs->transnoentities("PaymentConditions").':'; - $pdf->MultiCell(80, 4, $titre, 0, 'L'); + // Show payments conditions + if (!empty($object->cond_reglement_code) || $object->cond_reglement_id) { + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentConditions") . ':'; + $pdf->MultiCell(80, 4, $titre, 0, 'L'); $pdf->SetFont('', '', $default_font_size - 2); $pdf->SetXY($posxval, $posy); - $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) != ('PaymentCondition'.$object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement); + $lib_condition_paiement = $outputlangs->transnoentities("PaymentCondition" . $object->cond_reglement_code) != ('PaymentCondition' . $object->cond_reglement_code) ? $outputlangs->transnoentities("PaymentCondition" . $object->cond_reglement_code) : $outputlangs->convToOutputCharset($object->cond_reglement_id); $lib_condition_paiement = str_replace('\n', "\n", $lib_condition_paiement); $pdf->MultiCell(80, 4, $lib_condition_paiement, 0, 'L'); - $posy = $pdf->GetY() + 3; - } + $posy = $pdf->GetY() + 3; + } - // Show payment mode - if (!empty($object->mode_reglement_code)) - { - $pdf->SetFont('', 'B', $default_font_size - 2); - $pdf->SetXY($this->marge_gauche, $posy); - $titre = $outputlangs->transnoentities("PaymentMode").':'; - $pdf->MultiCell(80, 5, $titre, 0, 'L'); + // Show payment mode + if (!empty($object->mode_reglement_code)) { + $pdf->SetFont('', 'B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentMode") . ':'; + $pdf->MultiCell(80, 5, $titre, 0, 'L'); - $pdf->SetFont('', '', $default_font_size - 2); - $pdf->SetXY($posxval, $posy); - $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement); - $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L'); - - $posy = $pdf->GetY() + 2; - } + $pdf->SetFont('', '', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_mode_reg = $outputlangs->transnoentities("PaymentType" . $object->mode_reglement_code) != ('PaymentType' . $object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType" . $object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement); + $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L'); + $posy = $pdf->GetY() + 2; + } return $posy; } @@ -1174,7 +1170,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $pdf->SetXY($posx, $posy); $langs->load("projects"); $pdf->SetTextColor(0, 0, 60); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->ref) ? '' : $object->project->ref), '', 'R'); } } From fe24c2f8b8da65c2e83e6061d2945bc14a28dea0 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 8 Aug 2020 15:29:53 +0200 Subject: [PATCH 332/434] fix undefined variable --- .../supplier_proposal/doc/pdf_aurore.modules.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index e503f3cee56..e44be9f1bb3 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -707,7 +707,7 @@ class pdf_aurore extends ModelePDFSupplierProposal /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param TCPDF &$pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -746,7 +746,7 @@ class pdf_aurore extends ModelePDFSupplierProposal $pdf->SetFont('', '', $default_font_size - 2); $pdf->SetXY($posxval, $posy); //$dlp=dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true); - $pdf->MultiCell(80, 4, $dlp, 0, 'L'); + $pdf->MultiCell(80, 4, '', 0, 'L'); $posy = $pdf->GetY() + 1; } @@ -1093,13 +1093,10 @@ class pdf_aurore extends ModelePDFSupplierProposal $pdf->SetTextColor(0, 0, 0); - /* $resteapayer = $object->total_ttc - $deja_regle; - if (! empty($object->paye)) $resteapayer=0; - */ + if (!empty($object->paye)) $resteapayer = 0; - if ($deja_regle > 0) - { + if ($deja_regle > 0) { $index++; $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); From e7bea7c5ce8b629a7c3547bb015f381fd1d49535 Mon Sep 17 00:00:00 2001 From: Philippe Grand Date: Sat, 8 Aug 2020 15:34:38 +0200 Subject: [PATCH 333/434] Update pdf_cyan.modules.php --- htdocs/core/modules/propale/doc/pdf_cyan.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index cdb084aa861..e023465d8e3 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -1753,7 +1753,7 @@ class pdf_cyan extends ModelePDFPropales /** * Show area for the customer to sign * - * @param TCPDF &$pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Facture $object Object invoice * @param int $posy Position depart * @param Translate $outputlangs Objet langs From bb16564b982636ae5e54ddcf579702441661804b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 8 Aug 2020 22:08:46 +0200 Subject: [PATCH 334/434] NEW triggers create, modify, delete Also modified deleteByFkAttribute() to use the function delete() --- .../class/ProductAttributeValue.class.php | 99 ++++++++++++++----- 1 file changed, 75 insertions(+), 24 deletions(-) diff --git a/htdocs/variants/class/ProductAttributeValue.class.php b/htdocs/variants/class/ProductAttributeValue.class.php index 0a26b3eace2..2c48a6ce7ce 100644 --- a/htdocs/variants/class/ProductAttributeValue.class.php +++ b/htdocs/variants/class/ProductAttributeValue.class.php @@ -16,17 +16,18 @@ * along with this program. If not, see . */ +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; /** * Class ProductAttributeValue * Used to represent a product attribute value */ -class ProductAttributeValue +class ProductAttributeValue extends CommonObject { /** * Database handler * @var DoliDB */ - private $db; + public $db; /** * Attribute value id @@ -144,14 +145,24 @@ class ProductAttributeValue /** * Creates a value for a product attribute * - * @param User $user Object user - * @return int <0 KO >0 OK + * @param User $user Object user + * @param int $notrigger Do not execute trigger + * @return int <0 KO >0 OK */ - public function create(User $user) + public function create(User $user, $notrigger = 0) { if (!$this->fk_product_attribute) { return -1; } + + if (empty($notrigger)) { + // Call trigger + $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_CREATE', $user); + if ($result < 0) { + return -1; + } + // End call triggers + } // Ref must be uppercase $this->ref = strtoupper($this->ref); @@ -173,11 +184,21 @@ class ProductAttributeValue /** * Updates a product attribute value * - * @param User $user Object user - * @return int <0 if KO, >0 if OK + * @param User $user Object user + * @param int $notrigger Do not execute trigger + * @return int <0 if KO, >0 if OK */ - public function update(User $user) + public function update(User $user, $notrigger = 0) { + if (empty($notrigger)) { + // Call trigger + $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_MODIFY', $user); + if ($result < 0) { + return -1; + } + // End call triggers + } + //Ref must be uppercase $this->ref = trim(strtoupper($this->ref)); $this->value = trim($this->value); @@ -196,33 +217,63 @@ class ProductAttributeValue /** * Deletes a product attribute value * + * @param User $user Object user + * @param int $notrigger Do not execute trigger * @return int <0 KO, >0 OK */ - public function delete() + public function delete(User $user, $notrigger = 0) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $this->id; - - if ($this->db->query($sql)) { - return 1; - } - - return -1; + if (empty($notrigger)) { + // Call trigger + $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user); + if ($result < 0) { + return -1; + } + // End call triggers + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $this->id; + + if ($this->db->query($sql)) { + return 1; + } + + return -1; } /** * Deletes all product attribute values by a product attribute id * * @param int $fk_attribute Product attribute id + * @param int $notrigger Do not execute trigger * @return int <0 KO, >0 OK */ - public function deleteByFkAttribute($fk_attribute) + public function deleteByFkAttribute($fk_attribute, User $user) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE fk_product_attribute = ".(int) $fk_attribute; - - if ($this->db->query($sql)) { - return 1; - } - - return -1; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE fk_product_attribute = ".(int) $fk_attribute; + + $query = $this->db->query($sql); + + if (!$query) { + return -1; + } + + if (!$this->db->num_rows($query)) { + return 1; + } + + while ($obj = $this->db->fetch_object($query)) { + $tmp = new ProductAttributeValue($this->db); + if ($tmp->fetch($obj->rowid) > 0) { + $result = $tmp->delete($user); + if ($result < 0) { + return -1; + } + } else { + return -1; + } + } + + return 1; } } From e73a7c78f768c64ec0d46bfcae86349e96ab07f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 8 Aug 2020 22:10:50 +0200 Subject: [PATCH 335/434] NEW triggers create, modify, delete --- .../variants/class/ProductAttribute.class.php | 52 +++++++++++++++---- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/htdocs/variants/class/ProductAttribute.class.php b/htdocs/variants/class/ProductAttribute.class.php index 36b4823b51b..6d9fadf0101 100644 --- a/htdocs/variants/class/ProductAttribute.class.php +++ b/htdocs/variants/class/ProductAttribute.class.php @@ -16,17 +16,18 @@ * along with this program. If not, see . */ +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; /** * Class ProductAttribute * Used to represent a product attribute */ -class ProductAttribute +class ProductAttribute extends CommonObject { /** * Database handler * @var DoliDB */ - private $db; + public $db; /** * Id of the product attribute @@ -119,7 +120,8 @@ class ProductAttribute $return[] = $tmp; } - } else dol_print_error($this->db); + } + else dol_print_error($this->db); return $return; } @@ -127,11 +129,21 @@ class ProductAttribute /** * Creates a product attribute * - * @param User $user Object user that create + * @param User $user Object user + * @param int $notrigger Do not execute trigger * @return int <0 KO, Id of new variant if OK */ - public function create(User $user) + public function create(User $user, $notrigger = 0) { + if (empty($notrigger)) { + // Call trigger + $result = $this->call_trigger('PRODUCT_ATTRIBUTE_CREATE', $user); + if ($result < 0) { + return -1; + } + // End call triggers + } + //Ref must be uppercase $this->ref = strtoupper($this->ref); @@ -152,11 +164,21 @@ class ProductAttribute /** * Updates a product attribute * - * @param User $user Object user + * @param User $user Object user + * @param int $notrigger Do not execute trigger * @return int <0 KO, >0 OK */ - public function update(User $user) + public function update(User $user, $notrigger = 0) { + if (empty($notrigger)) { + // Call trigger + $result = $this->call_trigger('PRODUCT_ATTRIBUTE_MODIFY', $user); + if ($result < 0) { + return -1; + } + // End call triggers + } + //Ref must be uppercase $this->ref = trim(strtoupper($this->ref)); $this->label = trim($this->label); @@ -173,11 +195,21 @@ class ProductAttribute /** * Deletes a product attribute * - * @param User $user Object user - * @return int <0 KO, >0 OK + * @param User $user Object user + * @param int $notrigger Do not execute trigger + * @return int <0 KO, >0 OK */ - public function delete($user = null) + public function delete(User $user, $notrigger = 0) { + if (empty($notrigger)) { + // Call trigger + $result = $this->call_trigger('PRODUCT_ATTRIBUTE_DELETE', $user); + if ($result < 0) { + return -1; + } + // End call triggers + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute WHERE rowid = ".(int) $this->id; if ($this->db->query($sql)) { From ef57bb7e842d804c66052eca42388f9498d8a25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 8 Aug 2020 22:14:53 +0200 Subject: [PATCH 336/434] pass $user to delete functions --- htdocs/variants/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/variants/card.php b/htdocs/variants/card.php index 0669964ba57..6d077e85ad1 100644 --- a/htdocs/variants/card.php +++ b/htdocs/variants/card.php @@ -90,9 +90,9 @@ if ($confirm == 'yes') { if ($action == 'confirm_delete') { $db->begin(); - $res = $objectval->deleteByFkAttribute($object->id); + $res = $objectval->deleteByFkAttribute($object->id, $user); - if ($res < 1 || ($object->delete() < 1)) { + if ($res < 1 || ($object->delete($user) < 1)) { $db->rollback(); setEventMessages($langs->trans('CoreErrorMessage'), $object->errors, 'errors'); header('Location: '.dol_buildpath('/variants/card.php?id='.$object->id, 2)); @@ -105,7 +105,7 @@ if ($confirm == 'yes') { } elseif ($action == 'confirm_deletevalue') { if ($objectval->fetch($valueid) > 0) { - if ($objectval->delete() < 1) { + if ($objectval->delete($user) < 1) { setEventMessages($langs->trans('CoreErrorMessage'), $objectval->errors, 'errors'); } else { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); From ed1a2cd917e8c9722889fabd7f3c0483344d7031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 8 Aug 2020 22:45:51 +0200 Subject: [PATCH 337/434] Update 1 --- .../class/ProductAttributeValue.class.php | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/htdocs/variants/class/ProductAttributeValue.class.php b/htdocs/variants/class/ProductAttributeValue.class.php index 2c48a6ce7ce..c655e188c5d 100644 --- a/htdocs/variants/class/ProductAttributeValue.class.php +++ b/htdocs/variants/class/ProductAttributeValue.class.php @@ -154,27 +154,28 @@ class ProductAttributeValue extends CommonObject if (!$this->fk_product_attribute) { return -1; } - - if (empty($notrigger)) { - // Call trigger - $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_CREATE', $user); - if ($result < 0) { - return -1; - } - // End call triggers - } // Ref must be uppercase $this->ref = strtoupper($this->ref); + $this->value = $this->db->escape($this->value); $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_value (fk_product_attribute, ref, value, entity) VALUES ('".(int) $this->fk_product_attribute."', '".$this->db->escape($this->ref)."', - '".$this->db->escape($this->value)."', ".(int) $this->entity.")"; + '".$this->value."', ".(int) $this->entity.")"; $query = $this->db->query($sql); if ($query) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_value'); + if (empty($notrigger)) { + // Call trigger + $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_CREATE', $user); + if ($result < 0) { + return -1; + } + // End call triggers + } + return 1; } @@ -223,6 +224,7 @@ class ProductAttributeValue extends CommonObject */ public function delete(User $user, $notrigger = 0) { + if (empty($notrigger)) { // Call trigger $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user); @@ -231,9 +233,7 @@ class ProductAttributeValue extends CommonObject } // End call triggers } - $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $this->id; - if ($this->db->query($sql)) { return 1; } From 9b00a1f61a873438eab5e91c3587fdc85e6c6e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 8 Aug 2020 22:48:21 +0200 Subject: [PATCH 338/434] Some updates for attributes triggers --- htdocs/product/class/api_products.class.php | 630 ++++++++++---------- 1 file changed, 322 insertions(+), 308 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 89c9a78ddaa..a63709b5c4b 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -41,17 +41,17 @@ class Products extends DolibarrApi 'ref', 'label' ); - + /** * @var Product $product {@type Product} */ public $product; - + /** * @var ProductFournisseur $productsupplier {@type ProductFournisseur} */ public $productsupplier; - + /** * Constructor */ @@ -62,7 +62,7 @@ class Products extends DolibarrApi $this->product = new Product($this->db); $this->productsupplier = new ProductFournisseur($this->db); } - + /** * Get properties of a product object by id * @@ -81,7 +81,7 @@ class Products extends DolibarrApi { return $this->_fetch($id, '', '', '', $includestockdata, $includesubproducts); } - + /** * Get properties of a product object by ref * @@ -103,7 +103,7 @@ class Products extends DolibarrApi { return $this->_fetch('', $ref, '', '', $includestockdata, $includesubproducts); } - + /** * Get properties of a product object by ref_ext * @@ -125,7 +125,7 @@ class Products extends DolibarrApi { return $this->_fetch('', '', $ref_ext, '', $includestockdata, $includesubproducts); } - + /** * Get properties of a product object by barcode * @@ -147,7 +147,7 @@ class Products extends DolibarrApi { return $this->_fetch('', '', '', $barcode, $includestockdata, $includesubproducts); } - + /** * List products * @@ -165,11 +165,11 @@ class Products extends DolibarrApi public function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '') { global $db, $conf; - + $obj_ret = array(); - + $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; - + $sql = "SELECT t.rowid, t.ref, t.ref_ext"; $sql .= " FROM ".MAIN_DB_PREFIX."product as t"; if ($category > 0) { @@ -196,17 +196,17 @@ class Products extends DolibarrApi $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql .= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) { $page = 0; } $offset = $limit * $page; - + $sql .= $db->plimit($limit + 1, $offset); } - + $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); @@ -229,7 +229,7 @@ class Products extends DolibarrApi } return $obj_ret; } - + /** * Create product object * @@ -243,17 +243,17 @@ class Products extends DolibarrApi } // Check mandatory fields $result = $this->_validate($request_data); - + foreach ($request_data as $field => $value) { $this->product->$field = $value; } if ($this->product->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating product", array_merge(array($this->product->error), $this->product->errors)); } - + return $this->product->id; } - + /** * Update product. * Price will be updated by this API only if option is set on "One price per product". See other APIs for other price modes. @@ -268,38 +268,38 @@ class Products extends DolibarrApi public function put($id, $request_data = null) { global $conf; - + if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $result = $this->product->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $oldproduct = dol_clone($this->product, 0); - + foreach ($request_data as $field => $value) { if ($field == 'id') { continue; } - if ($field == 'stock_reel') { - throw new RestException(400, 'Stock reel cannot be updated here. Use the /stockmovements endpoint instead'); + if ($field == 'stock_reel') { + throw new RestException(400, 'Stock reel cannot be updated here. Use the /stockmovements endpoint instead'); } $this->product->$field = $value; } - + $updatetype = false; if ($this->product->type != $oldproduct->type && ($this->product->isProduct() || $this->product->isService())) { $updatetype = true; } - + $result = $this->product->update($id, DolibarrApiAccess::$user, 1, 'update', $updatetype); - + // If price mode is 1 price per product if ($result > 0 && !empty($conf->global->PRODUCT_PRICE_UNIQ)) { // We update price only if it was changed @@ -312,7 +312,7 @@ class Products extends DolibarrApi } if ($this->product->default_vat_code != $oldproduct->default_vat_code) { $pricemodified = true; } - + if ($this->product->price_base_type == 'TTC') { if ($this->product->price_ttc != $oldproduct->price_ttc) { $pricemodified = true; } @@ -325,30 +325,30 @@ class Products extends DolibarrApi } } } - + if ($pricemodified) { $newvat = $this->product->tva_tx; $newnpr = $this->product->tva_npr; $newvatsrccode = $this->product->default_vat_code; - + $newprice = $this->product->price; $newpricemin = $this->product->price_min; if ($this->product->price_base_type == 'TTC') { $newprice = $this->product->price_ttc; $newpricemin = $this->product->price_min_ttc; } - + $result = $this->product->updatePrice($newprice, $this->product->price_base_type, DolibarrApiAccess::$user, $newvat, $newpricemin, 0, $newnpr, 0, 0, array(), $newvatsrccode); } } - + if ($result <= 0) { throw new RestException(500, "Error updating product", array_merge(array($this->product->error), $this->product->errors)); } - + return $this->get($id); } - + /** * Delete product * @@ -364,18 +364,18 @@ class Products extends DolibarrApi if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + // The Product::delete() method uses the global variable $user. global $user; $user = DolibarrApiAccess::$user; - + return $this->product->delete(DolibarrApiAccess::$user); } - + /** * Get the list of subproducts of the product. * @@ -393,22 +393,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if (!DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $childsArbo = $this->product->getChildsArbo($id, 1); - + $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; $childs = []; foreach ($childsArbo as $values) { $childs[] = array_combine($keys, $values); } - + return $childs; } - + /** * Add subproduct. * @@ -431,18 +431,18 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (!DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->product->add_sousproduit($id, $subproduct_id, $qty, $incdec); if ($result <= 0) { throw new RestException(500, "Error adding product child"); } return $result; } - + /** * Remove subproduct. * @@ -462,19 +462,19 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (!DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->product->del_sousproduit($id, $subproduct_id); if ($result <= 0) { throw new RestException(500, "Error while removing product child"); } return $result; } - - + + /** * Get categories for a product * @@ -493,22 +493,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->categorie->lire) { throw new RestException(401); } - + $categories = new Categorie($this->db); - + $result = $categories->getListForItem($id, 'product', $sortfield, $sortorder, $limit, $page); - + if (empty($result)) { throw new RestException(404, 'No category found'); } - + if ($result < 0) { throw new RestException(503, 'Error when retrieve category list : '.array_merge(array($categories->error), $categories->errors)); } - + return $result; } - + /** * Get prices per segment for a product * @@ -521,24 +521,24 @@ class Products extends DolibarrApi public function getCustomerPricesPerSegment($id) { global $conf; - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if (empty($conf->global->PRODUIT_MULTIPRICES)) { throw new RestException(400, 'API not available: this mode of pricing is not enabled by setup'); } - + $result = $this->product->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if ($result < 0) { throw new RestException(503, 'Error when retrieve prices list : '.array_merge(array($this->product->error), $this->product->errors)); } - + return array( 'multiprices'=>$this->product->multiprices, 'multiprices_inc_tax'=>$this->product->multiprices_ttc, @@ -549,7 +549,7 @@ class Products extends DolibarrApi //'multiprices_default_vat_code'=>$this->product->multiprices_default_vat_code ); } - + /** * Get prices per customer for a product * @@ -563,36 +563,36 @@ class Products extends DolibarrApi public function getCustomerPricesPerCustomer($id, $thirdparty_id = '') { global $conf; - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if (empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { throw new RestException(400, 'API not available: this mode of pricing is not enabled by setup'); } - + $result = $this->product->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if ($result > 0) { - require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php'; - $prodcustprice = new Productcustomerprice($this->db); - $filter = array(); - $filter['t.fk_product'] .= $id; - if ($thirdparty_id) $filter['t.fk_soc'] .= $thirdparty_id; - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php'; + $prodcustprice = new Productcustomerprice($this->db); + $filter = array(); + $filter['t.fk_product'] .= $id; + if ($thirdparty_id) $filter['t.fk_soc'] .= $thirdparty_id; + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); } - + if (empty($prodcustprice->lines)) { throw new RestException(404, 'Prices not found'); } - + return $prodcustprice->lines; } - + /** * Get prices per quantity for a product * @@ -605,30 +605,30 @@ class Products extends DolibarrApi public function getCustomerPricesPerQuantity($id) { global $conf; - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if (empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) { throw new RestException(400, 'API not available: this mode of pricing is not enabled by setup'); } - + $result = $this->product->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if ($result < 0) { throw new RestException(503, 'Error when retrieve prices list : '.array_merge(array($this->product->error), $this->product->errors)); } - + return array( - 'prices_by_qty'=>$this->product->prices_by_qty[0], // 1 if price by quantity was activated for the product - 'prices_by_qty_list'=>$this->product->prices_by_qty_list[0] + 'prices_by_qty'=>$this->product->prices_by_qty[0], // 1 if price by quantity was activated for the product + 'prices_by_qty_list'=>$this->product->prices_by_qty_list[0] ); } - + /** * Add/Update purchase prices for a product. * @@ -641,11 +641,11 @@ class Products extends DolibarrApi * @param string $ref_fourn Supplier ref * @param float $tva_tx New VAT Rate (For example 8.5. Should not be a string) * @param string $charges costs affering to product - * @param float $remise_percent Discount regarding qty (percent) - * @param float $remise Discount regarding qty (amount) - * @param int $newnpr Set NPR or not - * @param int $delivery_time_days Delay in days for delivery (max). May be '' if not defined. - * @param string $supplier_reputation Reputation with this product to the defined supplier (empty, FAVORITE, DONOTORDER) + * @param float $remise_percent Discount regarding qty (percent) + * @param float $remise Discount regarding qty (amount) + * @param int $newnpr Set NPR or not + * @param int $delivery_time_days Delay in days for delivery (max). May be '' if not defined. + * @param string $supplier_reputation Reputation with this product to the defined supplier (empty, FAVORITE, DONOTORDER) * @param array $localtaxes_array Array with localtaxes info array('0'=>type1,'1'=>rate1,'2'=>type2,'3'=>rate2) (loaded by getLocalTaxesFromRate(vatrate, 0, ...) function). * @param string $newdefaultvatcode Default vat code * @param float $multicurrency_buyprice Purchase price for the quantity min in currency @@ -667,35 +667,35 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $result = $this->productsupplier->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->productsupplier->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->productsupplier->add_fournisseur(DolibarrApiAccess::$user, $fourn_id, $ref_fourn, $qty); if ($result < 0) { throw new RestException(500, "Error adding supplier to product : ".$this->db->lasterror()); } - + $fourn = new Fournisseur($this->db); $result = $fourn->fetch($fourn_id); if ($result <= 0) { throw new RestException(404, 'Supplier not found'); } - + $result = $this->productsupplier->update_buyprice($qty, $buyprice, DolibarrApiAccess::$user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges, $remise_percent, $remise, $newnpr, $delivery_time_days, $supplier_reputation, $localtaxes_array, $newdefaultvatcode, $multicurrency_buyprice, $multicurrency_price_base_type, $multicurrency_tx, $multicurrency_code, $desc_fourn, $barcode, $fk_barcode_type); - + if ($result <= 0) { throw new RestException(500, "Error updating buy price : ".$this->db->lasterror()); } return (int) $this->productsupplier->product_fourn_price_id; } - + /** * Delete purchase price for a product * @@ -719,19 +719,19 @@ class Products extends DolibarrApi if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->productsupplier->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $resultsupplier = 0; if ($result > 0) { $resultsupplier = $this->productsupplier->remove_product_fournisseur_price($priceid); } - + return $resultsupplier; } - + /** * Get a list of all purchase prices of products * @@ -749,79 +749,79 @@ class Products extends DolibarrApi */ public function getSupplierProducts($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $supplier = 0, $sqlfilters = '') { - global $db, $conf; - $obj_ret = array(); - $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; - $sql = "SELECT t.rowid, t.ref, t.ref_ext"; - $sql .= " FROM ".MAIN_DB_PREFIX."product as t"; - if ($category > 0) { - $sql .= ", ".MAIN_DB_PREFIX."categorie_product as c"; - } - $sql .= ", ".MAIN_DB_PREFIX."product_fournisseur_price as s"; - - $sql .= ' WHERE t.entity IN ('.getEntity('product').')'; - - if ($supplier > 0) { - $sql .= " AND s.fk_soc = ".$db->escape($supplier); - } - $sql .= " AND s.fk_product = t.rowid"; - // Select products of given category - if ($category > 0) { - $sql .= " AND c.fk_categorie = ".$db->escape($category); - $sql .= " AND c.fk_product = t.rowid"; - } - if ($mode == 1) { - // Show only products - $sql .= " AND t.fk_product_type = 0"; - } elseif ($mode == 2) { - // Show only services - $sql .= " AND t.fk_product_type = 1"; - } - // Add sql filters - if ($sqlfilters) { - if (!DolibarrApi::_checkFilters($sqlfilters)) { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - $sql .= $db->order($sortfield, $sortorder); - if ($limit) { - if ($page < 0) { - $page = 0; - } - $offset = $limit * $page; - $sql .= $db->plimit($limit + 1, $offset); - } - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - $i = 0; - while ($i < $min) - { - $obj = $db->fetch_object($result); - - $product_fourn = new ProductFournisseur($this->db); - $product_fourn_list = $product_fourn->list_product_fournisseur_price($obj->rowid, '', '', 0, 0); - foreach ($product_fourn_list as $tmpobj) { - $this->_cleanObjectDatas($tmpobj); - } - - //var_dump($product_fourn_list->db);exit; - $obj_ret[$obj->rowid] = $product_fourn_list; - - $i++; - } - } else { - throw new RestException(503, 'Error when retrieve product list : '.$db->lasterror()); - } - if (!count($obj_ret)) { - throw new RestException(404, 'No product found'); - } - return $obj_ret; + global $db, $conf; + $obj_ret = array(); + $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; + $sql = "SELECT t.rowid, t.ref, t.ref_ext"; + $sql .= " FROM ".MAIN_DB_PREFIX."product as t"; + if ($category > 0) { + $sql .= ", ".MAIN_DB_PREFIX."categorie_product as c"; + } + $sql .= ", ".MAIN_DB_PREFIX."product_fournisseur_price as s"; + + $sql .= ' WHERE t.entity IN ('.getEntity('product').')'; + + if ($supplier > 0) { + $sql .= " AND s.fk_soc = ".$db->escape($supplier); + } + $sql .= " AND s.fk_product = t.rowid"; + // Select products of given category + if ($category > 0) { + $sql .= " AND c.fk_categorie = ".$db->escape($category); + $sql .= " AND c.fk_product = t.rowid"; + } + if ($mode == 1) { + // Show only products + $sql .= " AND t.fk_product_type = 0"; + } elseif ($mode == 2) { + // Show only services + $sql .= " AND t.fk_product_type = 1"; + } + // Add sql filters + if ($sqlfilters) { + if (!DolibarrApi::_checkFilters($sqlfilters)) { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + $sql .= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + $sql .= $db->plimit($limit + 1, $offset); + } + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + $i = 0; + while ($i < $min) + { + $obj = $db->fetch_object($result); + + $product_fourn = new ProductFournisseur($this->db); + $product_fourn_list = $product_fourn->list_product_fournisseur_price($obj->rowid, '', '', 0, 0); + foreach ($product_fourn_list as $tmpobj) { + $this->_cleanObjectDatas($tmpobj); + } + + //var_dump($product_fourn_list->db);exit; + $obj_ret[$obj->rowid] = $product_fourn_list; + + $i++; + } + } else { + throw new RestException(503, 'Error when retrieve product list : '.$db->lasterror()); + } + if (!count($obj_ret)) { + throw new RestException(404, 'No product found'); + } + return $obj_ret; } - + /** * Get purchase prices for a product * @@ -846,36 +846,36 @@ class Products extends DolibarrApi if (empty($id) && empty($ref) && empty($ref_ext) && empty($barcode)) { throw new RestException(400, 'bad value for parameter id, ref, ref_ext or barcode'); } - + $id = (empty($id) ? 0 : $id); - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } - + $result = $this->product->fetch($id, $ref, $ref_ext, $barcode); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $product_fourn_list = array(); - + if ($result) { $product_fourn = new ProductFournisseur($this->db); $product_fourn_list = $product_fourn->list_product_fournisseur_price($this->product->id, '', '', 0, 0); } - + foreach ($product_fourn_list as $tmpobj) { $this->_cleanObjectDatas($tmpobj); } - + return $this->_cleanObjectDatas($product_fourn_list); } - + /** * Get attributes. * @@ -890,11 +890,11 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); return $prodattr->fetchAll(); } - + /** * Get attribute by ID. * @@ -912,17 +912,17 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $result = $prodattr->fetch((int) $id); - + if ($result < 0) { throw new RestException(404, "Attribute not found"); } - + return $prodattr; } - + /** * Get attributes by ref. * @@ -939,26 +939,26 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, ref, label, rang FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '".trim($ref)."' AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$this->db->num_rows($query)) { throw new RestException(404); } - + $result = $this->db->fetch_object($query); - + $attr = []; $attr['id'] = $result->rowid; $attr['ref'] = $result->ref; $attr['label'] = $result->label; $attr['rang'] = $result->rang; - + return $attr; } - + /** * Add attributes. * @@ -976,18 +976,18 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $prodattr->label = $label; $prodattr->ref = $ref; - + $resid = $prodattr->create(DolibarrApiAccess::$user); if ($resid <= 0) { throw new RestException(500, "Error creating new attribute"); } return $resid; } - + /** * Update attributes by id. * @@ -1006,22 +1006,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); - + $result = $prodattr->fetch((int) $id); if ($result == 0) { throw new RestException(404, 'Attribute not found'); } elseif ($result < 0) { throw new RestException(500, "Error fetching attribute"); } - + foreach ($request_data as $field => $value) { if ($field == 'rowid') { continue; } $prodattr->$field = $value; } - + if ($prodattr->update(DolibarrApiAccess::$user) > 0) { $result = $prodattr->fetch((int) $id); if ($result == 0) { @@ -1034,7 +1034,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error updating attribute"); } - + /** * Delete attributes by id. * @@ -1051,18 +1051,18 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $prodattr->id = (int) $id; $result = $prodattr->delete(DolibarrApiAccess::$user); - + if ($result <= 0) { - throw new RestException(500, "Error deleting attribute"); + throw new RestException(500, "Error deleting attribute"); } - + return $result; } - + /** * Get attribute value by id. * @@ -1079,30 +1079,30 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, fk_product_attribute, ref, value FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $id." AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$query) { throw new RestException(401); } - + if (!$this->db->num_rows($query)) { throw new RestException(404, 'Attribute value not found'); } - + $result = $this->db->fetch_object($query); - + $attrval = []; $attrval['id'] = $result->rowid; $attrval['fk_product_attribute'] = $result->fk_product_attribute; $attrval['ref'] = $result->ref; $attrval['value'] = $result->value; - + return $attrval; } - + /** * Get attribute value by ref. * @@ -1120,30 +1120,30 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, fk_product_attribute, ref, value FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '".trim($ref)."' AND fk_product_attribute = ".(int) $id." AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$query) { throw new RestException(401); } - + if (!$this->db->num_rows($query)) { throw new RestException(404, 'Attribute value not found'); } - + $result = $this->db->fetch_object($query); - + $attrval = []; $attrval['id'] = $result->rowid; $attrval['fk_product_attribute'] = $result->fk_product_attribute; $attrval['ref'] = $result->ref; $attrval['value'] = $result->value; - + return $attrval; } - + /** * Delete attribute value by ref. * @@ -1160,16 +1160,30 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '".trim($ref)."' AND fk_product_attribute = ".(int) $id; - - if ($this->db->query($sql)) { + + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '".trim($ref)."' AND fk_product_attribute = ".(int) $id." AND entity IN (".getEntity('product').")"; + $query = $this->db->query($sql); + + if (!$query) { + throw new RestException(401); + } + + if (!$this->db->num_rows($query)) { + throw new RestException(404, 'Attribute value not found'); + } + + $result = $this->db->fetch_object($query); + + $attrval = new ProductAttributeValue($this->db); + $attrval->id = $result->rowid; + $result = $attrval->delete(DolibarrApiAccess::$user); + if ($result > 0) { return 1; } - + throw new RestException(500, "Error deleting attribute value"); } - + /** * Get all values for an attribute id. * @@ -1186,11 +1200,11 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); return $objectval->fetchAllByProductAttribute((int) $id); } - + /** * Get all values for an attribute ref. * @@ -1206,28 +1220,28 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $return = array(); - + $sql = 'SELECT '; $sql .= 'v.fk_product_attribute, v.rowid, v.ref, v.value FROM '.MAIN_DB_PREFIX.'product_attribute_value v '; $sql .= "WHERE v.fk_product_attribute = ( SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '".strtoupper(trim($ref))."' LIMIT 1)"; - + $query = $this->db->query($sql); - + while ($result = $this->db->fetch_object($query)) { $tmp = new ProductAttributeValue($this->db); $tmp->fk_product_attribute = $result->fk_product_attribute; $tmp->id = $result->rowid; $tmp->ref = $result->ref; $tmp->value = $result->value; - + $return[] = $tmp; } - + return $return; } - + /** * Add attribute value. * @@ -1246,22 +1260,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (empty($ref) || empty($value)) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $objectval->fk_product_attribute = $id; $objectval->ref = $ref; $objectval->value = $value; - + if ($objectval->create(DolibarrApiAccess::$user) > 0) { return $objectval->id; } throw new RestException(500, "Error creating new attribute value"); } - + /** * Update attribute value. * @@ -1279,22 +1293,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $result = $objectval->fetch((int) $id); - + if ($result == 0) { throw new RestException(404, 'Attribute value not found'); } elseif ($result < 0) { throw new RestException(500, "Error fetching attribute value"); } - + foreach ($request_data as $field => $value) { if ($field == 'rowid') { continue; } $objectval->$field = $value; } - + if ($objectval->update(DolibarrApiAccess::$user) > 0) { $result = $objectval->fetch((int) $id); if ($result == 0) { @@ -1307,7 +1321,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error updating attribute"); } - + /** * Delete attribute value by id. * @@ -1324,16 +1338,16 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $objectval->id = (int) $id; - - if ($objectval->delete() > 0) { + + if ($objectval->delete(DolibarrApiAccess::$user) > 0) { return 1; } throw new RestException(500, "Error deleting attribute value"); } - + /** * Get product variants. * @@ -1350,18 +1364,18 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); $combinations = $prodcomb->fetchAllByFkProductParent((int) $id); - + foreach ($combinations as $key => $combination) { $prodc2vp = new ProductCombination2ValuePair($this->db); $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); } - + return $combinations; } - + /** * Get product variants by Product ref. * @@ -1378,23 +1392,23 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $result = $this->product->fetch('', $ref); if (!$result) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); $combinations = $prodcomb->fetchAllByFkProductParent((int) $this->product->id); - + foreach ($combinations as $key => $combination) { $prodc2vp = new ProductCombination2ValuePair($this->db); $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); } - + return $combinations; } - + /** * Add variant. * @@ -1419,14 +1433,14 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (empty($id) || empty($features) || !is_array($features)) { throw new RestException(401); } - + $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); - + $prodattr = new ProductAttribute($this->db); $prodattr_val = new ProductAttributeValue($this->db); foreach ($features as $id_attr => $id_value) { @@ -1437,23 +1451,23 @@ class Products extends DolibarrApi throw new RestException(401); } } - + $result = $this->product->fetch((int) $id); if (!$result) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); - + $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact, $reference); if ($result > 0) { - return $result; + return $result; } else { - throw new RestException(500, "Error creating new product variant"); + throw new RestException(500, "Error creating new product variant"); } } - + /** * Add variant by product ref. * @@ -1477,14 +1491,14 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (empty($ref) || empty($features) || !is_array($features)) { throw new RestException(401); } - + $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); - + $prodattr = new ProductAttribute($this->db); $prodattr_val = new ProductAttributeValue($this->db); foreach ($features as $id_attr => $id_value) { @@ -1495,12 +1509,12 @@ class Products extends DolibarrApi throw new RestException(404); } } - + $result = $this->product->fetch('', trim($ref)); if (!$result) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); if (!$prodcomb->fetchByProductCombination2ValuePairs($this->product->id, $features)) { @@ -1515,7 +1529,7 @@ class Products extends DolibarrApi return $prodcomb->id; } } - + /** * Put product variants. * @@ -1533,16 +1547,16 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); $prodcomb->fetch((int) $id); - + foreach ($request_data as $field => $value) { if ($field == 'rowid') { continue; } $prodcomb->$field = $value; } - + $result = $prodcomb->update(DolibarrApiAccess::$user); if ($result > 0) { @@ -1550,7 +1564,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error editing variant"); } - + /** * Delete product variants. * @@ -1567,17 +1581,17 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); $prodcomb->id = (int) $id; $result = $prodcomb->delete(DolibarrApiAccess::$user); if ($result <= 0) { - throw new RestException(500, "Error deleting variant"); + throw new RestException(500, "Error deleting variant"); } return $result; } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** * Clean sensible object datas @@ -1589,24 +1603,24 @@ class Products extends DolibarrApi { // phpcs:enable $object = parent::_cleanObjectDatas($object); - + unset($object->regeximgext); unset($object->price_by_qty); unset($object->prices_by_qty_id); unset($object->libelle); unset($object->product_id_already_linked); unset($object->reputations); - + unset($object->name); unset($object->firstname); unset($object->lastname); unset($object->civility_id); - + unset($object->recuperableonly); - + return $object; } - + /** * Validate fields before create or update object * @@ -1625,7 +1639,7 @@ class Products extends DolibarrApi } return $product; } - + /** * Get properties of a product object * @@ -1648,48 +1662,48 @@ class Products extends DolibarrApi if (empty($id) && empty($ref) && empty($ref_ext) && empty($barcode)) { throw new RestException(400, 'bad value for parameter id, ref, ref_ext or barcode'); } - + $id = (empty($id) ? 0 : $id); - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } - + $result = $this->product->fetch($id, $ref, $ref_ext, $barcode); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + if ($includestockdata) { - $this->product->load_stock(); - - if (is_array($this->product->stock_warehouse)) { - foreach ($this->product->stock_warehouse as $keytmp => $valtmp) { - if (is_array($this->product->stock_warehouse[$keytmp]->detail_batch)) { - foreach ($this->product->stock_warehouse[$keytmp]->detail_batch as $keytmp2 => $valtmp2) { - unset($this->product->stock_warehouse[$keytmp]->detail_batch[$keytmp2]->db); - } - } - } - } + $this->product->load_stock(); + + if (is_array($this->product->stock_warehouse)) { + foreach ($this->product->stock_warehouse as $keytmp => $valtmp) { + if (is_array($this->product->stock_warehouse[$keytmp]->detail_batch)) { + foreach ($this->product->stock_warehouse[$keytmp]->detail_batch as $keytmp2 => $valtmp2) { + unset($this->product->stock_warehouse[$keytmp]->detail_batch[$keytmp2]->db); + } + } + } + } } - + if ($includesubproducts) { $childsArbo = $this->product->getChildsArbo($id, 1); - + $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; $childs = []; foreach ($childsArbo as $values) { $childs[] = array_combine($keys, $values); } - + $this->product->sousprods = $childs; } - + return $this->_cleanObjectDatas($this->product); } } From d7a65a540e47a88517d7d342a9f5823ac3878599 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sat, 8 Aug 2020 20:58:51 +0000 Subject: [PATCH 339/434] Fixing style errors. --- htdocs/product/class/api_products.class.php | 426 +++++++++--------- .../variants/class/ProductAttribute.class.php | 6 +- .../class/ProductAttributeValue.class.php | 18 +- 3 files changed, 225 insertions(+), 225 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index a63709b5c4b..f1b3e91617b 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -41,17 +41,17 @@ class Products extends DolibarrApi 'ref', 'label' ); - + /** * @var Product $product {@type Product} */ public $product; - + /** * @var ProductFournisseur $productsupplier {@type ProductFournisseur} */ public $productsupplier; - + /** * Constructor */ @@ -62,7 +62,7 @@ class Products extends DolibarrApi $this->product = new Product($this->db); $this->productsupplier = new ProductFournisseur($this->db); } - + /** * Get properties of a product object by id * @@ -81,7 +81,7 @@ class Products extends DolibarrApi { return $this->_fetch($id, '', '', '', $includestockdata, $includesubproducts); } - + /** * Get properties of a product object by ref * @@ -103,7 +103,7 @@ class Products extends DolibarrApi { return $this->_fetch('', $ref, '', '', $includestockdata, $includesubproducts); } - + /** * Get properties of a product object by ref_ext * @@ -125,7 +125,7 @@ class Products extends DolibarrApi { return $this->_fetch('', '', $ref_ext, '', $includestockdata, $includesubproducts); } - + /** * Get properties of a product object by barcode * @@ -147,7 +147,7 @@ class Products extends DolibarrApi { return $this->_fetch('', '', '', $barcode, $includestockdata, $includesubproducts); } - + /** * List products * @@ -165,11 +165,11 @@ class Products extends DolibarrApi public function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $category = 0, $sqlfilters = '') { global $db, $conf; - + $obj_ret = array(); - + $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; - + $sql = "SELECT t.rowid, t.ref, t.ref_ext"; $sql .= " FROM ".MAIN_DB_PREFIX."product as t"; if ($category > 0) { @@ -196,17 +196,17 @@ class Products extends DolibarrApi $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql .= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) { $page = 0; } $offset = $limit * $page; - + $sql .= $db->plimit($limit + 1, $offset); } - + $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); @@ -229,7 +229,7 @@ class Products extends DolibarrApi } return $obj_ret; } - + /** * Create product object * @@ -243,17 +243,17 @@ class Products extends DolibarrApi } // Check mandatory fields $result = $this->_validate($request_data); - + foreach ($request_data as $field => $value) { $this->product->$field = $value; } if ($this->product->create(DolibarrApiAccess::$user) < 0) { throw new RestException(500, "Error creating product", array_merge(array($this->product->error), $this->product->errors)); } - + return $this->product->id; } - + /** * Update product. * Price will be updated by this API only if option is set on "One price per product". See other APIs for other price modes. @@ -268,22 +268,22 @@ class Products extends DolibarrApi public function put($id, $request_data = null) { global $conf; - + if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $result = $this->product->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $oldproduct = dol_clone($this->product, 0); - + foreach ($request_data as $field => $value) { if ($field == 'id') { continue; } @@ -292,14 +292,14 @@ class Products extends DolibarrApi } $this->product->$field = $value; } - + $updatetype = false; if ($this->product->type != $oldproduct->type && ($this->product->isProduct() || $this->product->isService())) { $updatetype = true; } - + $result = $this->product->update($id, DolibarrApiAccess::$user, 1, 'update', $updatetype); - + // If price mode is 1 price per product if ($result > 0 && !empty($conf->global->PRODUCT_PRICE_UNIQ)) { // We update price only if it was changed @@ -312,7 +312,7 @@ class Products extends DolibarrApi } if ($this->product->default_vat_code != $oldproduct->default_vat_code) { $pricemodified = true; } - + if ($this->product->price_base_type == 'TTC') { if ($this->product->price_ttc != $oldproduct->price_ttc) { $pricemodified = true; } @@ -325,30 +325,30 @@ class Products extends DolibarrApi } } } - + if ($pricemodified) { $newvat = $this->product->tva_tx; $newnpr = $this->product->tva_npr; $newvatsrccode = $this->product->default_vat_code; - + $newprice = $this->product->price; $newpricemin = $this->product->price_min; if ($this->product->price_base_type == 'TTC') { $newprice = $this->product->price_ttc; $newpricemin = $this->product->price_min_ttc; } - + $result = $this->product->updatePrice($newprice, $this->product->price_base_type, DolibarrApiAccess::$user, $newvat, $newpricemin, 0, $newnpr, 0, 0, array(), $newvatsrccode); } } - + if ($result <= 0) { throw new RestException(500, "Error updating product", array_merge(array($this->product->error), $this->product->errors)); } - + return $this->get($id); } - + /** * Delete product * @@ -364,18 +364,18 @@ class Products extends DolibarrApi if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + // The Product::delete() method uses the global variable $user. global $user; $user = DolibarrApiAccess::$user; - + return $this->product->delete(DolibarrApiAccess::$user); } - + /** * Get the list of subproducts of the product. * @@ -393,22 +393,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if (!DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $childsArbo = $this->product->getChildsArbo($id, 1); - + $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; $childs = []; foreach ($childsArbo as $values) { $childs[] = array_combine($keys, $values); } - + return $childs; } - + /** * Add subproduct. * @@ -431,18 +431,18 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (!DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->product->add_sousproduit($id, $subproduct_id, $qty, $incdec); if ($result <= 0) { throw new RestException(500, "Error adding product child"); } return $result; } - + /** * Remove subproduct. * @@ -462,19 +462,19 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (!DolibarrApi::_checkAccessToResource('product', $id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->product->del_sousproduit($id, $subproduct_id); if ($result <= 0) { throw new RestException(500, "Error while removing product child"); } return $result; } - - + + /** * Get categories for a product * @@ -493,22 +493,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->categorie->lire) { throw new RestException(401); } - + $categories = new Categorie($this->db); - + $result = $categories->getListForItem($id, 'product', $sortfield, $sortorder, $limit, $page); - + if (empty($result)) { throw new RestException(404, 'No category found'); } - + if ($result < 0) { throw new RestException(503, 'Error when retrieve category list : '.array_merge(array($categories->error), $categories->errors)); } - + return $result; } - + /** * Get prices per segment for a product * @@ -521,24 +521,24 @@ class Products extends DolibarrApi public function getCustomerPricesPerSegment($id) { global $conf; - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if (empty($conf->global->PRODUIT_MULTIPRICES)) { throw new RestException(400, 'API not available: this mode of pricing is not enabled by setup'); } - + $result = $this->product->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if ($result < 0) { throw new RestException(503, 'Error when retrieve prices list : '.array_merge(array($this->product->error), $this->product->errors)); } - + return array( 'multiprices'=>$this->product->multiprices, 'multiprices_inc_tax'=>$this->product->multiprices_ttc, @@ -549,7 +549,7 @@ class Products extends DolibarrApi //'multiprices_default_vat_code'=>$this->product->multiprices_default_vat_code ); } - + /** * Get prices per customer for a product * @@ -563,20 +563,20 @@ class Products extends DolibarrApi public function getCustomerPricesPerCustomer($id, $thirdparty_id = '') { global $conf; - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if (empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { throw new RestException(400, 'API not available: this mode of pricing is not enabled by setup'); } - + $result = $this->product->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if ($result > 0) { require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php'; $prodcustprice = new Productcustomerprice($this->db); @@ -585,14 +585,14 @@ class Products extends DolibarrApi if ($thirdparty_id) $filter['t.fk_soc'] .= $thirdparty_id; $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); } - + if (empty($prodcustprice->lines)) { throw new RestException(404, 'Prices not found'); } - + return $prodcustprice->lines; } - + /** * Get prices per quantity for a product * @@ -605,30 +605,30 @@ class Products extends DolibarrApi public function getCustomerPricesPerQuantity($id) { global $conf; - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + if (empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) { throw new RestException(400, 'API not available: this mode of pricing is not enabled by setup'); } - + $result = $this->product->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if ($result < 0) { throw new RestException(503, 'Error when retrieve prices list : '.array_merge(array($this->product->error), $this->product->errors)); } - + return array( 'prices_by_qty'=>$this->product->prices_by_qty[0], // 1 if price by quantity was activated for the product 'prices_by_qty_list'=>$this->product->prices_by_qty_list[0] ); } - + /** * Add/Update purchase prices for a product. * @@ -667,35 +667,35 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $result = $this->productsupplier->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->productsupplier->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->productsupplier->add_fournisseur(DolibarrApiAccess::$user, $fourn_id, $ref_fourn, $qty); if ($result < 0) { throw new RestException(500, "Error adding supplier to product : ".$this->db->lasterror()); } - + $fourn = new Fournisseur($this->db); $result = $fourn->fetch($fourn_id); if ($result <= 0) { throw new RestException(404, 'Supplier not found'); } - + $result = $this->productsupplier->update_buyprice($qty, $buyprice, DolibarrApiAccess::$user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges, $remise_percent, $remise, $newnpr, $delivery_time_days, $supplier_reputation, $localtaxes_array, $newdefaultvatcode, $multicurrency_buyprice, $multicurrency_price_base_type, $multicurrency_tx, $multicurrency_code, $desc_fourn, $barcode, $fk_barcode_type); - + if ($result <= 0) { throw new RestException(500, "Error updating buy price : ".$this->db->lasterror()); } return (int) $this->productsupplier->product_fourn_price_id; } - + /** * Delete purchase price for a product * @@ -719,19 +719,19 @@ class Products extends DolibarrApi if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->productsupplier->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $resultsupplier = 0; if ($result > 0) { $resultsupplier = $this->productsupplier->remove_product_fournisseur_price($priceid); } - + return $resultsupplier; } - + /** * Get a list of all purchase prices of products * @@ -758,9 +758,9 @@ class Products extends DolibarrApi $sql .= ", ".MAIN_DB_PREFIX."categorie_product as c"; } $sql .= ", ".MAIN_DB_PREFIX."product_fournisseur_price as s"; - + $sql .= ' WHERE t.entity IN ('.getEntity('product').')'; - + if ($supplier > 0) { $sql .= " AND s.fk_soc = ".$db->escape($supplier); } @@ -801,16 +801,16 @@ class Products extends DolibarrApi while ($i < $min) { $obj = $db->fetch_object($result); - + $product_fourn = new ProductFournisseur($this->db); $product_fourn_list = $product_fourn->list_product_fournisseur_price($obj->rowid, '', '', 0, 0); foreach ($product_fourn_list as $tmpobj) { $this->_cleanObjectDatas($tmpobj); } - + //var_dump($product_fourn_list->db);exit; $obj_ret[$obj->rowid] = $product_fourn_list; - + $i++; } } else { @@ -821,7 +821,7 @@ class Products extends DolibarrApi } return $obj_ret; } - + /** * Get purchase prices for a product * @@ -846,36 +846,36 @@ class Products extends DolibarrApi if (empty($id) && empty($ref) && empty($ref_ext) && empty($barcode)) { throw new RestException(400, 'bad value for parameter id, ref, ref_ext or barcode'); } - + $id = (empty($id) ? 0 : $id); - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } - + $result = $this->product->fetch($id, $ref, $ref_ext, $barcode); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $product_fourn_list = array(); - + if ($result) { $product_fourn = new ProductFournisseur($this->db); $product_fourn_list = $product_fourn->list_product_fournisseur_price($this->product->id, '', '', 0, 0); } - + foreach ($product_fourn_list as $tmpobj) { $this->_cleanObjectDatas($tmpobj); } - + return $this->_cleanObjectDatas($product_fourn_list); } - + /** * Get attributes. * @@ -890,11 +890,11 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); return $prodattr->fetchAll(); } - + /** * Get attribute by ID. * @@ -912,17 +912,17 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $result = $prodattr->fetch((int) $id); - + if ($result < 0) { throw new RestException(404, "Attribute not found"); } - + return $prodattr; } - + /** * Get attributes by ref. * @@ -939,26 +939,26 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, ref, label, rang FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '".trim($ref)."' AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$this->db->num_rows($query)) { throw new RestException(404); } - + $result = $this->db->fetch_object($query); - + $attr = []; $attr['id'] = $result->rowid; $attr['ref'] = $result->ref; $attr['label'] = $result->label; $attr['rang'] = $result->rang; - + return $attr; } - + /** * Add attributes. * @@ -976,18 +976,18 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $prodattr->label = $label; $prodattr->ref = $ref; - + $resid = $prodattr->create(DolibarrApiAccess::$user); if ($resid <= 0) { throw new RestException(500, "Error creating new attribute"); } return $resid; } - + /** * Update attributes by id. * @@ -1006,22 +1006,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); - + $result = $prodattr->fetch((int) $id); if ($result == 0) { throw new RestException(404, 'Attribute not found'); } elseif ($result < 0) { throw new RestException(500, "Error fetching attribute"); } - + foreach ($request_data as $field => $value) { if ($field == 'rowid') { continue; } $prodattr->$field = $value; } - + if ($prodattr->update(DolibarrApiAccess::$user) > 0) { $result = $prodattr->fetch((int) $id); if ($result == 0) { @@ -1034,7 +1034,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error updating attribute"); } - + /** * Delete attributes by id. * @@ -1051,18 +1051,18 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - + $prodattr = new ProductAttribute($this->db); $prodattr->id = (int) $id; $result = $prodattr->delete(DolibarrApiAccess::$user); - + if ($result <= 0) { throw new RestException(500, "Error deleting attribute"); } - + return $result; } - + /** * Get attribute value by id. * @@ -1079,30 +1079,30 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, fk_product_attribute, ref, value FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE rowid = ".(int) $id." AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$query) { throw new RestException(401); } - + if (!$this->db->num_rows($query)) { throw new RestException(404, 'Attribute value not found'); } - + $result = $this->db->fetch_object($query); - + $attrval = []; $attrval['id'] = $result->rowid; $attrval['fk_product_attribute'] = $result->fk_product_attribute; $attrval['ref'] = $result->ref; $attrval['value'] = $result->value; - + return $attrval; } - + /** * Get attribute value by ref. * @@ -1120,30 +1120,30 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $sql = "SELECT rowid, fk_product_attribute, ref, value FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '".trim($ref)."' AND fk_product_attribute = ".(int) $id." AND entity IN (".getEntity('product').")"; - + $query = $this->db->query($sql); - + if (!$query) { throw new RestException(401); } - + if (!$this->db->num_rows($query)) { throw new RestException(404, 'Attribute value not found'); } - + $result = $this->db->fetch_object($query); - + $attrval = []; $attrval['id'] = $result->rowid; $attrval['fk_product_attribute'] = $result->fk_product_attribute; $attrval['ref'] = $result->ref; $attrval['value'] = $result->value; - + return $attrval; } - + /** * Delete attribute value by ref. * @@ -1160,30 +1160,30 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE ref LIKE '".trim($ref)."' AND fk_product_attribute = ".(int) $id." AND entity IN (".getEntity('product').")"; $query = $this->db->query($sql); - + if (!$query) { throw new RestException(401); } - + if (!$this->db->num_rows($query)) { throw new RestException(404, 'Attribute value not found'); } - + $result = $this->db->fetch_object($query); - + $attrval = new ProductAttributeValue($this->db); $attrval->id = $result->rowid; $result = $attrval->delete(DolibarrApiAccess::$user); if ($result > 0) { return 1; } - + throw new RestException(500, "Error deleting attribute value"); } - + /** * Get all values for an attribute id. * @@ -1200,11 +1200,11 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); return $objectval->fetchAllByProductAttribute((int) $id); } - + /** * Get all values for an attribute ref. * @@ -1220,28 +1220,28 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $return = array(); - + $sql = 'SELECT '; $sql .= 'v.fk_product_attribute, v.rowid, v.ref, v.value FROM '.MAIN_DB_PREFIX.'product_attribute_value v '; $sql .= "WHERE v.fk_product_attribute = ( SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute WHERE ref LIKE '".strtoupper(trim($ref))."' LIMIT 1)"; - + $query = $this->db->query($sql); - + while ($result = $this->db->fetch_object($query)) { $tmp = new ProductAttributeValue($this->db); $tmp->fk_product_attribute = $result->fk_product_attribute; $tmp->id = $result->rowid; $tmp->ref = $result->ref; $tmp->value = $result->value; - + $return[] = $tmp; } - + return $return; } - + /** * Add attribute value. * @@ -1260,22 +1260,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (empty($ref) || empty($value)) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $objectval->fk_product_attribute = $id; $objectval->ref = $ref; $objectval->value = $value; - + if ($objectval->create(DolibarrApiAccess::$user) > 0) { return $objectval->id; } throw new RestException(500, "Error creating new attribute value"); } - + /** * Update attribute value. * @@ -1293,22 +1293,22 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $result = $objectval->fetch((int) $id); - + if ($result == 0) { throw new RestException(404, 'Attribute value not found'); } elseif ($result < 0) { throw new RestException(500, "Error fetching attribute value"); } - + foreach ($request_data as $field => $value) { if ($field == 'rowid') { continue; } $objectval->$field = $value; } - + if ($objectval->update(DolibarrApiAccess::$user) > 0) { $result = $objectval->fetch((int) $id); if ($result == 0) { @@ -1321,7 +1321,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error updating attribute"); } - + /** * Delete attribute value by id. * @@ -1338,16 +1338,16 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - + $objectval = new ProductAttributeValue($this->db); $objectval->id = (int) $id; - + if ($objectval->delete(DolibarrApiAccess::$user) > 0) { return 1; } throw new RestException(500, "Error deleting attribute value"); } - + /** * Get product variants. * @@ -1364,18 +1364,18 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); $combinations = $prodcomb->fetchAllByFkProductParent((int) $id); - + foreach ($combinations as $key => $combination) { $prodc2vp = new ProductCombination2ValuePair($this->db); $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); } - + return $combinations; } - + /** * Get product variants by Product ref. * @@ -1392,23 +1392,23 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(401); } - + $result = $this->product->fetch('', $ref); if (!$result) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); $combinations = $prodcomb->fetchAllByFkProductParent((int) $this->product->id); - + foreach ($combinations as $key => $combination) { $prodc2vp = new ProductCombination2ValuePair($this->db); $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); } - + return $combinations; } - + /** * Add variant. * @@ -1433,14 +1433,14 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (empty($id) || empty($features) || !is_array($features)) { throw new RestException(401); } - + $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); - + $prodattr = new ProductAttribute($this->db); $prodattr_val = new ProductAttributeValue($this->db); foreach ($features as $id_attr => $id_value) { @@ -1451,14 +1451,14 @@ class Products extends DolibarrApi throw new RestException(401); } } - + $result = $this->product->fetch((int) $id); if (!$result) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); - + $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact, $reference); if ($result > 0) { @@ -1467,7 +1467,7 @@ class Products extends DolibarrApi throw new RestException(500, "Error creating new product variant"); } } - + /** * Add variant by product ref. * @@ -1491,14 +1491,14 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + if (empty($ref) || empty($features) || !is_array($features)) { throw new RestException(401); } - + $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); - + $prodattr = new ProductAttribute($this->db); $prodattr_val = new ProductAttributeValue($this->db); foreach ($features as $id_attr => $id_value) { @@ -1509,12 +1509,12 @@ class Products extends DolibarrApi throw new RestException(404); } } - + $result = $this->product->fetch('', trim($ref)); if (!$result) { throw new RestException(404, 'Product not found'); } - + $prodcomb = new ProductCombination($this->db); if (!$prodcomb->fetchByProductCombination2ValuePairs($this->product->id, $features)) { @@ -1529,7 +1529,7 @@ class Products extends DolibarrApi return $prodcomb->id; } } - + /** * Put product variants. * @@ -1547,16 +1547,16 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); $prodcomb->fetch((int) $id); - + foreach ($request_data as $field => $value) { if ($field == 'rowid') { continue; } $prodcomb->$field = $value; } - + $result = $prodcomb->update(DolibarrApiAccess::$user); if ($result > 0) { @@ -1564,7 +1564,7 @@ class Products extends DolibarrApi } throw new RestException(500, "Error editing variant"); } - + /** * Delete product variants. * @@ -1581,7 +1581,7 @@ class Products extends DolibarrApi if (!DolibarrApiAccess::$user->rights->produit->supprimer) { throw new RestException(401); } - + $prodcomb = new ProductCombination($this->db); $prodcomb->id = (int) $id; $result = $prodcomb->delete(DolibarrApiAccess::$user); @@ -1591,7 +1591,7 @@ class Products extends DolibarrApi } return $result; } - + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** * Clean sensible object datas @@ -1603,24 +1603,24 @@ class Products extends DolibarrApi { // phpcs:enable $object = parent::_cleanObjectDatas($object); - + unset($object->regeximgext); unset($object->price_by_qty); unset($object->prices_by_qty_id); unset($object->libelle); unset($object->product_id_already_linked); unset($object->reputations); - + unset($object->name); unset($object->firstname); unset($object->lastname); unset($object->civility_id); - + unset($object->recuperableonly); - + return $object; } - + /** * Validate fields before create or update object * @@ -1639,7 +1639,7 @@ class Products extends DolibarrApi } return $product; } - + /** * Get properties of a product object * @@ -1662,25 +1662,25 @@ class Products extends DolibarrApi if (empty($id) && empty($ref) && empty($ref_ext) && empty($barcode)) { throw new RestException(400, 'bad value for parameter id, ref, ref_ext or barcode'); } - + $id = (empty($id) ? 0 : $id); - + if (!DolibarrApiAccess::$user->rights->produit->lire) { throw new RestException(403); } - + $result = $this->product->fetch($id, $ref, $ref_ext, $barcode); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->product->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + if ($includestockdata) { $this->product->load_stock(); - + if (is_array($this->product->stock_warehouse)) { foreach ($this->product->stock_warehouse as $keytmp => $valtmp) { if (is_array($this->product->stock_warehouse[$keytmp]->detail_batch)) { @@ -1691,19 +1691,19 @@ class Products extends DolibarrApi } } } - + if ($includesubproducts) { $childsArbo = $this->product->getChildsArbo($id, 1); - + $keys = ['rowid', 'qty', 'fk_product_type', 'label', 'incdec']; $childs = []; foreach ($childsArbo as $values) { $childs[] = array_combine($keys, $values); } - + $this->product->sousprods = $childs; } - + return $this->_cleanObjectDatas($this->product); } } diff --git a/htdocs/variants/class/ProductAttribute.class.php b/htdocs/variants/class/ProductAttribute.class.php index 6d9fadf0101..6e2335c2f99 100644 --- a/htdocs/variants/class/ProductAttribute.class.php +++ b/htdocs/variants/class/ProductAttribute.class.php @@ -143,7 +143,7 @@ class ProductAttribute extends CommonObject } // End call triggers } - + //Ref must be uppercase $this->ref = strtoupper($this->ref); @@ -178,7 +178,7 @@ class ProductAttribute extends CommonObject } // End call triggers } - + //Ref must be uppercase $this->ref = trim(strtoupper($this->ref)); $this->label = trim($this->label); @@ -209,7 +209,7 @@ class ProductAttribute extends CommonObject } // End call triggers } - + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute WHERE rowid = ".(int) $this->id; if ($this->db->query($sql)) { diff --git a/htdocs/variants/class/ProductAttributeValue.class.php b/htdocs/variants/class/ProductAttributeValue.class.php index c655e188c5d..b93f8b04c0b 100644 --- a/htdocs/variants/class/ProductAttributeValue.class.php +++ b/htdocs/variants/class/ProductAttributeValue.class.php @@ -175,7 +175,7 @@ class ProductAttributeValue extends CommonObject } // End call triggers } - + return 1; } @@ -199,7 +199,7 @@ class ProductAttributeValue extends CommonObject } // End call triggers } - + //Ref must be uppercase $this->ref = trim(strtoupper($this->ref)); $this->value = trim($this->value); @@ -224,7 +224,7 @@ class ProductAttributeValue extends CommonObject */ public function delete(User $user, $notrigger = 0) { - + if (empty($notrigger)) { // Call trigger $result = $this->call_trigger('PRODUCT_ATTRIBUTE_VALUE_DELETE', $user); @@ -237,7 +237,7 @@ class ProductAttributeValue extends CommonObject if ($this->db->query($sql)) { return 1; } - + return -1; } @@ -251,17 +251,17 @@ class ProductAttributeValue extends CommonObject public function deleteByFkAttribute($fk_attribute, User $user) { $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."product_attribute_value WHERE fk_product_attribute = ".(int) $fk_attribute; - + $query = $this->db->query($sql); - + if (!$query) { return -1; } - + if (!$this->db->num_rows($query)) { return 1; } - + while ($obj = $this->db->fetch_object($query)) { $tmp = new ProductAttributeValue($this->db); if ($tmp->fetch($obj->rowid) > 0) { @@ -273,7 +273,7 @@ class ProductAttributeValue extends CommonObject return -1; } } - + return 1; } } From 3f233a3200f93990ef8cf1136c883831f681c969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 8 Aug 2020 23:01:41 +0200 Subject: [PATCH 340/434] Fix comment params --- htdocs/variants/class/ProductAttributeValue.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/variants/class/ProductAttributeValue.class.php b/htdocs/variants/class/ProductAttributeValue.class.php index b93f8b04c0b..ab998c6752b 100644 --- a/htdocs/variants/class/ProductAttributeValue.class.php +++ b/htdocs/variants/class/ProductAttributeValue.class.php @@ -244,8 +244,8 @@ class ProductAttributeValue extends CommonObject /** * Deletes all product attribute values by a product attribute id * - * @param int $fk_attribute Product attribute id - * @param int $notrigger Do not execute trigger + * @param int $fk_attribute Product attribute id + * @param User $user Object user * @return int <0 KO, >0 OK */ public function deleteByFkAttribute($fk_attribute, User $user) From 4aa71240d26e497b071a4761260116540e7dfa93 Mon Sep 17 00:00:00 2001 From: Egil Priskorn Date: Sun, 9 Aug 2020 16:33:34 +0200 Subject: [PATCH 341/434] Update README.md Fix spelling, grammar and a add a few clarifications. --- README.md | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index fa5326079ec..d15808d2cac 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ ![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg) ![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg) -Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…). +Dolibarr ERP & CRM is a modern software package that helps manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…). -It's an Open Source Software (written in PHP language) designed for small, medium or large companies, foundations and freelancers. +It's Open Source Software (written in PHP) designed for small, medium or large companies, foundations and freelancers. -You can freely use, study, modify or distribute it according to its Free Software licence. +You can freely use, study, modify or distribute it according to its licence. -You can use it as a standalone application or as a web application to be able to access it from the Internet or a LAN. +You can use it as a standalone application or as a web application to access it from the Internet or a LAN. ![ScreenShot](https://www.dolibarr.org/images/dolibarr_screenshot1_1920x1080.jpg) @@ -35,11 +35,15 @@ Releases can be downloaded from [official website](https://www.dolibarr.org/). ### Advanced setup -You can use a Web server and a supported database (MariaDB, MySQL or PostgreSQL) to install the standard version. +You can use a web server and a supported database (MariaDB, MySQL or PostgreSQL) to install the standard version. + +On GNU/Linux, first check if your distribution has already packaged Dolibarr. + +#### Generic install steps: - Check that your installed PHP version is supported [see PHP support](https://wiki.dolibarr.org/index.php/Versions). -- Uncompress the downloaded .zip archive to copy the "dolibarr/htdocs" directory and all its files inside your web server root or get the files directly from GitHub (recommanded if you known git): +- Uncompress the downloaded .zip archive to copy the "dolibarr/htdocs" directory and all its files inside your web server root or get the files directly from GitHub (recommanded if you know git as it makes it easier if you want to upgrade later): `git clone https://github.com/dolibarr/dolibarr -b x.y` (where x.y is main version like 3.6, 9.0, ...) @@ -70,11 +74,11 @@ If you don't have time to install it yourself, you can try some commercial 'read ## UPGRADING -- At first make a backup of your Dolibarr files & than see https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr +- At first make a backup of your Dolibarr files & then read https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr - Check that your installed PHP version is supported by the new version [see PHP support](./doc/phpmatrix.md). - Overwrite all old files from 'dolibarr' directory with files provided into the new version's package. -- At first next access, Dolibarr will redirect your to the "install/" page to follow the upgrade process. -  If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file into the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*"). +- At first next access, Dolibarr will redirect you to the "install/" page to follow the upgrade process. +  If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file in the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*"). *Note: migration process can be safely done multiple times by calling the `/install/index.php` page* @@ -138,8 +142,8 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - customizable Dashboard - Highly customizable: enable only the modules you need, add user personalized fields, choose your skin, several menu managers (can be used by internal users as a back-office with a particular menu, or by external users as a front-office with another one) -- APIs -- An easy to understand, maintain and develop code (PHP with no heavy framework; trigger and hook architecture) +- SOAP & REST APIs +- Code that is easy to understand, maintain and develop (PHP with no heavy framework; trigger and hook architecture) - Support a lot of country specific features: - Spanish Tax RE and ISPF - French NPR VAT rate (VAT called "Non Perçue Récupérable" for DOM-TOM) @@ -149,7 +153,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Compatible with [European directives](http://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE) - Compatible with European GDPR rules - ... -- PDF or ODT generation for invoice, proposals, orders... +- Flexible PDF & ODT generation for invoices, proposals, orders... - … ### System Environment / Requirements @@ -167,12 +171,12 @@ These are features that Dolibarr does **not** yet fully support: - Tasks dependencies in projects - Payroll module -- No native embedded Webmail +- No native embedded Webmail, but you can send email to contacts in Dolibarr with e.g. offers, invoices, etc. - Dolibarr can't do coffee (yet) ## DOCUMENTATION -Administrator, user, developer and translator's documentations are available along with other community resources on the [Wiki](https://wiki.dolibarr.org). +Administrator, user, developer and translator's documentations are available along with other community resources in the [Wiki](https://wiki.dolibarr.org). ## CONTRIBUTING @@ -182,7 +186,7 @@ This project exists thanks to all the people who contribute. [[Contribute](https ## CREDITS -Dolibarr is the work of many contributors over the years and uses some fine libraries. +Dolibarr is the work of many contributors over the years and uses some fine PHP libraries. See [COPYRIGHT](https://github.com/Dolibarr/dolibarr/blob/develop/COPYRIGHT) file. From ca465373ea1021cecbe670b66e049c17c7f34816 Mon Sep 17 00:00:00 2001 From: Egil Priskorn Date: Sun, 9 Aug 2020 17:16:36 +0200 Subject: [PATCH 342/434] Update README.md Remove some paragraphs that are not essential to new users and 2 new paragraphs about preferred partners and upgrading supported all the way from 2.8 to 12 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fa5326079ec..52748e8000f 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ Dolibarr ERP & CRM is a modern software package to manage your organization's ac It's an Open Source Software (written in PHP language) designed for small, medium or large companies, foundations and freelancers. -You can freely use, study, modify or distribute it according to its Free Software licence. - You can use it as a standalone application or as a web application to be able to access it from the Internet or a LAN. +Dolibarr has a large community ready to help you and [oficially preferred partners ready to offer commercial support should you need it](https://wiki.dolibarr.org/index.php/List_of_Dolibarr_partners_and_providers) + ![ScreenShot](https://www.dolibarr.org/images/dolibarr_screenshot1_1920x1080.jpg) ## LICENSE @@ -70,14 +70,14 @@ If you don't have time to install it yourself, you can try some commercial 'read ## UPGRADING +Dolibarr supports upgrading usually wihtout the need for any (commercial) support (depending on if you use any commercial extensions) and supports upgrading all the way from 2.8-12.0 without breakage. This is unique in the ERP ecosystem and a benefit our users highly appreciate! + - At first make a backup of your Dolibarr files & than see https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr - Check that your installed PHP version is supported by the new version [see PHP support](./doc/phpmatrix.md). - Overwrite all old files from 'dolibarr' directory with files provided into the new version's package. - At first next access, Dolibarr will redirect your to the "install/" page to follow the upgrade process.  If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file into the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*"). -*Note: migration process can be safely done multiple times by calling the `/install/index.php` page* - ## WHAT'S NEW See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) file. From dd7e673aee8050ccb7e9c5a06b6f96238d83ebb2 Mon Sep 17 00:00:00 2001 From: Egil Priskorn Date: Sun, 9 Aug 2020 17:24:09 +0200 Subject: [PATCH 343/434] Update README.md Written in PHP with optional JS --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa5326079ec..564a4171116 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…). -It's an Open Source Software (written in PHP language) designed for small, medium or large companies, foundations and freelancers. +It's an Open Source Software (written in PHP with optional JavaScript enhancements) designed for small, medium or large companies, foundations and freelancers. You can freely use, study, modify or distribute it according to its Free Software licence. From 10df9777b54154a30a64652c941e1e5176e60dce Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Mon, 10 Aug 2020 09:53:20 +0200 Subject: [PATCH 344/434] FIX: Visualization rights correction on last modified contacts box --- htdocs/core/boxes/box_contacts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index caea252c571..7141728c23d 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -94,7 +94,7 @@ class box_contacts extends ModeleBoxes $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON sp.fk_soc = s.rowid"; if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; - if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND sp.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; if ($user->socid) $sql .= " AND sp.fk_soc = ".$user->socid; $sql .= " ORDER BY sp.tms DESC"; $sql .= $this->db->plimit($max, 0); From f014365b650c31d34b250038d69115e4a2d11727 Mon Sep 17 00:00:00 2001 From: John Botella Date: Mon, 10 Aug 2020 10:35:50 +0200 Subject: [PATCH 345/434] Fix lang fr --- htdocs/langs/fr_FR/main.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index 611d27d7723..ff74af2ad5c 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -353,8 +353,8 @@ PriceUTTC=P.U TTC Amount=Montant AmountInvoice=Montant facture AmountInvoiced=Montant facturé -AmountInvoicedHT=Montant facturé (TTC) -AmountInvoicedTTC=Montant facturé (HT) +AmountInvoicedHT=Montant facturé (HT) +AmountInvoicedTTC=Montant facturé (TTC) AmountPayment=Montant paiement AmountHTShort=Montant HT AmountTTCShort=Montant TTC From 821e7e289403e85a83c31442a76c253a4602a526 Mon Sep 17 00:00:00 2001 From: Christian Foellmann Date: Mon, 10 Aug 2020 15:39:05 +0200 Subject: [PATCH 346/434] set default unit to `PRODUCT_USE_UNITS` value --- htdocs/bom/tpl/objectline_create.tpl.php | 2 +- htdocs/core/tpl/objectline_create.tpl.php | 2 +- htdocs/product/card.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index 8501f1ca30f..74eb88393df 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -113,7 +113,7 @@ if ($conf->global->PRODUCT_USE_UNITS) { $coldisplay++; print ''; - print $form->selectUnits($line->fk_unit, "units"); + print $form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, "units"); print ''; } diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 9bb792afbc7..821b18a3c3f 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -362,7 +362,7 @@ if ($nolinesbefore) { if (!empty($conf->global->PRODUCT_USE_UNITS)) { $coldisplay++; print ''; - print $form->selectUnits($line->fk_unit, "units"); + print $form->selectUnits( empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, "units"); print ''; } $remise_percent = $buyer->remise_percent; diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 0327456615c..32c50ccb661 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -1107,7 +1107,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''.$langs->trans('DefaultUnitToShow').''; print ''; - print $form->selectUnits('', 'units'); + print $form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, 'units'); print ''; } From 3e168f949579f9955d4ec2a90a64491ddb3c632b Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 10 Aug 2020 14:06:22 +0000 Subject: [PATCH 347/434] Fixing style errors. --- htdocs/core/tpl/objectline_create.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 821b18a3c3f..6c38f5560a7 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -362,7 +362,7 @@ if ($nolinesbefore) { if (!empty($conf->global->PRODUCT_USE_UNITS)) { $coldisplay++; print ''; - print $form->selectUnits( empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, "units"); + print $form->selectUnits(empty($line->fk_unit) ? $conf->global->PRODUCT_USE_UNITS : $line->fk_unit, "units"); print ''; } $remise_percent = $buyer->remise_percent; From 308dea92b31be946ff54512841bb680217b56d50 Mon Sep 17 00:00:00 2001 From: josemariagomezroncero Date: Mon, 10 Aug 2020 20:40:11 +0200 Subject: [PATCH 348/434] Bug, this option disable topic input. Bug, MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES disable topic input. We need the subject for email for save. --- htdocs/admin/mails_templates.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 0f490bb828a..3ac0a5df674 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -540,7 +540,7 @@ print ""; // Show fields for topic, join files and body $fieldsforcontent = array('topic', 'joinfiles', 'content'); -if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $fieldsforcontent = array('content', 'content_lines'); } +if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $fieldsforcontent = array('topic', 'content', 'content_lines'); } foreach ($fieldsforcontent as $tmpfieldlist) { print ''; From 3be723f3a1b3e1852db9f6d7678c90a7f59e8bd5 Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Tue, 11 Aug 2020 07:49:54 +0200 Subject: [PATCH 349/434] NEW: Delayed payment in TakePOS --- htdocs/langs/en_US/cashdesk.lang | 1 + htdocs/takepos/admin/setup.php | 7 +++++++ htdocs/takepos/invoice.php | 6 +++--- htdocs/takepos/pay.php | 4 ++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index 73d8bdaa0df..9d4856135ef 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -120,3 +120,4 @@ DefineTablePlan=Define tables plan GiftReceiptButton=Gift receipt button GiftReceipt=Gift receipt ModuleReceiptPrinterMustBeEnabled=Module Receipt printer must have been enabled first +AllowDelayedPayment=Allow delayed payment diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php index 22355c70d9d..82d31045897 100644 --- a/htdocs/takepos/admin/setup.php +++ b/htdocs/takepos/admin/setup.php @@ -372,6 +372,13 @@ print ''; print ajax_constantonoff("TAKEPOS_GIFT_RECEIPT", array(), $conf->entity, 0, 0, 1, 0); print "\n"; +// Delayed Pay Button +print ''; +print $langs->trans('AllowDelayedPayment'); +print ''; +print ajax_constantonoff("TAKEPOS_DELAYED_PAYMENT", array(), $conf->entity, 0, 0, 1, 0); +print "\n"; + // Numbering module //print ''; //print $langs->trans("BillsNumberingModule"); diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index cfde72c9fd3..ce4219ab5cd 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -156,7 +156,7 @@ if ($action == 'valid' && $user->rights->facture->creer) } } - if ($bankaccount <= 0) { + if ($bankaccount <= 0 && $pay != "delayed") { $errormsg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankAccount")); $error++; } @@ -249,8 +249,8 @@ if ($action == 'valid' && $user->rights->facture->creer) $payment->paiementid = $paiementid; $payment->num_payment = $invoice->ref; - $payment->create($user); - $payment->addPaymentToBank($user, 'payment', '(CustomerInvoicePayment)', $bankaccount, '', ''); + if ($pay!="delayed") $payment->create($user); + if ($pay!="delayed") $payment->addPaymentToBank($user, 'payment', '(CustomerInvoicePayment)', $bankaccount, '', ''); $remaintopay = $invoice->getRemainToPay(); // Recalculate remain to pay after the payment is recorded if ($remaintopay == 0) { diff --git a/htdocs/takepos/pay.php b/htdocs/takepos/pay.php index 0f47c7f2b04..0a1c60a5a57 100644 --- a/htdocs/takepos/pay.php +++ b/htdocs/takepos/pay.php @@ -375,6 +375,10 @@ foreach ($action_buttons as $button) { $newclass = $class.($button["class"] ? " ".$button["class"] : ""); print ''; } + +if ($conf->global->TAKEPOS_DELAYED_PAYMENT) { + print ''; +} ?> From b1735b0f80fd7b73087133ba92ffb32a555d1897 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Tue, 11 Aug 2020 10:02:46 +0200 Subject: [PATCH 350/434] FIX: MySql Strict mode --- htdocs/compta/index.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index 00b4987ad66..ba7ff6af444 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -2,7 +2,7 @@ /* Copyright (C) 2001-2005 Rodolphe Quiedeville * Copyright (C) 2004-2013 Laurent Destailleur * Copyright (C) 2005-2015 Regis Houssin - * Copyright (C) 2015-2016 Juanjo Menent + * Copyright (C) 2015-2020 Juanjo Menent * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Marcos García @@ -161,6 +161,14 @@ if (!empty($conf->facture->enabled) && $user->rights->facture->lire) $reshook = $hookmanager->executeHooks('printFieldListWhereCustomerDraft', $parameters); $sql .= $hookmanager->resPrint; + $sql.= " GROUP BY f.rowid, f.ref, f.datef, f.total, f.tva, f.total_ttc, f.ref_client, f.type, "; + $sql.= "s.email, s.nom, s.rowid, s.code_client, s.code_compta, s.code_fournisseur, s.code_compta_fournisseur"; + + // Add Group from hooks + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListGroupByCustomerDraft', $parameters); + $sql .= $hookmanager->resPrint; + $resql = $db->query($sql); if ($resql) From 4e6b7289f277a3097632e828490a3554bcc45ced Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Tue, 11 Aug 2020 10:07:38 +0200 Subject: [PATCH 351/434] FIX: MySql Strict mode --- htdocs/compta/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index ba7ff6af444..23ef5b6d0d9 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -478,7 +478,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU $sql .= $hookmanager->resPrint; $sql .= " GROUP BY ff.rowid, ff.ref, ff.fk_statut, ff.libelle, ff.total_ht, ff.tva, ff.total_tva, ff.total_ttc, ff.tms, ff.paye,"; - $sql .= " s.nom, s.rowid, s.code_fournisseur, s.code_compta_fournisseur"; + $sql .= " s.nom, s.rowid, s.code_fournisseur, s.code_compta_fournisseur, s.email"; $sql .= " ORDER BY ff.tms DESC "; $sql .= $db->plimit($max, 0); From 3eb23d3325e291022407f665080258d72f4a76a0 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Tue, 11 Aug 2020 10:12:19 +0200 Subject: [PATCH 352/434] FIX: MySql Strict mode --- htdocs/compta/facture/list.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 9b9b986324f..71184d905b3 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -5,7 +5,7 @@ * Copyright (C) 2005 Marc Barilley / Ocebo * Copyright (C) 2005-2015 Regis Houssin * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2010-2012 Juanjo Menent + * Copyright (C) 2010-2020 Juanjo Menent * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Cédric Salvador @@ -554,6 +554,8 @@ if (!$sall) $sql .= ' f.paye, f.fk_statut, f.close_code,'; $sql .= ' f.datec, f.tms, f.date_closing,'; $sql .= ' f.retained_warranty, f.retained_warranty_date_limit, f.situation_final, f.situation_cycle_ref, f.situation_counter,'; + $sql .= ' f.fk_user_author, f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva,'; + $sql .= ' f.multicurrency_total_tva, f.multicurrency_total_ttc,'; $sql .= ' s.rowid, s.nom, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,'; $sql .= ' typent.code,'; $sql .= ' state.code_departement, state.nom,'; From ef78b85062afcf86914300939e780104e8df8acb Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 11 Aug 2020 10:42:27 +0000 Subject: [PATCH 353/434] Fixing style errors. --- htdocs/core/tpl/objectline_create.tpl.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 8a745d10d92..86d321e0598 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -487,7 +487,7 @@ if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dat if($prefillDates) { -?> + ?> function prefill_service_dates() { $('#date_start').val("").trigger('change'); @@ -501,7 +501,7 @@ if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dat $('#prefill_service_dates').click(prefill_service_dates); }); - Date: Wed, 12 Aug 2020 07:07:18 +0200 Subject: [PATCH 354/434] Avoid empty sales and orders when all lines are removed. --- htdocs/takepos/invoice.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index cfde72c9fd3..350299814ec 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -398,6 +398,7 @@ if ($action == "deleteline") { $invoice->deleteline($deletelineid); $invoice->fetch($placeid); } + if (count($invoice->lines)==0) $invoice->delete($user); } if ($action == "delete") { From 10810bc5bb3ed80a4892068e36cc21491be9479b Mon Sep 17 00:00:00 2001 From: atm-thibaultf Date: Wed, 12 Aug 2020 09:09:59 +0200 Subject: [PATCH 355/434] Modify int to float for stock limit alert and desired stock --- htdocs/install/mysql/migration/12.0.0-13.0.0.sql | 7 +++++++ htdocs/install/mysql/tables/llx_product.sql | 4 ++-- htdocs/install/mysql/tables/llx_product_stock_entrepot.sql | 4 ++-- htdocs/product/class/product.class.php | 6 +++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 3bb62c53e61..8859a6b5f0b 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -219,3 +219,10 @@ create table llx_c_recruitment_origin label varchar(64) NOT NULL, active tinyint DEFAULT 1 NOT NULL )ENGINE=innodb; + + + +ALTER TABLE llx_product MODIFY COLUMN seuil_stock_alerte float; +ALTER TABLE llx_product MODIFY COLUMN desiredstock float; +ALTER TABLE llx_product_warehouse_properties MODIFY COLUMN seuil_stock_alerte float; +ALTER TABLE llx_product_warehouse_properties MODIFY COLUMN desiredstock float; diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index b360b4d7f9d..074012e138c 100644 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -60,7 +60,7 @@ create table llx_product tobatch tinyint DEFAULT 0 NOT NULL, -- Is it a product that need a batch management (eat-by or lot management) fk_product_type integer DEFAULT 0, -- Type of product: 0 for regular product, 1 for service, 9 for other (used by external module) duration varchar(6), - seuil_stock_alerte integer DEFAULT NULL, + seuil_stock_alerte float DEFAULT NULL, url varchar(255), barcode varchar(180) DEFAULT NULL, -- barcode fk_barcode_type integer DEFAULT NULL, -- barcode type @@ -96,7 +96,7 @@ create table llx_product import_key varchar(14), -- Import key model_pdf varchar(255), -- model save dodument used fk_price_expression integer, -- Link to the rule for dynamic price calculation - desiredstock integer DEFAULT 0, + desiredstock float DEFAULT 0, fk_unit integer DEFAULT NULL, price_autogen tinyint DEFAULT 0, fk_project integer DEFAULT NULL -- Used when product was generated by a project or is specifif to a project diff --git a/htdocs/install/mysql/tables/llx_product_stock_entrepot.sql b/htdocs/install/mysql/tables/llx_product_stock_entrepot.sql index b5d69defd9e..903bd59b524 100644 --- a/htdocs/install/mysql/tables/llx_product_stock_entrepot.sql +++ b/htdocs/install/mysql/tables/llx_product_stock_entrepot.sql @@ -24,8 +24,8 @@ create table llx_product_warehouse_properties tms timestamp, fk_product integer NOT NULL, fk_entrepot integer NOT NULL, - seuil_stock_alerte integer DEFAULT '0', - desiredstock integer DEFAULT '0', + seuil_stock_alerte float DEFAULT '0', + desiredstock float DEFAULT '0', import_key varchar(14) -- Import key )ENGINE=innodb; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index d5dbc0204c0..52c7d329b0d 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -205,7 +205,7 @@ class Product extends CommonObject /** * Stock alert * - * @var int + * @var float */ public $seuil_stock_alerte = 0; @@ -995,7 +995,7 @@ class Product extends CommonObject $sql .= ", volume = ".($this->volume != '' ? "'".$this->db->escape($this->volume)."'" : 'null'); $sql .= ", volume_units = ".($this->volume_units != '' ? "'".$this->db->escape($this->volume_units)."'" : 'null'); $sql .= ", fk_default_warehouse = ".($this->fk_default_warehouse > 0 ? $this->db->escape($this->fk_default_warehouse) : 'null'); - $sql .= ", seuil_stock_alerte = ".((isset($this->seuil_stock_alerte) && is_numeric($this->seuil_stock_alerte)) ? (int) $this->seuil_stock_alerte : 'null'); + $sql .= ", seuil_stock_alerte = ".((isset($this->seuil_stock_alerte) && is_numeric($this->seuil_stock_alerte)) ? (float) $this->seuil_stock_alerte : 'null'); $sql .= ", description = '".$this->db->escape($this->description)."'"; $sql .= ", url = ".($this->url ? "'".$this->db->escape($this->url)."'" : 'null'); $sql .= ", customcode = '".$this->db->escape($this->customcode)."'"; @@ -1008,7 +1008,7 @@ class Product extends CommonObject $sql .= ", accountancy_code_sell= '".$this->db->escape($this->accountancy_code_sell)."'"; $sql .= ", accountancy_code_sell_intra= '".$this->db->escape($this->accountancy_code_sell_intra)."'"; $sql .= ", accountancy_code_sell_export= '".$this->db->escape($this->accountancy_code_sell_export)."'"; - $sql .= ", desiredstock = ".((isset($this->desiredstock) && is_numeric($this->desiredstock)) ? (int) $this->desiredstock : "null"); + $sql .= ", desiredstock = ".((isset($this->desiredstock) && is_numeric($this->desiredstock)) ? (float) $this->desiredstock : "null"); $sql .= ", cost_price = ".($this->cost_price != '' ? $this->db->escape($this->cost_price) : 'null'); $sql .= ", fk_unit= ".(!$this->fk_unit ? 'NULL' : (int) $this->fk_unit); $sql .= ", price_autogen = ".(!$this->price_autogen ? 0 : 1); From f0268b4aafa979d9502cb72666f039602765d46d Mon Sep 17 00:00:00 2001 From: John Botella Date: Wed, 12 Aug 2020 10:14:29 +0200 Subject: [PATCH 356/434] Add declinaison price level --- .../install/mysql/migration/12.0.0-13.0.0.sql | 10 +- ...duct_attribute_combination_price_level.sql | 28 ++ htdocs/langs/en_US/products.lang | 3 + htdocs/product/class/product.class.php | 2 +- .../class/ProductCombination.class.php | 440 +++++++++++++++++- htdocs/variants/combinations.php | 95 +++- 6 files changed, 562 insertions(+), 16 deletions(-) create mode 100644 htdocs/install/mysql/tables/llx_product_attribute_combination_price_level.sql diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 24b6fd687e1..cf4339f56b9 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -123,5 +123,13 @@ create table llx_recruitment_recruitmentjobposition_extrafields ALTER TABLE llx_recruitment_recruitmentjobposition_extrafields ADD INDEX idx_fk_object(fk_object); +CREATE TABLE llx_product_attribute_combination_price_level +( + rowid INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT, + fk_product_attribute_combination INTEGER DEFAULT 1 NOT NULL, + fk_price_level INTEGER DEFAULT 1 NOT NULL, + variation_price DOUBLE(24,8) NOT NULL, + variation_price_percentage INTEGER NULL +)ENGINE=innodb; - +ALTER TABLE llx_product_attribute_combination_price_level ADD UNIQUE( fk_product_attribute_combination, fk_price_level); diff --git a/htdocs/install/mysql/tables/llx_product_attribute_combination_price_level.sql b/htdocs/install/mysql/tables/llx_product_attribute_combination_price_level.sql new file mode 100644 index 00000000000..ae068b71ed0 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_product_attribute_combination_price_level.sql @@ -0,0 +1,28 @@ +-- ============================================================================ +-- Copyright (C) 2020 John BOTELLA +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- ============================================================================ + +CREATE TABLE llx_product_attribute_combination_price_level +( + rowid INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT, + fk_product_attribute_combination INTEGER DEFAULT 1 NOT NULL, + fk_price_level INTEGER DEFAULT 1 NOT NULL, + variation_price DOUBLE(24,8) NOT NULL, + variation_price_percentage INTEGER NULL +)ENGINE=innodb; + +ALTER TABLE llx_product_attribute_combination_price_level ADD UNIQUE( fk_product_attribute_combination, fk_price_level); diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 7f82db63178..be1afc5b7e7 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -361,6 +361,9 @@ SelectCombination=Select combination ProductCombinationGenerator=Variants generator Features=Features PriceImpact=Price impact +ImpactOnPriceLevel=Impact on price level %s +ApplyToAllPriceImpactLevel= Apply to all levels +ApplyToAllPriceImpactLevelHelp=By clicking here you set the same price impact on all levels WeightImpact=Weight impact NewProductAttribute=New attribute NewProductAttributeValue=New attribute value diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 07450eef805..39634c11302 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1077,7 +1077,7 @@ class Product extends CommonObject $comb = new ProductCombination($this->db); foreach ($comb->fetchAllByFkProductParent($this->id) as $currcomb) { - $currcomb->updateProperties($this, $user); + $currcomb->updateProperties($this, $user); } } diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 3bb4f7312ee..777cb136b05 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -71,6 +71,12 @@ class ProductCombination */ public $entity; + /** + * Combination price level + * @var ProductCombinationLevel[] + */ + public $combination_price_levels; + /** * Constructor * @@ -92,6 +98,8 @@ class ProductCombination */ public function fetch($rowid) { + global $conf; + $sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE rowid = ".(int) $rowid." AND entity IN (".getEntity('product').")"; $query = $this->db->query($sql); @@ -113,9 +121,95 @@ class ProductCombination $this->variation_price_percentage = $obj->variation_price_percentage; $this->variation_weight = $obj->variation_weight; + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $this->fetchCombinationPriceLevels(); + } + return 1; } + + /** + * Retrieves combination price levels + * + * @param int $fk_price_level the price level to fetch, use 0 for all + * @param bool $useCache to use cache or not + * @return int <0 KO, >0 OK + */ + public function fetchCombinationPriceLevels($fk_price_level = 0, $useCache = true) + { + // Check cache + if(!empty($this->combination_price_levels) && $useCache){ + if((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)){ + return 1; + } + } + + if(!is_array($this->combination_price_levels) + || empty($fk_price_level) // if fetch an unique level dont erase all already fetched + ){ + $this->combination_price_levels = array(); + } + + $staticProductCombinationLevel = new ProductCombinationLevel($this->db); + $combination_price_levels = $staticProductCombinationLevel->fetchAll($this->id, $fk_price_level); + + if (!$combination_price_levels || !is_array($combination_price_levels)) { + return -1; + } + + $this->combination_price_levels = $combination_price_levels; + + return 1; + } + + /** + * Retrieves combination price levels + * + * @param int $clean levels off PRODUIT_MULTIPRICES_LIMIT + * @return int <0 KO, >0 OK + */ + public function saveCombinationPriceLevels($clean = 1) + { + global $conf; + + $errors = 0; + + $staticProductCombinationLevel = new ProductCombinationLevel($this->db); + + // Delete all + if(empty($this->combination_price_levels)){ + return $staticProductCombinationLevel->deleteAllForCombination($this->id); + } + + // Clean not needed price levels + if($clean){ + $res = $staticProductCombinationLevel->clean($this->id); + + if($res<0){ + $this->errors[] = 'Fail to clean not needed price levels'; + return -1; + } + } + + foreach ($this->combination_price_levels as $fk_price_level => $combination_price_level){ + $res = $combination_price_level->save(); + if($res<1){ + $this->error = 'save combination price level '.$fk_price_level . ' '.$combination_price_level->error; + $this->errors[] = $this->error; + $errors ++; + } + } + + if($errors > 0){ + return $errors*-1; + } + else{ + return 1; + } + } + + /** * Retrieves a product combination by a child product row id * @@ -124,6 +218,8 @@ class ProductCombination */ public function fetchByFkProductChild($fk_child) { + global $conf; + $sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_child = ".(int) $fk_child." AND entity IN (".getEntity('product').")"; $query = $this->db->query($sql); @@ -145,6 +241,10 @@ class ProductCombination $this->variation_price_percentage = $result->variation_price_percentage; $this->variation_weight = $result->variation_weight; + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $this->fetchCombinationPriceLevels(); + } + return 1; } @@ -156,6 +256,8 @@ class ProductCombination */ public function fetchAllByFkProductParent($fk_product_parent) { + global $conf; + $sql = "SELECT rowid, fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".(int) $fk_product_parent." AND entity IN (".getEntity('product').")"; $query = $this->db->query($sql); @@ -175,6 +277,10 @@ class ProductCombination $tmp->variation_price_percentage = $result->variation_price_percentage; $tmp->variation_weight = $result->variation_weight; + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $tmp->fetchCombinationPriceLevels(); + } + $return[] = $tmp; } @@ -209,6 +315,8 @@ class ProductCombination */ public function create($user) { + global $conf; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_combination (fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight, entity) VALUES (".(int) $this->fk_product_parent.", ".(int) $this->fk_product_child.", @@ -221,6 +329,13 @@ class ProductCombination return -1; } + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $res = $this->saveCombinationPriceLevels(); + if($res<0){ + return -2; + } + } + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_combination'); return 1; @@ -234,6 +349,8 @@ class ProductCombination */ public function update(User $user) { + global $conf; + $sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute_combination SET fk_product_parent = ".(int) $this->fk_product_parent.", fk_product_child = ".(int) $this->fk_product_child.", variation_price = ".(float) $this->variation_price.", variation_price_percentage = ".(int) $this->variation_price_percentage.", @@ -245,6 +362,14 @@ class ProductCombination return -1; } + + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $res = $this->saveCombinationPriceLevels(); + if($res<0){ + return -2; + } + } + $parent = new Product($this->db); $parent->fetch($this->fk_product_parent); @@ -266,6 +391,12 @@ class ProductCombination $comb2val = new ProductCombination2ValuePair($this->db); $comb2val->deleteByFkCombination($this->id); + // remove combination price levels + if(!$this->db->query("DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination_price_level WHERE fk_product_attribute_combination = ".(int) $this->id)) { + $this->db->rollback(); + return -1; + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE rowid = ".(int) $this->id; if ($this->db->query($sql)) { @@ -341,6 +472,7 @@ class ProductCombination $child->label = $parent->label.$varlabel;; } + if ($child->update($child->id, $user) > 0) { $new_vat = $parent->tva_tx; $new_npr = $parent->tva_npr; @@ -349,9 +481,12 @@ class ProductCombination if (!empty($conf->global->PRODUIT_MULTIPRICES)) { for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { - if ($parent->multiprices[$i] != '') { + if ($parent->multiprices[$i] != '' || isset($this->combination_price_levels[$i]->variation_price)) { $new_type = $parent->multiprices_base_type[$i]; $new_min_price = $parent->multiprices_min[$i]; + $variation_price = doubleval(!isset($this->combination_price_levels[$i]->variation_price) ? $this->variation_price : $this->combination_price_levels[$i]->variation_price); + $variation_price_percentage = doubleval(!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage); + if ($parent->prices_by_qty_list[$i]) { $new_psq = 1; } else { @@ -364,12 +499,12 @@ class ProductCombination $new_price = $parent->multiprices[$i]; } - if ($this->variation_price_percentage) { + if ($variation_price_percentage) { if ($new_price != 0) { - $new_price *= 1 + ($this->variation_price / 100); + $new_price *= 1 + ($variation_price / 100); } } else { - $new_price += $this->variation_price; + $new_price += $variation_price; } $child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, $i, $new_npr, $new_psq); @@ -508,7 +643,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; * @param Product $product Parent product * @param array $combinations Attribute and value combinations. * @param array $variations Price and weight variations - * @param bool $price_var_percent Is the price variation a relative variation? + * @param bool|array $price_var_percent Is the price variation a relative variation? * @param bool|float $forced_pricevar If the price variation is forced * @param bool|float $forced_weightvar If the weight variation is forced * @param bool|string $forced_refvar If the reference is forced @@ -523,6 +658,8 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $db->begin(); + $price_impact = array(1=>0); // init level price impact + $forced_refvar = trim($forced_refvar); if (!empty($forced_refvar) && $forced_refvar != $product->ref) { @@ -545,7 +682,12 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $weight_impact = (float) $forced_weightvar; // If false, return 0 //Final price impact - $price_impact = (float) $forced_pricevar; // If false, return 0 + if(!is_array($forced_pricevar)){ + $price_impact[1] = (float) $forced_pricevar; // If false, return 0 + } + else{ + $price_impact = $forced_pricevar; + } $newcomb = new ProductCombination($db); $existingCombination = $newcomb->fetchByProductCombination2ValuePairs($product->id, $combinations); @@ -587,7 +729,15 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $weight_impact += (float) price2num($variations[$currcombattr][$currcombval]['weight']); } if ($forced_pricevar === false) { - $price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']); + $price_impact[1] += (float) price2num($variations[$currcombattr][$currcombval]['price']); + + // Manage Price levels + if($conf->global->PRODUIT_MULTIPRICES){ + for ($i = 2; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) + { + $price_impact[$i] += (float) price2num($variations[$currcombattr][$currcombval]['price']); + } + } } if ($forced_refvar === false) { @@ -606,9 +756,27 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; } $newcomb->variation_price_percentage = $price_var_percent; - $newcomb->variation_price = $price_impact; + $newcomb->variation_price = $price_impact[1]; $newcomb->variation_weight = $weight_impact; + // Init price level + if($conf->global->PRODUIT_MULTIPRICES){ + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){ + $productCombinationLevel = new ProductCombinationLevel($this->db); + $productCombinationLevel->fk_product_attribute_combination = 0; + $productCombinationLevel->fk_price_level = $i; + $productCombinationLevel->variation_price = $price_impact[$i]; + + if(is_array($price_var_percent)){ + $productCombinationLevel->variation_price_percentage = !empty($price_var_percent[$i]) ? $price_var_percent[$i] : 0; + }else{ + $productCombinationLevel->variation_price_percentage = $price_var_percent; + } + + $newcomb->combination_price_levels[$i] = $productCombinationLevel; + } + } + $newproduct->weight += $weight_impact; // Now create the product @@ -764,3 +932,259 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; return $label; } } + + + +/** + * Class ProductCombinationLevel + * Used to represent a product combination Level + */ +class ProductCombinationLevel +{ + /** + * Database handler + * @var DoliDB + */ + private $db; + + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'product_attribute_combination_price_level'; + + /** + * Rowid of combination + * @var int + */ + public $id; + + /** + * Rowid of parent product combination + * @var int + */ + public $fk_product_attribute_combination; + + /** + * Combination price level + * @var int + */ + public $fk_price_level; + + /** + * Price variation + * @var float + */ + public $variation_price; + + /** + * Is the price variation a relative variation? + * @var bool + */ + public $variation_price_percentage = false; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Retrieves a combination level by its rowid + * + * @param int $rowid Row id + * @return int <0 KO, >0 OK + */ + public function fetch($rowid) + { + $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage FROM " . MAIN_DB_PREFIX . $this->table_element." WHERE rowid = " . (int)$rowid; + + $obj = $this->db->getRow($sql); + + if($obj){ + return $this->fetchFormObj($obj); + } + + return -1; + } + + + /** + * Retrieves combination price levels + * + * @param int $fk_product_attribute_combination + * @param int $fk_price_level the price level to fetch, use 0 for all + * @return self[] | -1 on KO + */ + public function fetchAll($fk_product_attribute_combination, $fk_price_level = 0) + { + + $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage" + ." FROM ".MAIN_DB_PREFIX.$this->table_element + ." WHERE fk_product_attribute_combination = ".intval($fk_product_attribute_combination); + + if(!empty($fk_price_level)){ + $sql.= ' AND fk_price_level = '.intval($fk_price_level); + } + + $combination_price_levels = $this->db->getRows($sql); + + if (!$combination_price_levels || !is_array($combination_price_levels)) { + return -1; + } + + $result = array(); + + // For more simple usage set level as array key + foreach($combination_price_levels as $k => $row){ + $productCombinationLevel = new ProductCombinationLevel($this->db); + $productCombinationLevel->fetchFormObj($row); + $result[$row->fk_price_level] = $productCombinationLevel; + } + + return $result; + } + + /** + * assign vars form an stdclass like sql obj + * + * @param int $rowid Row id + * @return int <0 KO, >0 OK + */ + public function fetchFormObj($obj) + { + if (!$obj) { + return -1; + } + + $this->id = $obj->rowid; + $this->fk_product_attribute_combination = doubleval($obj->fk_product_attribute_combination); + $this->fk_price_level = intval($obj->fk_price_level); + $this->variation_price = doubleval($obj->variation_price); + $this->variation_price_percentage = (bool)$obj->variation_price_percentage; + + return 1; + } + + + /** + * save + * + * @return int <0 KO, >0 OK + */ + public function save() + { + $errors = 0; + + + if(empty($this->fk_product_attribute_combination) || empty($this->fk_price_level)){ + return -1; + } + + // check if level exist in DB before add + if(empty($this->id)){ + $sql = "SELECT rowid id" + ." FROM ".MAIN_DB_PREFIX . $this->table_element + ." WHERE fk_product_attribute_combination = ".(int) $this->fk_product_attribute_combination + .' AND fk_price_level = '.intval($this->fk_price_level); + + $existObj = $this->db->getRow($sql); + if($existObj){ + $this->id = $existObj->id; + } + } + + // Update + if(!empty($this->id)) { + $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET ' + . ' variation_price = '.doubleval($this->variation_price) + . ' , variation_price_percentage = '.intval($this->variation_price_percentage) + . ' WHERE rowid = '.intval($this->id); + + $res = $this->db->query($sql); + if($res>0){ + return $this->id; + } + else{ + $this->error = $this->db->error(); + $this->errors[] = $this->error; + return -1; + } + } + else{ + // ADD + $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (" + . " fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage" + . " ) VALUES ( " + . intval($this->fk_product_attribute_combination) + . ' , '.intval($this->fk_price_level) + . ' , '.doubleval($this->variation_price) + . ' , '.intval($this->variation_price_percentage) + . " )"; + + $res = $this->db->query($sql); + if($res){ + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); + } + else{ + $this->error = $this->db->error(); + $this->errors[] = $this->error; + return -1; + } + } + + return $this->id; + } + + + /** + * delete + * + * @return int <0 KO, >0 OK + */ + public function delete() + { + $res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element + ." WHERE rowid = ".(int) $this->id); + + return $res ? 1 : -1; + } + + + /** + * delete all for a combination + * + * @param $fk_product_attribute_combination + * @return int <0 KO, >0 OK + */ + public function deleteAllForCombination($fk_product_attribute_combination) + { + $res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element + ." WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination); + + return $res ? 1 : -1; + } + + + /** + * Clean not needed price levels for a combination + * + * @param $fk_product_attribute_combination + * @return int <0 KO, >0 OK + */ + public function clean($fk_product_attribute_combination) + { + global $conf; + + $res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element + . " WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination + . " AND fk_price_level > ".intval($conf->global->PRODUIT_MULTIPRICES_LIMIT) ); + + + return $res ? 1 : -1; + } + +} diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 3886a8fcdce..5ad7b38af2e 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -33,6 +33,10 @@ $ref = GETPOST('ref', 'alpha'); $weight_impact = GETPOST('weight_impact', 'alpha'); $price_impact = GETPOST('price_impact', 'alpha'); $price_impact_percent = (bool) GETPOST('price_impact_percent'); + +$level_price_impact = GETPOST('level_price_impact', 'array'); +$level_price_impact_percent = GETPOST('level_price_impact_percent', 'array'); + $reference = GETPOST('reference', 'alpha'); $form = new Form($db); @@ -112,6 +116,18 @@ if ($_POST) { } $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); + + // for conf PRODUIT_MULTIPRICES + if($conf->global->PRODUIT_MULTIPRICES) { + $level_price_impact = array_map('price2num', $level_price_impact); + $level_price_impact_percent = array_map('price2num', $level_price_impact_percent); + } + else{ + $level_price_impact = array(1 => $weight_impact); + $level_price_impact_percent = array(1 => $price_impact_percent); + } + + $sanit_features = array(); //First, sanitize @@ -141,11 +157,10 @@ if ($_POST) { // sanit_feature is an array with 1 (and only 1) value per attribute. // For example: Color->blue, Size->Small, Option->2 //var_dump($sanit_features); - //var_dump($productCombination2ValuePairs1); exit; if (!$prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features)) { - $result = $prodcomb->createProductCombination($user, $object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact, $reference); + $result = $prodcomb->createProductCombination($user, $object, $sanit_features, array(), $level_price_impact_percent, $level_price_impact, $weight_impact, $reference); if ($result > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); @@ -227,6 +242,31 @@ if ($_POST) { $prodcomb->variation_price = $price_impact; $prodcomb->variation_weight = $weight_impact; + // for conf PRODUIT_MULTIPRICES + if($conf->global->PRODUIT_MULTIPRICES) { + $level_price_impact = array_map('price2num', $level_price_impact); + $level_price_impact_percent = array_map(function($a){ return !empty($a);}, $level_price_impact_percent); + + $prodcomb->variation_price = $level_price_impact[1]; + $prodcomb->variation_price_percentage = (bool)$level_price_impact_percent[1]; + } + else{ + $level_price_impact = array(1 => $weight_impact); + $level_price_impact_percent = array(1 => $price_impact_percent); + } + + if($conf->global->PRODUIT_MULTIPRICES){ + $prodcomb->combination_price_levels = array(); + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){ + $productCombinationLevel = new ProductCombinationLevel($db); + $productCombinationLevel->fk_product_attribute_combination = $prodcomb->id; + $productCombinationLevel->fk_price_level = $i; + $productCombinationLevel->variation_price = $level_price_impact[$i]; + $productCombinationLevel->variation_price_percentage = $level_price_impact_percent[$i]; + $prodcomb->combination_price_levels[$i] = $productCombinationLevel; + } + } + if ($prodcomb->update($user) > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2)); @@ -594,12 +634,34 @@ if (!empty($id) || !empty($ref)) +global->PRODUIT_MULTIPRICES)){ ?> - > + > + - fetchCombinationPriceLevels(); + + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) + { + + print ''; + print ''; + if($i===1){ + print ' ('.$langs->trans('ApplyToAllPriceImpactLevel').')'; + } + print ''; + print ''; + print 'combination_price_levels[$i]->variation_price_percentage) ? ' checked' : '' ).'> '; + + print ''; + print ''; + } + } + if ($object->isProduct()) { print ''; print ''; @@ -609,9 +671,30 @@ if (!empty($id) || !empty($ref)) print ''; } - dol_fiche_end(); - ?> + if (!empty($conf->global->PRODUIT_MULTIPRICES)){ +?> + +
    value="trans('Create') : $langs->trans('Save') ?>" class="button">   From 1cc673a9c61722dd9c628f3dde9d386c374bc7bb Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 12 Aug 2020 08:53:24 +0000 Subject: [PATCH 357/434] Fixing style errors. --- .../class/ProductCombination.class.php | 65 +++++++++---------- htdocs/variants/combinations.php | 32 ++++----- 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 777cb136b05..17d1688d268 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -139,13 +139,13 @@ class ProductCombination public function fetchCombinationPriceLevels($fk_price_level = 0, $useCache = true) { // Check cache - if(!empty($this->combination_price_levels) && $useCache){ - if((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)){ + if (!empty($this->combination_price_levels) && $useCache){ + if ((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)){ return 1; } } - if(!is_array($this->combination_price_levels) + if (!is_array($this->combination_price_levels) || empty($fk_price_level) // if fetch an unique level dont erase all already fetched ){ $this->combination_price_levels = array(); @@ -178,15 +178,15 @@ class ProductCombination $staticProductCombinationLevel = new ProductCombinationLevel($this->db); // Delete all - if(empty($this->combination_price_levels)){ + if (empty($this->combination_price_levels)){ return $staticProductCombinationLevel->deleteAllForCombination($this->id); } // Clean not needed price levels - if($clean){ + if ($clean){ $res = $staticProductCombinationLevel->clean($this->id); - if($res<0){ + if ($res<0){ $this->errors[] = 'Fail to clean not needed price levels'; return -1; } @@ -194,17 +194,17 @@ class ProductCombination foreach ($this->combination_price_levels as $fk_price_level => $combination_price_level){ $res = $combination_price_level->save(); - if($res<1){ + if ($res<1){ $this->error = 'save combination price level '.$fk_price_level . ' '.$combination_price_level->error; $this->errors[] = $this->error; $errors ++; } } - if($errors > 0){ + if ($errors > 0){ return $errors*-1; } - else{ + else { return 1; } } @@ -331,7 +331,7 @@ class ProductCombination if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $res = $this->saveCombinationPriceLevels(); - if($res<0){ + if ($res<0){ return -2; } } @@ -365,7 +365,7 @@ class ProductCombination if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $res = $this->saveCombinationPriceLevels(); - if($res<0){ + if ($res<0){ return -2; } } @@ -392,7 +392,7 @@ class ProductCombination $comb2val->deleteByFkCombination($this->id); // remove combination price levels - if(!$this->db->query("DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination_price_level WHERE fk_product_attribute_combination = ".(int) $this->id)) { + if (!$this->db->query("DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination_price_level WHERE fk_product_attribute_combination = ".(int) $this->id)) { $this->db->rollback(); return -1; } @@ -682,10 +682,10 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $weight_impact = (float) $forced_weightvar; // If false, return 0 //Final price impact - if(!is_array($forced_pricevar)){ + if (!is_array($forced_pricevar)){ $price_impact[1] = (float) $forced_pricevar; // If false, return 0 } - else{ + else { $price_impact = $forced_pricevar; } @@ -732,7 +732,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $price_impact[1] += (float) price2num($variations[$currcombattr][$currcombval]['price']); // Manage Price levels - if($conf->global->PRODUIT_MULTIPRICES){ + if ($conf->global->PRODUIT_MULTIPRICES){ for ($i = 2; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { $price_impact[$i] += (float) price2num($variations[$currcombattr][$currcombval]['price']); @@ -760,16 +760,16 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newcomb->variation_weight = $weight_impact; // Init price level - if($conf->global->PRODUIT_MULTIPRICES){ + if ($conf->global->PRODUIT_MULTIPRICES){ for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){ $productCombinationLevel = new ProductCombinationLevel($this->db); $productCombinationLevel->fk_product_attribute_combination = 0; $productCombinationLevel->fk_price_level = $i; $productCombinationLevel->variation_price = $price_impact[$i]; - if(is_array($price_var_percent)){ + if (is_array($price_var_percent)){ $productCombinationLevel->variation_price_percentage = !empty($price_var_percent[$i]) ? $price_var_percent[$i] : 0; - }else{ + }else { $productCombinationLevel->variation_price_percentage = $price_var_percent; } @@ -1000,11 +1000,11 @@ class ProductCombinationLevel */ public function fetch($rowid) { - $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage FROM " . MAIN_DB_PREFIX . $this->table_element." WHERE rowid = " . (int)$rowid; + $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage FROM " . MAIN_DB_PREFIX . $this->table_element." WHERE rowid = " . (int) $rowid; $obj = $this->db->getRow($sql); - if($obj){ + if ($obj){ return $this->fetchFormObj($obj); } @@ -1026,7 +1026,7 @@ class ProductCombinationLevel ." FROM ".MAIN_DB_PREFIX.$this->table_element ." WHERE fk_product_attribute_combination = ".intval($fk_product_attribute_combination); - if(!empty($fk_price_level)){ + if (!empty($fk_price_level)){ $sql.= ' AND fk_price_level = '.intval($fk_price_level); } @@ -1039,7 +1039,7 @@ class ProductCombinationLevel $result = array(); // For more simple usage set level as array key - foreach($combination_price_levels as $k => $row){ + foreach ($combination_price_levels as $k => $row){ $productCombinationLevel = new ProductCombinationLevel($this->db); $productCombinationLevel->fetchFormObj($row); $result[$row->fk_price_level] = $productCombinationLevel; @@ -1064,7 +1064,7 @@ class ProductCombinationLevel $this->fk_product_attribute_combination = doubleval($obj->fk_product_attribute_combination); $this->fk_price_level = intval($obj->fk_price_level); $this->variation_price = doubleval($obj->variation_price); - $this->variation_price_percentage = (bool)$obj->variation_price_percentage; + $this->variation_price_percentage = (bool) $obj->variation_price_percentage; return 1; } @@ -1080,41 +1080,41 @@ class ProductCombinationLevel $errors = 0; - if(empty($this->fk_product_attribute_combination) || empty($this->fk_price_level)){ + if (empty($this->fk_product_attribute_combination) || empty($this->fk_price_level)){ return -1; } // check if level exist in DB before add - if(empty($this->id)){ + if (empty($this->id)){ $sql = "SELECT rowid id" ." FROM ".MAIN_DB_PREFIX . $this->table_element ." WHERE fk_product_attribute_combination = ".(int) $this->fk_product_attribute_combination .' AND fk_price_level = '.intval($this->fk_price_level); $existObj = $this->db->getRow($sql); - if($existObj){ + if ($existObj){ $this->id = $existObj->id; } } // Update - if(!empty($this->id)) { + if (!empty($this->id)) { $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET ' . ' variation_price = '.doubleval($this->variation_price) . ' , variation_price_percentage = '.intval($this->variation_price_percentage) . ' WHERE rowid = '.intval($this->id); $res = $this->db->query($sql); - if($res>0){ + if ($res>0){ return $this->id; } - else{ + else { $this->error = $this->db->error(); $this->errors[] = $this->error; return -1; } } - else{ + else { // ADD $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (" . " fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage" @@ -1126,10 +1126,10 @@ class ProductCombinationLevel . " )"; $res = $this->db->query($sql); - if($res){ + if ($res){ $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); } - else{ + else { $this->error = $this->db->error(); $this->errors[] = $this->error; return -1; @@ -1186,5 +1186,4 @@ class ProductCombinationLevel return $res ? 1 : -1; } - } diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 5ad7b38af2e..b9f62bdcf73 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -118,11 +118,11 @@ if ($_POST) { $price_impact = price2num($price_impact); // for conf PRODUIT_MULTIPRICES - if($conf->global->PRODUIT_MULTIPRICES) { + if ($conf->global->PRODUIT_MULTIPRICES) { $level_price_impact = array_map('price2num', $level_price_impact); $level_price_impact_percent = array_map('price2num', $level_price_impact_percent); } - else{ + else { $level_price_impact = array(1 => $weight_impact); $level_price_impact_percent = array(1 => $price_impact_percent); } @@ -243,19 +243,20 @@ if ($_POST) { $prodcomb->variation_weight = $weight_impact; // for conf PRODUIT_MULTIPRICES - if($conf->global->PRODUIT_MULTIPRICES) { + if ($conf->global->PRODUIT_MULTIPRICES) { $level_price_impact = array_map('price2num', $level_price_impact); - $level_price_impact_percent = array_map(function($a){ return !empty($a);}, $level_price_impact_percent); + $level_price_impact_percent = array_map(function ($a) { + return !empty($a);}, $level_price_impact_percent); $prodcomb->variation_price = $level_price_impact[1]; - $prodcomb->variation_price_percentage = (bool)$level_price_impact_percent[1]; + $prodcomb->variation_price_percentage = (bool) $level_price_impact_percent[1]; } - else{ + else { $level_price_impact = array(1 => $weight_impact); $level_price_impact_percent = array(1 => $price_impact_percent); } - if($conf->global->PRODUIT_MULTIPRICES){ + if ($conf->global->PRODUIT_MULTIPRICES){ $prodcomb->combination_price_levels = array(); for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){ $productCombinationLevel = new ProductCombinationLevel($db); @@ -634,23 +635,22 @@ if (!empty($id) || !empty($ref)) -global->PRODUIT_MULTIPRICES)){ ?> + global->PRODUIT_MULTIPRICES)){ ?> > -fetchCombinationPriceLevels(); for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { - print ''; - print ''; - if($i===1){ + print ''; + if ($i===1){ print ' ('.$langs->trans('ApplyToAllPriceImpactLevel').')'; } print ''; @@ -672,7 +672,7 @@ if (!empty($id) || !empty($ref)) } if (!empty($conf->global->PRODUIT_MULTIPRICES)){ -?> + ?> - + ?>
    value="trans('Create') : $langs->trans('Save') ?>" class="button">   From 355d62e7db0d050a1e7296bb4f7195d78f3a6129 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 12 Aug 2020 20:24:44 +0200 Subject: [PATCH 358/434] FIX Update line of BOM --- htdocs/bom/bom_card.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index c98dee97f51..bd5e6fe7789 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -194,10 +194,10 @@ if (empty($reshook)) $error = 0; // Set if we used free entry or predefined product - $qty = GETPOST('qty', 'int'); + $qty = price2num(GETPOST('qty', 'int')); $qty_frozen = GETPOST('qty_frozen', 'int'); $disable_stock_change = GETPOST('disable_stock_change', 'int'); - $efficiency = GETPOST('efficiency', 'int'); + $efficiency = price2num(GETPOST('efficiency', 'int')); if ($qty == '') { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors'); @@ -223,6 +223,8 @@ if (empty($reshook)) unset($_POST['qty']); unset($_POST['qty_frozen']); unset($_POST['disable_stock_change']); + + $object->fetchLines(); } } } @@ -545,7 +547,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (!empty($object->table_element_line)) { - print ' + print ' From 4e1f554c15b0368a43fa2eb56fca821801d9cea5 Mon Sep 17 00:00:00 2001 From: John Botella Date: Thu, 13 Aug 2020 11:43:33 +0200 Subject: [PATCH 359/434] Fix - add variation price fallback behavior --- .../class/ProductCombination.class.php | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 777cb136b05..0b3b3843867 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -138,6 +138,8 @@ class ProductCombination */ public function fetchCombinationPriceLevels($fk_price_level = 0, $useCache = true) { + global $conf; + // Check cache if(!empty($this->combination_price_levels) && $useCache){ if((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)){ @@ -154,10 +156,31 @@ class ProductCombination $staticProductCombinationLevel = new ProductCombinationLevel($this->db); $combination_price_levels = $staticProductCombinationLevel->fetchAll($this->id, $fk_price_level); - if (!$combination_price_levels || !is_array($combination_price_levels)) { + if (!is_array($combination_price_levels)) { return -1; } + if(empty($combination_price_levels)){ + + /** + * for auto retrocompatibility with last behavior + */ + $productCombinationLevel = new ProductCombinationLevel($this->db); + $productCombinationLevel->fk_price_level = intval($fk_price_level); + $productCombinationLevel->fk_product_attribute_combination = $this->id; + $productCombinationLevel->variation_price = $this->variation_price; + $productCombinationLevel->variation_price_percentage = $this->variation_price_percentage; + + if($fk_price_level>0){ + $combination_price_levels[$fk_price_level] = $productCombinationLevel; + } + else{ + for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){ + $combination_price_levels[$i] = $productCombinationLevel; + } + } + } + $this->combination_price_levels = $combination_price_levels; return 1; @@ -1032,17 +1055,19 @@ class ProductCombinationLevel $combination_price_levels = $this->db->getRows($sql); - if (!$combination_price_levels || !is_array($combination_price_levels)) { + if (!is_array($combination_price_levels)) { return -1; } $result = array(); - // For more simple usage set level as array key - foreach($combination_price_levels as $k => $row){ - $productCombinationLevel = new ProductCombinationLevel($this->db); - $productCombinationLevel->fetchFormObj($row); - $result[$row->fk_price_level] = $productCombinationLevel; + if(!empty($combination_price_levels)) { + // For more simple usage set level as array key + foreach($combination_price_levels as $k => $row){ + $productCombinationLevel = new ProductCombinationLevel($this->db); + $productCombinationLevel->fetchFormObj($row); + $result[$row->fk_price_level] = $productCombinationLevel; + } } return $result; From 959ccce7770fe1174a07b31991f5a15e478c34c5 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 13 Aug 2020 09:48:28 +0000 Subject: [PATCH 360/434] Fixing style errors. --- .../class/ProductCombination.class.php | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 0b3b3843867..7d6a07d736d 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -141,13 +141,13 @@ class ProductCombination global $conf; // Check cache - if(!empty($this->combination_price_levels) && $useCache){ - if((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)){ + if (!empty($this->combination_price_levels) && $useCache){ + if ((!empty($fk_price_level) && isset($this->combination_price_levels[$fk_price_level])) || empty($fk_price_level)){ return 1; } } - if(!is_array($this->combination_price_levels) + if (!is_array($this->combination_price_levels) || empty($fk_price_level) // if fetch an unique level dont erase all already fetched ){ $this->combination_price_levels = array(); @@ -160,7 +160,7 @@ class ProductCombination return -1; } - if(empty($combination_price_levels)){ + if (empty($combination_price_levels)){ /** * for auto retrocompatibility with last behavior @@ -171,10 +171,10 @@ class ProductCombination $productCombinationLevel->variation_price = $this->variation_price; $productCombinationLevel->variation_price_percentage = $this->variation_price_percentage; - if($fk_price_level>0){ + if ($fk_price_level>0){ $combination_price_levels[$fk_price_level] = $productCombinationLevel; } - else{ + else { for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){ $combination_price_levels[$i] = $productCombinationLevel; } @@ -201,15 +201,15 @@ class ProductCombination $staticProductCombinationLevel = new ProductCombinationLevel($this->db); // Delete all - if(empty($this->combination_price_levels)){ + if (empty($this->combination_price_levels)){ return $staticProductCombinationLevel->deleteAllForCombination($this->id); } // Clean not needed price levels - if($clean){ + if ($clean){ $res = $staticProductCombinationLevel->clean($this->id); - if($res<0){ + if ($res<0){ $this->errors[] = 'Fail to clean not needed price levels'; return -1; } @@ -217,17 +217,17 @@ class ProductCombination foreach ($this->combination_price_levels as $fk_price_level => $combination_price_level){ $res = $combination_price_level->save(); - if($res<1){ + if ($res<1){ $this->error = 'save combination price level '.$fk_price_level . ' '.$combination_price_level->error; $this->errors[] = $this->error; $errors ++; } } - if($errors > 0){ + if ($errors > 0){ return $errors*-1; } - else{ + else { return 1; } } @@ -354,7 +354,7 @@ class ProductCombination if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $res = $this->saveCombinationPriceLevels(); - if($res<0){ + if ($res<0){ return -2; } } @@ -388,7 +388,7 @@ class ProductCombination if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $res = $this->saveCombinationPriceLevels(); - if($res<0){ + if ($res<0){ return -2; } } @@ -415,7 +415,7 @@ class ProductCombination $comb2val->deleteByFkCombination($this->id); // remove combination price levels - if(!$this->db->query("DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination_price_level WHERE fk_product_attribute_combination = ".(int) $this->id)) { + if (!$this->db->query("DELETE FROM ".MAIN_DB_PREFIX."product_attribute_combination_price_level WHERE fk_product_attribute_combination = ".(int) $this->id)) { $this->db->rollback(); return -1; } @@ -705,10 +705,10 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $weight_impact = (float) $forced_weightvar; // If false, return 0 //Final price impact - if(!is_array($forced_pricevar)){ + if (!is_array($forced_pricevar)){ $price_impact[1] = (float) $forced_pricevar; // If false, return 0 } - else{ + else { $price_impact = $forced_pricevar; } @@ -755,7 +755,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $price_impact[1] += (float) price2num($variations[$currcombattr][$currcombval]['price']); // Manage Price levels - if($conf->global->PRODUIT_MULTIPRICES){ + if ($conf->global->PRODUIT_MULTIPRICES){ for ($i = 2; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { $price_impact[$i] += (float) price2num($variations[$currcombattr][$currcombval]['price']); @@ -783,16 +783,16 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newcomb->variation_weight = $weight_impact; // Init price level - if($conf->global->PRODUIT_MULTIPRICES){ + if ($conf->global->PRODUIT_MULTIPRICES){ for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){ $productCombinationLevel = new ProductCombinationLevel($this->db); $productCombinationLevel->fk_product_attribute_combination = 0; $productCombinationLevel->fk_price_level = $i; $productCombinationLevel->variation_price = $price_impact[$i]; - if(is_array($price_var_percent)){ + if (is_array($price_var_percent)){ $productCombinationLevel->variation_price_percentage = !empty($price_var_percent[$i]) ? $price_var_percent[$i] : 0; - }else{ + }else { $productCombinationLevel->variation_price_percentage = $price_var_percent; } @@ -1023,11 +1023,11 @@ class ProductCombinationLevel */ public function fetch($rowid) { - $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage FROM " . MAIN_DB_PREFIX . $this->table_element." WHERE rowid = " . (int)$rowid; + $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage FROM " . MAIN_DB_PREFIX . $this->table_element." WHERE rowid = " . (int) $rowid; $obj = $this->db->getRow($sql); - if($obj){ + if ($obj){ return $this->fetchFormObj($obj); } @@ -1049,7 +1049,7 @@ class ProductCombinationLevel ." FROM ".MAIN_DB_PREFIX.$this->table_element ." WHERE fk_product_attribute_combination = ".intval($fk_product_attribute_combination); - if(!empty($fk_price_level)){ + if (!empty($fk_price_level)){ $sql.= ' AND fk_price_level = '.intval($fk_price_level); } @@ -1061,9 +1061,9 @@ class ProductCombinationLevel $result = array(); - if(!empty($combination_price_levels)) { + if (!empty($combination_price_levels)) { // For more simple usage set level as array key - foreach($combination_price_levels as $k => $row){ + foreach ($combination_price_levels as $k => $row){ $productCombinationLevel = new ProductCombinationLevel($this->db); $productCombinationLevel->fetchFormObj($row); $result[$row->fk_price_level] = $productCombinationLevel; @@ -1089,7 +1089,7 @@ class ProductCombinationLevel $this->fk_product_attribute_combination = doubleval($obj->fk_product_attribute_combination); $this->fk_price_level = intval($obj->fk_price_level); $this->variation_price = doubleval($obj->variation_price); - $this->variation_price_percentage = (bool)$obj->variation_price_percentage; + $this->variation_price_percentage = (bool) $obj->variation_price_percentage; return 1; } @@ -1105,41 +1105,41 @@ class ProductCombinationLevel $errors = 0; - if(empty($this->fk_product_attribute_combination) || empty($this->fk_price_level)){ + if (empty($this->fk_product_attribute_combination) || empty($this->fk_price_level)){ return -1; } // check if level exist in DB before add - if(empty($this->id)){ + if (empty($this->id)){ $sql = "SELECT rowid id" ." FROM ".MAIN_DB_PREFIX . $this->table_element ." WHERE fk_product_attribute_combination = ".(int) $this->fk_product_attribute_combination .' AND fk_price_level = '.intval($this->fk_price_level); $existObj = $this->db->getRow($sql); - if($existObj){ + if ($existObj){ $this->id = $existObj->id; } } // Update - if(!empty($this->id)) { + if (!empty($this->id)) { $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET ' . ' variation_price = '.doubleval($this->variation_price) . ' , variation_price_percentage = '.intval($this->variation_price_percentage) . ' WHERE rowid = '.intval($this->id); $res = $this->db->query($sql); - if($res>0){ + if ($res>0){ return $this->id; } - else{ + else { $this->error = $this->db->error(); $this->errors[] = $this->error; return -1; } } - else{ + else { // ADD $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (" . " fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage" @@ -1151,10 +1151,10 @@ class ProductCombinationLevel . " )"; $res = $this->db->query($sql); - if($res){ + if ($res){ $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); } - else{ + else { $this->error = $this->db->error(); $this->errors[] = $this->error; return -1; @@ -1211,5 +1211,4 @@ class ProductCombinationLevel return $res ? 1 : -1; } - } From 88c07e86add27428ea6f919408e87baafb3620dd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 13 Aug 2020 13:46:53 +0200 Subject: [PATCH 361/434] Organization of setup for Takepos bar features --- htdocs/core/lib/takepos.lib.php | 11 +- htdocs/langs/en_US/cashdesk.lang | 8 +- htdocs/takepos/admin/bar.php | 263 ++++++++++++++++--------------- htdocs/takepos/admin/receipt.php | 13 ++ htdocs/takepos/admin/setup.php | 16 -- 5 files changed, 160 insertions(+), 151 deletions(-) diff --git a/htdocs/core/lib/takepos.lib.php b/htdocs/core/lib/takepos.lib.php index 083e54c66c0..bf90f818b3e 100644 --- a/htdocs/core/lib/takepos.lib.php +++ b/htdocs/core/lib/takepos.lib.php @@ -48,13 +48,10 @@ function takepos_prepare_head() $head[$h][2] = 'receipt'; $h++; - if ($conf->global->TAKEPOS_BAR_RESTAURANT) - { - $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/bar.php'; - $head[$h][1] = $langs->trans("BarRestaurant"); - $head[$h][2] = 'bar'; - $h++; - } + $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/bar.php'; + $head[$h][1] = $langs->trans("BarRestaurant"); + $head[$h][2] = 'bar'; + $h++; $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS); for ($i = 1; $i <= $numterminals; $i++) diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index 73d8bdaa0df..a96f919e4f4 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -77,7 +77,7 @@ POSModule=POS Module BasicPhoneLayout=Use basic layout for phones SetupOfTerminalNotComplete=Setup of terminal %s is not complete DirectPayment=Direct payment -DirectPaymentButton=Direct cash payment button +DirectPaymentButton=Add a "Direct cash payment" button InvoiceIsAlreadyValidated=Invoice is already validated NoLinesToBill=No lines to bill CustomReceipt=Custom Receipt @@ -94,12 +94,12 @@ TakeposConnectorMethodDescription=External module with extra features. Posibilit PrintMethod=Print method ReceiptPrinterMethodDescription=Powerful method with a lot of parameters. Full customizable with templates. Cannot print from the cloud. ByTerminal=By terminal -TakeposNumpadUsePaymentIcon=Use payment icon on numpad +TakeposNumpadUsePaymentIcon=Use icon instead of text on payment buttons of numpad CashDeskRefNumberingModules=Numbering module for POS sales CashDeskGenericMaskCodes6 =
    {TN} tag is used to add the terminal number TakeposGroupSameProduct=Group same products lines StartAParallelSale=Start a new parallel sale -ControlCashOpening=Control cash box at opening pos +ControlCashOpening=Control cash box at opening POS CloseCashFence=Close cash fence CashReport=Cash report MainPrinterToUse=Main printer to use @@ -117,6 +117,6 @@ HideCategoryImages=Hide Category Images HideProductImages=Hide Product Images NumberOfLinesToShow=Number of lines of images to show DefineTablePlan=Define tables plan -GiftReceiptButton=Gift receipt button +GiftReceiptButton=Add a "Gift receipt" button GiftReceipt=Gift receipt ModuleReceiptPrinterMustBeEnabled=Module Receipt printer must have been enabled first diff --git a/htdocs/takepos/admin/bar.php b/htdocs/takepos/admin/bar.php index b6a06dee9fb..2ec623024c7 100644 --- a/htdocs/takepos/admin/bar.php +++ b/htdocs/takepos/admin/bar.php @@ -34,7 +34,8 @@ if (!$user->admin) accessforbidden(); $langs->loadLangs(array("admin", "cashdesk", "printing")); -global $db; +$res = 0; + /* * Actions @@ -44,9 +45,15 @@ if (GETPOST('action', 'alpha') == 'set') { $db->begin(); - dol_syslog("admin/cashdesk: level ".GETPOST('level', 'alpha')); + dol_syslog("admin/bar"); - if (!$res > 0) $error++; + $suplement_category = GETPOST('TAKEPOS_SUPPLEMENTS_CATEGORY', 'alpha'); + if ($suplement_category < 0) $suplement_category= 0; + + $res = dolibarr_set_const($db, "TAKEPOS_SUPPLEMENTS_CATEGORY", $suplement_category, 'chaine', 0, '', $conf->entity); + if ($res <= 0) { + $error++; + } if (!$error) { @@ -74,7 +81,6 @@ $linkback = ''.$langs->trans("BackT print load_fiche_titre($langs->trans("CashDeskSetup").' (TakePOS)', $linkback, 'title_setup'); $head = takepos_prepare_head(); dol_fiche_head($head, 'bar', 'TakePOS', -1, 'cash-register'); -print '
    '; // Mode @@ -93,129 +99,138 @@ function Floors() { '.$langs->trans("DefineTablePlan").'

    '; -print '

    '; - -print '
    '; -print ''; -print ''; -print ''; -print "\n"; - -if ($conf->global->TAKEPOS_BAR_RESTAURANT && $conf->global->TAKEPOS_PRINT_METHOD != "browser") { - print ''; - print ''; - - print ''; - print ''; -} - -print ''; -print ''; - -print ''; -print ''; - -if ($conf->global->TAKEPOS_SUPPLEMENTS) -{ - print ''; - print '\n"; -} - -print ''; -print ''; - -print ''; -print ''; - -print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '; - print $langs->trans("OrderPrinters").' ('.$langs->trans("Setup").')'; - print ''; - print ajax_constantonoff("TAKEPOS_ORDER_PRINTERS", array(), $conf->entity, 0, 0, 1, 0); - //print $form->selectyesno("TAKEPOS_ORDER_PRINTERS", $conf->global->TAKEPOS_ORDER_PRINTERS, 1); - print '
    '; - print $langs->trans("OrderNotes"); - print ''; - print ajax_constantonoff("TAKEPOS_ORDER_NOTES", array(), $conf->entity, 0, 0, 1, 0); - //print $form->selectyesno("TAKEPOS_ORDER_NOTES", $conf->global->TAKEPOS_ORDER_NOTES, 1); - print '
    '; -print $langs->trans("BasicPhoneLayout"); -print ''; -//print $form->selectyesno("TAKEPOS_PHONE_BASIC_LAYOUT", $conf->global->TAKEPOS_PHONE_BASIC_LAYOUT, 1); -print ajax_constantonoff("TAKEPOS_PHONE_BASIC_LAYOUT", array(), $conf->entity, 0, 0, 1, 0); -print '
    '; -print $langs->trans("ProductSupplements"); -print ''; -//print $form->selectyesno("TAKEPOS_SUPPLEMENTS", $conf->global->TAKEPOS_SUPPLEMENTS, 1); -print ajax_constantonoff("TAKEPOS_SUPPLEMENTS", array(), $conf->entity, 0, 0, 1, 0); -print '
    '; - print $langs->trans("SupplementCategory"); - print ''; - print $form->select_all_categories(Categorie::TYPE_PRODUCT, $conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, 'TAKEPOS_SUPPLEMENTS_CATEGORY', 64, 0, 0); - print ajax_combobox('TAKEPOS_SUPPLEMENTS_CATEGORY'); - print "
    '; -print 'QR - '.$langs->trans("CustomerMenu"); -print ''; -print ajax_constantonoff("TAKEPOS_QR_MENU", array(), $conf->entity, 0, 0, 1, 0); -print '
    '; -print 'QR - '.$langs->trans("AutoOrder"); -print ''; -print ajax_constantonoff("TAKEPOS_AUTO_ORDER", array(), $conf->entity, 0, 0, 1, 0); -print '
    '; - - -if ($conf->global->TAKEPOS_QR_MENU) -{ - $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); - $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file - print '
    '; - print ''; - print ''; - print ''; - print "\n"; - print ''; - print ''; - print '
    '.$langs->trans("URL").''.$langs->trans("QR").'
    '; - print "".$urlwithroot."/takepos/public/menu.php"; - print ''; - print ""; - print '
    '; -} - -if ($conf->global->TAKEPOS_AUTO_ORDER) -{ - print '
    '; - print ''; - print ''; - print ''; - print "\n"; - - //global $dolibarr_main_url_root; - $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); - $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file - $sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables"; - $resql = $db->query($sql); - $rows = array(); - while ($row = $db->fetch_array($resql)) { - print ''; - print ''; - print ''; - } - - print '
    '.$langs->trans("Table").''.$langs->trans("URL").''.$langs->trans("QR").'
    '; - print $langs->trans("Table")." ".$row['label']; - print ''; - print "".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid']).""; - print ''; - print ""; - print '
    '; -} - -print '
    '; +print $langs->trans("EnableBarOrRestaurantFeatures"); +print ajax_constantonoff("TAKEPOS_BAR_RESTAURANT", array(), $conf->entity, 0, 0, 1, 0); print '
    '; -print '
    '; +if ($conf->global->TAKEPOS_BAR_RESTAURANT) { + print '
    '; + print ' '.$langs->trans("DefineTablePlan").'
    '; + print '

    '; + + print '
    '; + print ''; + print ''; + print ''; + print "\n"; + + if ($conf->global->TAKEPOS_PRINT_METHOD != "browser") { + print ''; + print ''; + + print ''; + print ''; + } + + print ''; + print ''; + + print ''; + print ''; + + if ($conf->global->TAKEPOS_SUPPLEMENTS) + { + print ''; + print '\n"; + } + + print ''; + print ''; + + print ''; + print ''; + + print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '; + print $langs->trans("OrderPrinters").' ('.$langs->trans("Setup").')'; + print ''; + print ajax_constantonoff("TAKEPOS_ORDER_PRINTERS", array(), $conf->entity, 0, 0, 1, 0); + //print $form->selectyesno("TAKEPOS_ORDER_PRINTERS", $conf->global->TAKEPOS_ORDER_PRINTERS, 1); + print '
    '; + print $langs->trans("OrderNotes"); + print ''; + print ajax_constantonoff("TAKEPOS_ORDER_NOTES", array(), $conf->entity, 0, 0, 1, 0); + //print $form->selectyesno("TAKEPOS_ORDER_NOTES", $conf->global->TAKEPOS_ORDER_NOTES, 1); + print '
    '; + print $langs->trans("BasicPhoneLayout"); + print ''; + //print $form->selectyesno("TAKEPOS_PHONE_BASIC_LAYOUT", $conf->global->TAKEPOS_PHONE_BASIC_LAYOUT, 1); + print ajax_constantonoff("TAKEPOS_PHONE_BASIC_LAYOUT", array(), $conf->entity, 0, 0, 1, 0); + print '
    '; + print $langs->trans("ProductSupplements"); + print ''; + //print $form->selectyesno("TAKEPOS_SUPPLEMENTS", $conf->global->TAKEPOS_SUPPLEMENTS, 1); + print ajax_constantonoff("TAKEPOS_SUPPLEMENTS", array(), $conf->entity, 0, 0, 1, 0); + print '
    '; + print $langs->trans("SupplementCategory"); + print ''; + print $form->select_all_categories(Categorie::TYPE_PRODUCT, $conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, 'TAKEPOS_SUPPLEMENTS_CATEGORY', 64, 0, 0); + print ajax_combobox('TAKEPOS_SUPPLEMENTS_CATEGORY'); + print "
    '; + print 'QR - '.$langs->trans("CustomerMenu"); + print ''; + print ajax_constantonoff("TAKEPOS_QR_MENU", array(), $conf->entity, 0, 0, 1, 0); + print '
    '; + print 'QR - '.$langs->trans("AutoOrder"); + print ''; + print ajax_constantonoff("TAKEPOS_AUTO_ORDER", array(), $conf->entity, 0, 0, 1, 0); + print '
    '; + print '
    '; + + print '
    '; + + print '
    '; +} + +if ($conf->global->TAKEPOS_BAR_RESTAURANT) { + if ($conf->global->TAKEPOS_QR_MENU) + { + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + print '
    '; + print ''; + print ''; + print ''; + print "\n"; + print ''; + print ''; + print '
    '.$langs->trans("URL").''.$langs->trans("QR").'
    '; + print "".$urlwithroot."/takepos/public/menu.php"; + print ''; + print ""; + print '
    '; + } + + if ($conf->global->TAKEPOS_AUTO_ORDER) + { + print '
    '; + print ''; + print ''; + print ''; + print "\n"; + + //global $dolibarr_main_url_root; + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + $sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables"; + $resql = $db->query($sql); + $rows = array(); + while ($row = $db->fetch_array($resql)) { + print ''; + print ''; + print ''; + } + + print '
    '.$langs->trans("Table").''.$langs->trans("URL").''.$langs->trans("QR").'
    '; + print $langs->trans("Table")." ".$row['label']; + print ''; + print "".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid']).""; + print ''; + print ""; + print '
    '; + } +} + print "\n"; diff --git a/htdocs/takepos/admin/receipt.php b/htdocs/takepos/admin/receipt.php index 59e0f3da96c..252781ec635 100644 --- a/htdocs/takepos/admin/receipt.php +++ b/htdocs/takepos/admin/receipt.php @@ -87,6 +87,7 @@ print ''; print load_fiche_titre($langs->trans("PrintMethod"), '', ''); +print '
    '; print ''; print ''; print ''; @@ -143,14 +144,25 @@ if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") } print "\n"; print '
    '.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status").'
    '; +print '
    '; + print load_fiche_titre($langs->trans("Setup"), '', ''); +print '
    '; print ''; print ''; print ''; print "\n"; +// VAT Grouped on ticket +print '\n"; + if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { print '\n"; print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '; +print $langs->trans('TicketVatGrouped'); +print ''; +print ajax_constantonoff("TAKEPOS_TICKET_VAT_GROUPPED", array(), $conf->entity, 0, 0, 1, 0); +//print $form->selectyesno("TAKEPOS_TICKET_VAT_GROUPPED", $conf->global->TAKEPOS_TICKET_VAT_GROUPPED, 1); +print "
    '; print $langs->trans("URL")." / ".$langs->trans("IPAddress").' ('.$langs->trans("TakeposConnectorNecesary").')'; @@ -214,6 +226,7 @@ print $form->selectyesno("TAKEPOS_AUTO_PRINT_TICKETS", $conf->global->TAKEPOS_AU print "
    '; +print '
    '; print '
    '; diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php index 22355c70d9d..ab3b200df35 100644 --- a/htdocs/takepos/admin/setup.php +++ b/htdocs/takepos/admin/setup.php @@ -274,14 +274,6 @@ print img_object('', 'category', 'class="paddingright"').$form->select_all_categ print ajax_combobox('TAKEPOS_ROOT_CATEGORY_ID'); print "\n"; -// VAT Grouped on ticket -print ''; -print $langs->trans('TicketVatGrouped'); -print ''; -print ajax_constantonoff("TAKEPOS_TICKET_VAT_GROUPPED", array(), $conf->entity, 0, 0, 1, 0); -//print $form->selectyesno("TAKEPOS_TICKET_VAT_GROUPPED", $conf->global->TAKEPOS_TICKET_VAT_GROUPPED, 1); -print "\n"; - // Sort product print ''; print $langs->trans("SortProductField"); @@ -429,14 +421,6 @@ print "\n"; //print $form->selectarray('TAKEPOS_ADDON', $array, (empty($conf->global->TAKEPOS_ADDON) ? '0' : $conf->global->TAKEPOS_ADDON), 0); //print "\n"; -print ''; -print $langs->trans("EnableBarOrRestaurantFeatures"); -print ''; -print ''; -print ajax_constantonoff("TAKEPOS_BAR_RESTAURANT", array(), $conf->entity, 0, 0, 1, 0); -//print $form->selectyesno("TAKEPOS_BAR_RESTAURANT", $conf->global->TAKEPOS_BAR_RESTAURANT, 1); -print "\n"; - print ''; print '
    '; From 7ce1d36b59423d44d2ca05ddfb31755db283cf5d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 13 Aug 2020 13:51:08 +0200 Subject: [PATCH 362/434] FIX Category for suplements not saved --- htdocs/takepos/admin/bar.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/takepos/admin/bar.php b/htdocs/takepos/admin/bar.php index b6a06dee9fb..c9e53a86664 100644 --- a/htdocs/takepos/admin/bar.php +++ b/htdocs/takepos/admin/bar.php @@ -44,9 +44,15 @@ if (GETPOST('action', 'alpha') == 'set') { $db->begin(); - dol_syslog("admin/cashdesk: level ".GETPOST('level', 'alpha')); + dol_syslog("admin/bar"); - if (!$res > 0) $error++; + $suplement_category = GETPOST('TAKEPOS_SUPPLEMENTS_CATEGORY', 'alpha'); + if ($suplement_category < 0) $suplement_category= 0; + + $res = dolibarr_set_const($db, "TAKEPOS_SUPPLEMENTS_CATEGORY", $suplement_category, 'chaine', 0, '', $conf->entity); + if ($res <= 0) { + $error++; + } if (!$error) { From 990217fcb00b5354c9853b79fe9254094231b019 Mon Sep 17 00:00:00 2001 From: Adrien Raze Date: Thu, 13 Aug 2020 16:59:27 +0200 Subject: [PATCH 363/434] FIX : task leftmenu --- htdocs/core/menus/standard/eldy.lib.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index f6d8aa401a5..78d3d8d91b8 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -531,6 +531,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = } if (empty($noout)) { + foreach ($menu->liste as $menuval) { print_start_menu_entry($menuval['idsel'], $menuval['classname'], $menuval['enabled']); print_text_menu_entry($menuval['titre'], $menuval['enabled'], (($menuval['url'] != '#' && !preg_match('/^(http:\/\/|https:\/\/)/i', $menuval['url'])) ? DOL_URL_ROOT:'').$menuval['url'], $menuval['id'], $menuval['idsel'], $menuval['classname'], ($menuval['target'] ? $menuval['target'] : $atarget)); @@ -540,6 +541,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = $showmode = 1; if (empty($noout)) { + print_start_menu_entry('', 'class="tmenuend"', $showmode); print_end_menu_entry($showmode); print_end_menu_array(); @@ -1706,7 +1708,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM if (empty($conf->global->PROJECT_HIDE_TASKS)) { // Project affected to user - $newmenu->add("/projet/activity/index.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("Activities"), 0, $user->rights->projet->lire); + $newmenu->add("/projet/activity/index.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("Activities"), 0, $user->rights->projet->lire, '', 'project', 'tasks'); $newmenu->add("/projet/tasks.php?leftmenu=tasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); $newmenu->add("/projet/tasks/list.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $user->rights->projet->lire); $newmenu->add("/projet/tasks/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); From d784c621c99d64c600309c84da3cada8c9d8e46e Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 13 Aug 2020 15:07:06 +0000 Subject: [PATCH 364/434] Fixing style errors. --- htdocs/core/menus/standard/eldy.lib.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 78d3d8d91b8..ca7220037a5 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -531,7 +531,6 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = } if (empty($noout)) { - foreach ($menu->liste as $menuval) { print_start_menu_entry($menuval['idsel'], $menuval['classname'], $menuval['enabled']); print_text_menu_entry($menuval['titre'], $menuval['enabled'], (($menuval['url'] != '#' && !preg_match('/^(http:\/\/|https:\/\/)/i', $menuval['url'])) ? DOL_URL_ROOT:'').$menuval['url'], $menuval['id'], $menuval['idsel'], $menuval['classname'], ($menuval['target'] ? $menuval['target'] : $atarget)); @@ -541,7 +540,6 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = $showmode = 1; if (empty($noout)) { - print_start_menu_entry('', 'class="tmenuend"', $showmode); print_end_menu_entry($showmode); print_end_menu_array(); From f385e02c5317baa7464ef80c2d8eb018adc9e06b Mon Sep 17 00:00:00 2001 From: lvessiller Date: Thu, 13 Aug 2020 17:43:18 +0200 Subject: [PATCH 365/434] FIX title button attribute id empty --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1f7c08c8d7a..97ad5d58969 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8258,7 +8258,7 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u $attr['class'] .= ' classfortooltip'; } - if(empty($id)){ + if(!empty($id)){ $attr['id'] = $id; } From b57c2585ad5337d4e8289f14cbde808866fa7b60 Mon Sep 17 00:00:00 2001 From: Tim Otte Date: Fri, 14 Aug 2020 10:00:40 +0200 Subject: [PATCH 366/434] Fixed the smtps recipent to use the forced address --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 48a2b503eca..79791854a8f 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -355,7 +355,7 @@ class CMailFile } $smtps->setSubject($subjecttouse); - $smtps->setTO($this->getValidAddress($this->to, 0, 1)); + $smtps->setTO($this->getValidAddress($this->addr_to, 0, 1)); $smtps->setFrom($this->getValidAddress($this->from, 0, 1)); $smtps->setTrackId($this->trackid); $smtps->setReplyTo($this->getValidAddress($this->replyto, 0, 1)); From d35c7ed49b6322053e8abd3ddf8a64e5260fd86e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 14 Aug 2020 11:03:12 +0200 Subject: [PATCH 367/434] Fix trans --- htdocs/langs/en_US/main.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 051dde11ff7..e7c35f6d9f7 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -353,8 +353,8 @@ PriceUTTC=U.P. (inc. tax) Amount=Amount AmountInvoice=Invoice amount AmountInvoiced=Amount invoiced -AmountInvoicedHT=Amount invoiced (incl. tax) -AmountInvoicedTTC=Amount invoiced (excl. tax) +AmountInvoicedHT=Amount invoiced (excl. tax) +AmountInvoicedTTC=Amount invoiced (inc. tax) AmountPayment=Payment amount AmountHTShort=Amount (excl.) AmountTTCShort=Amount (inc. tax) From 52f20a1047acda7d13dca7d8fe6fdbf69b560fdc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 14 Aug 2020 11:52:21 +0200 Subject: [PATCH 368/434] Fix travis --- htdocs/categories/class/categorie.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 40c37d4dd93..fe44c7393ba 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -755,7 +755,8 @@ class Categorie extends CommonObject { $objs = array(); - $obj = new $this->MAP_OBJ_CLASS[$type]( $this->db ); + $classnameforobj = $this->MAP_OBJ_CLASS[$type]; + $obj = new $classnameforobj($this->db); $sql = "SELECT c.fk_" . $this->MAP_CAT_FK[$type]; $sql .= " FROM " . MAIN_DB_PREFIX . "categorie_" . $this->MAP_CAT_TABLE[$type] . " as c"; From fe0b1c5ee49b2f8e41a088cac8ac8138a4360f4c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 14 Aug 2020 11:53:54 +0200 Subject: [PATCH 369/434] Fix travis --- htdocs/categories/class/categorie.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index fe44c7393ba..b0bcbadc010 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -777,7 +777,9 @@ class Categorie extends CommonObject } else { - $obj = new $this->MAP_OBJ_CLASS[$type]( $this->db ); + $classnameforobj = $this->MAP_OBJ_CLASS[$type]; + + $obj = new $classnameforobj($this->db); $obj->fetch($rec['fk_' . $this->MAP_CAT_FK[$type]]); $objs[] = $obj; } From d8c6e17efd0159f1595ccef86fd82aed1524875c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 14 Aug 2020 11:59:51 +0200 Subject: [PATCH 370/434] Fix travis --- htdocs/core/tpl/objectline_create.tpl.php | 8 ++++---- htdocs/product/stock/list.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 305be25347d..42c5ea0d2a9 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -426,9 +426,9 @@ if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dat $prefillDates = false; - if(! empty($conf->global->MAIN_FILL_SERVICE_DATES_FROM_LAST_SERVICE_LINE) && ! empty($object->lines)) + if (!empty($conf->global->MAIN_FILL_SERVICE_DATES_FROM_LAST_SERVICE_LINE) && ! empty($object->lines)) { - for($i = count($object->lines) - 1; $i >= 0; $i--) + for ($i = count($object->lines) - 1; $i >= 0; $i--) { $lastline = $object->lines[$i]; @@ -457,14 +457,14 @@ if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dat print $form->selectDate($date_end, 'date_end', empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE) ? 0 : 1, empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE) ? 0 : 1, 1, "addproduct", 1, 0); }; - if($prefillDates) + if ($prefillDates) { echo ' ' . $langs->trans('FillWithLastServiceDates') . ''; } print ' - +
    global->MAIN_AUTO_OPEN_SELECT2_ON_FOCUS_FOR_CUSTOMER_PRODUCTS)) { ?> - - + google->enabled) && !empty($conf->global->MAIN_GOOGLE_AD_CLIEN if (empty($conf->dol_use_jmobile)) { print '
    '."\n"; - print ''."\n"; - print ''."\n"; + print ''."\n"; print '
    '."\n"; } else { print ''."\n"; From 4c0785e996fcf1a95aebcdda1e5efb38ae41497b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:13:27 +0200 Subject: [PATCH 380/434] FIX #14469 --- dev/initdemo/mysqldump_dolibarr_12.0.0.sql | 2 +- htdocs/admin/boxes.php | 37 +++++++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/dev/initdemo/mysqldump_dolibarr_12.0.0.sql b/dev/initdemo/mysqldump_dolibarr_12.0.0.sql index 25663fa6991..3cc1db1cf34 100644 --- a/dev/initdemo/mysqldump_dolibarr_12.0.0.sql +++ b/dev/initdemo/mysqldump_dolibarr_12.0.0.sql @@ -1326,7 +1326,7 @@ CREATE TABLE `llx_boxes_def` ( LOCK TABLES `llx_boxes_def` WRITE; /*!40000 ALTER TABLE `llx_boxes_def` DISABLE KEYS */; -INSERT INTO `llx_boxes_def` VALUES (188,'box_services_vendus.php',1,'2013-08-05 20:40:27',NULL),(323,'box_actions.php',2,'2015-03-13 15:29:19',NULL),(324,'box_clients.php',2,'2015-03-13 20:21:35',NULL),(325,'box_prospect.php',2,'2015-03-13 20:21:35',NULL),(326,'box_contacts.php',2,'2015-03-13 20:21:35',NULL),(327,'box_activity.php',2,'2015-03-13 20:21:35','(WarningUsingThisBoxSlowDown)'),(328,'box_propales.php',2,'2015-03-13 20:32:38',NULL),(329,'box_comptes.php',2,'2015-03-13 20:33:09',NULL),(330,'box_factures_imp.php',2,'2015-03-13 20:33:09',NULL),(331,'box_factures.php',2,'2015-03-13 20:33:09',NULL),(332,'box_produits.php',2,'2015-03-13 20:33:09',NULL),(333,'box_produits_alerte_stock.php',2,'2015-03-13 20:33:09',NULL),(347,'box_clients.php',1,'2017-11-15 22:05:57',NULL),(348,'box_prospect.php',1,'2017-11-15 22:05:57',NULL),(349,'box_contacts.php',1,'2017-11-15 22:05:57',NULL),(350,'box_activity.php',1,'2017-11-15 22:05:57','(WarningUsingThisBoxSlowDown)'),(374,'box_services_contracts.php',1,'2017-11-15 22:38:37',NULL),(377,'box_project.php',1,'2017-11-15 22:38:44',NULL),(378,'box_task.php',1,'2017-11-15 22:38:44',NULL),(388,'box_contracts.php',1,'2017-11-15 22:39:52',NULL),(389,'box_services_expired.php',1,'2017-11-15 22:39:52',NULL),(390,'box_ficheinter.php',1,'2017-11-15 22:39:56',NULL),(392,'box_graph_propales_permonth.php',1,'2017-11-15 22:41:47',NULL),(393,'box_propales.php',1,'2017-11-15 22:41:47',NULL),(396,'box_graph_product_distribution.php',1,'2017-11-15 22:41:47',NULL),(403,'box_goodcustomers.php',1,'2018-07-30 11:13:20','(WarningUsingThisBoxSlowDown)'),(404,'box_external_rss.php',1,'2018-07-30 11:15:25','1 (Dolibarr.org News)'),(409,'box_produits.php',1,'2018-07-30 13:38:11',NULL),(410,'box_produits_alerte_stock.php',1,'2018-07-30 13:38:11',NULL),(411,'box_commandes.php',1,'2018-07-30 13:38:11',NULL),(412,'box_graph_orders_permonth.php',1,'2018-07-30 13:38:11',NULL),(413,'box_graph_invoices_supplier_permonth.php',1,'2018-07-30 13:38:11',NULL),(414,'box_graph_orders_supplier_permonth.php',1,'2018-07-30 13:38:11',NULL),(415,'box_fournisseurs.php',1,'2018-07-30 13:38:11',NULL),(416,'box_factures_fourn_imp.php',1,'2018-07-30 13:38:11',NULL),(417,'box_factures_fourn.php',1,'2018-07-30 13:38:11',NULL),(418,'box_supplier_orders.php',1,'2018-07-30 13:38:11',NULL),(419,'box_actions.php',1,'2018-07-30 15:42:32',NULL),(424,'box_factures_imp.php',1,'2017-02-07 18:56:12',NULL),(425,'box_factures.php',1,'2017-02-07 18:56:12',NULL),(426,'box_graph_invoices_permonth.php',1,'2017-02-07 18:56:12',NULL),(427,'box_comptes.php',1,'2017-02-07 18:56:12',NULL),(429,'box_lastlogin.php',1,'2017-08-27 13:29:14',NULL),(430,'box_bookmarks.php',1,'2018-01-19 11:27:34',NULL),(431,'box_members.php',1,'2018-01-19 11:27:56',NULL),(432,'box_birthdays.php',1,'2019-06-05 08:45:40',NULL),(433,'box_last_ticket',1,'2019-06-05 09:15:29',NULL),(434,'box_last_modified_ticket',1,'2019-06-05 09:15:29',NULL),(436,'box_accountancy_last_manual_entries.php',1,'2019-11-28 11:52:58',NULL),(437,'box_accountancy_suspense_account.php',1,'2019-11-28 11:52:58',NULL),(438,'box_supplier_orders_awaiting_reception.php',1,'2019-11-28 11:52:59',NULL),(439,'box_mos.php',1,'2019-11-29 08:57:42',NULL),(445,'box_shipments.php',1,'2020-01-13 14:38:20',NULL); +INSERT INTO `llx_boxes_def` VALUES (323,'box_actions.php',2,'2015-03-13 15:29:19',NULL),(324,'box_clients.php',2,'2015-03-13 20:21:35',NULL),(325,'box_prospect.php',2,'2015-03-13 20:21:35',NULL),(326,'box_contacts.php',2,'2015-03-13 20:21:35',NULL),(327,'box_activity.php',2,'2015-03-13 20:21:35','(WarningUsingThisBoxSlowDown)'),(328,'box_propales.php',2,'2015-03-13 20:32:38',NULL),(329,'box_comptes.php',2,'2015-03-13 20:33:09',NULL),(330,'box_factures_imp.php',2,'2015-03-13 20:33:09',NULL),(331,'box_factures.php',2,'2015-03-13 20:33:09',NULL),(332,'box_produits.php',2,'2015-03-13 20:33:09',NULL),(333,'box_produits_alerte_stock.php',2,'2015-03-13 20:33:09',NULL),(347,'box_clients.php',1,'2017-11-15 22:05:57',NULL),(348,'box_prospect.php',1,'2017-11-15 22:05:57',NULL),(349,'box_contacts.php',1,'2017-11-15 22:05:57',NULL),(350,'box_activity.php',1,'2017-11-15 22:05:57','(WarningUsingThisBoxSlowDown)'),(374,'box_services_contracts.php',1,'2017-11-15 22:38:37',NULL),(377,'box_project.php',1,'2017-11-15 22:38:44',NULL),(378,'box_task.php',1,'2017-11-15 22:38:44',NULL),(388,'box_contracts.php',1,'2017-11-15 22:39:52',NULL),(389,'box_services_expired.php',1,'2017-11-15 22:39:52',NULL),(390,'box_ficheinter.php',1,'2017-11-15 22:39:56',NULL),(392,'box_graph_propales_permonth.php',1,'2017-11-15 22:41:47',NULL),(393,'box_propales.php',1,'2017-11-15 22:41:47',NULL),(396,'box_graph_product_distribution.php',1,'2017-11-15 22:41:47',NULL),(403,'box_goodcustomers.php',1,'2018-07-30 11:13:20','(WarningUsingThisBoxSlowDown)'),(404,'box_external_rss.php',1,'2018-07-30 11:15:25','1 (Dolibarr.org News)'),(409,'box_produits.php',1,'2018-07-30 13:38:11',NULL),(410,'box_produits_alerte_stock.php',1,'2018-07-30 13:38:11',NULL),(411,'box_commandes.php',1,'2018-07-30 13:38:11',NULL),(412,'box_graph_orders_permonth.php',1,'2018-07-30 13:38:11',NULL),(413,'box_graph_invoices_supplier_permonth.php',1,'2018-07-30 13:38:11',NULL),(414,'box_graph_orders_supplier_permonth.php',1,'2018-07-30 13:38:11',NULL),(415,'box_fournisseurs.php',1,'2018-07-30 13:38:11',NULL),(416,'box_factures_fourn_imp.php',1,'2018-07-30 13:38:11',NULL),(417,'box_factures_fourn.php',1,'2018-07-30 13:38:11',NULL),(418,'box_supplier_orders.php',1,'2018-07-30 13:38:11',NULL),(419,'box_actions.php',1,'2018-07-30 15:42:32',NULL),(424,'box_factures_imp.php',1,'2017-02-07 18:56:12',NULL),(425,'box_factures.php',1,'2017-02-07 18:56:12',NULL),(426,'box_graph_invoices_permonth.php',1,'2017-02-07 18:56:12',NULL),(427,'box_comptes.php',1,'2017-02-07 18:56:12',NULL),(429,'box_lastlogin.php',1,'2017-08-27 13:29:14',NULL),(430,'box_bookmarks.php',1,'2018-01-19 11:27:34',NULL),(431,'box_members.php',1,'2018-01-19 11:27:56',NULL),(432,'box_birthdays.php',1,'2019-06-05 08:45:40',NULL),(433,'box_last_ticket',1,'2019-06-05 09:15:29',NULL),(434,'box_last_modified_ticket',1,'2019-06-05 09:15:29',NULL),(436,'box_accountancy_last_manual_entries.php',1,'2019-11-28 11:52:58',NULL),(437,'box_accountancy_suspense_account.php',1,'2019-11-28 11:52:58',NULL),(438,'box_supplier_orders_awaiting_reception.php',1,'2019-11-28 11:52:59',NULL),(439,'box_mos.php',1,'2019-11-29 08:57:42',NULL),(445,'box_shipments.php',1,'2020-01-13 14:38:20',NULL); /*!40000 ALTER TABLE `llx_boxes_def` ENABLE KEYS */; UNLOCK TABLES; diff --git a/htdocs/admin/boxes.php b/htdocs/admin/boxes.php index afad55a6211..4bba5475bb8 100644 --- a/htdocs/admin/boxes.php +++ b/htdocs/admin/boxes.php @@ -97,8 +97,10 @@ if ($action == 'add') { { if (!$error && $fk_user != '') { + $arrayofexistingboxid = array(); $nbboxonleft = $nbboxonright = 0; - $sql = "SELECT box_order FROM ".MAIN_DB_PREFIX."boxes WHERE position = ".$pos." AND fk_user = ".$fk_user." AND entity = ".$conf->entity; + $sql = "SELECT box_id, box_order FROM ".MAIN_DB_PREFIX."boxes"; + $sql .= " WHERE position = ".$pos." AND fk_user = ".$fk_user." AND entity = ".$conf->entity; dol_syslog("boxes.php activate box", LOG_DEBUG); $resql = $db->query($sql); if ($resql) @@ -108,22 +110,27 @@ if ($action == 'add') { $boxorder = $obj->box_order; if (preg_match('/A/', $boxorder)) $nbboxonleft++; if (preg_match('/B/', $boxorder)) $nbboxonright++; + $arrayofexistingboxid[$obj->box_id] = 1; } } else dol_print_error($db); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes ("; - $sql .= "box_id, position, box_order, fk_user, entity"; - $sql .= ") values ("; - $sql .= $boxid['value'].", ".$pos.", '".(($nbboxonleft > $nbboxonright) ? 'B01' : 'A01')."', ".$fk_user.", ".$conf->entity; - $sql .= ")"; + if (! $arrayofexistingboxid[$boxid['value']]) { + $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes ("; + $sql .= "box_id, position, box_order, fk_user, entity"; + $sql .= ") values ("; + $sql .= $boxid['value'].", ".$pos.", '".(($nbboxonleft > $nbboxonright) ? 'B01' : 'A01')."', ".$fk_user.", ".$conf->entity; + $sql .= ")"; - dol_syslog("boxes.php activate box", LOG_DEBUG); - $resql = $db->query($sql); - if (!$resql) - { - setEventMessages($db->lasterror(), null, 'errors'); - $error++; + dol_syslog("boxes.php activate box", LOG_DEBUG); + $resql = $db->query($sql); + if (!$resql) + { + setEventMessages($db->lasterror(), null, 'errors'); + $error++; + } + } else { + dol_syslog("boxes.php activate box - already exists in database", LOG_DEBUG); } } } @@ -353,7 +360,7 @@ foreach ($boxtoadd as $box) print "\n".''."\n"; print ''."\n"; - print ''.img_object("", $logo).' '.$langs->transnoentitiesnoconv($box->boxlabel); + print ''.img_object("", $logo, 'height="14px"').' '.$langs->transnoentitiesnoconv($box->boxlabel); if (!empty($box->class) && preg_match('/graph_/', $box->class)) print ' ('.$langs->trans("Graph").')'; print ''."\n"; print ''; @@ -368,7 +375,7 @@ foreach ($boxtoadd as $box) // For each possible position, an activation link is displayed if the box is not already active for that position print ''; - print $form->selectarray("boxid[".$box->box_id."][pos]", $pos_name, 0, 1, 0, 0, '', 1)."\n"; + print $form->selectarray("boxid[".$box->box_id."][pos]", $pos_name, -1, 1, 0, 0, '', 1)."\n"; print ''."\n"; print ''; @@ -418,7 +425,7 @@ foreach ($boxactivated as $key => $box) print "\n".''."\n"; print ''; - print ''.img_object("", $logo).' '.$langs->transnoentitiesnoconv($box->boxlabel); + print ''.img_object("", $logo, 'height="14px"').' '.$langs->transnoentitiesnoconv($box->boxlabel); if (!empty($box->class) && preg_match('/graph_/', $box->class)) print ' ('.$langs->trans("Graph").')'; print ''; print ''; From 657e6a20379ce927eeb5ff5e99edcc041413f790 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:14:53 +0200 Subject: [PATCH 381/434] No warning --- htdocs/admin/boxes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/boxes.php b/htdocs/admin/boxes.php index 4bba5475bb8..7f222547deb 100644 --- a/htdocs/admin/boxes.php +++ b/htdocs/admin/boxes.php @@ -115,7 +115,7 @@ if ($action == 'add') { } else dol_print_error($db); - if (! $arrayofexistingboxid[$boxid['value']]) { + if (empty($arrayofexistingboxid[$boxid['value']])) { $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes ("; $sql .= "box_id, position, box_order, fk_user, entity"; $sql .= ") values ("; From 99809b487e042ac55d5e8159a2fabc1b8ecdd02f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:33:50 +0200 Subject: [PATCH 382/434] Standardize code --- htdocs/accountancy/admin/fiscalyear.php | 9 ++- htdocs/core/class/fiscalyear.class.php | 75 +++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/admin/fiscalyear.php b/htdocs/accountancy/admin/fiscalyear.php index b5cc46a3d0d..89aad6e2d0d 100644 --- a/htdocs/accountancy/admin/fiscalyear.php +++ b/htdocs/accountancy/admin/fiscalyear.php @@ -79,6 +79,7 @@ $object = new Fiscalyear($db); $max = 100; $form = new Form($db); +$fiscalyearstatic = new Fiscalyear($db); $title = $langs->trans('AccountingPeriods'); $helpurl = ""; @@ -132,13 +133,15 @@ if ($result) print ''; if ($num) { - $fiscalyearstatic = new Fiscalyear($db); - while ($i < $num && $i < $max) { $obj = $db->fetch_object($result); + $fiscalyearstatic->id = $obj->rowid; + print ''; - print ''.img_object($langs->trans("ShowFiscalYear"), "technic").' '.$obj->rowid.''; + print ''; + print $fiscalyearstatic->getNomUrl(1); + print ''; print ''.$obj->label.''; print ''.dol_print_date($db->jdate($obj->date_start), 'day').''; print ''.dol_print_date($db->jdate($obj->date_end), 'day').''; diff --git a/htdocs/core/class/fiscalyear.class.php b/htdocs/core/class/fiscalyear.class.php index 0686b68115a..c0216f16a19 100644 --- a/htdocs/core/class/fiscalyear.class.php +++ b/htdocs/core/class/fiscalyear.class.php @@ -35,6 +35,8 @@ class Fiscalyear extends CommonObject */ public $element = 'fiscalyear'; + public $picto = 'technic'; + /** * @var string Name of table without prefix where object is stored */ @@ -97,6 +99,7 @@ class Fiscalyear extends CommonObject public $statuts = array(); public $statuts_short = array(); + /** * Constructor * @@ -267,6 +270,78 @@ class Fiscalyear extends CommonObject } } + /** + * Return clicable link of object (with eventually picto) + * + * @param int $withpicto Add picto into link + * @param int $notooltip 1=Disable tooltip + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + public function getNomUrl($withpicto = 0, $notooltip = 0, $save_lastsearch_value = -1) + { + global $conf, $langs, $user; + + if (empty($this->ref)) $this->ref = $this->id; + + if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips + + $result = ''; + + $url = DOL_URL_ROOT.'/accountancy/admin/fiscalyear_card.php?id='.$this->id; + + if (!$user->rights->accounting->fiscalyear->write) + $option = 'nolink'; + + if ($option !== 'nolink') + { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1; + if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1'; + } + + if ($short) return $url; + + $label = ''; + + if ($user->rights->accounting->fiscalyear->write) { + $label = ''.$langs->trans("FiscalPeriod").''; + $label .= '
    '.$langs->trans('Ref').': '.$this->id; + if (isset($this->statut)) { + $label .= '
    '.$langs->trans("Status").": ".$this->getLibStatut(5); + } + } + + $linkclose = ''; + if (empty($notooltip) && $user->rights->accounting->fiscalyear->write) + { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label = $langs->trans("FiscalYear"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip"'; + } + + $linkstart = ''; + $linkend = ''; + + if ($option === 'nolink') { + $linkstart = ''; + $linkend = ''; + } + + $result .= $linkstart; + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + if ($withpicto != 2) $result .= $this->ref; + $result .= $linkend; + + return $result; + } + /** * Give a label from a status * From d2db1a3557ac221f5d5d5b0f824334934fd32d10 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:38:19 +0200 Subject: [PATCH 383/434] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d15808d2cac..17d56c6ec62 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - customizable Dashboard - Highly customizable: enable only the modules you need, add user personalized fields, choose your skin, several menu managers (can be used by internal users as a back-office with a particular menu, or by external users as a front-office with another one) -- SOAP & REST APIs +- APIs - Code that is easy to understand, maintain and develop (PHP with no heavy framework; trigger and hook architecture) - Support a lot of country specific features: - Spanish Tax RE and ISPF From d0ffba3e22b7fd4360f067ca02a93f578da0808b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:51:57 +0200 Subject: [PATCH 384/434] Update doc --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 58513986a1e..61c0f338175 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,7 +11,7 @@ WARNING: Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: * Properties ->contactid has been renamed into ->contact_id - +* Rename property $paiementid in API api_supplier_invoices into $payment_mode_id ***** ChangeLog for 12.0.2 compared to 12.0.1 ***** From ab871f44be5e4f451b7f226c1bbd14c90bd6272b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:55:27 +0200 Subject: [PATCH 385/434] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 52748e8000f..a732c1cf1fd 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ Dolibarr ERP & CRM is a modern software package to manage your organization's ac It's an Open Source Software (written in PHP language) designed for small, medium or large companies, foundations and freelancers. +You can freely use, study, modify or distribute it according to its Free Software licence. + You can use it as a standalone application or as a web application to be able to access it from the Internet or a LAN. Dolibarr has a large community ready to help you and [oficially preferred partners ready to offer commercial support should you need it](https://wiki.dolibarr.org/index.php/List_of_Dolibarr_partners_and_providers) From 867ae0c32d6d103c1f78581fcad0c6aaed180de9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:56:08 +0200 Subject: [PATCH 386/434] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a732c1cf1fd..9d6a168ac3a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ You can freely use, study, modify or distribute it according to its Free Softwar You can use it as a standalone application or as a web application to be able to access it from the Internet or a LAN. -Dolibarr has a large community ready to help you and [oficially preferred partners ready to offer commercial support should you need it](https://wiki.dolibarr.org/index.php/List_of_Dolibarr_partners_and_providers) +Dolibarr has a large community ready to help you and [oficially preferred partners ready to offer commercial support should you need it](https://partners.dolibarr.org) ![ScreenShot](https://www.dolibarr.org/images/dolibarr_screenshot1_1920x1080.jpg) From bd5ad1aef2f3db9e553f8b3fcd19daa82ebb5b48 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:57:01 +0200 Subject: [PATCH 387/434] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d6a168ac3a..b14edb8d1da 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ You can freely use, study, modify or distribute it according to its Free Softwar You can use it as a standalone application or as a web application to be able to access it from the Internet or a LAN. -Dolibarr has a large community ready to help you and [oficially preferred partners ready to offer commercial support should you need it](https://partners.dolibarr.org) +Dolibarr has a large community ready to help you, free forums and [oficially preferred partners ready to offer commercial support should you need it](https://partners.dolibarr.org) ![ScreenShot](https://www.dolibarr.org/images/dolibarr_screenshot1_1920x1080.jpg) From 942a236c2ce197ad5fd48de9449e1e364c06b16e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 16 Aug 2020 23:57:49 +0200 Subject: [PATCH 388/434] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b14edb8d1da..c35cbe6f536 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ If you don't have time to install it yourself, you can try some commercial 'read ## UPGRADING -Dolibarr supports upgrading usually wihtout the need for any (commercial) support (depending on if you use any commercial extensions) and supports upgrading all the way from 2.8-12.0 without breakage. This is unique in the ERP ecosystem and a benefit our users highly appreciate! +Dolibarr supports upgrading usually wihtout the need for any (commercial) support (depending on if you use any commercial extensions) and supports upgrading all the way from any version after 2.8 without breakage. This is unique in the ERP ecosystem and a benefit our users highly appreciate! - At first make a backup of your Dolibarr files & than see https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr - Check that your installed PHP version is supported by the new version [see PHP support](./doc/phpmatrix.md). From 5a6f459db5d650fcbd7ad2b8254b7ff3db4e4003 Mon Sep 17 00:00:00 2001 From: asolslk <52134143+asolslk@users.noreply.github.com> Date: Sat, 8 Aug 2020 19:07:55 +0800 Subject: [PATCH 389/434] Update accounting.lib.php --- htdocs/core/lib/accounting.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index 317c639ad91..24ba8ced2e4 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -96,7 +96,7 @@ function length_accountg($account) if ($account < 0 || is_empty($account)) return ''; - if (!is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; + if (is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; $g = $conf->global->ACCOUNTING_LENGTH_GACCOUNT; if (!is_empty($g)) { @@ -131,7 +131,7 @@ function length_accounta($accounta) if ($accounta < 0 || is_empty($accounta)) return ''; - if (!is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $accounta; + if (is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $accounta; $a = $conf->global->ACCOUNTING_LENGTH_AACCOUNT; if (!is_empty($a)) { From 5987504fa5eb31a81dfdeeb92ae9987b61af9528 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 04:34:03 +0200 Subject: [PATCH 390/434] Better test --- htdocs/core/lib/accounting.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index 24ba8ced2e4..16b124443da 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -96,7 +96,7 @@ function length_accountg($account) if ($account < 0 || is_empty($account)) return ''; - if (is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; + if (!empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; $g = $conf->global->ACCOUNTING_LENGTH_GACCOUNT; if (!is_empty($g)) { @@ -131,7 +131,7 @@ function length_accounta($accounta) if ($accounta < 0 || is_empty($accounta)) return ''; - if (is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $accounta; + if (!empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $accounta; $a = $conf->global->ACCOUNTING_LENGTH_AACCOUNT; if (!is_empty($a)) { From 86a31d17a52110d84335bd2b5d0e471719cea57b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 04:34:03 +0200 Subject: [PATCH 391/434] Better test --- htdocs/core/lib/accounting.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index 24ba8ced2e4..16b124443da 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -96,7 +96,7 @@ function length_accountg($account) if ($account < 0 || is_empty($account)) return ''; - if (is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; + if (!empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $account; $g = $conf->global->ACCOUNTING_LENGTH_GACCOUNT; if (!is_empty($g)) { @@ -131,7 +131,7 @@ function length_accounta($accounta) if ($accounta < 0 || is_empty($accounta)) return ''; - if (is_empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $accounta; + if (!empty($conf->global->ACCOUNTING_MANAGE_ZERO)) return $accounta; $a = $conf->global->ACCOUNTING_LENGTH_AACCOUNT; if (!is_empty($a)) { From f6c444c23573a066443623996d48d483efaca95c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 05:03:44 +0200 Subject: [PATCH 392/434] css --- htdocs/accountancy/customer/list.php | 10 +++++----- htdocs/accountancy/supplier/list.php | 18 ++++++++++-------- htdocs/theme/eldy/theme_vars.inc.php | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index bf28da1d5d2..1a29daab275 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -384,7 +384,7 @@ if ($result) { print ''; print ''; print ''; - print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth150', 'code2', 1, 0, 1); + print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth125', 'code2', 1, 0, 1); //print ''; print ''; print ''; @@ -407,7 +407,7 @@ if ($result) { print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "s.nom", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Country", $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("VATIntra", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("VATIntraShort", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("AccountAccountingSuggest", '', '', '', '', '', '', '', 'nowraponall '); print_liste_field_titre("IntoAccount", '', '', '', '', '', '', '', 'center '); $checkpicto = ''; @@ -553,14 +553,14 @@ if ($result) { print ''.dol_print_date($db->jdate($objp->datef), 'day').''; // Ref Product - print ''; + print ''; if ($product_static->id > 0) { print $product_static->getNomUrl(1); } - if ($objp->product_label) print '
    '.$objp->product_label.''; + if ($objp->product_label) print '
    '.$objp->product_label.''; print ''; - print ''; + print ''; $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index de562d8dbbf..dbdc1a3bb56 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -371,7 +371,7 @@ if ($result) { print ''; print ''; print ''; - print ''; + //print ''; print ''; if (!empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print ''; print ''; @@ -383,7 +383,7 @@ if ($result) { print ''; print ''; print ''; - print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth150', 'code2', 1, 0, 1); + print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth125', 'code2', 1, 0, 1); //print ''; print ''; print ''; @@ -398,7 +398,7 @@ if ($result) { print ''; print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); + //print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); //print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); @@ -407,7 +407,7 @@ if ($result) { print_liste_field_titre("VATRate", $_SERVER["PHP_SELF"], "l.tva_tx", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "s.nom", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Country", $_SERVER["PHP_SELF"], "co.label", "", $param, '', $sortfield, $sortorder); - print_liste_field_titre("VATIntra", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("VATIntraShort", $_SERVER["PHP_SELF"], "s.tva_intra", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("AccountAccountingSuggest", '', '', '', '', '', '', '', 'nowraponall '); print_liste_field_titre("IntoAccount", '', '', '', '', '', '', '', 'center '); $checkpicto = ''; @@ -459,6 +459,7 @@ if ($result) { $facturefourn_static->ref = $objp->ref; $facturefourn_static->id = $objp->facid; $facturefourn_static->type = $objp->type; + $facturefourn_static->label = $objp->invoice_label; $code_buy_p_notset = ''; $objp->aarowid_suggest = ''; // Will be set later @@ -531,21 +532,22 @@ if ($result) { // Ref Invoice print ''.$facturefourn_static->getNomUrl(1).''; - print ''; + /*print ''; print $objp->invoice_label; print ''; + */ print ''.dol_print_date($db->jdate($objp->datef), 'day').''; // Ref Product - print ''; + print ''; if ($product_static->id > 0) print $product_static->getNomUrl(1); - if ($objp->product_label) print '
    '.$objp->product_label.''; + if ($objp->product_label) print '
    '.$objp->product_label.''; print ''; // Description - print ''; + print ''; $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); diff --git a/htdocs/theme/eldy/theme_vars.inc.php b/htdocs/theme/eldy/theme_vars.inc.php index c28b9a21e0c..293dc6a2c39 100644 --- a/htdocs/theme/eldy/theme_vars.inc.php +++ b/htdocs/theme/eldy/theme_vars.inc.php @@ -71,7 +71,7 @@ $colortexttitle = '0,0,0'; $colortexttitlelink = '10, 20, 100'; $colortext = '0,0,0'; $colortextlink = '10, 20, 100'; -$fontsize = '0.95em'; +$fontsize = '0.90em'; $fontsizesmaller = '0.75em'; $topMenuFontSize = '1.1em'; $toolTipBgColor = 'rgba(255, 255, 255, 0.96)'; From 9712e3d28fd5fc239fbb39db08976a42183eee25 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 05:09:27 +0200 Subject: [PATCH 393/434] Fix travis --- .../class/ProductCombination.class.php | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 7d6a07d736d..4bf2b58ce13 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -1038,9 +1038,9 @@ class ProductCombinationLevel /** * Retrieves combination price levels * - * @param int $fk_product_attribute_combination - * @param int $fk_price_level the price level to fetch, use 0 for all - * @return self[] | -1 on KO + * @param int $fk_product_attribute_combination Id of product combination + * @param int $fk_price_level The price level to fetch, use 0 for all + * @return mixed self[] | -1 on KO */ public function fetchAll($fk_product_attribute_combination, $fk_price_level = 0) { @@ -1111,10 +1111,10 @@ class ProductCombinationLevel // check if level exist in DB before add if (empty($this->id)){ - $sql = "SELECT rowid id" - ." FROM ".MAIN_DB_PREFIX . $this->table_element - ." WHERE fk_product_attribute_combination = ".(int) $this->fk_product_attribute_combination - .' AND fk_price_level = '.intval($this->fk_price_level); + $sql = "SELECT rowid id"; + $sql .= " FROM ".MAIN_DB_PREFIX . $this->table_element; + $sql .= " WHERE fk_product_attribute_combination = ".(int) $this->fk_product_attribute_combination; + $sql .= ' AND fk_price_level = '.intval($this->fk_price_level); $existObj = $this->db->getRow($sql); if ($existObj){ @@ -1124,10 +1124,9 @@ class ProductCombinationLevel // Update if (!empty($this->id)) { - $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET ' - . ' variation_price = '.doubleval($this->variation_price) - . ' , variation_price_percentage = '.intval($this->variation_price_percentage) - . ' WHERE rowid = '.intval($this->id); + $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element; + $sql .= ' SET variation_price = '.doubleval($this->variation_price).' , variation_price_percentage = '.intval($this->variation_price_percentage); + $sql .= ' WHERE rowid = '.intval($this->id); $res = $this->db->query($sql); if ($res>0){ @@ -1141,14 +1140,14 @@ class ProductCombinationLevel } else { // ADD - $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (" - . " fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage" - . " ) VALUES ( " - . intval($this->fk_product_attribute_combination) - . ' , '.intval($this->fk_price_level) - . ' , '.doubleval($this->variation_price) - . ' , '.intval($this->variation_price_percentage) - . " )"; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (; + $sql .= " fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"; + $sql .= " ) VALUES ("; + $sql .= intval($this->fk_product_attribute_combination); + $sql .= " , ".intval($this->fk_price_level); + $sql .= " , ".doubleval($this->variation_price); + $sql .= " , ".intval($this->variation_price_percentage); + $sql .= ")"; $res = $this->db->query($sql); if ($res){ @@ -1172,8 +1171,8 @@ class ProductCombinationLevel */ public function delete() { - $res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element - ." WHERE rowid = ".(int) $this->id); + $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE rowid = ".(int) $this->id; + $res = $this->db->query($sql); return $res ? 1 : -1; } @@ -1187,8 +1186,8 @@ class ProductCombinationLevel */ public function deleteAllForCombination($fk_product_attribute_combination) { - $res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element - ." WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination); + $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination; + $res = $this->db->query($sql); return $res ? 1 : -1; } From cf73c2d8e14ba56591405605339c40a273374825 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 05:26:32 +0200 Subject: [PATCH 394/434] Fix travis --- .../variants/class/ProductCombination.class.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 4bf2b58ce13..6c7149f1212 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -1126,7 +1126,7 @@ class ProductCombinationLevel if (!empty($this->id)) { $sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element; $sql .= ' SET variation_price = '.doubleval($this->variation_price).' , variation_price_percentage = '.intval($this->variation_price_percentage); - $sql .= ' WHERE rowid = '.intval($this->id); + $sql .= ' WHERE rowid = '.((int) $this->id); $res = $this->db->query($sql); if ($res>0){ @@ -1140,13 +1140,13 @@ class ProductCombinationLevel } else { // ADD - $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " (; - $sql .= " fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"; - $sql .= " ) VALUES ("; - $sql .= intval($this->fk_product_attribute_combination); - $sql .= " , ".intval($this->fk_price_level); - $sql .= " , ".doubleval($this->variation_price); - $sql .= " , ".intval($this->variation_price_percentage); + $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " ("; + $sql .= "fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"; + $sql .= ") VALUES ("; + $sql .= (int) $this->fk_product_attribute_combination; + $sql .= ", ".intval($this->fk_price_level); + $sql .= ", ".doubleval($this->variation_price); + $sql .= ", ".intval($this->variation_price_percentage); $sql .= ")"; $res = $this->db->query($sql); From 15e7cd0fb379f474d3db2eb610a023fe763ed604 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 05:54:22 +0200 Subject: [PATCH 395/434] Fix doxygen --- .../class/ProductCombination.class.php | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 6c7149f1212..34de51259fa 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -93,8 +93,8 @@ class ProductCombination /** * Retrieves a combination by its rowid * - * @param int $rowid Row id - * @return int <0 KO, >0 OK + * @param int $rowid Row id + * @return int <0 KO, >0 OK */ public function fetch($rowid) { @@ -132,9 +132,9 @@ class ProductCombination /** * Retrieves combination price levels * - * @param int $fk_price_level the price level to fetch, use 0 for all - * @param bool $useCache to use cache or not - * @return int <0 KO, >0 OK + * @param int $fk_price_level The price level to fetch, use 0 for all + * @param bool $useCache To use cache or not + * @return int <0 KO, >0 OK */ public function fetchCombinationPriceLevels($fk_price_level = 0, $useCache = true) { @@ -189,14 +189,14 @@ class ProductCombination /** * Retrieves combination price levels * - * @param int $clean levels off PRODUIT_MULTIPRICES_LIMIT - * @return int <0 KO, >0 OK + * @param int $clean Levels off PRODUIT_MULTIPRICES_LIMIT + * @return int <0 KO, >0 OK */ public function saveCombinationPriceLevels($clean = 1) { global $conf; - $errors = 0; + $error = 0; $staticProductCombinationLevel = new ProductCombinationLevel($this->db); @@ -220,12 +220,12 @@ class ProductCombination if ($res<1){ $this->error = 'save combination price level '.$fk_price_level . ' '.$combination_price_level->error; $this->errors[] = $this->error; - $errors ++; + $error++; } } - if ($errors > 0){ - return $errors*-1; + if ($error){ + return $error * -1; } else { return 1; @@ -1045,9 +1045,9 @@ class ProductCombinationLevel public function fetchAll($fk_product_attribute_combination, $fk_price_level = 0) { - $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage" - ." FROM ".MAIN_DB_PREFIX.$this->table_element - ." WHERE fk_product_attribute_combination = ".intval($fk_product_attribute_combination); + $sql = "SELECT rowid, fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"; + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " WHERE fk_product_attribute_combination = ".intval($fk_product_attribute_combination); if (!empty($fk_price_level)){ $sql.= ' AND fk_price_level = '.intval($fk_price_level); @@ -1076,8 +1076,8 @@ class ProductCombinationLevel /** * assign vars form an stdclass like sql obj * - * @param int $rowid Row id - * @return int <0 KO, >0 OK + * @param int $obj Object resultset + * @return int <0 KO, >0 OK */ public function fetchFormObj($obj) { @@ -1102,8 +1102,7 @@ class ProductCombinationLevel */ public function save() { - $errors = 0; - + $error = 0; if (empty($this->fk_product_attribute_combination) || empty($this->fk_price_level)){ return -1; @@ -1181,8 +1180,8 @@ class ProductCombinationLevel /** * delete all for a combination * - * @param $fk_product_attribute_combination - * @return int <0 KO, >0 OK + * @param int $fk_product_attribute_combination Id of combination + * @return int <0 KO, >0 OK */ public function deleteAllForCombination($fk_product_attribute_combination) { @@ -1196,17 +1195,17 @@ class ProductCombinationLevel /** * Clean not needed price levels for a combination * - * @param $fk_product_attribute_combination - * @return int <0 KO, >0 OK + * @param int $fk_product_attribute_combination Id of combination + * @return int <0 KO, >0 OK */ public function clean($fk_product_attribute_combination) { global $conf; - $res = $this->db->query("DELETE FROM ".MAIN_DB_PREFIX.$this->table_element - . " WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination - . " AND fk_price_level > ".intval($conf->global->PRODUIT_MULTIPRICES_LIMIT) ); - + $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination; + $sql .= " AND fk_price_level > ".intval($conf->global->PRODUIT_MULTIPRICES_LIMIT) ); + $res = $this->db->query($sql); return $res ? 1 : -1; } From 96d4eeb8beaa893a26a167c7dd8a10ac0ac0a4e3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 12:24:32 +0200 Subject: [PATCH 396/434] Fix syntax error --- htdocs/variants/class/ProductCombination.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 34de51259fa..e580289d44e 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -1204,7 +1204,7 @@ class ProductCombinationLevel $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element; $sql .= " WHERE fk_product_attribute_combination = ".(int) $fk_product_attribute_combination; - $sql .= " AND fk_price_level > ".intval($conf->global->PRODUIT_MULTIPRICES_LIMIT) ); + $sql .= " AND fk_price_level > ".intval($conf->global->PRODUIT_MULTIPRICES_LIMIT); $res = $this->db->query($sql); return $res ? 1 : -1; From 5be10f133cadf27c946a3d5ed542ebd1823a6684 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 13:55:18 +0200 Subject: [PATCH 397/434] Fix several regressions with variants creation --- .../class/ProductCombination.class.php | 138 +++++++++--------- htdocs/variants/combinations.php | 22 +-- htdocs/variants/list.php | 3 +- 3 files changed, 84 insertions(+), 79 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index e580289d44e..50c0dedaced 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -189,7 +189,7 @@ class ProductCombination /** * Retrieves combination price levels * - * @param int $clean Levels off PRODUIT_MULTIPRICES_LIMIT + * @param int $clean Levels of PRODUIT_MULTIPRICES_LIMIT * @return int <0 KO, >0 OK */ public function saveCombinationPriceLevels($clean = 1) @@ -201,26 +201,26 @@ class ProductCombination $staticProductCombinationLevel = new ProductCombinationLevel($this->db); // Delete all - if (empty($this->combination_price_levels)){ + if (empty($this->combination_price_levels)) { return $staticProductCombinationLevel->deleteAllForCombination($this->id); } - // Clean not needed price levels - if ($clean){ + // Clean not needed price levels (level higher than number max defined into setup) + if ($clean) { $res = $staticProductCombinationLevel->clean($this->id); - - if ($res<0){ + if ($res < 0) { $this->errors[] = 'Fail to clean not needed price levels'; return -1; } } - foreach ($this->combination_price_levels as $fk_price_level => $combination_price_level){ + foreach ($this->combination_price_levels as $fk_price_level => $combination_price_level) { $res = $combination_price_level->save(); - if ($res<1){ - $this->error = 'save combination price level '.$fk_price_level . ' '.$combination_price_level->error; + if ($res < 1) { + $this->error = 'Error saving combination price level '.$fk_price_level . ' : '.$combination_price_level->error; $this->errors[] = $this->error; $error++; + break; } } @@ -340,27 +340,29 @@ class ProductCombination { global $conf; - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_combination - (fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight, entity) - VALUES (".(int) $this->fk_product_parent.", ".(int) $this->fk_product_child.", - ".(float) $this->variation_price.", ".(int) $this->variation_price_percentage.", - ".(float) $this->variation_weight.", ".(int) $this->entity.")"; + /* $this->fk_product_child may be empty and will be filled later after subproduct has been created */ - $query = $this->db->query($sql); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_combination"; + $sql .= " (fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight, entity)"; + $sql .= " VALUES (".((int) $this->fk_product_parent).", ".((int) $this->fk_product_child).","; + $sql .= (float) $this->variation_price.", ".(int) $this->variation_price_percentage.","; + $sql .= (float) $this->variation_weight.", ".(int) $this->entity.")"; - if (!$query) { + $resql = $this->db->query($sql); + if ($resql) { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_combination'); + } else { + $this->error = $this->db->lasterror(); return -1; } if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $res = $this->saveCombinationPriceLevels(); - if ($res<0){ + if ($res < 0) { return -2; } } - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'product_attribute_combination'); - return 1; } @@ -374,21 +376,19 @@ class ProductCombination { global $conf; - $sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute_combination - SET fk_product_parent = ".(int) $this->fk_product_parent.", fk_product_child = ".(int) $this->fk_product_child.", - variation_price = ".(float) $this->variation_price.", variation_price_percentage = ".(int) $this->variation_price_percentage.", - variation_weight = ".(float) $this->variation_weight." WHERE rowid = ".(int) $this->id; + $sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute_combination"; + $sql .= " SET fk_product_parent = ".(int) $this->fk_product_parent.", fk_product_child = ".(int) $this->fk_product_child.","; + $sql .= " variation_price = ".(float) $this->variation_price.", variation_price_percentage = ".(int) $this->variation_price_percentage.","; + $sql .= " variation_weight = ".(float) $this->variation_weight." WHERE rowid = ".((int) $this->id); - $query = $this->db->query($sql); - - if (!$query) { + $resql = $this->db->query($sql); + if (! $resql) { return -1; } - if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $res = $this->saveCombinationPriceLevels(); - if ($res<0){ + if ($res < 0) { return -2; } } @@ -603,10 +603,10 @@ class ProductCombination } /** - * Retrieves all unique attributres for a parent product + * Retrieves all unique attributes for a parent product * - * @param int $productid Product rowid - * @return ProductAttribute[] + * @param int $productid Product rowid + * @return ProductAttribute[] Array of attributes */ public function getUniqueAttributesAndValuesByFkProductParent($productid) { @@ -616,13 +616,11 @@ class ProductCombination $variants = array(); //Attributes - $sql = "SELECT DISTINCT fk_prod_attr, a.rang -FROM ".MAIN_DB_PREFIX."product_attribute_combination2val c2v LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination c - ON c2v.fk_prod_combination = c.rowid - LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = c.fk_product_child - LEFT JOIN ".MAIN_DB_PREFIX."product_attribute a ON a.rowid = fk_prod_attr -WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; - + $sql = "SELECT DISTINCT fk_prod_attr, a.rang"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_attribute_combination2val c2v LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination c ON c2v.fk_prod_combination = c.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = c.fk_product_child"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute a ON a.rowid = fk_prod_attr"; + $sql .= " WHERE c.fk_product_parent = ".((int) $productid)." AND p.tosell = 1"; $sql .= $this->db->order('a.rang', 'asc'); $query = $this->db->query($sql); @@ -651,7 +649,6 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; /** * Creates a product combination. Check usages to find more about its use - * * Format of $combinations array: * array( * 0 => array( @@ -662,15 +659,15 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; * [...] * ) * - * @param User $user Object user - * @param Product $product Parent product - * @param array $combinations Attribute and value combinations. - * @param array $variations Price and weight variations - * @param bool|array $price_var_percent Is the price variation a relative variation? - * @param bool|float $forced_pricevar If the price variation is forced - * @param bool|float $forced_weightvar If the weight variation is forced - * @param bool|string $forced_refvar If the reference is forced - * @return int <0 KO, >0 OK + * @param User $user Object user + * @param Product $product Parent product + * @param array $combinations Attribute and value combinations. + * @param array $variations Price and weight variations + * @param bool|array $price_var_percent Is the price variation a relative variation? + * @param bool|float $forced_pricevar If the price variation is forced + * @param bool|float $forced_weightvar If the weight variation is forced + * @param bool|string $forced_refvar If the reference is forced + * @return int <0 KO, >0 OK */ public function createProductCombination(User $user, Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false, $forced_refvar = false) { @@ -705,7 +702,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $weight_impact = (float) $forced_weightvar; // If false, return 0 //Final price impact - if (!is_array($forced_pricevar)){ + if (!is_array($forced_pricevar)) { $price_impact[1] = (float) $forced_pricevar; // If false, return 0 } else { @@ -719,7 +716,12 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newcomb = $existingCombination; } else { $newcomb->fk_product_parent = $product->id; - if ($newcomb->create($user) < 0) { // Create 1 entry into product_attribute_combination (1 entry for all combinations) + + // Create 1 entry into product_attribute_combination (1 entry for each combinations). This init also $newcomb->id + $result = $newcomb->create($user); + if ($result < 0) { + $this->error = $newcomb->error; + $this->errors = $newcomb->errors; $db->rollback(); return -1; } @@ -743,6 +745,8 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $tmp->fk_prod_combination = $newcomb->id; if ($tmp->create($user) < 0) { // Create 1 entry into product_attribute_combination2val + $this->error = $tmp->error; + $this->errors = $tmp->errors; $db->rollback(); return -1; } @@ -786,7 +790,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; if ($conf->global->PRODUIT_MULTIPRICES){ for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++){ $productCombinationLevel = new ProductCombinationLevel($this->db); - $productCombinationLevel->fk_product_attribute_combination = 0; + $productCombinationLevel->fk_product_attribute_combination = $newcomb->id; $productCombinationLevel->fk_price_level = $i; $productCombinationLevel->variation_price = $price_impact[$i]; @@ -799,6 +803,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newcomb->combination_price_levels[$i] = $productCombinationLevel; } } + //var_dump($newcomb->combination_price_levels); $newproduct->weight += $weight_impact; @@ -867,6 +872,8 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; if ($newcomb->update($user) < 0) { + $this->error = $newcomb->error; + $this->errors = $newcomb->errors; $db->rollback(); return -1; } @@ -1096,27 +1103,25 @@ class ProductCombinationLevel /** - * save + * Save a price impact of a product combination for a price level * - * @return int <0 KO, >0 OK + * @return int <0 KO, >0 OK */ public function save() { - $error = 0; - - if (empty($this->fk_product_attribute_combination) || empty($this->fk_price_level)){ + if (($this->id > 0 && empty($this->fk_product_attribute_combination)) || empty($this->fk_price_level)) { return -1; } - // check if level exist in DB before add - if (empty($this->id)){ + // Check if level exist in DB before add + if ($this->fk_product_attribute_combination > 0 && empty($this->id)) { $sql = "SELECT rowid id"; $sql .= " FROM ".MAIN_DB_PREFIX . $this->table_element; $sql .= " WHERE fk_product_attribute_combination = ".(int) $this->fk_product_attribute_combination; $sql .= ' AND fk_price_level = '.intval($this->fk_price_level); $existObj = $this->db->getRow($sql); - if ($existObj){ + if ($existObj) { $this->id = $existObj->id; } } @@ -1128,17 +1133,15 @@ class ProductCombinationLevel $sql .= ' WHERE rowid = '.((int) $this->id); $res = $this->db->query($sql); - if ($res>0){ + if ($res > 0) { return $this->id; - } - else { + } else { $this->error = $this->db->error(); $this->errors[] = $this->error; return -1; } - } - else { - // ADD + } else { + // Add $sql = "INSERT INTO " . MAIN_DB_PREFIX . $this->table_element . " ("; $sql .= "fk_product_attribute_combination, fk_price_level, variation_price, variation_price_percentage"; $sql .= ") VALUES ("; @@ -1149,10 +1152,9 @@ class ProductCombinationLevel $sql .= ")"; $res = $this->db->query($sql); - if ($res){ + if ($res) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element); - } - else { + } else { $this->error = $this->db->error(); $this->errors[] = $this->error; return -1; diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index b9f62bdcf73..217fb56ae9f 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -127,7 +127,6 @@ if ($_POST) { $level_price_impact_percent = array(1 => $price_impact_percent); } - $sanit_features = array(); //First, sanitize @@ -157,7 +156,6 @@ if ($_POST) { // sanit_feature is an array with 1 (and only 1) value per attribute. // For example: Color->blue, Size->Small, Option->2 //var_dump($sanit_features); - if (!$prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features)) { $result = $prodcomb->createProductCombination($user, $object, $sanit_features, array(), $level_price_impact_percent, $level_price_impact, $weight_impact, $reference); @@ -171,7 +169,7 @@ if ($_POST) { exit(); } else { $langs->load("errors"); - setEventMessages('', $prodcomb->errors, 'errors'); + setEventMessages($prodcomb->error, $prodcomb->errors, 'errors'); } } else { setEventMessages($langs->trans('ErrorRecordAlreadyExists'), null, 'errors'); @@ -599,29 +597,32 @@ if (!empty($id) || !empty($ref)) print ''; print ''; print ''; + print '
    '; } if (is_array($productCombination2ValuePairs1)) { ?> -
    + - + '; print ''; @@ -566,9 +566,9 @@ if (!empty($id) || !empty($ref)) print $langs->trans("Create"); print '';*/ + print ''; + print ''; ?> - - @@ -592,18 +592,19 @@ if (!empty($id) || !empty($ref)) "> - '; print ''; + print '
    $val) { $result1 = $prodattr->fetch($val->fk_prod_attr); $result2 = $prodattr_val->fetch($val->fk_prod_attr_val); + //print 'rr'.$result1.' '.$result2; if ($result1 > 0 && $result2 > 0) { print $prodattr->label.' - '.$prodattr_val->value.'
    '; // TODO Add delete link } } - } ?>
    \n"; print '
    - '; + print $listofvariantselected; print '
    '; print '
    '; } if (is_array($productCombination2ValuePairs1)) { - ?> - - '; + // When in edit mode if (is_array($productCombination2ValuePairs1) && count($productCombination2ValuePairs1)) { @@ -639,15 +640,17 @@ if (!empty($id) || !empty($ref)) - global->PRODUIT_MULTIPRICES)){ ?> + global->PRODUIT_MULTIPRICES)) { + ?> - fetchCombinationPriceLevels(); for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) @@ -672,33 +675,35 @@ if (!empty($id) || !empty($ref)) print ''; print ''; } + print '
    >
    '; } if (!empty($conf->global->PRODUIT_MULTIPRICES)){ ?> - + +
    value="trans('Create') : $langs->trans('Save') ?>" class="button">   @@ -731,7 +736,7 @@ if (!empty($id) || !empty($ref)) if ($productCombinations) { - ?> + ?> - '; From 4f93de6d0b902662058a07eea7811c512572a4e8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 17 Aug 2020 23:30:53 +0200 Subject: [PATCH 414/434] Fix phpcs --- htdocs/variants/combinations.php | 56 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 366d6ac5d2f..87d99bcae32 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -608,32 +608,32 @@ if (!empty($id) || !empty($ref)) // When in edit mode if (is_array($productCombination2ValuePairs1) && count($productCombination2ValuePairs1)) { - ?> - - - -
    + ?> + + + +
    $val) { - $result1 = $prodattr->fetch($val->fk_prod_attr); - $result2 = $prodattr_val->fetch($val->fk_prod_attr_val); - //print 'rr'.$result1.' '.$result2; - if ($result1 > 0 && $result2 > 0) - { - print $prodattr->label.' - '.$prodattr_val->value.'
    '; - // TODO Add delete link - } - } + foreach ($productCombination2ValuePairs1 as $key => $val) { + $result1 = $prodattr->fetch($val->fk_prod_attr); + $result2 = $prodattr_val->fetch($val->fk_prod_attr_val); + //print 'rr'.$result1.' '.$result2; + if ($result1 > 0 && $result2 > 0) + { + print $prodattr->label.' - '.$prodattr_val->value.'
    '; + // TODO Add delete link + } + } ?> -
    - - - - - - + + + + + + @@ -642,14 +642,14 @@ if (!empty($id) || !empty($ref)) global->PRODUIT_MULTIPRICES)) { - ?> + ?> > - fetchCombinationPriceLevels(); @@ -736,7 +736,7 @@ if (!empty($id) || !empty($ref)) if ($productCombinations) { - ?> + ?> - Date: Tue, 18 Aug 2020 00:29:13 +0200 Subject: [PATCH 415/434] Fix phpcs --- htdocs/variants/combinations.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 87d99bcae32..9b9a2ba6680 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -614,16 +614,16 @@ if (!empty($id) || !empty($ref))
    $val) { - $result1 = $prodattr->fetch($val->fk_prod_attr); - $result2 = $prodattr_val->fetch($val->fk_prod_attr_val); - //print 'rr'.$result1.' '.$result2; - if ($result1 > 0 && $result2 > 0) - { - print $prodattr->label.' - '.$prodattr_val->value.'
    '; - // TODO Add delete link - } - } + foreach ($productCombination2ValuePairs1 as $key => $val) { + $result1 = $prodattr->fetch($val->fk_prod_attr); + $result2 = $prodattr_val->fetch($val->fk_prod_attr_val); + //print 'rr'.$result1.' '.$result2; + if ($result1 > 0 && $result2 > 0) + { + print $prodattr->label.' - '.$prodattr_val->value.'
    '; + // TODO Add delete link + } + } ?>