From 3299e5f88906bab19d6d53aa86ead716d4bd2648 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 26 Mar 2017 19:13:10 +0200 Subject: [PATCH 001/174] PRODUCT_PRICE_SUPPLIER_NO_LOG test inverted if PRODUCT_PRICE_SUPPLIER_NO_LOG is empty, no log is stored if PRODUCT_PRICE_SUPPLIER_NO_LOG is not empty log is stored they are inversion @eldy maybe add more field in this table --- htdocs/fourn/class/fournisseur.product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index eaff46ddc2c..94034408e49 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -310,7 +310,7 @@ class ProductFournisseur extends Product $error++; } - if (! $error && ! empty($conf->global->PRODUCT_PRICE_SUPPLIER_NO_LOG)) { + if (! $error && empty($conf->global->PRODUCT_PRICE_SUPPLIER_NO_LOG)) { // Add record into log table $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price_log("; $sql .= "datec, fk_product_fournisseur,fk_user,price,quantity)"; From d8018f7937c2ae4c9a499df2eae9591876461735 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 26 Mar 2017 19:16:19 +0200 Subject: [PATCH 002/174] add trigger on product price add/update --- .../product/class/productcustomerprice.class.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php index fd36c55dcf9..9c2ce3e99d2 100644 --- a/htdocs/product/class/productcustomerprice.class.php +++ b/htdocs/product/class/productcustomerprice.class.php @@ -669,15 +669,12 @@ class Productcustomerprice extends CommonObject if (! $error) { if (! $notrigger) { - // Uncomment this and change MYOBJECT to your own tag if you - // want this action calls a trigger. - - // // Call triggers - // include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - // $interface=new Interfaces($this->db); - // $result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf); - // if ($result < 0) { $error++; $this->errors=$interface->errors; } - // // End call triggers + // Call triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('CUSTOMER_PRODUCT_SELLPRICE_CREATE',$this,$user,$langs,$conf); + if ($result < 0) { $error++; $this->errors=$interface->errors; } + // End call triggers } } From d60f1d8402a085c54953af11471016f0383689a7 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 26 Mar 2017 19:29:16 +0200 Subject: [PATCH 003/174] add price_level on product_customer_price_log fk_soc can be 0 when generic price is stored on log --- htdocs/install/mysql/tables/llx_product_customer_price_log.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_product_customer_price_log.sql b/htdocs/install/mysql/tables/llx_product_customer_price_log.sql index 699060cdc98..1d728dd2486 100644 --- a/htdocs/install/mysql/tables/llx_product_customer_price_log.sql +++ b/htdocs/install/mysql/tables/llx_product_customer_price_log.sql @@ -24,7 +24,8 @@ create table llx_product_customer_price_log entity integer DEFAULT 1 NOT NULL, -- multi company id datec datetime, fk_product integer NOT NULL, - fk_soc integer NOT NULL, + fk_soc integer DEFAULT 0 NOT NULL, + price_level smallint NULL DEFAULT 1, price double(24,8) DEFAULT 0, price_ttc double(24,8) DEFAULT 0, price_min double(24,8) DEFAULT 0, From 9871bc3d9a006e6275eebbdaf6c0a6f78ad1bc92 Mon Sep 17 00:00:00 2001 From: BENKE Charlie Date: Sun, 26 Mar 2017 19:35:00 +0200 Subject: [PATCH 004/174] Update 5.0.0-6.0.0.sql --- htdocs/install/mysql/migration/5.0.0-6.0.0.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 25145dc7cfe..bdc2630a4c4 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -25,6 +25,8 @@ -- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); +ALTER TABLE llx_product_customer_price_log ADD COLUMN price_level smallint default 1; + ALTER TABLE llx_ecm_files ADD COLUMN ref varchar(128) AFTER rowid; ALTER TABLE llx_ecm_files CHANGE COLUMN fullpath filepath varchar(255); ALTER TABLE llx_ecm_files CHANGE COLUMN filepath filepath varchar(255); From d34a8f42842a7fdd390640e9351c1e2d49d224af Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Mon, 26 Jun 2017 14:15:36 +0200 Subject: [PATCH 005/174] Refactoring tpl Folder --- htdocs/core/tpl/originproductline.tpl.php | 29 +++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/htdocs/core/tpl/originproductline.tpl.php b/htdocs/core/tpl/originproductline.tpl.php index 78006316f63..c8cd6674a7a 100644 --- a/htdocs/core/tpl/originproductline.tpl.php +++ b/htdocs/core/tpl/originproductline.tpl.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2017 Charlie Benke * * 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 @@ -18,16 +19,20 @@ ?> -> - tpl['label']; ?> - tpl['description']; ?> - tpl['vat_rate']; ?> - tpl['price']; ?> - multicurrency->enabled)) { ?>tpl['multicurrency_price']; ?> - tpl['qty']; ?> - global->PRODUCT_USE_UNITS) echo ''.$langs->trans($this->tpl['unit']).''; - ?> - tpl['remise_percent']; ?> - +'; +print ''.$this->tpl['label'].''; +print ''.$this->tpl['description'].''; +print ''.$this->tpl['vat_rate'].''; +print ''.$this->tpl['price'].''; +if (!empty($conf->multicurrency->enabled)) + print ''.$this->tpl['multicurrency_price'].''; + +print ''.$this->tpl['qty'].''; +if($conf->global->PRODUCT_USE_UNITS) + print ''.$langs->trans($this->tpl['unit']).''; + +print ''.$this->tpl['remise_percent'].''; +print ''."\n"; +?> From 01c3e6fb82fd95ef28eb3201588e2dab11796358 Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Mon, 26 Jun 2017 23:06:24 +0200 Subject: [PATCH 006/174] TPL refactoring --- htdocs/core/tpl/notes.tpl.php | 40 +++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index 2538e052ae4..e925fa64783 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -66,21 +66,29 @@ elseif ($module == 'product') { $permission=$user->rights->produit->creer; if (! empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata='ckeditor:dolibarr_notes:100%:200::1:12:95%'; // Rem: This var is for all notes, not only thirdparties note. 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"; +} +if (empty($user->societe_id)) { + print '
'."\n"; + print '
'."\n"; + print $form->editfieldkey("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, $moreparam, '', 0); + print '
'."\n"; + print '
'."\n"; + print $form->editfieldval("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, '', null, null, $moreparam, 1); + print '
'."\n"; + print '
'."\n"; +} +print '
'."\n"; ?> - - -
- -
-
>editfieldkey("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, $moreparam, '', 0); ?>
-
editfieldval("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, '', null, null, $moreparam, 1); ?>
-
- -societe_id)) { ?> -
-
>editfieldkey("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, $moreparam, '', 0); ?>
-
editfieldval("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, '', null, null, $moreparam, 1); ?>
-
- -
From bb6b8015fe8dd841a1f45eb6e56f24a1f5fa94af Mon Sep 17 00:00:00 2001 From: TuxGasy Date: Mon, 3 Jul 2017 12:30:41 +0200 Subject: [PATCH 007/174] Add docker-compose.yml file to build development environment based on Docker --- Dockerfile | 15 ++++++++------- docker-compose.yml | 33 +++++++++++++++++++++++++++++++++ docker-run.sh | 15 +++++++++++++++ 3 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 docker-compose.yml create mode 100644 docker-run.sh diff --git a/Dockerfile b/Dockerfile index 00a5d0ef567..caa7b0c436a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,7 @@ -FROM php:5.6-apache +FROM php:7.0-apache + +ENV HOST_USER_ID 33 +ENV PHP_INI_DATE_TIMEZONE 'UTC' RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev libldap2-dev \ && rm -rf /var/lib/apt/lists/* \ @@ -9,11 +12,9 @@ RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev libldap2-dev \ && docker-php-ext-install mysqli \ && apt-get purge -y libpng12-dev libjpeg-dev libldap2-dev -COPY htdocs/ /var/www/html/ - -RUN chown -hR www-data:www-data /var/www/html - -VOLUME /var/www/html/conf -VOLUME /var/www/html/documents +COPY docker-run.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-run.sh EXPOSE 80 + +ENTRYPOINT ["docker-run.sh"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000000..2f0b5536d4f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,33 @@ +# This docker-compose.yml file is used to build and run Dolibarr +# in the current workspace +# +# Before build/run, define the variable HOST_USER_ID as following: +# $ export HOST_USER_ID=$(id -u) +# And then, you can run : +# $ docker-compose up + +mariadb: + image: mariadb:latest + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: dolibarr + +phpmyadmin: + image: phpmyadmin/phpmyadmin + environment: + PMA_HOST: mariadb + links: + - mariadb + ports: + - "8080:80" + +web: + build: . + environment: + HOST_USER_ID: $HOST_USER_ID + volumes: + - ./htdocs:/var/www/html + links: + - mariadb + ports: + - "80:80" diff --git a/docker-run.sh b/docker-run.sh new file mode 100644 index 00000000000..c151e1c3cab --- /dev/null +++ b/docker-run.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +usermod -u $HOST_USER_ID www-data +groupmod -g $HOST_USER_ID www-data + +chown -hR www-data:www-data /var/www + +if [ ! -f /usr/local/etc/php/php.ini ]; then + cat < /usr/local/etc/php/php.ini +date.timezone = $PHP_INI_DATE_TIMEZONE +display_errors = On +EOF +fi + +exec apache2-foreground From 0932ebd6c87f86fa70f2d737102fed64d487b6a8 Mon Sep 17 00:00:00 2001 From: Andreas Pachler Date: Mon, 10 Jul 2017 14:09:21 +0200 Subject: [PATCH 008/174] Added functionality to get order customer contact as contact_xx tags --- .../doc/doc_generic_order_odt.modules.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index 9e26b31b0ce..4629f52294b 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -275,9 +275,9 @@ class doc_generic_order_odt extends ModelePDFCommandes dol_mkdir($conf->commande->dir_temp); - // If BILLING contact defined on invoice, we use it + // If CUSTOMER contact defined on order, we use it $usecontact=false; - $arrayidcontact=$object->getIdContact('external','BILLING'); + $arrayidcontact=$object->getIdContact('external','CUSTOMER'); if (count($arrayidcontact) > 0) { $usecontact=true; @@ -289,7 +289,11 @@ class doc_generic_order_odt extends ModelePDFCommandes { // On peut utiliser le nom de la societe du contact if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; - else $socobject = $object->thirdparty; + else { + $socobject = $object->thirdparty; + // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + $contactobject = $object->contact; + } } else { @@ -356,8 +360,12 @@ class doc_generic_order_odt extends ModelePDFCommandes $array_thirdparty=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); $array_objet=$this->get_substitutionarray_object($object,$outputlangs); $array_other=$this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in order as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact) + $array_thirdparty_contact=$this->get_substitutionarray_contact($contactobject,$outputlangs,'contact'); - $tmparray = array_merge($array_user,$array_soc,$array_thirdparty,$array_objet,$array_other); + $tmparray = array_merge($array_user,$array_soc,$array_thirdparty,$array_objet,$array_other,$array_thirdparty_contact); complete_substitutions_array($tmparray, $outputlangs, $object); // Call the ODTSubstitution hook From dcc3febf6f99fdcc70580aee153bd41396a7c3a7 Mon Sep 17 00:00:00 2001 From: Darkjeff Date: Thu, 20 Jul 2017 18:22:53 +0200 Subject: [PATCH 009/174] add bookkkeeping in report turnover --- htdocs/compta/stats/index.php | 42 +++++++++++++++++++++++++++++----- htdocs/langs/fr_FR/compta.lang | 1 + 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php index 19c106a44dc..0c4a16edf7b 100644 --- a/htdocs/compta/stats/index.php +++ b/htdocs/compta/stats/index.php @@ -1,7 +1,8 @@ - * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2017 Olivier Geffroy * * 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 @@ -62,6 +63,7 @@ if ($modecompta=="CREANCES-DETTES") $nom=$langs->trans("SalesTurnover"); $calcmode=$langs->trans("CalcModeDebt"); $calcmode.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; + $calcmode.='
('.$langs->trans("SeeReportInBookkeepingMode",'','').')'; $period="$year_start - $year_end"; $periodlink=($year_start?"".img_previous()." ".img_next()."":""); $description=$langs->trans("RulesCADue"); @@ -70,10 +72,12 @@ if ($modecompta=="CREANCES-DETTES") $builddate=time(); //$exportlink=$langs->trans("NotYetAvailable"); } -else { +else if ($modecompta=="RECETTES-DEPENSES") +{ $nom=$langs->trans("SalesTurnover"); $calcmode=$langs->trans("CalcModeEngagement"); $calcmode.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; + $calcmode.='
('.$langs->trans("SeeReportInBookkeepingMode",'','').')'; $period="$year_start - $year_end"; $periodlink=($year_start?"".img_previous()." ".img_next()."":""); $description=$langs->trans("RulesCAIn"); @@ -81,6 +85,20 @@ else { $builddate=time(); //$exportlink=$langs->trans("NotYetAvailable"); } +else if ($modecompta=="BOOKKEEPING") +{ + $nom=$langs->trans("BookkeepingTurnover"); + $calcmode=$langs->trans("CalcModeBookkeeping"); + $calcmode.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; + $calcmode.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; + $period="$year_start - $year_end"; + $periodlink=($year_start?"".img_previous()." ".img_next()."":""); + $description=$langs->trans("RulesCABookkeeping"); + $description.= $langs->trans("DepositsAreIncluded"); + $builddate=time(); + //$exportlink=$langs->trans("NotYetAvailable"); +} + $moreparam=array(); if (! empty($modecompta)) $moreparam['modecompta']=$modecompta; report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$moreparam,$calcmode); @@ -98,8 +116,10 @@ if ($modecompta == 'CREANCES-DETTES') $sql.= " WHERE f.fk_statut in (1,2)"; if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2,5)"; else $sql.= " AND f.type IN (0,1,2,3,5)"; + $sql.= " AND f.entity = ".$conf->entity; +if ($socid) $sql.= " AND f.fk_soc = ".$socid; } -else +else if ($modecompta=="RECETTES-DEPENSES") { /* * Liste des paiements (les anciens paiements ne sont pas vus par cette requete car, sur les @@ -111,9 +131,19 @@ else $sql.= ", ".MAIN_DB_PREFIX."paiement as p"; $sql.= " WHERE p.rowid = pf.fk_paiement"; $sql.= " AND pf.fk_facture = f.rowid"; -} -$sql.= " AND f.entity = ".$conf->entity; + $sql.= " AND f.entity = ".$conf->entity; if ($socid) $sql.= " AND f.fk_soc = ".$socid; +} +else if ($modecompta=="BOOKKEEPING") +{ + $sql = "SELECT date_format(b.doc_date,'%Y-%m') as dm, sum(b.credit) as amount_ttc"; + $sql.= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as b"; + $sql.= " WHERE b.numero_compte IN (SELECT a.account_number" ; + $sql.= " FROM ".MAIN_DB_PREFIX."accounting_account as a"; + $sql.= " WHERE a.fk_accounting_category = 1 ) " ; // todo sql with accounting category, but we need to define category in turnover +} + + $sql.= " GROUP BY dm"; $sql.= " ORDER BY dm"; @@ -481,7 +511,7 @@ print ''; $i++; } - print "Facture a encaisser : ".price($total_ttc_Rac)."<-- bug ici car n'exclut pas le deja r�gl� des factures partiellement r�gl�es"; + print "Facture a encaisser : ".price($total_ttc_Rac)."<-- bug ici car n'exclut pas le deja r?gl? des factures partiellement r?gl?es"; } $db->free($resql); } diff --git a/htdocs/langs/fr_FR/compta.lang b/htdocs/langs/fr_FR/compta.lang index ae51312a5f7..067a349aefd 100644 --- a/htdocs/langs/fr_FR/compta.lang +++ b/htdocs/langs/fr_FR/compta.lang @@ -130,6 +130,7 @@ AnnualByCompaniesDueDebtMode=Bilan des recettes et dépenses, détail par tiers AnnualByCompaniesInputOutputMode=Bilan des recettes et dépenses, détail par tiers SeeReportInInputOutputMode=Cliquer sur %sRecettes-Dépenses%s dit comptabilité de caisse pour un calcul sur les paiements effectivement réalisés SeeReportInDueDebtMode=Cliquer sur %sCréances-Dettes%s dit comptabilité d'engagement pour un calcul sur les factures émises +SeeReportInBookkeepingMode=Cliquer sur %sGrand Livre%s dit comptabilité avance pour un calcul sur les factures dans le grand livre RulesAmountWithTaxIncluded=- Les montants affichés sont les montants taxe incluse RulesResultDue=- Il comprend les factures impayées, les dépenses, la TVA, les dons qu'elles soient payées ou non. Il comprend également les salaires versés.
- Il est basé sur la date de validation de factures et de la TVA et à la date prévue pour les dépenses. Pour les salaires définis avec le module de salaire, la date de paiement de la valeur est utilisée. RulesResultInOut=- Il comprend les paiements réels effectués sur les factures, les dépenses, la TVA et les salaires.
- Il est basé sur les dates de paiement des factures, les dépenses, la TVA et les salaires. La date du don pour le don. From d09ca6f3da0c621820dc3f8374d12bdf65a6f461 Mon Sep 17 00:00:00 2001 From: TuxGasy Date: Wed, 26 Jul 2017 11:41:12 +0200 Subject: [PATCH 010/174] Move all docker files into build/docker --- .dockerignore | 16 -------------- build/docker/.dockerignore | 3 +++ Dockerfile => build/docker/Dockerfile | 0 build/docker/README.md | 21 +++++++++++++++++++ .../docker/docker-compose.yml | 10 +-------- docker-run.sh => build/docker/docker-run.sh | 0 6 files changed, 25 insertions(+), 25 deletions(-) delete mode 100644 .dockerignore create mode 100644 build/docker/.dockerignore rename Dockerfile => build/docker/Dockerfile (100%) create mode 100644 build/docker/README.md rename docker-compose.yml => build/docker/docker-compose.yml (59%) rename docker-run.sh => build/docker/docker-run.sh (100%) diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index e5908c26ac0..00000000000 --- a/.dockerignore +++ /dev/null @@ -1,16 +0,0 @@ -build -build.xml -ChangeLog -composer.json -CONTRIBUTING.md -COPYING -COPYRIGHT -dev -doc -Dockerfile -INSTALL -README-FR.md -README.md -robots.txt -scripts -test \ No newline at end of file diff --git a/build/docker/.dockerignore b/build/docker/.dockerignore new file mode 100644 index 00000000000..e345920fb8c --- /dev/null +++ b/build/docker/.dockerignore @@ -0,0 +1,3 @@ +Dockerfile +README.md +docker-compose.yml diff --git a/Dockerfile b/build/docker/Dockerfile similarity index 100% rename from Dockerfile rename to build/docker/Dockerfile diff --git a/build/docker/README.md b/build/docker/README.md new file mode 100644 index 00000000000..113c03d21b5 --- /dev/null +++ b/build/docker/README.md @@ -0,0 +1,21 @@ +# How to use it ? + +The docker-compose.yml file is used to build and run Dolibarr in the current workspace. + +Before build/run, define the variable HOST_USER_ID as following: + + export HOST_USER_ID=$(id -u) + +And then, you can run : + + docker-compose up + +This will run 3 container Docker : Dolibarr, MariaDB and PhpMyAdmin. + +The URL to go to the Dolibarr is : + + http://0.0.0.0 + +The URL to go to PhpMyAdmin is (login/password is root/root) : + + http://0.0.0.0:8080 diff --git a/docker-compose.yml b/build/docker/docker-compose.yml similarity index 59% rename from docker-compose.yml rename to build/docker/docker-compose.yml index 2f0b5536d4f..a2017335197 100644 --- a/docker-compose.yml +++ b/build/docker/docker-compose.yml @@ -1,11 +1,3 @@ -# This docker-compose.yml file is used to build and run Dolibarr -# in the current workspace -# -# Before build/run, define the variable HOST_USER_ID as following: -# $ export HOST_USER_ID=$(id -u) -# And then, you can run : -# $ docker-compose up - mariadb: image: mariadb:latest environment: @@ -26,7 +18,7 @@ web: environment: HOST_USER_ID: $HOST_USER_ID volumes: - - ./htdocs:/var/www/html + - ../../htdocs:/var/www/html links: - mariadb ports: diff --git a/docker-run.sh b/build/docker/docker-run.sh similarity index 100% rename from docker-run.sh rename to build/docker/docker-run.sh From 677d50df5ba788f89895b59a0143d610b1fba560 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Thu, 27 Jul 2017 17:11:15 +0200 Subject: [PATCH 011/174] NEW: add 'formObjectOptions' hook to the form setting the product selling price --- htdocs/product/price.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 2b5617c601d..54138d099a2 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1171,6 +1171,9 @@ if ($action == 'edit_price' && $object->getRights()->creer) } print ''; print ''; + + $parameters=array('colspan' => 2); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook print ''; From ded6b40489e6755c93816a89159c07324280cba3 Mon Sep 17 00:00:00 2001 From: GUERRIER Kevin Date: Sat, 29 Jul 2017 14:21:58 +0200 Subject: [PATCH 012/174] Add possibility to propose last num releve in conciliation --- htdocs/admin/bank.php | 366 +++++++++++++++++------------ htdocs/compta/bank/bankentries.php | 12 +- htdocs/langs/en_GB/banks.lang | 2 + htdocs/langs/fr_FR/banks.lang | 3 + 4 files changed, 231 insertions(+), 152 deletions(-) diff --git a/htdocs/admin/bank.php b/htdocs/admin/bank.php index afe60acff2e..c8162c5229f 100644 --- a/htdocs/admin/bank.php +++ b/htdocs/admin/bank.php @@ -1,4 +1,5 @@ * Copyright (C) 2010-2016 Juanjo Menent * Copyright (C) 2013-2014 Philippe Grand @@ -21,15 +22,14 @@ /** * \file htdocs/admin/bank.php - * \ingroup bank - * \brief Page to setup the bank module + * \ingroup bank + * \brief Page to setup the bank module */ - require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; -require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/bank.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php'; +require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php'; $langs->load("admin"); $langs->load("companies"); @@ -38,12 +38,12 @@ $langs->load("other"); $langs->load("banks"); if (!$user->admin) - accessforbidden(); + accessforbidden(); -$action = GETPOST('action','alpha'); -$value = GETPOST('value','alpha'); -$label = GETPOST('label','alpha'); -$scandir = GETPOST('scandir','alpha'); +$action = GETPOST('action', 'alpha'); +$value = GETPOST('value', 'alpha'); +$label = GETPOST('label', 'alpha'); +$scandir = GETPOST('scandir', 'alpha'); $type = 'bankaccount'; @@ -52,100 +52,109 @@ $type = 'bankaccount'; */ //Order display of bank account -if ($action == 'setbankorder') -{ - if (dolibarr_set_const($db, "BANK_SHOW_ORDER_OPTION",GETPOST('value','alpha'),'chaine',0,'',$conf->entity) > 0) - { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; - } - else - { - dol_print_error($db); - } +if ($action == 'setbankorder') { + if (dolibarr_set_const($db, "BANK_SHOW_ORDER_OPTION", + GETPOST('value', 'alpha'), 'chaine', 0, '', $conf->entity) > 0) { + header("Location: " . $_SERVER["PHP_SELF"]); + exit; + } + else { + dol_print_error($db); + } +} + +//Auto report last num releve on conciliate +if ($action == 'setreportlastnumreleve') { + if (dolibarr_set_const($db, "BANK_REPORT_LAST_NUM_RELEVE", 1, 'chaine', 0, + '', $conf->entity) > 0) { + header("Location: " . $_SERVER["PHP_SELF"]); + exit; + } + else { + dol_print_error($db); + } +} +elseif ($action == 'unsetreportlastnumreleve') { + if (dolibarr_set_const($db, "BANK_REPORT_LAST_NUM_RELEVE", 0, 'chaine', 0, + '', $conf->entity) > 0) { + header("Location: " . $_SERVER["PHP_SELF"]); + exit; + } + else { + dol_print_error($db); + } } -if ($action == 'specimen') -{ - $modele=GETPOST('module','alpha'); - - if ($modele == 'sepamandate') - { +if ($action == 'specimen') { + $modele = GETPOST('module', 'alpha'); + + if ($modele == 'sepamandate') { $object = new CompanyBankAccount($db); } - else - { + else { $object = new Account($db); } $object->initAsSpecimen(); - + // Search template files - $file=''; $classname=''; $filefound=0; - $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); - foreach($dirmodels as $reldir) - { - $file=dol_buildpath($reldir."core/modules/bank/doc/pdf_".$modele.".modules.php",0); - if (file_exists($file)) - { - $filefound=1; - $classname = "pdf_".$modele; + $file = ''; + $classname = ''; + $filefound = 0; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $file = dol_buildpath($reldir . "core/modules/bank/doc/pdf_" . $modele . ".modules.php", + 0); + if (file_exists($file)) { + $filefound = 1; + $classname = "pdf_" . $modele; break; } } - - if ($filefound) - { + + if ($filefound) { require_once $file; - + $module = new $classname($db); - - if ($module->write_file($object,$langs) > 0) - { - header("Location: ".DOL_URL_ROOT."/document.php?modulepart=bank&file=SPECIMEN.pdf"); + + if ($module->write_file($object, $langs) > 0) { + header("Location: " . DOL_URL_ROOT . "/document.php?modulepart=bank&file=SPECIMEN.pdf"); return; } - else - { + else { setEventMessages($module->error, null, 'errors'); dol_syslog($module->error, LOG_ERR); } } - else - { + else { setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); } } // Activate a model -if ($action == 'set') -{ - $ret = addDocumentModel($value, $type, $label, $scandir); +if ($action == 'set') { + $ret = addDocumentModel($value, $type, $label, $scandir); } - -else if ($action == 'del') -{ - $ret = delDocumentModel($value, $type); - if ($ret > 0) - { - if ($conf->global->BANKADDON_PDF == "$value") dolibarr_del_const($db, 'BANKADDON_PDF',$conf->entity); - } +else if ($action == 'del') { + $ret = delDocumentModel($value, $type); + if ($ret > 0) { + if ($conf->global->BANKADDON_PDF == "$value") + dolibarr_del_const($db, 'BANKADDON_PDF', $conf->entity); + } } // Set default model -else if ($action == 'setdoc') -{ - if (dolibarr_set_const($db, "BANKADDON_PDF",$value,'chaine',0,'',$conf->entity)) - { +else if ($action == 'setdoc') { + if (dolibarr_set_const($db, "BANKADDON_PDF", $value, 'chaine', 0, '', + $conf->entity)) { // The constant that was read before the new set // We therefore requires a variable to have a coherent view $conf->global->BANKADDON_PDF = $value; } - + // On active le modele $ret = delDocumentModel($value, $type); - if ($ret > 0) - { + if ($ret > 0) { $ret = addDocumentModel($value, $type, $label, $scandir); } } @@ -156,80 +165,78 @@ else if ($action == 'setdoc') * view */ -$form=new Form($db); +$form = new Form($db); -$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); -llxHeader("",$langs->trans("BankSetupModule")); +llxHeader("", $langs->trans("BankSetupModule")); -$linkback=''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("BankSetupModule"),$linkback,'title_setup'); +$linkback = '' . $langs->trans("BackToModuleList") . ''; +print load_fiche_titre($langs->trans("BankSetupModule"), $linkback, + 'title_setup'); $head = bank_admin_prepare_head(null); dol_fiche_head($head, 'general', $langs->trans("BankSetupModule"), -1, 'account'); -$var=true; +$var = true; -$var=! $var; +$var = !$var; //Show bank account order print load_fiche_titre($langs->trans("BankOrderShow"), '', ''); print ''; print ''; -print ''; -print ''; -print ''; -print ''; +print ''; +print ''; +print ''; +print ''; print ''; print "\n"; -$bankorder[0][0]=$langs->trans("BankOrderGlobal"); -$bankorder[0][1]=$langs->trans("BankOrderGlobalDesc"); -$bankorder[0][2]='BankCode DeskCode BankAccountNumber BankAccountNumberKey'; -$bankorder[1][0]=$langs->trans("BankOrderES"); -$bankorder[1][1]=$langs->trans("BankOrderESDesc"); -$bankorder[1][2]='BankCode DeskCode BankAccountNumberKey BankAccountNumber'; +$bankorder[0][0] = $langs->trans("BankOrderGlobal"); +$bankorder[0][1] = $langs->trans("BankOrderGlobalDesc"); +$bankorder[0][2] = 'BankCode DeskCode BankAccountNumber BankAccountNumberKey'; +$bankorder[1][0] = $langs->trans("BankOrderES"); +$bankorder[1][1] = $langs->trans("BankOrderESDesc"); +$bankorder[1][2] = 'BankCode DeskCode BankAccountNumberKey BankAccountNumber'; $var = true; -$i=0; +$i = 0; -$nbofbank=count($bankorder); -while ($i < $nbofbank) -{ - $var = !$var; +$nbofbank = count($bankorder); +while ($i < $nbofbank) { + $var = !$var; - print ''; - print ''; - print '\n"; + print ''; + print ''; + print '\n"; - if ($conf->global->BANK_SHOW_ORDER_OPTION == $i) - { - print ''; - } - else - { - print ''; - } - print ''; - print ''."\n"; - $i++; + if ($conf->global->BANK_SHOW_ORDER_OPTION == $i) { + print ''; + } + else { + print ''; + } + print ''; + print '' . "\n"; + $i++; } -print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").'' . $langs->trans("Name") . '' . $langs->trans("Description") . '' . $langs->trans("Example") . '' . $langs->trans("Status") . ' 
'.$bankorder[$i][0]."\n"; - print $bankorder[$i][1]; - print ''; - $tmparray=explode(' ',$bankorder[$i][2]); - foreach($tmparray as $key => $val) - { - if ($key > 0) print ', '; - print $langs->trans($val); - } - print "
' . $bankorder[$i][0] . "\n"; + print $bankorder[$i][1]; + print ''; + $tmparray = explode(' ', $bankorder[$i][2]); + foreach ($tmparray as $key => $val) { + if ($key > 0) + print ', '; + print $langs->trans($val); + } + print "'; - print img_picto($langs->trans("Activated"),'on'); - print ''; - print img_picto($langs->trans("Disabled"),'off'); - print ' 
'; + print img_picto($langs->trans("Activated"), 'on'); + print ''; + print img_picto($langs->trans("Disabled"), 'off'); + print ' 
'."\n"; +print '' . "\n"; print '

'; @@ -257,7 +264,8 @@ if ($resql) { array_push($def, $array[0]); $i ++; } -} else { +} +else { dol_print_error($db); } @@ -273,11 +281,10 @@ print "\n"; clearstatcache(); -foreach ($dirmodels as $reldir) -{ +foreach ($dirmodels as $reldir) { foreach (array('', '/doc') as $valdir) { $dir = dol_buildpath($reldir . "core/modules/bank" . $valdir); - + if (is_dir($dir)) { $handle = opendir($dir); if (is_resource($handle)) { @@ -286,23 +293,26 @@ foreach ($dirmodels as $reldir) } closedir($handle); arsort($filelist); - + foreach ($filelist as $file) { - if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) { - + if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', + $file)) { + if (file_exists($dir . '/' . $file)) { $name = substr($file, 4, dol_strlen($file) - 16); $classname = substr($file, 0, dol_strlen($file) - 12); - + require_once $dir . '/' . $file; $module = new $classname($db); - + $modulequalified = 1; - if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL + < 2) $modulequalified = 0; - if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL + < 1) $modulequalified = 0; - + if ($modulequalified) { print ''; print(empty($module->name) ? $name : $module->name); @@ -312,29 +322,35 @@ foreach ($dirmodels as $reldir) else print $module->description; print ''; - + // Active if (in_array($name, $def)) { print '' . "\n"; print ''; - print img_picto($langs->trans("Enabled"), 'switch_on'); + print img_picto($langs->trans("Enabled"), + 'switch_on'); print ''; print ''; - } else { + } + else { print '' . "\n"; - print '' . img_picto($langs->trans("Disabled"), 'switch_off') . ''; + print '' . img_picto($langs->trans("Disabled"), + 'switch_off') . ''; print ""; } - + // Default print ''; if ($conf->global->BANKADDON_PDF == $name) { - print img_picto($langs->trans("Default"), 'on'); - } else { - print '' . img_picto($langs->trans("Disabled"), 'off') . ''; + print img_picto($langs->trans("Default"), + 'on'); + } + else { + print '' . img_picto($langs->trans("Disabled"), + 'off') . ''; } print ''; - + // Info $htmltooltip = '' . $langs->trans("Name") . ': ' . $module->name; $htmltooltip .= '
' . $langs->trans("Type") . ': ' . ($module->type ? $module->type : $langs->trans("Unknown")); @@ -342,27 +358,33 @@ foreach ($dirmodels as $reldir) $htmltooltip .= '
' . $langs->trans("Width") . '/' . $langs->trans("Height") . ': ' . $module->page_largeur . '/' . $module->page_hauteur; } $htmltooltip .= '

' . $langs->trans("FeaturesSupported") . ':'; - $htmltooltip .= '
' . $langs->trans("Logo") . ': ' . yn($module->option_logo, 1, 1); + $htmltooltip .= '
' . $langs->trans("Logo") . ': ' . yn($module->option_logo, + 1, 1); //$htmltooltip .= '
' . $langs->trans("PaymentMode") . ': ' . yn($module->option_modereg, 1, 1); //$htmltooltip .= '
' . $langs->trans("PaymentConditions") . ': ' . yn($module->option_condreg, 1, 1); - $htmltooltip .= '
' . $langs->trans("MultiLanguage") . ': ' . yn($module->option_multilang, 1, 1); + $htmltooltip .= '
' . $langs->trans("MultiLanguage") . ': ' . yn($module->option_multilang, + 1, 1); // $htmltooltip.='
'.$langs->trans("Discounts").': '.yn($module->option_escompte,1,1); // $htmltooltip.='
'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); //$htmltooltip .= '
' . $langs->trans("WatermarkOnDraftOrders") . ': ' . yn($module->option_draft_watermark, 1, 1); - + print ''; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $form->textwithpicto('', $htmltooltip, 1, + 0); print ''; - + // Preview print ''; if ($module->type == 'pdf') { - print '' . img_object($langs->trans("Preview"), 'bill') . ''; - } else { - print img_object($langs->trans("PreviewNotAvailable"), 'generic'); + print '' . img_object($langs->trans("Preview"), + 'bill') . ''; + } + else { + print img_object($langs->trans("PreviewNotAvailable"), + 'generic'); } print ''; - + print "\n"; } } @@ -372,9 +394,51 @@ foreach ($dirmodels as $reldir) } } } +print ''; //} + +print '

'; + + +/* + * Document templates generators + */ +//if (! empty($conf->global->MAIN_FEATURES_LEVEL)) +//{ +print load_fiche_titre($langs->trans("BankAccountReleveModule"), '', ''); + + +print "\n"; +print "\n"; +print ''; +print ''; +print '\n"; +print "\n"; + +print ''; +// Active +if ($conf->global->BANK_REPORT_LAST_NUM_RELEVE) { + print ''; +} +else { + print '"; +} + +print "\n"; +print '
' . $langs->trans("Name") . '' . $langs->trans("Description") . '' . $langs->trans("Status") . "
'; +print $langs->trans('AccountStatement'); +print "\n"; +print $langs->trans('AutoReportLastAccountStatement'); +print '' . "\n"; + print ''; + print img_picto($langs->trans("Enabled"), 'switch_on'); + print ''; + print '' . "\n"; + print '' . img_picto($langs->trans("Disabled"), + 'switch_off') . ''; + print "
'; dol_fiche_end(); llxFooter(); diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index a19ccbb6b7c..42c295b3600 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -605,7 +605,7 @@ if ($resql) // print ''; print '
'; print ''.$langs->trans("InputReceiptNumber").': '; - print ''; // The only default value is value we just entered + print ''; // The only default value is value we just entered print '
'; if ($options) { print $langs->trans("EventualyAddCategory").': '; @@ -649,6 +649,16 @@ if ($resql) { dol_print_error($db); } + /** + * Using BANK_REPORT_LAST_NUM_RELEVE to automatically report last num (or not) + */ + if ($conf->global->BANK_REPORT_LAST_NUM_RELEVE == 1) { + print ' + + '; + } print '

'; // print ''; } diff --git a/htdocs/langs/en_GB/banks.lang b/htdocs/langs/en_GB/banks.lang index 6bc449c5864..71e43f01f8e 100644 --- a/htdocs/langs/en_GB/banks.lang +++ b/htdocs/langs/en_GB/banks.lang @@ -18,3 +18,5 @@ RejectCheck=Cheque returned RejectCheckDate=Date the cheque was returned CheckRejected=Cheque returned CheckRejectedAndInvoicesReopened=Cheque returned and invoices reopened +AutoReportLastAccountStatement=Use automatically last account statement to reconcile +BankAccountReleveModule=Bank Statement \ No newline at end of file diff --git a/htdocs/langs/fr_FR/banks.lang b/htdocs/langs/fr_FR/banks.lang index c28a15a6e16..bf481e5c8e4 100644 --- a/htdocs/langs/fr_FR/banks.lang +++ b/htdocs/langs/fr_FR/banks.lang @@ -38,6 +38,9 @@ AccountStatement=Relevé AccountStatementShort=Relevé AccountStatements=Relevés LastAccountStatements=Derniers relevés bancaires +AutoReportLastAccountStatement=Proposer automatiquement le dernier relevé bancaire rapproché +BankAccountReleveModule=Rapprochement relevés bancaires +Conciliated=Rapproché IOMonthlyReporting=Rapport mensuel E/S BankAccountDomiciliation=Domiciliation du compte BankAccountCountry=Pays du compte From b6b3ab3f1bf062bf957518ff779cec822f29cc14 Mon Sep 17 00:00:00 2001 From: GUERRIER Kevin Date: Sat, 29 Jul 2017 15:07:27 +0200 Subject: [PATCH 013/174] NEW Add Next/Previous button on operation date of bank line Operation date has to be frequently updated because some bank change them in many case. With this feature, this value can be updated simply like the value date. --- htdocs/compta/bank/bankentries.php | 11 +++- htdocs/compta/bank/class/account.class.php | 61 ++++++++++++++++++++++ htdocs/compta/bank/ligne.php | 23 ++++++-- htdocs/core/ajax/bankconciliate.php | 24 +++++++++ 4 files changed, 114 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/bank/bankentries.php b/htdocs/compta/bank/bankentries.php index 42c295b3600..559e16627f8 100644 --- a/htdocs/compta/bank/bankentries.php +++ b/htdocs/compta/bank/bankentries.php @@ -1127,7 +1127,16 @@ if ($resql) // Date ope if (! empty($arrayfields['b.dateo']['checked'])) { - print ''.dol_print_date($db->jdate($objp->do),"day")."\n"; + print ''; + print ''.dol_print_date($db->jdate($objp->do),"day").""; + print ' '; + print ''; + print ''; + print img_edit_remove() . " "; + print ''; + print img_edit_add() .""; + print ''; + print "\n"; if (! $i) $totalarray['nbfield']++; } diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 08631abec79..47c3e5122ff 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1959,6 +1959,67 @@ class AccountLine extends CommonObject } + /** + * Increase/decrease operation date of a rowid + * + * @param int $rowid Id of line + * @param int $sign 1 or -1 + * @return int >0 if OK, 0 if KO + */ + function dateo_change($rowid,$sign=1) + { + $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".$rowid; + $resql = $this->db->query($sql); + if ($resql) + { + $obj=$this->db->fetch_object($resql); + $newdate=$this->db->jdate($obj->dateo)+(3600*24*$sign); + + $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET"; + $sql.= " dateo = '".$this->db->idate($newdate)."'"; + $sql.= " WHERE rowid = ".$rowid; + + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->affected_rows($result)) + { + return 1; + } + } + else + { + dol_print_error($this->db); + return 0; + } + } + else dol_print_error($this->db); + return 0; + } + + /** + * Increase operation date of a rowid + * + * @param int $id Id of line to change + * @return int >0 if OK, 0 if KO + */ + function dateo_next($id) + { + return $this->dateo_change($id,1); + } + + /** + * Decrease operation date of a rowid + * + * @param int $id Id of line to change + * @return int >0 if OK, 0 if KO + */ + function dateo_previous($id) + { + return $this->dateo_change($id,-1); + } + + /** * Load miscellaneous information for tab "Info" * diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php index 99362167a07..525b7a72e12 100644 --- a/htdocs/compta/bank/ligne.php +++ b/htdocs/compta/bank/ligne.php @@ -71,13 +71,20 @@ if ($cancel) } } -if ($user->rights->banque->consolidate && $action == 'dvnext') + +if ($user->rights->banque->consolidate && $action == 'donext') +{ + $al = new AccountLine($db); + $al->dateo_next($_GET["rowid"]); +}elseif ($user->rights->banque->consolidate && $action == 'doprev') +{ + $al = new AccountLine($db); + $al->dateo_previous($_GET["rowid"]); +}elseif ($user->rights->banque->consolidate && $action == 'dvnext') { $al = new AccountLine($db); $al->datev_next($_GET["rowid"]); -} - -if ($user->rights->banque->consolidate && $action == 'dvprev') +}elseif ($user->rights->banque->consolidate && $action == 'dvprev') { $al = new AccountLine($db); $al->datev_previous($_GET["rowid"]); @@ -479,6 +486,14 @@ if ($result) { print ''; print $form->select_date($db->jdate($objp->do),'dateo','','','','update',1,0,1,$objp->rappro); + if (! $objp->rappro) + { + print '   '; + print ''; + print img_edit_remove() . " "; + print ''; + print img_edit_add() .""; + } print ''; } else diff --git a/htdocs/core/ajax/bankconciliate.php b/htdocs/core/ajax/bankconciliate.php index 65620c5429c..e5bfb674e8f 100644 --- a/htdocs/core/ajax/bankconciliate.php +++ b/htdocs/core/ajax/bankconciliate.php @@ -71,3 +71,27 @@ if (($user->rights->banque->modifier || $user->rights->banque->consolidate) && $ exit; } +if (($user->rights->banque->modifier || $user->rights->banque->consolidate) && $action == 'donext') +{ + // Increase date + $al = new AccountLine($db); + $al->dateo_next(GETPOST('rowid','int')); + $al->fetch(GETPOST('rowid','int')); + + print ''.dol_print_date($db->jdate($al->dateo),"day").''; + + exit; +} + +if (($user->rights->banque->modifier || $user->rights->banque->consolidate) && $action == 'doprev') +{ + // Decrease date + $al =new AccountLine($db); + $al->dateo_previous(GETPOST('rowid','int')); + $al->fetch(GETPOST('rowid','int')); + + print ''.dol_print_date($db->jdate($al->dateo),"day").''; + + exit; +} + From e039f7cc22eea102f4b233af0236b2777fed69df Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Aug 2017 16:37:24 +0200 Subject: [PATCH 014/174] Complete repair script --- htdocs/install/mysql/migration/repair.sql | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index 5e888399d9c..c86ab8d7ff7 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -13,11 +13,26 @@ -- flush privileges; --- Requests to change character set and collation of a column +-- Request to change default pagecode + colation of database +-- ALTER DATABASE name_of_database CHARACTER SET utf8 COLLATE utf8_unicode_ci; --- ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) CHARACTER SET utf8; --- ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) COLLATE utf8_unicode_ci; --- You can check with "show full columns from llx_accountingaccount"; +-- Request to change default pagecode + colation of table +-- ALTER TABLE name_of_table CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci; + +-- Request to change character set and collation of a varchar column. +-- utf8 and utf8_unicode_ci is recommended (or even better utf8mb4 and utf8mb4_unicode_ci with mysql 5.5.3+) +-- ALTER TABLE name_of_table MODIFY field VARCHAR(20) CHARACTER SET utf8; +-- ALTER TABLE name_of_table MODIFY field VARCHAR(20) COLLATE utf8_unicode_ci; +-- You can check with 'show full columns from mytablename'; + + + +-- VMYSQLUTF8UNICODE ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) CHARACTER SET utf8; +-- VMYSQLUTF8UNICODE ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) COLLATE utf8_unicode_ci; +-- VMYSQLUTF8UNICODE ALTER TABLE llx_stock_mouvement MODIFY batch VARCHAR(30) CHARACTER SET utf8; +-- VMYSQLUTF8UNICODE ALTER TABLE llx_stock_mouvement MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; +-- VMYSQLUTF8UNICODE ALTER TABLE llx_product_lot MODIFY batch VARCHAR(30) CHARACTER SET utf8; +-- VMYSQLUTF8UNICODE ALTER TABLE llx_product_lot MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; From a3b5caaae0f7f35b38648e8ac82d96d1f274e18d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Aug 2017 18:41:05 +0200 Subject: [PATCH 015/174] Prepare rc --- 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 6d14f47af10..9b6435d8210 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','6.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','6.0.0-rc'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); From 1c157c7c3d5f149e2c18cca4ac3c2613d60ba7e7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Aug 2017 21:23:40 +0200 Subject: [PATCH 016/174] Fix pb with mix collation. Add a way to fix this in repair. --- htdocs/core/lib/admin.lib.php | 43 ++++++++++++++--------- htdocs/install/mysql/migration/repair.sql | 12 +++---- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 288082296f3..1225f510774 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -146,7 +146,7 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker $buf = fgets($fp, 4096); // Test if request must be ran only for particular database or version (if yes, we must remove the -- comment) - if (preg_match('/^--\sV(MYSQL|PGSQL|)([0-9\.]+)/i',$buf,$reg)) + if (preg_match('/^--\sV(MYSQL|PGSQL)([^\s]*)/i',$buf,$reg)) { $qualified=1; @@ -159,20 +159,29 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker // restrict on version if ($qualified) { - - $versionrequest=explode('.',$reg[2]); - //print var_dump($versionrequest); - //print var_dump($versionarray); - if (! count($versionrequest) || ! count($versionarray) || versioncompare($versionrequest,$versionarray) > 0) - { - $qualified=0; - } + if (! empty($reg[2])) + { + if (is_numeric($reg[2])) // This is a version + { + $versionrequest=explode('.',$reg[2]); + //print var_dump($versionrequest); + //print var_dump($versionarray); + if (! count($versionrequest) || ! count($versionarray) || versioncompare($versionrequest,$versionarray) > 0) + { + $qualified=0; + } + } + else // This is a test on a constant. For example when we have -- VMYSQLUTF8UNICODE, we test constant $conf->global->UTF8UNICODE + { + if (empty($conf->db->dolibarr_main_db_collation) || ($reg[2] != strtoupper(preg_replace('/_/', '', $conf->db->dolibarr_main_db_collation)))) $qualified=0; + } + } } if ($qualified) { // Version qualified, delete SQL comments - $buf=preg_replace('/^--\sV(MYSQL|PGSQL|)([0-9\.]+)/i','',$buf); + $buf=preg_replace('/^--\sV(MYSQL|PGSQL)([^\s]*)/i','',$buf); //print "Ligne $i qualifi?e par version: ".$buf.'
'; } } @@ -769,7 +778,7 @@ function activateModule($value,$withdeps=1) } $result=$objMod->init(); - if ($result <= 0) + if ($result <= 0) { $ret['errors'][]=$objMod->error; } @@ -799,19 +808,19 @@ function activateModule($value,$withdeps=1) break; } } - + if ($activate) { $ret['nbmodules']+=$resarray['nbmodules']; $ret['nbperms']+=$resarray['nbperms']; } - else + else { $ret['errors'][] = $langs->trans('activateModuleDependNotSatisfied', $objMod->name, $objMod->depends[$i]); } } } - + if (isset($objMod->conflictwith) && is_array($objMod->conflictwith) && ! empty($objMod->conflictwith)) { // Desactivation des modules qui entrent en conflit @@ -830,12 +839,12 @@ function activateModule($value,$withdeps=1) } } - if (! count($ret['errors'])) + if (! count($ret['errors'])) { $ret['nbmodules']++; $ret['nbperms']+=count($objMod->rights); } - + return $ret; } @@ -1307,7 +1316,7 @@ function showModulesExludedForExternal($modules) //if (empty($conf->global->$moduleconst)) continue; if (! in_array($modulename,$listofmodules)) continue; //var_dump($modulename.'eee'.$langs->trans('Module'.$module->numero.'Name')); - + if ($i > 0) $text.=', '; else $text.=' '; $i++; diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index c86ab8d7ff7..fa48dfad9d2 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -27,12 +27,12 @@ --- VMYSQLUTF8UNICODE ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) CHARACTER SET utf8; --- VMYSQLUTF8UNICODE ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) COLLATE utf8_unicode_ci; --- VMYSQLUTF8UNICODE ALTER TABLE llx_stock_mouvement MODIFY batch VARCHAR(30) CHARACTER SET utf8; --- VMYSQLUTF8UNICODE ALTER TABLE llx_stock_mouvement MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; --- VMYSQLUTF8UNICODE ALTER TABLE llx_product_lot MODIFY batch VARCHAR(30) CHARACTER SET utf8; --- VMYSQLUTF8UNICODE ALTER TABLE llx_product_lot MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; +-- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) CHARACTER SET utf8; +-- VMYSQLUTF8UNICODECI ALTER TABLE llx_accounting_account MODIFY account_number VARCHAR(20) COLLATE utf8_unicode_ci; +-- VMYSQLUTF8UNICODECI ALTER TABLE llx_stock_mouvement MODIFY batch VARCHAR(30) CHARACTER SET utf8; +-- VMYSQLUTF8UNICODECI ALTER TABLE llx_stock_mouvement MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; +-- VMYSQLUTF8UNICODECI ALTER TABLE llx_product_lot MODIFY batch VARCHAR(30) CHARACTER SET utf8; +-- VMYSQLUTF8UNICODECI ALTER TABLE llx_product_lot MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; From c2a89ae58e935955bd73b142f4d9e5d1c91155cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Aug 2017 22:58:52 +0200 Subject: [PATCH 017/174] Code comment --- htdocs/install/mysql/data/llx_c_tva.sql | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql index 7f9c5f97ea4..df533f39db0 100644 --- a/htdocs/install/mysql/data/llx_c_tva.sql +++ b/htdocs/install/mysql/data/llx_c_tva.sql @@ -133,13 +133,13 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 3 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 34, 3, '0','0','VAT Rate 0',1); -- INDIA (id country=117) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '12.5','0','VAT standard rate',0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1172, 117, '4','0','VAT reduced rate',0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '12.5','0','VAT standard rate', 0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1172, 117, '4','0','VAT reduced rate', 0); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1173, 117, '1','0','VAT super-reduced rate',0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1174, 117, '0','0','VAT Rate 0',0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1174, 117, '0','0','VAT Rate 0', 0); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'IGST+CGST', 8, 8, '1', 0, '0', 0, 'IGST+CGST', 1); -insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'SGST', 0, 0, '0', 16, '1', 0, 'SGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1176, 117, 'IGST+CGST', 8, 8, '1', 0, '0', 0, 'IGST+CGST', 1); +insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1177, 117, 'SGST' , 0, 0, '0', 16, '1', 0, 'SGST', 1); -- IRELAND (id country=8) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (81, 8, '0','0','VAT Rate 0',1); From 2be75420caaf2e95a29585d3f73ae24194dd592e Mon Sep 17 00:00:00 2001 From: altatof Date: Mon, 7 Aug 2017 10:21:38 +0200 Subject: [PATCH 018/174] FIX : supplier id was not passed to hooks --- htdocs/fourn/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index d3c0fa7357d..ee6ac67412a 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -66,7 +66,7 @@ $hookmanager->initHooks(array('suppliercard','globalcard')); * Action */ -$parameters=array('socid'=>$socid); +$parameters=array('id'=>$id); $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'); From 975fd0a6d3f37a7b7ba6f92a851e51be408e8f59 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Aug 2017 15:43:42 +0200 Subject: [PATCH 019/174] Fix font size --- htdocs/core/lib/pdf.lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 19063ae79c2..5b344056efb 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -748,7 +748,7 @@ function pdf_bank(&$pdf,$outputlangs,$curx,$cury,$account,$onlynumber=0,$default $pdf->MultiCell($tmplength, 3, $outputlangs->convToOutputCharset($content), 0, 'C', 0); $pdf->SetXY($curx, $cury + 1); $curx += $tmplength; - $pdf->SetFont('', 'B', $default_font_size - 4); + $pdf->SetFont('', 'B', $default_font_size - $diffsizecontent); $pdf->MultiCell($tmplength, 3, $outputlangs->transnoentities($val), 0, 'C', 0); if (empty($onlynumber)) { $pdf->line($curx, $cury + 1, $curx, $cury + 7); @@ -794,6 +794,7 @@ function pdf_bank(&$pdf,$outputlangs,$curx,$cury,$account,$onlynumber=0,$default $pdf->MultiCell(100, 3, $val, 0, 'L', 0); $tmpy=$pdf->getStringHeight(100, $val); $cury+=$tmpy; + $cur+=1; } else if (! $usedetailedbban) $cury+=1; From d791476708274b0ff152a161ae4eca50f7203c6c Mon Sep 17 00:00:00 2001 From: John Date: Mon, 7 Aug 2017 15:47:55 +0200 Subject: [PATCH 020/174] Fix doaction call --- htdocs/resource/card.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php index 02d38c2b924..42b8b953c87 100644 --- a/htdocs/resource/card.php +++ b/htdocs/resource/card.php @@ -58,6 +58,9 @@ if( ! $user->rights->resource->read) accessforbidden(); $object = new Dolresource($db); +$objectFetchRes = $object->fetch($id); +if ( !$objectFetchRes> 0 ) dol_print_error(); + $extrafields = new ExtraFields($db); @@ -162,7 +165,7 @@ llxHeader('',$pagetitle,''); $form = new Form($db); $formresource = new FormResource($db); -if ( $object->fetch($id) > 0 ) +if ( $objectFetchRes > 0 ) { $head=resource_prepare_head($object); From 76bee575536bd3729b5f180408e809fa36560180 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 7 Aug 2017 15:49:17 +0200 Subject: [PATCH 021/174] Fix Add doaction hook --- htdocs/resource/add.php | 116 +++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/htdocs/resource/add.php b/htdocs/resource/add.php index a294dfb94db..a6cd75cccf8 100644 --- a/htdocs/resource/add.php +++ b/htdocs/resource/add.php @@ -66,64 +66,72 @@ $extrafields = new ExtraFields($db); // fetch optionals attributes and labels $extralabels=$extrafields->fetch_name_optionals_label($object->table_element); -if ($action == 'confirm_add_resource') +$hookmanager->initHooks(array('resource_card_add','globalcard')); +$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)) { - if (! $cancel) - { - $error=''; - $ref=GETPOST('ref','alpha'); - $description=GETPOST('description','alpha'); - $fk_code_type_resource=GETPOST('fk_code_type_resource','alpha'); - - if (empty($ref)) - { - $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")); - setEventMessages($mesg, null, 'errors'); - $error++; - } - - if (! $error) - { - $object=new Dolresource($db); - $object->ref=$ref; - $object->description=$description; - $object->fk_code_type_resource=$fk_code_type_resource; - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) { - $error ++; - } - - $result=$object->create($user); - if ($result > 0) - { - // Creation OK - $db->commit(); - setEventMessages($langs->trans('ResourceCreatedWithSuccess'), null, 'mesgs'); - Header("Location: card.php?id=" . $object->id); - return; - } - else - { - // Creation KO - setEventMessages($object->error, $object->errors, 'errors'); - $action = ''; - } - } - else - { - $action = ''; - } - } - else - { - Header("Location: list.php"); - } + if ($action == 'confirm_add_resource') + { + if (! $cancel) + { + $error=''; + + $ref=GETPOST('ref','alpha'); + $description=GETPOST('description','alpha'); + $fk_code_type_resource=GETPOST('fk_code_type_resource','alpha'); + + if (empty($ref)) + { + $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref")); + setEventMessages($mesg, null, 'errors'); + $error++; + } + + if (! $error) + { + $object=new Dolresource($db); + $object->ref=$ref; + $object->description=$description; + $object->fk_code_type_resource=$fk_code_type_resource; + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) { + $error ++; + } + + $result=$object->create($user); + if ($result > 0) + { + // Creation OK + $db->commit(); + setEventMessages($langs->trans('ResourceCreatedWithSuccess'), null, 'mesgs'); + Header("Location: card.php?id=" . $object->id); + return; + } + else + { + // Creation KO + setEventMessages($object->error, $object->errors, 'errors'); + $action = ''; + } + } + else + { + $action = ''; + } + } + else + { + Header("Location: list.php"); + } + } } - /* * View */ From fd38a55f51fe28c71035116d77fec53c2d9eaf9c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Aug 2017 15:49:54 +0200 Subject: [PATCH 022/174] FIX amount overlap other amount when a pagebreak is done due to an image at the bottom of page. --- htdocs/core/modules/propale/doc/pdf_azur.modules.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 3eb284ec7fc..d2ecfb60d81 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -451,8 +451,6 @@ class pdf_azur extends ModelePDFPropales // Description of product line $curX = $this->posxdesc-1; - $showpricebeforepagebreak=1; - $pdf->startTransaction(); pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->posxpicture-$curX,3,$curX,$curY,$hideref,$hidedesc); $pageposafter=$pdf->getPage(); From 0960473c9b9e47e99fdc2272f36f452f10f5a98b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Aug 2017 15:51:30 +0200 Subject: [PATCH 023/174] More complete repair of unicode field --- htdocs/install/mysql/migration/repair.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index fa48dfad9d2..467455e57de 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -33,6 +33,8 @@ -- VMYSQLUTF8UNICODECI ALTER TABLE llx_stock_mouvement MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; -- VMYSQLUTF8UNICODECI ALTER TABLE llx_product_lot MODIFY batch VARCHAR(30) CHARACTER SET utf8; -- VMYSQLUTF8UNICODECI ALTER TABLE llx_product_lot MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; +-- VMYSQLUTF8UNICODECI ALTER TABLE llx_product_batchlot MODIFY batch VARCHAR(30) CHARACTER SET utf8; +-- VMYSQLUTF8UNICODECI ALTER TABLE llx_product_batch MODIFY batch VARCHAR(30) COLLATE utf8_unicode_ci; From a7c1ff402afe89ea9857be73024261d0dfe9c355 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Aug 2017 16:06:38 +0200 Subject: [PATCH 024/174] Fix picto on support page --- htdocs/support/index.php | 81 +++------------------------------------- 1 file changed, 5 insertions(+), 76 deletions(-) diff --git a/htdocs/support/index.php b/htdocs/support/index.php index 0e27107ef54..dc1872a1b45 100644 --- a/htdocs/support/index.php +++ b/htdocs/support/index.php @@ -70,12 +70,12 @@ print ''; print ''; print ''; print ''; - + $resteapayer = $object->total_ttc - $totalpaye; - + print ''; print ''; } @@ -2402,7 +2430,7 @@ else dol_print_error($db); } - if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE) + if ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE) { // Total already paid print ''; print ''; print ''; - } + } else // Credit note { // Total already paid back @@ -2534,9 +2562,9 @@ else print ''; print ''; print ''; - + print '

'; - + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) { $blocname = 'contacts'; diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index fee2d3b4a1c..26729ecf866 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -579,7 +579,7 @@ if (empty($reshook)) { $productsupplier = new ProductFournisseur($db); - if (empty($conf->global->SUPPLIER_PROPOSAL_WITH_NOPRICEDEFINED)) + if (empty($conf->global->SUPPLIER_PROPOSAL_WITH_NOPRICEDEFINED)) // TODO this test seems useless { $idprod=0; if (GETPOST('idprodfournprice') == -1 || GETPOST('idprodfournprice') == '') $idprod=-99; // Same behaviour than with combolist. When not select idprodfournprice is now -99 (to avoid conflict with next action that may return -1, -2, ...) @@ -594,8 +594,9 @@ if (empty($reshook)) } elseif (GETPOST('idprodfournprice') > 0) { - //$idprod=$productsupplier->get_buyprice(GETPOST('idprodfournprice'), $qty); // Just to see if a price exists for the quantity. Not used to found vat. - $idprod=$productsupplier->get_buyprice(GETPOST('idprodfournprice'), -1); // We force qty to -1 to be sure to find if a supplier price exist + //$qtytosearch=$qty; // Just to see if a price exists for the quantity. Not used to found vat. + $qtytosearch=-1; // We force qty to -1 to be sure to find if a supplier price exist + $idprod=$productsupplier->get_buyprice(GETPOST('idprodfournprice'), $qtytosearch); $res=$productsupplier->fetch($idprod); } @@ -605,7 +606,7 @@ if (empty($reshook)) $price_base_type = $productsupplier->fourn_price_base_type; $type = $productsupplier->type; $label = $productsupplier->label; - $desc = $productsupplier->description; + $desc = $productsupplier->description; if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc); $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice')); From 4c243d3b9e16062866079144d9674ccc49310797 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 15:18:54 +0200 Subject: [PATCH 116/174] Fix index declaration must be moved into the .key.sql files. --- .../install/mysql/migration/6.0.0-7.0.0.sql | 6 ++++++ .../mysql/tables/llx_holiday_config.key.sql | 20 +++++++++++++++++++ .../mysql/tables/llx_holiday_config.sql | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 htdocs/install/mysql/tables/llx_holiday_config.key.sql diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index b027f560aa0..5759423abbb 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -190,3 +190,9 @@ ALTER TABLE llx_extrafields ADD COLUMN fk_user_author integer; ALTER TABLE llx_extrafields ADD COLUMN fk_user_modif integer; ALTER TABLE llx_extrafields ADD COLUMN datec datetime; ALTER TABLE llx_extrafields ADD COLUMN tms timestamp; + +ALTER TABLE llx_holiday_config MODIFY COLUMN name varchar(128); +ALTER TABLE llx_holiday_config ADD UNIQUE INDEX idx_holiday_config (name); + + + diff --git a/htdocs/install/mysql/tables/llx_holiday_config.key.sql b/htdocs/install/mysql/tables/llx_holiday_config.key.sql new file mode 100644 index 00000000000..cda95c87f39 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_holiday_config.key.sql @@ -0,0 +1,20 @@ +-- =================================================================== +-- Copyright (C) 2012 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 . +-- +-- =================================================================== + +ALTER TABLE llx_holiday_config ADD UNIQUE INDEX idx_holiday_config (name); + diff --git a/htdocs/install/mysql/tables/llx_holiday_config.sql b/htdocs/install/mysql/tables/llx_holiday_config.sql index 2f08bf5aa41..4ef6f15c7df 100644 --- a/htdocs/install/mysql/tables/llx_holiday_config.sql +++ b/htdocs/install/mysql/tables/llx_holiday_config.sql @@ -19,7 +19,7 @@ CREATE TABLE llx_holiday_config ( rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY, -name VARCHAR( 255 ) NOT NULL UNIQUE, +name VARCHAR(128) NOT NULL, value TEXT NULL ) ENGINE=innodb; \ No newline at end of file From 52a8692a8508fcef88fe4b36067af3bfdc84030a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 16:07:11 +0200 Subject: [PATCH 117/174] FIX #7226 --- .../class/fournisseur.commande.class.php | 22 ++- htdocs/fourn/commande/dispatch.php | 144 +++++++++++++----- 2 files changed, 123 insertions(+), 43 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 1d099ee9265..d7d1e542b3a 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2832,8 +2832,9 @@ class CommandeFournisseur extends CommonOrder $supplierorderdispatch = new CommandeFournisseurDispatch($this->db); $filter=array('t.fk_commande'=>$this->id); if (! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS)) { - $filter['t.status']=1; + $filter['t.status']=1; // Restrict to lines with status validated } + $ret=$supplierorderdispatch->fetchAll('','',0,0,$filter); if ($ret<0) { @@ -2844,20 +2845,27 @@ class CommandeFournisseur extends CommonOrder { if (is_array($supplierorderdispatch->lines) && count($supplierorderdispatch->lines)>0) { - //Build array with quantity deliverd by product + $date_liv = dol_now(); + + // Build array with quantity deliverd by product foreach($supplierorderdispatch->lines as $line) { $qtydelivered[$line->fk_product]+=$line->qty; } foreach($this->lines as $line) { $qtywished[$line->fk_product]+=$line->qty; } - - $date_liv = dol_now(); - //Compare array - $diff_array=array_diff_assoc($qtydelivered,$qtywished); + $diff_array=array_diff_assoc($qtydelivered,$qtywished); // Warning: $diff_array is done only on common keys. + $keysinwishednotindelivered=array_diff(array_keys($qtywished),array_keys($qtydelivered)); // To check we also have same number of keys + $keysindeliverednotinwished=array_diff(array_keys($qtydelivered),array_keys($qtywished)); // To check we also have same number of keys + /*var_dump(array_keys($qtydelivered)); + var_dump(array_keys($qtywished)); + var_dump($diff_array); + var_dump($keysinwishednotindelivered); + var_dump($keysindeliverednotinwished); + exit;*/ - if (count($diff_array)==0) //No diff => mean everythings is received + if (count($diff_array)==0 && count($keysinwishednotindelivered)==0 && count($keysindeliverednotinwished)==0) //No diff => mean everythings is received { if ($closeopenorder) { diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index c87b3a62bed..c6a6034c684 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -28,6 +28,7 @@ * \ingroup commande * \brief Page to dispatch receiving */ + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT . '/core/modules/supplier_order/modules_commandefournisseur.php'; require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php'; @@ -84,17 +85,33 @@ if ($id > 0 || ! empty($ref)) { * Actions */ -if ($action == 'checkdispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) { +if ($action == 'checkdispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) +{ + $error=0; $supplierorderdispatch = new CommandeFournisseurDispatch($db); + + $db->begin(); + $result = $supplierorderdispatch->fetch($lineid); if (! $result) - dol_print_error($db); - $result = $supplierorderdispatch->setStatut(1); - if ($result < 0) { + { + $error++; setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors'); - $error ++; $action = ''; - } else { + } + + if (! $error) + { + $result = $supplierorderdispatch->setStatut(1); + if ($result < 0) { + setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors'); + $error++; + $action = ''; + } + } + + if (! $error) + { $result = $object->calcAndSetStatusDispatch($user); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -102,19 +119,42 @@ if ($action == 'checkdispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED $action = ''; } } + if (! $error) + { + $db->commit(); + } + else + { + $db->rollback(); + } } -if ($action == 'uncheckdispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) { +if ($action == 'uncheckdispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) +{ + $error=0; $supplierorderdispatch = new CommandeFournisseurDispatch($db); + + $db->begin(); + $result = $supplierorderdispatch->fetch($lineid); if (! $result) - dol_print_error($db); - $result = $supplierorderdispatch->setStatut(0); - if ($result < 0) { + { + $error++; setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors'); - $error ++; $action = ''; - } else { + } + + if (! $error) + { + $result = $supplierorderdispatch->setStatut(0); + if ($result < 0) { + setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors'); + $error ++; + $action = ''; + } + } + if (! $error) + { $result = $object->calcAndSetStatusDispatch($user); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -122,19 +162,42 @@ if ($action == 'uncheckdispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANC $action = ''; } } + if (! $error) + { + $db->commit(); + } + else + { + $db->rollback(); + } } -if ($action == 'denydispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) { +if ($action == 'denydispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check)))) +{ + $error=0; $supplierorderdispatch = new CommandeFournisseurDispatch($db); + + $db->begin(); + $result = $supplierorderdispatch->fetch($lineid); if (! $result) - dol_print_error($db); - $result = $supplierorderdispatch->setStatut(2); - if ($result < 0) { + { + $error++; setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors'); - $error ++; $action = ''; - } else { + } + + if (! $error) + { + $result = $supplierorderdispatch->setStatut(2); + if ($result < 0) { + setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors'); + $error ++; + $action = ''; + } + } + if (! $error) + { $result = $object->calcAndSetStatusDispatch($user); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -142,6 +205,14 @@ if ($action == 'denydispatchline' && ! ((empty($conf->global->MAIN_USE_ADVANCED_ $action = ''; } } + if (! $error) + { + $db->commit(); + } + else + { + $db->rollback(); + } } if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) { @@ -150,10 +221,10 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) $db->begin(); $pos = 0; - foreach ($_POST as $key => $value) + foreach ($_POST as $key => $value) { // without batch module enabled - if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) + if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) { $pos ++; @@ -184,7 +255,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) } } // with batch module enabled - if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) + if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) { $pos ++; @@ -286,11 +357,11 @@ if ($id > 0 || ! empty($ref)) { $title = $langs->trans("SupplierOrder"); dol_fiche_head($head, 'dispatch', $title, 0, 'order'); - + // Supplier order card $linkback = ''.$langs->trans("BackToList").''; - + $morehtmlref='
'; // Ref supplier $morehtmlref.=$form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', 0, 1); @@ -331,14 +402,14 @@ if ($id > 0 || ! empty($ref)) { } } $morehtmlref.='
'; - - - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + print '
'; print '
'; - + print '
'; // Date @@ -362,7 +433,7 @@ if ($id > 0 || ! empty($ref)) { print "
"; print ''; - + // if ($mesg) print $mesg; print '
'; @@ -382,7 +453,7 @@ if ($id > 0 || ! empty($ref)) { print '
'; print ''; print ''; - + print '
'; print ''; @@ -585,10 +656,10 @@ if ($id > 0 || ! empty($ref)) { print ''; print "
\n"; - if ($nbproduct) + if ($nbproduct) { $checkboxlabel=$langs->trans("CloseReceivedSupplierOrdersAutomatically", $langs->transnoentitiesnoconv($object->statuts[5])); - + print '
'; print $langs->trans("Comment") . ' : '; print '
'; print ' '.$checkboxlabel; - + print '
0 || ! empty($ref)) { if (! $nbproduct) { if (empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED)) print '
'.$langs->trans("NoPredefinedProductToDispatch").'
'; // No predefined line at all - else + else print '
'.$langs->trans("NoMorePredefinedProductToDispatch").'
'; // No predefined line that remain to be dispatched. } @@ -618,7 +689,7 @@ if ($id > 0 || ! empty($ref)) { dol_fiche_end(); - + // List of lines already dispatched $sql = "SELECT p.ref, p.label,"; $sql .= " e.rowid as warehouse_id, e.label as entrepot,"; @@ -699,7 +770,8 @@ if ($id > 0 || ! empty($ref)) { // Add button to check/uncheck disaptching print '
'; - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check))) { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande->receptionner)) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->fournisseur->commande_advance->check))) + { if (empty($objp->status)) { print '' . $langs->trans("Approve") . ''; print '' . $langs->trans("Deny") . ''; From 6b5b10fc949fd04451a595a59cb14c33beca904c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 16:28:34 +0200 Subject: [PATCH 118/174] FIX #7224 --- htdocs/product/class/productcustomerprice.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php index 5b9050077c9..b3066df8188 100644 --- a/htdocs/product/class/productcustomerprice.class.php +++ b/htdocs/product/class/productcustomerprice.class.php @@ -169,12 +169,12 @@ class Productcustomerprice extends CommonObject $sql .= " " . (empty($this->price_min_ttc) ? '0' : "'" . $this->price_min_ttc . "'") . ","; $sql .= " " . (! isset($this->price_base_type) ? 'NULL' : "'" . $this->db->escape($this->price_base_type) . "'") . ","; $sql .= " ".($this->default_vat_code ? "'".$this->db->escape($this->default_vat_code)."'" : "null").","; - $sql .= " " . (! isset($this->tva_tx) ? 'NULL' : "'" . $this->tva_tx . "'") . ","; + $sql .= " " . (! isset($this->tva_tx) ? 'NULL' : (empty($this->tva_tx)?0:$this->tva_tx)) . ","; $sql .= " " . (! isset($this->recuperableonly) ? 'NULL' : "'" . $this->recuperableonly . "'") . ","; $sql .= " " . (empty($this->localtax1_type) ? "'0'" : "'" . $this->localtax1_type . "'") . ","; - $sql .= " " . (! isset($this->localtax1_tx) ? 'NULL' : "'" . $this->localtax1_tx . "'") . ","; + $sql .= " " . (! isset($this->localtax1_tx) ? 'NULL' : (empty($this->localtax1_tx)?0:$this->localtax1_tx)) . ","; $sql .= " " . (empty($this->localtax2_type) ? "'0'" : "'" . $this->localtax2_type . "'") . ","; - $sql .= " " . (! isset($this->localtax2_tx) ? 'NULL' : "'" . $this->localtax2_tx . "'") . ","; + $sql .= " " . (! isset($this->localtax2_tx) ? 'NULL' : (empty($this->localtax2_tx)?0:$this->localtax2_tx)) . ","; $sql .= " " . $user->id . ","; $sql .= " " . (! isset($this->import_key) ? 'NULL' : "'" . $this->db->escape($this->import_key) . "'") . ""; $sql .= ")"; @@ -656,10 +656,10 @@ class Productcustomerprice extends CommonObject $sql .= " price_min_ttc=" . (isset($this->price_min_ttc) ? $this->price_min_ttc : "null") . ","; $sql .= " price_base_type=" . (isset($this->price_base_type) ? "'" . $this->db->escape($this->price_base_type) . "'" : "null") . ","; $sql .= " default_vat_code = ".($this->default_vat_code ? "'".$this->db->escape($this->default_vat_code)."'" : "null").","; - $sql .= " tva_tx=" . (isset($this->tva_tx) ? $this->tva_tx : "null") . ","; + $sql .= " tva_tx=" . (isset($this->tva_tx) ? (empty($this->tva_tx)?0:$this->tva_tx) : "null") . ","; $sql .= " recuperableonly=" . (isset($this->recuperableonly) ? $this->recuperableonly : "null") . ","; - $sql .= " localtax1_tx=" . (isset($this->localtax1_tx) ? $this->localtax1_tx : "null") . ","; - $sql .= " localtax2_tx=" . (isset($this->localtax2_tx) ? $this->localtax2_tx : "null") . ","; + $sql .= " localtax1_tx=" . (isset($this->localtax1_tx) ? (empty($this->localtax1_tx)?0:$this->localtax1_tx) : "null") . ","; + $sql .= " localtax2_tx=" . (isset($this->localtax2_tx) ? (empty($this->localtax2_tx)?0:$this->localtax2_tx) : "null") . ","; $sql .= " localtax1_type=" . (! empty($this->localtax1_type) ? "'".$this->localtax1_type."'": "'0'") . ","; $sql .= " localtax2_type=" . (! empty($this->localtax2_type) ? "'".$this->localtax2_type."'": "'0'") . ","; $sql .= " fk_user=" . $user->id . ","; From 947acfffe204575feeee6eb5bb38cd88bd09424a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 16:53:29 +0200 Subject: [PATCH 119/174] FIX #7173 --- htdocs/adherents/subscription.php | 52 +++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 0c9c8467f1f..c7904667846 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -113,7 +113,6 @@ if ($action == 'confirm_create_thirdparty' && $confirm == 'yes' && $user->rights if ($result < 0) { $langs->load("errors"); - $errmsg=$langs->trans($company->error); setEventMessages($company->error, $company->errors, 'errors'); } else @@ -123,7 +122,7 @@ if ($action == 'confirm_create_thirdparty' && $confirm == 'yes' && $user->rights } else { - $errmsg=$object->error; + setEventMessages($object->error, $object->errors, 'errors'); } } @@ -211,7 +210,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $paymentdate=dol_mktime(0, 0, 0, $_POST["paymentmonth"], $_POST["paymentday"], $_POST["paymentyear"]); } - $subscription=$_POST["subscription"]; // Amount of subscription + $subscription=price2num(GETPOST("subscription",'alpha')); // Amount of subscription $label=$_POST["label"]; // Payment informations @@ -229,6 +228,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! $error++; $langs->load("errors"); $errmsg=$langs->trans("ErrorBadDateFormat",$langs->transnoentitiesnoconv("DateSubscription")); + setEventMessages($errmsg, null, 'errors'); $action='addsubscription'; } if (GETPOST('end') && ! $datesubend) @@ -236,6 +236,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! $error++; $langs->load("errors"); $errmsg=$langs->trans("ErrorBadDateFormat",$langs->transnoentitiesnoconv("DateEndSubscription")); + setEventMessages($errmsg, null, 'errors'); $action='addsubscription'; } if (! $datesubend) @@ -246,16 +247,20 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $error++; $errmsg=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DatePayment")); + setEventMessages($errmsg, null, 'errors'); $action='addsubscription'; } + $amount = price2num(GETPOST("subscription",'alpha')); + // Check if a payment is mandatory or not if (! $error && $adht->subscription) // Member type need subscriptions { - if (! is_numeric($_POST["subscription"])) + if (! is_numeric($amount)) { // If field is '' or not a numeric value $errmsg=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Amount")); + setEventMessages($errmsg, null, 'errors'); $error++; $action='addsubscription'; } @@ -273,7 +278,11 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { if ($_POST["accountid"]) $errmsg=$langs->trans("ErrorDoNotProvideAccountsIfNullAmount"); } - if ($errmsg) $action='addsubscription'; + if ($errmsg) + { + setEventMessages($errmsg, null, 'errors'); + $action='addsubscription'; + } } } } @@ -319,6 +328,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $error++; $errmsg=$db->lasterror(); + setEventMessages($errmsg, null, 'errors'); } } else @@ -326,14 +336,16 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! $error++; $errmsg=$acct->error; $errmsgs=$acct->errors; - } + setEventMessages($errmsg, $errmsgs, 'errors'); + } } else { $error++; $errmsg=$acct->error; $errmsgs=$acct->errors; - } + setEventMessages($errmsg, $errmsgs, 'errors'); + } } // If option choosed, we create invoice @@ -351,6 +363,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $langs->load("errors"); $errmsg=$langs->trans("ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst"); + setEventMessages($errmsg, null, 'errors'); $error++; } } @@ -361,6 +374,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $errmsg=$customer->error; $errmsgs=$acct->errors; + setEventMessages($errmsg, $errmsgs, 'errors'); $error++; } } @@ -378,6 +392,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $error++; $errmsg='ErrorNoPaymentTermRECEPFound'; + setEventMessages($errmsg, null, 'errors'); } } $invoice->socid=$object->fk_soc; @@ -389,12 +404,13 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $invoice->linked_objects = array_merge($invoice->linked_objects, $_POST['other_linked_objects']); } - + $result=$invoice->create($user); if ($result <= 0) { $errmsg=$invoice->error; $errmsgs=$invoice->errors; + setEventMessages($errmsg, $errmsgs, 'errors'); $error++; } } @@ -415,6 +431,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! if ($result <= 0) { $errmsg=$invoice->error; + setEventMessages($errmsg, null, 'errors'); $error++; } } @@ -427,6 +444,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $errmsg=$invoice->error; $errmsgs=$invoice->errors; + setEventMessages($errmsg, $errmsgs, 'errors'); $error++; } } @@ -454,6 +472,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! { $errmsg=$paiement->error; $errmsgs=$paiement->errors; + setEventMessages($errmsg, $errmsgs, 'errors'); $error++; } } @@ -535,6 +554,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! if ($result < 0) { $errmsg=$object->error; + setEventMessages($errmsg, null, 'errors'); } } @@ -581,12 +601,12 @@ if ($rowid > 0) dol_fiche_head($head, 'subscription', $langs->trans("Member"), 0, 'user'); $linkback = ''.$langs->trans("BackToList").''; - + dol_banner_tab($object, 'rowid', $linkback); - + print '
'; print '
'; - + print '
'; print ''; @@ -624,13 +644,13 @@ if ($rowid > 0) } print '
'; - + print '
'; print '
'; - + print '
'; print ''; - + // Birthday print ''; @@ -677,7 +697,7 @@ if ($rowid > 0) } } print ''; - + // Third party Dolibarr if (! empty($conf->societe->enabled)) { @@ -752,7 +772,7 @@ if ($rowid > 0) print "\n"; print '
'; - + dol_fiche_end(); print ''; From 1b1d1a8d0b093f0bc34d717acce479048afea69e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 16:57:07 +0200 Subject: [PATCH 120/174] FIX #7156 --- htdocs/societe/soc.php | 55 ++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index b9c962a5168..06846d34203 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -140,7 +140,7 @@ if (empty($reshook)) if (!$errors) { // TODO Move the merge function into class of object. - + $db->begin(); // Recopy some data @@ -157,26 +157,29 @@ if (empty($reshook)) { if (empty($object->$property)) $object->$property = $soc_origin->$property; } - + // Concat some data $listofproperties=array( - 'note_public', 'note_private' + 'note_public', 'note_private' ); foreach ($listofproperties as $property) { $object->$property = dol_concatdesc($object->$property, $soc_origin->$property); } - + // Merge extrafields - foreach ($soc_origin->array_options as $key => $val) + if (is_array($soc_origin->array_options)) { - if (empty($object->array_options[$key])) $object->array_options[$key] = $val; + foreach ($soc_origin->array_options as $key => $val) + { + if (empty($object->array_options[$key])) $object->array_options[$key] = $val; + } } // TODO Merge categories $object->update($object->id, $user); - - // Move links + + // Move links $objects = array( 'Adherent' => '/adherents/class/adherent.class.php', 'Societe' => '/societe/class/societe.class.php', @@ -487,7 +490,7 @@ if (empty($reshook)) if (empty($object->fournisseur)) $object->code_fournisseur=''; $result = $object->create($user); - + if ($result >= 0) { if ($object->particulier) @@ -557,7 +560,7 @@ if (empty($reshook)) $object->code_fournisseur = null; $object->code_client = null; } - + $error=$object->error; $errors=$object->errors; } @@ -852,7 +855,7 @@ else $object->particulier = $private; $object->prefix_comm = GETPOST('prefix_comm'); $object->client = GETPOST('client')?GETPOST('client'):$object->client; - + if(empty($duplicate_code_error)) { $object->code_client = GETPOST('code_client', 'alpha'); $object->fournisseur = GETPOST('fournisseur')?GETPOST('fournisseur'):$object->fournisseur; @@ -860,7 +863,7 @@ else else { setEventMessages($langs->trans('NewCustomerSupplierCodeProposed'),'', 'warnings'); } - + $object->code_fournisseur = GETPOST('code_fournisseur', 'alpha'); $object->address = GETPOST('address', 'alpha'); $object->zip = GETPOST('zipcode', 'alpha'); @@ -1136,7 +1139,7 @@ else print ''; print ''; print ''; - + // Skype if (! empty($conf->skype->enabled)) { @@ -1216,7 +1219,7 @@ else print ''; - + } elseif($mysoc->localtax1_assuj=="1") { @@ -1230,7 +1233,7 @@ else print $form->selectyesno('localtax2assuj_value',(isset($conf->global->THIRDPARTY_DEFAULT_USELOCALTAX2)?$conf->global->THIRDPARTY_DEFAULT_USELOCALTAX2:0),1); print ''; } - + // Type - Size print ''; - + } elseif($mysoc->localtax1_assuj=="1" && $mysoc->localtax2_assuj!="1") { @@ -1774,7 +1777,7 @@ else print ''; } print ''; - + } elseif($mysoc->localtax2_assuj=="1" && $mysoc->localtax1_assuj!="1") { @@ -1788,7 +1791,7 @@ else } print ''; } - + // VAT Code print ''; print ''; - + if($object->localtax1_assuj=="1" && (! isOnlyOneLocalTax(1))) { print ''; @@ -2144,7 +2147,7 @@ else print ''; } print ''; - + } } elseif($mysoc->localtax2_assuj=="1" && $mysoc->localtax1_assuj!="1") @@ -2154,7 +2157,7 @@ else print ''; if($object->localtax2_assuj=="1" && (! isOnlyOneLocalTax(2))) { - + print ''; print ''; print ''; @@ -2167,7 +2170,7 @@ else print ''; } print ''; - + } } /* @@ -2178,7 +2181,7 @@ else print ''; } */ - + // VAT Code print ''; print ''; */ + // Project + print ""; + // Ref print ''; + if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) + { + // Thirdparty + print ''; + } + // Label task print "\n"; - // Project - print ""; - - if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) - { - // Thirdparty - print ''; - } - // Planned Workload print ''; print "\n"; @@ -834,6 +840,12 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $workloadforid[$projectstatic->id]=1; } + $projectstatic->id=$lines[$i]->fk_project; + $projectstatic->ref=$lines[$i]->projectref; + $projectstatic->title=$lines[$i]->projectlabel; + $projectstatic->public=$lines[$i]->public; + $projectstatic->thirdparty_name=$lines[$i]->thirdparty_name; + print ''."\n"; // User @@ -843,6 +855,21 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ print ''; */ + // Project + print '"; + + if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) + { + // Thirdparty + print ''; + } + // Ref print '\n"; - // Project - print '"; - - if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) - { - // Thirdparty - print ''; - } - // Planned Workload print ''; print "\n"; diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index a30768709f9..8b380645f73 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -12,13 +12,13 @@ PrivateProject=Project contacts ProjectsImContactFor=Projects I'm explicitely a contact of AllAllowedProjects=All project I can read (mine + public) AllProjects=All projects -MyProjectsDesc=This view is limited to projects you are a contact for (whatever is the type). +MyProjectsDesc=This view is limited to projects you are a contact for. ProjectsPublicDesc=This view presents all projects you are allowed to read. TasksOnProjectsPublicDesc=This view presents all tasks on projects you are allowed to read. ProjectsPublicTaskDesc=This view presents all projects and tasks you are allowed to read. ProjectsDesc=This view presents all projects (your user permissions grant you permission to view everything). TasksOnProjectsDesc=This view presents all tasks on all projects (your user permissions grant you permission to view everything). -MyTasksDesc=This view is limited to projects or tasks you are a contact for (whatever is the type). +MyTasksDesc=This view is limited to projects or tasks you are a contact for. OnlyOpenedProject=Only open projects are visible (projects in draft or closed status are not visible). ClosedProjectsAreHidden=Closed projects are not visible. TasksPublicDesc=This view presents all projects and tasks you are allowed to read. diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index 45d7aa237ad..73197025df6 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -439,10 +439,10 @@ print '
'; print '
'.$langs->trans("Birthday").''.dol_print_date($object->birth,'day').'
'.fieldLabel('Web','url').'
'.$langs->transcountry("LocalTax2IsUsed",$mysoc->country_code).''; print $form->selectyesno('localtax2assuj_value',(isset($conf->global->THIRDPARTY_DEFAULT_USELOCALTAX2)?$conf->global->THIRDPARTY_DEFAULT_USELOCALTAX2:0),1); print '
'.fieldLabel('ThirdPartyType','typent_id').''."\n"; $sortparam=(empty($conf->global->SOCIETE_SORT_ON_TYPEENT)?'ASC':$conf->global->SOCIETE_SORT_ON_TYPEENT); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label. @@ -1751,7 +1754,7 @@ else $formcompany->select_localtax(1,$object->localtax1_value, "lt1"); print ''; } - + print ''.fieldLabel($langs->transcountry("LocalTax2IsUsed",$mysoc->country_code),'localtax2assuj_value').''; print $form->selectyesno('localtax2assuj_value',$object->localtax2_assuj,1); if (! isOnlyOneLocalTax(2)) @@ -1761,7 +1764,7 @@ else print ''; } print '
'.fieldLabel('VATIntra','intra_vat').''; @@ -2090,7 +2093,7 @@ else print '
'.$langs->transcountry("LocalTax2IsUsed",$mysoc->country_code).''; print yn($object->localtax2_assuj); print '
'.$object->localtax1_value.'
'.$object->localtax2_value.'
'.$langs->trans('VATIntra').''; @@ -2573,10 +2576,10 @@ else // Subsidiaries list if (empty($conf->global->SOCIETE_DISABLE_SUBSIDIARIES)) - { + { $result=show_subsidiaries($conf,$langs,$db,$object); } - + // Contacts list if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) { From d90a23efb69efc9f6aeec5c93a10ae2f042de8f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 17:00:50 +0200 Subject: [PATCH 121/174] Fix for old php --- htdocs/admin/dolistore/class/dolistore.class.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/htdocs/admin/dolistore/class/dolistore.class.php b/htdocs/admin/dolistore/class/dolistore.class.php index acf86766e25..482bd124a40 100644 --- a/htdocs/admin/dolistore/class/dolistore.class.php +++ b/htdocs/admin/dolistore/class/dolistore.class.php @@ -56,13 +56,11 @@ class Dolistore extends DolistoreModel $this->end = $this->per_page; } - $lang = explode('_', $langs->defaultlang); - $lang = $lang[0]; - $lang_array = ['fr', 'en', 'es', 'it', 'de']; - if (!in_array($lang, $lang_array)) { - $lang = 'en'; - } - $this->lang = array_search($lang, $lang_array) + 1; // 1=fr 2=en ... + $langtmp = explode('_', $langs->defaultlang); + $lang = $langtmp[0]; + $lang_array = array('fr'=>1, 'en'=>2, 'es'=>3, 'it'=>4, 'de'=>5); + if (! in_array($lang, array_keys($lang_array))) $lang = 'en'; + $this->lang = $lang_array[$lang]; // 1=fr 2=en ... try { $this->api = new PrestaShopWebservice($conf->global->MAIN_MODULE_DOLISTORE_API_SRV, From 9079d2890c429ac8012a70a3546f238d1330e1b8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 18:13:42 +0200 Subject: [PATCH 122/174] Fix ajout du code devise Franc Pacifique --- htdocs/install/mysql/data/llx_c_currencies.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/data/llx_c_currencies.sql b/htdocs/install/mysql/data/llx_c_currencies.sql index d9b1390bb32..cb34f60291f 100644 --- a/htdocs/install/mysql/data/llx_c_currencies.sql +++ b/htdocs/install/mysql/data/llx_c_currencies.sql @@ -154,7 +154,7 @@ INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'VEF' INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'VND', '[8363]', 1, 'Viet Nam Dong'); INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'XAF', NULL, 1, 'Communaute Financiere Africaine (BEAC) CFA Franc'); INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'XOF', NULL, 1, 'Communaute Financiere Africaine (BCEAO) Franc'); -INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'XPF', NULL, 1, 'Franc pacifique (XPF)'); +INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'XPF', '[70]', 1, 'Franc pacifique (XPF)'); INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'YER', '[65020]', 1, 'Yemen Rial'); INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'ZWD', '[90,36]', 1, 'Zimbabwe Dollar'); From ccb5344d32b803dd8abb02d27e2888f856f24612 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 18:52:03 +0200 Subject: [PATCH 123/174] Fix links --- htdocs/core/boxes/box_activity.php | 494 +++++++++--------- .../install/mysql/data/llx_c_currencies.sql | 2 +- 2 files changed, 248 insertions(+), 248 deletions(-) diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index ae3e270101e..02b1d1880c8 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -97,181 +97,95 @@ class box_activity extends ModeleBoxes $cumuldata = array(); - // list the summary of the bills - if (! empty($conf->facture->enabled) && $user->rights->facture->lire) + + // list the summary of the propals + if (! empty($conf->propal->enabled) && $user->rights->propale->lire) { - include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - $facturestatic=new Facture($db); + include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; + $propalstatic=new Propal($db); - // part 1 - $cachedir = DOL_DATA_ROOT.'/facture/temp'; - $filename = '/boxactivity-invoice'.$fileid; + $cachedir = DOL_DATA_ROOT.'/propale/temp'; + $filename = '/boxactivity-propal'.$fileid; + $refresh = dol_cache_refresh($cachedir, $filename, $cachetime); + $data = array(); + if ($refresh) + { + $sql = "SELECT p.fk_statut, SUM(p.total) as Mnttot, COUNT(*) as nb"; + $sql.= " FROM (".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p"; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= ")"; + $sql.= " WHERE p.entity = ".$conf->entity; + $sql.= " AND p.fk_soc = s.rowid"; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; + $sql.= " AND p.datep >= '".$db->idate($tmpdate)."'"; + $sql.= " AND p.date_cloture IS NULL"; // just unclosed + $sql.= " GROUP BY p.fk_statut"; + $sql.= " ORDER BY p.fk_statut DESC"; - $refresh = dol_cache_refresh($cachedir, $filename, $cachetime); - $data = array(); - if ($refresh) - { - $sql = "SELECT f.fk_statut, SUM(f.total_ttc) as Mnttot, COUNT(*) as nb"; - $sql.= " FROM (".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= ")"; - $sql.= " WHERE f.entity = ".$conf->entity; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; - $sql.= " AND f.fk_soc = s.rowid"; - $sql.= " AND f.datef >= '".$db->idate($tmpdate)."' AND paye=1"; - $sql.= " GROUP BY f.fk_statut"; - $sql.= " ORDER BY f.fk_statut DESC"; + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - $j=0; - while ($j < $num) { - $data[$j]=$db->fetch_object($result); - $j++; - } - if (! empty($conf->global->MAIN_ACTIVATE_FILECACHE)) { - dol_filecache($cachedir, $filename, $data); - } - $db->free($result); - } else { - dol_print_error($db); - } - } else { - $data = dol_readcachefile($cachedir, $filename); - } + $j=0; + while ($j < $num) { + $data[$j]=$db->fetch_object($result); + $j++; + } + if (! empty($conf->global->MAIN_ACTIVATE_FILECACHE)) { + dol_filecache($cachedir, $filename, $data); + } + $db->free($result); + } else { + dol_print_error($db); + } + } + else + { + $data = dol_readcachefile($cachedir, $filename); + } - $cumuldata=array_merge($cumuldata, $data); - if (! empty($data)) { - $j=0; - while ($line < count($cumuldata)) { - $billurl="viewstatut=2&paye=1&year=".$data[$j]->annee; - $this->info_box_contents[$line][0] = array( - 'td' => 'align="left" width="16"', - 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(1,$data[$j]->fk_statut,0), - 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", - 'logo' => 'bill', - ); + $cumuldata=array_merge($cumuldata, $data); + if (! empty($data)) + { + $j=0; + while ($line < count($cumuldata)) + { + $this->info_box_contents[$line][0] = array( + 'td' => 'align="left" width="16"', + 'url' => DOL_URL_ROOT."/comm/propal/list.php?mainmenu=commercial&leftmenu=propals&viewstatut=".$data[$j]->fk_statut, + 'tooltip' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), + 'logo' => 'object_propal' + ); - $this->info_box_contents[$line][1] = array( - 'td' => '', - 'text' => $langs->trans("Bills")." ".$facturestatic->LibStatut(1,$data[$j]->fk_statut,0)." ".$data[$j]->annee, - ); + $this->info_box_contents[$line][1] = array( + 'td' => '', + 'text' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), + ); - $this->info_box_contents[$line][2] = array( - 'td' => 'class="right"', - 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(1,$data[$j]->fk_statut,0), - 'text' => $data[$j]->nb, - 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", - ); + $this->info_box_contents[$line][2] = array( + 'td' => 'class="right"', + 'text' => $data[$j]->nb, + 'tooltip' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), + 'url' => DOL_URL_ROOT."/comm/propal/list.php?mainmenu=commercial&leftmenu=propals&viewstatut=".$data[$j]->fk_statut, + ); + $totalnb += $data[$j]->nb; - $this->info_box_contents[$line][3] = array( - 'td' => 'class="right"', - 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency) - ); + $this->info_box_contents[$line][3] = array( + 'td' => 'class="right"', + 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), + ); + $totalMnt += $data[$j]->Mnttot; + $this->info_box_contents[$line][4] = array( + 'td' => 'align="right" width="18"', + 'text' => $propalstatic->LibStatut($data[$j]->fk_statut,3), + ); - // We add only for the current year - if ($data[$j]->annee == date("Y")) { - $totalnb += $data[$j]->nb; - $totalMnt += $data[$j]->Mnttot; - } - $this->info_box_contents[$line][4] = array( - 'td' => 'align="right" width="18"', - 'text' => $facturestatic->LibStatut(1,$data[$j]->fk_statut,3), - ); - $line++; - $j++; - } - if (count($data)==0) - $this->info_box_contents[$line][0] = array( - 'td' => 'align="center"', - 'text'=>$langs->trans("NoRecordedInvoices"), - ); - } - - // part 2 - $cachedir = DOL_DATA_ROOT.'/facture/temp'; - $filename = '/boxactivity-invoice2'.$fileid; - - $refresh = dol_cache_refresh($cachedir, $filename, $cachetime); - - if ($refresh) { - $sql = "SELECT f.fk_statut, SUM(f.total_ttc) as Mnttot, COUNT(*) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f"; - $sql.= " WHERE f.entity = ".$conf->entity; - $sql.= " AND f.fk_soc = s.rowid"; - $sql.= " AND paye=0"; - $sql.= " GROUP BY f.fk_statut"; - $sql.= " ORDER BY f.fk_statut DESC"; - - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - $j=0; - while ($j < $num) { - $data[$j]=$db->fetch_object($result); - $j++; - } - if (! empty($conf->global->MAIN_ACTIVATE_FILECACHE)) { - dol_filecache($cachedir, $filename, $data); - } - $db->free($result); - } else { - dol_print_error($db); - } - } else { - $data = dol_readcachefile($cachedir, $filename); - } - - $cumuldata=array_merge($cumuldata, $data); - if (! empty($data)) { - $j=0; - - while ($line < count($cumuldata)) { - $billurl="viewstatut=".$data[$j]->fk_statut."&paye=0"; - $this->info_box_contents[$line][0] = array( - 'td' => 'align="left" width="16"', - 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(0,$data[$j]->fk_statut,0), - 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", - 'logo' => 'bill', - ); - - $this->info_box_contents[$line][1] = array( - 'td' => '', - 'text' => $langs->trans("Bills")." ".$facturestatic->LibStatut(0,$data[$j]->fk_statut,0), - ); - - $this->info_box_contents[$line][2] = array( - 'td' => 'class="right"', - 'text' => $data[$j]->nb, - 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(0,$data[$j]->fk_statut,0), - 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", - ); - $totalnb += $data[$j]->nb; - $this->info_box_contents[$line][3] = array( - 'td' => 'class="right"', - 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), - ); - $totalMnt += $objp->Mnttot; - $this->info_box_contents[$line][4] = array( - 'td' => 'align="right" width="18"', - 'text' => $facturestatic->LibStatut(0,$data[$j]->fk_statut,3), - ); - $line++; - $j++; - } - if ($num==0) - $this->info_box_contents[$line][0] = array( - 'td' => 'align="center"', - 'text'=>$langs->trans("NoRecordedInvoices"), - ); - } else { - $this->info_box_contents[0][0] = array( - 'td' => '', - 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), - ); - } + $line++; + $j++; + } + } } // list the summary of the orders @@ -295,12 +209,10 @@ class box_activity extends ModeleBoxes if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; $sql.= " AND c.date_commande >= '".$db->idate($tmpdate)."'"; - $sql.= " AND c.facture=0"; $sql.= " GROUP BY c.fk_statut"; $sql.= " ORDER BY c.fk_statut DESC"; $result = $db->query($sql); - if ($result) { $num = $db->num_rows($result); $j=0; @@ -359,94 +271,182 @@ class box_activity extends ModeleBoxes } } - // list the summary of the propals - if (! empty($conf->propal->enabled) && $user->rights->propale->lire) + + // list the summary of the bills + if (! empty($conf->facture->enabled) && $user->rights->facture->lire) { - include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; - $propalstatic=new Propal($db); + include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $facturestatic=new Facture($db); - $cachedir = DOL_DATA_ROOT.'/propale/temp'; - $filename = '/boxactivity-propal'.$fileid; - $refresh = dol_cache_refresh($cachedir, $filename, $cachetime); - $data = array(); - if ($refresh) - { - $sql = "SELECT p.fk_statut, SUM(p.total) as Mnttot, COUNT(*) as nb"; - $sql.= " FROM (".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= ")"; - $sql.= " WHERE p.entity = ".$conf->entity; - $sql.= " AND p.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; - $sql.= " AND p.datep >= '".$db->idate($tmpdate)."'"; - $sql.= " AND p.date_cloture IS NULL"; // just unclosed - $sql.= " GROUP BY p.fk_statut"; - $sql.= " ORDER BY p.fk_statut DESC"; + // part 1 + $cachedir = DOL_DATA_ROOT.'/facture/temp'; + $filename = '/boxactivity-invoice'.$fileid; - $result = $db->query($sql); - if ($result) - { - $num = $db->num_rows($result); + $refresh = dol_cache_refresh($cachedir, $filename, $cachetime); + $data = array(); + if ($refresh) + { + $sql = "SELECT f.fk_statut, SUM(f.total_ttc) as Mnttot, COUNT(*) as nb"; + $sql.= " FROM (".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f"; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= ")"; + $sql.= " WHERE f.entity = ".$conf->entity; + if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if($user->societe_id) $sql.= " AND s.rowid = ".$user->societe_id; + $sql.= " AND f.fk_soc = s.rowid"; + $sql.= " AND f.datef >= '".$db->idate($tmpdate)."' AND paye=1"; + $sql.= " GROUP BY f.fk_statut"; + $sql.= " ORDER BY f.fk_statut DESC"; - $j=0; - while ($j < $num) { - $data[$j]=$db->fetch_object($result); - $j++; - } - if (! empty($conf->global->MAIN_ACTIVATE_FILECACHE)) { - dol_filecache($cachedir, $filename, $data); - } - $db->free($result); - } else { - dol_print_error($db); - } - } - else - { - $data = dol_readcachefile($cachedir, $filename); - } + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + $j=0; + while ($j < $num) { + $data[$j]=$db->fetch_object($result); + $j++; + } + if (! empty($conf->global->MAIN_ACTIVATE_FILECACHE)) { + dol_filecache($cachedir, $filename, $data); + } + $db->free($result); + } else { + dol_print_error($db); + } + } else { + $data = dol_readcachefile($cachedir, $filename); + } - $cumuldata=array_merge($cumuldata, $data); - if (! empty($data)) - { - $j=0; - while ($line < count($cumuldata)) - { - $this->info_box_contents[$line][0] = array( - 'td' => 'align="left" width="16"', - 'url' => DOL_URL_ROOT."/comm/propal/list.php?mainmenu=commercial&leftmenu=propals&viewstatut=".$data[$j]->fk_statut, - 'tooltip' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), - 'logo' => 'object_propal' - ); + $cumuldata=array_merge($cumuldata, $data); + if (! empty($data)) { + $j=0; + while ($line < count($cumuldata)) { + $billurl="search_status=2&paye=1&year=".$data[$j]->annee; + $this->info_box_contents[$line][0] = array( + 'td' => 'align="left" width="16"', + 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(1,$data[$j]->fk_statut,0), + 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", + 'logo' => 'bill', + ); - $this->info_box_contents[$line][1] = array( - 'td' => '', - 'text' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), - ); + $this->info_box_contents[$line][1] = array( + 'td' => '', + 'text' => $langs->trans("Bills")." ".$facturestatic->LibStatut(1,$data[$j]->fk_statut,0)." ".$data[$j]->annee, + ); - $this->info_box_contents[$line][2] = array( - 'td' => 'class="right"', - 'text' => $data[$j]->nb, - 'tooltip' => $langs->trans("Proposals")." ".$propalstatic->LibStatut($data[$j]->fk_statut,0), - 'url' => DOL_URL_ROOT."/comm/propal/list.php?mainmenu=commercial&leftmenu=propals&viewstatut=".$data[$j]->fk_statut, - ); - $totalnb += $data[$j]->nb; + $this->info_box_contents[$line][2] = array( + 'td' => 'class="right"', + 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(1,$data[$j]->fk_statut,0), + 'text' => $data[$j]->nb, + 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", + ); - $this->info_box_contents[$line][3] = array( - 'td' => 'class="right"', - 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), - ); - $totalMnt += $data[$j]->Mnttot; - $this->info_box_contents[$line][4] = array( - 'td' => 'align="right" width="18"', - 'text' => $propalstatic->LibStatut($data[$j]->fk_statut,3), - ); + $this->info_box_contents[$line][3] = array( + 'td' => 'class="right"', + 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency) + ); - $line++; - $j++; - } - } + // We add only for the current year + if ($data[$j]->annee == date("Y")) { + $totalnb += $data[$j]->nb; + $totalMnt += $data[$j]->Mnttot; + } + $this->info_box_contents[$line][4] = array( + 'td' => 'align="right" width="18"', + 'text' => $facturestatic->LibStatut(1,$data[$j]->fk_statut,3), + ); + $line++; + $j++; + } + if (count($data)==0) + $this->info_box_contents[$line][0] = array( + 'td' => 'align="center"', + 'text'=>$langs->trans("NoRecordedInvoices"), + ); + } + + // part 2 + $cachedir = DOL_DATA_ROOT.'/facture/temp'; + $filename = '/boxactivity-invoice2'.$fileid; + + $refresh = dol_cache_refresh($cachedir, $filename, $cachetime); + + if ($refresh) { + $sql = "SELECT f.fk_statut, SUM(f.total_ttc) as Mnttot, COUNT(*) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as s,".MAIN_DB_PREFIX."facture as f"; + $sql.= " WHERE f.entity = ".$conf->entity; + $sql.= " AND f.fk_soc = s.rowid"; + $sql.= " AND paye=0"; + $sql.= " GROUP BY f.fk_statut"; + $sql.= " ORDER BY f.fk_statut DESC"; + + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + $j=0; + while ($j < $num) { + $data[$j]=$db->fetch_object($result); + $j++; + } + if (! empty($conf->global->MAIN_ACTIVATE_FILECACHE)) { + dol_filecache($cachedir, $filename, $data); + } + $db->free($result); + } else { + dol_print_error($db); + } + } else { + $data = dol_readcachefile($cachedir, $filename); + } + + $cumuldata=array_merge($cumuldata, $data); + if (! empty($data)) { + $j=0; + + while ($line < count($cumuldata)) { + $billurl="search_status=".$data[$j]->fk_statut."&paye=0"; + $this->info_box_contents[$line][0] = array( + 'td' => 'align="left" width="16"', + 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(0,$data[$j]->fk_statut,0), + 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", + 'logo' => 'bill', + ); + + $this->info_box_contents[$line][1] = array( + 'td' => '', + 'text' => $langs->trans("Bills")." ".$facturestatic->LibStatut(0,$data[$j]->fk_statut,0), + ); + + $this->info_box_contents[$line][2] = array( + 'td' => 'class="right"', + 'text' => $data[$j]->nb, + 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(0,$data[$j]->fk_statut,0), + 'url' => DOL_URL_ROOT."/compta/facture/list.php?".$billurl."&mainmenu=accountancy&leftmenu=customers_bills", + ); + $totalnb += $data[$j]->nb; + $this->info_box_contents[$line][3] = array( + 'td' => 'class="right"', + 'text' => price($data[$j]->Mnttot,1,$langs,0,0,-1,$conf->currency), + ); + $totalMnt += $objp->Mnttot; + $this->info_box_contents[$line][4] = array( + 'td' => 'align="right" width="18"', + 'text' => $facturestatic->LibStatut(0,$data[$j]->fk_statut,3), + ); + $line++; + $j++; + } + if ($num==0) + $this->info_box_contents[$line][0] = array( + 'td' => 'align="center"', + 'text'=>$langs->trans("NoRecordedInvoices"), + ); + } else { + $this->info_box_contents[0][0] = array( + 'td' => '', + 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), + ); + } } // Add the sum in the bottom of the boxes diff --git a/htdocs/install/mysql/data/llx_c_currencies.sql b/htdocs/install/mysql/data/llx_c_currencies.sql index cb34f60291f..db1ba19aa6e 100644 --- a/htdocs/install/mysql/data/llx_c_currencies.sql +++ b/htdocs/install/mysql/data/llx_c_currencies.sql @@ -154,7 +154,7 @@ INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'VEF' INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'VND', '[8363]', 1, 'Viet Nam Dong'); INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'XAF', NULL, 1, 'Communaute Financiere Africaine (BEAC) CFA Franc'); INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'XOF', NULL, 1, 'Communaute Financiere Africaine (BCEAO) Franc'); -INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'XPF', '[70]', 1, 'Franc pacifique (XPF)'); +INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'XPF', '[70]', 1, 'Franc CFP'); INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'YER', '[65020]', 1, 'Yemen Rial'); INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'ZWD', '[90,36]', 1, 'Zimbabwe Dollar'); From ab37794f616a4f8df4a5a5ba5d6b308b55015b1c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 19:34:26 +0200 Subject: [PATCH 124/174] Fix text --- htdocs/core/class/html.formmail.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index f2e861ea932..4ec9c91aa80 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -473,7 +473,7 @@ class FormMail extends Form $out.= ' <'.$this->tomail.'>'; if ($this->withtofree) { - $out.= '
'.$langs->trans("or").' withto) :"").'" />'; + $out.= '
'.$langs->trans("and").' withto) :"").'" />'; } } else @@ -489,7 +489,7 @@ class FormMail extends Form } if (! empty($this->withto) && is_array($this->withto)) { - if (! empty($this->withtofree)) $out.= " ".$langs->trans("or")." "; + if (! empty($this->withtofree)) $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time $tmparray = $this->withto; foreach($tmparray as $key => $val) @@ -522,7 +522,7 @@ class FormMail extends Form $out.= 'withtocc) : (isset($_POST["sendtocc"])?$_POST["sendtocc"]:"") ).'" />'; if (! empty($this->withtocc) && is_array($this->withtocc)) { - $out.= " ".$langs->trans("or")." "; + $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time $tmparray = $this->withtocc; foreach($tmparray as $key => $val) @@ -551,7 +551,7 @@ class FormMail extends Form $out.= 'withtoccc) : (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:"") ).'" />'; if (! empty($this->withtoccc) && is_array($this->withtoccc)) { - $out.= " ".$langs->trans("or")." "; + $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; // multiselect array convert html entities into options tags, even if we dont want this, so we encode them a second time $tmparray = $this->withtoccc; foreach($tmparray as $key => $val) From 9f5718f00a5842008b923298d82cdef24ac54f6b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Aug 2017 19:38:06 +0200 Subject: [PATCH 125/174] Fix php unit --- htdocs/admin/dolistore/class/dolistore.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/dolistore/class/dolistore.class.php b/htdocs/admin/dolistore/class/dolistore.class.php index 482bd124a40..5e0aa546cc0 100644 --- a/htdocs/admin/dolistore/class/dolistore.class.php +++ b/htdocs/admin/dolistore/class/dolistore.class.php @@ -306,11 +306,11 @@ class DolistoreModel function get_previous_link($text = '<<') { - return "$text"; + return ''.$text.''; } function get_next_link($text = '>>') { - return "$text"; + return ''.$text.''; } } From 7da1b215f36508062c22d12559f8297d2a6c7a1b Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 23 Aug 2017 21:01:14 +0200 Subject: [PATCH 126/174] Fix: avoid error "A non-numeric value encountered" --- htdocs/compta/bank/document.php | 16 +++++++--------- htdocs/core/class/dolgraph.class.php | 5 +++-- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/htdocs/compta/bank/document.php b/htdocs/compta/bank/document.php index 084cddf51cd..befccb3c4d3 100644 --- a/htdocs/compta/bank/document.php +++ b/htdocs/compta/bank/document.php @@ -3,7 +3,7 @@ /* Copyright (C) 2003-2007 Rodolphe Quiedeville * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2005 Marc Barilley / Ocebo - * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2005-2017 Regis Houssin * * 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 @@ -62,9 +62,7 @@ $result = restrictedArea($user, 'banque', $fieldvalue, 'bank_account', '', '', $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOST("page", 'int'); -if ($page == -1) { - $page = 0; -} +if (empty($page) || $page == -1) { $page = 0; } $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -122,21 +120,21 @@ if ($id > 0 || !empty($ref)) { $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - + + print '
'; print '
'; - + print ''; print ''; print ''; print "
' . $langs->trans("NbOfAttachedFiles") . '' . count($filearray) . '
' . $langs->trans("TotalSizeOfAttachedFiles") . '' . $totalsize . ' ' . $langs->trans("bytes") . '
\n"; print '
'; - + dol_fiche_end(); - + $modulepart = 'bank'; $permission = $user->rights->banque->modifier; $permtoedit = $user->rights->banque->modifier; diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 4fad0149a5b..d603d1b6cc1 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -25,7 +25,7 @@ /** * Class to build graphs. - * Usage is: + * Usage is: * $dolgraph=new DolGraph(); * $dolgraph->SetTitle($langs->transnoentities('Tracking_Projects_Pourcent').'
'.$langs->transnoentities('Tracking_IndicatorDefGraph').'%'); * $dolgraph->SetMaxValue(50); @@ -570,6 +570,7 @@ class DolGraph function GetFloorMinValue() { $min = $this->GetMinValueInData(); + if ($min == '') $min=0; if ($min != 0) $min--; $size=dol_strlen(abs(floor($min))); $factor=1; @@ -868,7 +869,7 @@ class DolGraph return; } $this->stringtoshow.='
'."\n"; - + $this->stringtoshow.=''."\n"; + } + + print '
'; + print ''; + print ''; + + dol_fiche_head($head, 'common_emailing', '', -1); + + print $langs->trans("EMailsDesc")."
\n"; + print "
\n"; + + + clearstatcache(); + $var=true; + + print ''; + print ''; + + // Method + + print ''; + + // Host server + + print ''; + + // Port + + print ''; + + // ID + if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) + { + + $mainstmpid=(! empty($conf->global->MAIN_MAIL_SMTPS_ID_EMAILING)?$conf->global->MAIN_MAIL_SMTPS_ID_EMAILING:''); + print ''; + } + + // PW + if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) + { + + $mainsmtppw=(! empty($conf->global->MAIN_MAIL_SMTPS_PW_EMAILING)?$conf->global->MAIN_MAIL_SMTPS_PW_EMAILING:''); + print ''; + } + + // TLS + + print ''; + + // STARTTLS + + print ''; + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("MAIN_MAIL_SENDMODE").''; + + // SuperAdministrator access only + if ((empty($conf->global->MAIN_MODULE_MULTICOMPANY)) || ($user->admin && !$user->entity)) + { + print $form->selectarray('MAIN_MAIL_SENDMODE_EMAILING',$listofmethods,$conf->global->MAIN_MAIL_SENDMODE_EMAILING); + } + else + { + $text = $listofmethods[$conf->global->MAIN_MAIL_SENDMODE_EMAILING]; + if (empty($text)) $text = $langs->trans("Undefined"); + $htmltext = $langs->trans("ContactSuperAdminForChange"); + print $form->textwithpicto($text,$htmltext,1,'superadmin'); + print ''; + } + print '
'; + if (! $conf->use_javascript_ajax && $linuxlike && $conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail') + { + print $langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike"); + print ''; + print $langs->trans("SeeLocalSendMailSetup"); + } + else + { + $mainserver = (! empty($conf->global->MAIN_MAIL_SMTP_SERVER_EMAILING)?$conf->global->MAIN_MAIL_SMTP_SERVER_EMAILING:''); + $smtpserver = ini_get('SMTP')?ini_get('SMTP'):$langs->transnoentities("Undefined"); + if ($linuxlike) print $langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike"); + else print $langs->trans("MAIN_MAIL_SMTP_SERVER",$smtpserver); + print ''; + // SuperAdministrator access only + if (empty($conf->multicompany->enabled) || ($user->admin && ! $user->entity)) + { + print ''; + print ''; + print ''.$langs->trans("SeeLocalSendMailSetup").''; + } + else + { + $text = ! empty($mainserver) ? $mainserver : $smtpserver; + $htmltext = $langs->trans("ContactSuperAdminForChange"); + print $form->textwithpicto($text,$htmltext,1,'superadmin'); + print ''; + } + } + print '
'; + if (! $conf->use_javascript_ajax && $linuxlike && $conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail') + { + print $langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike"); + print ''; + print $langs->trans("SeeLocalSendMailSetup"); + } + else + { + $mainport = (! empty($conf->global->MAIN_MAIL_SMTP_PORT_EMAILING) ? $conf->global->MAIN_MAIL_SMTP_PORT_EMAILING : ''); + $smtpport = ini_get('smtp_port')?ini_get('smtp_port'):$langs->transnoentities("Undefined"); + if ($linuxlike) print $langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike"); + else print $langs->trans("MAIN_MAIL_SMTP_PORT",$smtpport); + print ''; + // SuperAdministrator access only + if (empty($conf->multicompany->enabled) || ($user->admin && ! $user->entity)) + { + print ''; + print ''; + print ''.$langs->trans("SeeLocalSendMailSetup").''; + } + else + { + $text = (! empty($mainport) ? $mainport : $smtpport); + $htmltext = $langs->trans("ContactSuperAdminForChange"); + print $form->textwithpicto($text,$htmltext,1,'superadmin'); + print ''; + } + } + print '
'.$langs->trans("MAIN_MAIL_SMTPS_ID").''; + // SuperAdministrator access only + if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity)) + { + print ''; + } + else + { + $htmltext = $langs->trans("ContactSuperAdminForChange"); + print $form->textwithpicto($conf->global->MAIN_MAIL_SMTPS_ID_EMAILING,$htmltext,1,'superadmin'); + print ''; + } + print '
'.$langs->trans("MAIN_MAIL_SMTPS_PW").''; + // SuperAdministrator access only + if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity)) + { + print ''; + } + else + { + $htmltext = $langs->trans("ContactSuperAdminForChange"); + print $form->textwithpicto($conf->global->MAIN_MAIL_SMTPS_PW_EMAILING,$htmltext,1,'superadmin'); + print ''; + } + print '
'.$langs->trans("MAIN_MAIL_EMAIL_TLS").''; + if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) + { + if (function_exists('openssl_open')) + { + print $form->selectyesno('MAIN_MAIL_EMAIL_TLS_EMAILING',(! empty($conf->global->MAIN_MAIL_EMAIL_TLS_EMAILING)?$conf->global->MAIN_MAIL_EMAIL_TLS_EMAILING:0),1); + } + else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')'; + } + else print yn(0).' ('.$langs->trans("NotSupported").')'; + print '
'.$langs->trans("MAIN_MAIL_EMAIL_STARTTLS").''; + if (! empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) + { + if (function_exists('openssl_open')) + { + print $form->selectyesno('MAIN_MAIL_EMAIL_STARTTLS_EMAILING',(! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS_EMAILING)?$conf->global->MAIN_MAIL_EMAIL_STARTTLS_EMAILING:0),1); + } + else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')'; + } + else print yn(0).' ('.$langs->trans("NotSupported").')'; + print '
'; + + dol_fiche_end(); + + print '
'; + print ''; + print '     '; + print ''; + print '
'; + + print '
'; +} +else +{ + dol_fiche_head($head, 'common_emailing', '', -1); + + print $langs->trans("EMailsDesc")."
\n"; + print "
\n"; + + + $var=true; + + print ''; + print ''; + + // Method + + print ''; + + if (! empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default') + { + // Host server + + if ($linuxlike && (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail')) + { + print ''; + } + else + { + print ''; + } + + // Port + + if ($linuxlike && (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail')) + { + print ''; + } + else + { + print ''; + } + + // SMTPS ID + + if (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer'))) + { + print ''; + } + + // SMTPS PW + + if (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer'))) + { + print ''; + } + + // TLS + + print ''; + + // STARTTLS + + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("MAIN_MAIL_SENDMODE").''; + $text=$listofmethods[$conf->global->MAIN_MAIL_SENDMODE_EMAILING]; + if (empty($text)) $text=$langs->trans("Undefined").img_warning(); + print $text; + print '
'.$langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike").''.$langs->trans("SeeLocalSendMailSetup").'
'.$langs->trans("MAIN_MAIL_SMTP_SERVER",ini_get('SMTP')?ini_get('SMTP'):$langs->transnoentities("Undefined")).''.(! empty($conf->global->MAIN_MAIL_SMTP_SERVER_EMAILING)?$conf->global->MAIN_MAIL_SMTP_SERVER_EMAILING:'').'
'.$langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike").''.$langs->trans("SeeLocalSendMailSetup").'
'.$langs->trans("MAIN_MAIL_SMTP_PORT",ini_get('smtp_port')?ini_get('smtp_port'):$langs->transnoentities("Undefined")).''.(! empty($conf->global->MAIN_MAIL_SMTP_PORT_EMAILING)?$conf->global->MAIN_MAIL_SMTP_PORT_EMAILING:'').'
'.$langs->trans("MAIN_MAIL_SMTPS_ID").''.$conf->global->MAIN_MAIL_SMTPS_ID_EMAILING.'
'.$langs->trans("MAIN_MAIL_SMTPS_PW").''.preg_replace('/./','*',$conf->global->MAIN_MAIL_SMTPS_PW_EMAILING).'
'.$langs->trans("MAIN_MAIL_EMAIL_TLS").''; + if (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer'))) + { + if (function_exists('openssl_open')) + { + print yn($conf->global->MAIN_MAIL_EMAIL_TLS_EMAILING); + } + else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')'; + } + else print yn(0).' ('.$langs->trans("NotSupported").')'; + print '
'.$langs->trans("MAIN_MAIL_EMAIL_STARTTLS").''; + if (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer'))) + { + if (function_exists('openssl_open')) + { + print yn($conf->global->MAIN_MAIL_EMAIL_STARTTLS_EMAILING); + } + else print yn(0).' ('.$langs->trans("YourPHPDoesNotHaveSSLSupport").')'; + } + else print yn(0).' ('.$langs->trans("NotSupported").')'; + print '
'; + + dol_fiche_end(); + + + if ($conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail' && empty($conf->global->MAIN_FIX_FOR_BUGGED_MTA)) + { + print '
'; + /* + // Warning 1 + if ($linuxlike) + { + $sendmailoption=ini_get('mail.force_extra_parameters'); + if (empty($sendmailoption) || ! preg_match('/ba/',$sendmailoption)) + { + print info_admin($langs->trans("SendmailOptionNotComplete")); + } + }*/ + // Warning 2 + print info_admin($langs->trans("SendmailOptionMayHurtBuggedMTA")); + } + + + // Boutons actions + print '
'; + + print ''.$langs->trans("Modify").''; + + if (! empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default') + { + if ($conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'mail' || ! $linuxlike) + { + if (function_exists('fsockopen') && $port && $server) + { + print ''.$langs->trans("DoTestServerAvailability").''; + } + } + else + { + print ''.$langs->trans("DoTestServerAvailability").''; + } + + print ''.$langs->trans("DoTestSend").''; + + if (! empty($conf->fckeditor->enabled)) + { + print ''.$langs->trans("DoTestSendHTML").''; + } + } + + print '
'; + + + if ($conf->global->MAIN_MAIL_SENDMODE_EMAILING == 'mail' && ! in_array($action, array('testconnect', 'test', 'testhtml'))) + { + $text = $langs->trans("WarningPHPMail"); + print info_admin($text); + } + + // Run the test to connect + if ($action == 'testconnect') + { + print load_fiche_titre($langs->trans("DoTestServerAvailability")); + + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mail = new CMailFile('','','',''); + $result=$mail->check_server_port($server,$port); + if ($result) print '
'.$langs->trans("ServerAvailableOnIPOrPort",$server,$port).'
'; + else + { + $errormsg = $langs->trans("ServerNotAvailableOnIPOrPort",$server,$port); + + if ($mail->error) { + $errormsg .= ' - '.$mail->error; + } + + setEventMessages($errormsg, null, 'errors'); + } + print '
'; + } + + // Show email send test form + if ($action == 'test' || $action == 'testhtml') + { + print '
'; + print load_fiche_titre($action == 'testhtml'?$langs->trans("DoTestSendHTML"):$langs->trans("DoTestSend")); + + dol_fiche_head(''); + + // Cree l'objet formulaire mail + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + $formmail->fromname = (isset($_POST['fromname'])?$_POST['fromname']:$conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->frommail = (isset($_POST['frommail'])?$_POST['frommail']:$conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->trackid=(($action == 'testhtml')?"testhtml":"test"); + $formmail->withfromreadonly=0; + $formmail->withsubstit=0; + $formmail->withfrom=1; + $formmail->witherrorsto=1; + $formmail->withto=(! empty($_POST['sendto'])?$_POST['sendto']:($user->email?$user->email:1)); + $formmail->withtocc=(! empty($_POST['sendtocc'])?$_POST['sendtocc']:1); // ! empty to keep field if empty + $formmail->withtoccc=(! empty($_POST['sendtoccc'])?$_POST['sendtoccc']:1); // ! empty to keep field if empty + $formmail->withtopic=(isset($_POST['subject'])?$_POST['subject']:$langs->trans("Test")); + $formmail->withtopicreadonly=0; + $formmail->withfile=2; + $formmail->withbody=(isset($_POST['message'])?$_POST['message']:($action == 'testhtml'?$langs->transnoentities("PredefinedMailTestHtml"):$langs->transnoentities("PredefinedMailTest"))); + $formmail->withbodyreadonly=0; + $formmail->withcancel=1; + $formmail->withdeliveryreceipt=1; + $formmail->withfckeditor=($action == 'testhtml'?1:0); + $formmail->ckeditortoolbar='dolibarr_mailings'; + // Tableau des substitutions + $formmail->substit=$substitutionarrayfortest; + // Tableau des parametres complementaires du post + $formmail->param["action"]="send"; + $formmail->param["models"]="body"; + $formmail->param["mailid"]=0; + $formmail->param["returnurl"]=$_SERVER["PHP_SELF"]; + + // Init list of files + if (GETPOST("mode")=='init') + { + $formmail->clear_attached_files(); + } + + print $formmail->get_form('addfile','removefile'); + + dol_fiche_end(); + } +} + + +llxFooter(); + +$db->close(); diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index dabc0f5f730..f0cbb91c6c3 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -410,6 +410,14 @@ $head[$h][1] = $langs->trans("OutGoingEmailSetup"); $head[$h][2] = 'common'; $h++; +if ($conf->mailing->enabled) +{ + $head[$h][0] = DOL_URL_ROOT."/admin/mails_emailing.php"; + $head[$h][1] = $langs->trans("OutGoingEmailSetupForEmailing"); + $head[$h][2] = 'common_emailing'; + $h++; +} + $head[$h][0] = DOL_URL_ROOT."/admin/mails_templates.php"; $head[$h][1] = $langs->trans("DictionaryEMailTemplates"); $head[$h][2] = 'templates'; diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 1998808bf11..58bc00e3f0f 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -345,7 +345,8 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO } // Send mail - $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1,'','',$trackid); + if (empty($sendcontext)) $sendcontext = 'standard'; + $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1,'','',$trackid,'',$sendcontext); if ($mailfile->error) { setEventMessage($mailfile->error, 'errors'); diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 3b3efe96fb0..b05b8a162a1 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -38,8 +38,7 @@ class CMailFile { public $sendcontext; public $sendmode; - public $sendsetup; - + var $subject; // Topic: Subject of email var $addr_from; // From: Label and EMail of sender (must include '<>'). For example '' or 'John Doe ' or ''). Note that with gmail smtps, value here is forced by google to account (but not the reply-to). // Sender: Who send the email ("Sender" has sent emails on behalf of "From"). @@ -115,14 +114,15 @@ class CMailFile global $conf, $dolibarr_main_data_root; $this->sendcontext = $sendcontext; - + + // Define this->sendmode $this->sendmode = ''; - if ($this->sendcontext == 'emailing') $this->sendmode = $conf->global->EMAILING_MAIL_SENDMODE; + if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default') + { + $this->sendmode = $conf->global->MAIN_MAIL_SENDMODE_EMAILING; + } if (empty($this->sendmode)) $this->sendmode=$conf->global->MAIN_MAIL_SENDMODE; if (empty($this->sendmode)) $this->sendmode='mail'; - - $this->sendsetup = array(); - // We define end of line (RFC 821). $this->eol="\r\n"; @@ -145,7 +145,7 @@ class CMailFile $this->alternative_boundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3); // Force md5 hash (does not contains special chars) dol_syslog("CMailFile::CMailfile: sendmode=".$this->sendmode." charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, trackid=$trackid sendcontext=$sendcontext", LOG_DEBUG); - dol_syslog("CMailFile::CMailfile: subject=$subject, deliveryreceipt=$deliveryreceipt, msgishtml=$msgishtml", LOG_DEBUG); + dol_syslog("CMailFile::CMailfile: subject=".$subject.", deliveryreceipt=".$deliveryreceipt.", msgishtml=".$msgishtml, LOG_DEBUG); if (empty($subject)) { @@ -157,7 +157,7 @@ class CMailFile { dol_syslog("CMailFile::CMailfile: Try to send an email with empty body"); $msg='.'; // Avoid empty message (with empty message conten show a multipart structure) - } + } // Detect if message is HTML (use fast method) if ($msgishtml == -1) @@ -230,7 +230,7 @@ class CMailFile $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 @@ -339,7 +339,7 @@ class CMailFile $this->phpmailer->SetReplyTo($this->getValidAddress($from,0,1)); // Set property with this->phpmailer->setReplyTo after constructor if you want to use another value than the From // TODO Add trackid into smtp header // TODO if (! empty($moreinheader)) ... - + if (! empty($this->html)) { if (!empty($css)) @@ -487,9 +487,7 @@ class CMailFile { require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; $hookmanager = new HookManager($db); - $hookmanager->initHooks(array( - 'maildao' - )); + $hookmanager->initHooks(array('maildao')); $reshook = $hookmanager->executeHooks('doactions', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (! empty($reshook)) { @@ -532,6 +530,22 @@ class CMailFile return false; } + $keyforsmtpserver='MAIN_MAIL_SMTP_SERVER'; + $keyforsmtpport ='MAIN_MAIL_SMTP_PORT'; + $keyforsmtpid ='MAIN_MAIL_SMTPS_ID'; + $keyforsmtppw ='MAIN_MAIL_SMTPS_PW'; + $keyfortls ='MAIN_MAIL_EMAIL_TLS'; + $keyforstarttls ='MAIN_MAIL_EMAIL_STARTTLS'; + if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default') + { + $keyforsmtpserver='MAIN_MAIL_SMTP_SERVER_EMAILING'; + $keyforsmtpport ='MAIN_MAIL_SMTP_PORT_EMAILING'; + $keyforsmtpid ='MAIN_MAIL_SMTPS_ID_EMAILING'; + $keyforsmtppw ='MAIN_MAIL_SMTPS_PW_EMAILING'; + $keyfortls ='MAIN_MAIL_EMAIL_TLS_EMAILING'; + $keyforstarttls ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING'; + } + // Action according to choosed sending method if ($this->sendmode == 'mail') { @@ -548,9 +562,9 @@ class CMailFile @ini_set('sendmail_from',$this->getValidAddress($this->addr_from,2)); } - // Forcage parametres - if (! empty($conf->global->MAIN_MAIL_SMTP_SERVER)) ini_set('SMTP',$conf->global->MAIN_MAIL_SMTP_SERVER); - if (! empty($conf->global->MAIN_MAIL_SMTP_PORT)) ini_set('smtp_port',$conf->global->MAIN_MAIL_SMTP_PORT); + // Force parameters + if (! empty($conf->global->$keyforsmtpserver)) ini_set('SMTP',$conf->global->$keyforsmtpserver); + if (! empty($conf->global->$keyforsmtpport)) ini_set('smtp_port',$conf->global->$keyforsmtpport); $dest=$this->getValidAddress($this->addr_to,2); if (! $dest) @@ -610,9 +624,9 @@ class CMailFile @ini_restore('sendmail_from'); } - // Forcage parametres - if (! empty($conf->global->MAIN_MAIL_SMTP_SERVER)) ini_restore('SMTP'); - if (! empty($conf->global->MAIN_MAIL_SMTP_PORT)) ini_restore('smtp_port'); + // Restore parameters + if (! empty($conf->global->$keyforsmtpserver)) ini_restore('SMTP'); + if (! empty($conf->global->$keyforsmtpport)) ini_restore('smtp_port'); } else if ($this->sendmode == 'smtps') { @@ -622,28 +636,30 @@ class CMailFile $this->smtps->setTransportType(0); // Only this method is coded in SMTPs library // Clean parameters - if (empty($conf->global->MAIN_MAIL_SMTP_SERVER)) $conf->global->MAIN_MAIL_SMTP_SERVER=ini_get('SMTP'); - if (empty($conf->global->MAIN_MAIL_SMTP_PORT)) $conf->global->MAIN_MAIL_SMTP_PORT=ini_get('smtp_port'); - - // TODO Manage alternative parameters + if (empty($conf->global->$keyforsmtpserver)) $conf->global->$keyforsmtpserver=ini_get('SMTP'); + if (empty($conf->global->$keyforsmtpport)) $conf->global->$keyforsmtpport=ini_get('smtp_port'); // If we use SSL/TLS - $server=$conf->global->MAIN_MAIL_SMTP_SERVER; - if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $server='ssl://'.$server; - $port=$conf->global->MAIN_MAIL_SMTP_PORT; + $server=$conf->global->$keyforsmtpserver; + $secure=''; + if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $secure='ssl'; + if (! empty($conf->global->$keyforstarttls) && function_exists('openssl_open')) $secure='tls'; + $server=($secure?$secure.'://':'').$server; + + $port=$conf->global->$keyforsmtpport; $this->smtps->setHost($server); $this->smtps->setPort($port); // 25, 465...; $loginid=''; $loginpass=''; - if (! empty($conf->global->MAIN_MAIL_SMTPS_ID)) + if (! empty($conf->global->$keyforsmtpid)) { - $loginid = $conf->global->MAIN_MAIL_SMTPS_ID; + $loginid = $conf->global->$keyforsmtpid; $this->smtps->setID($loginid); } - if (! empty($conf->global->MAIN_MAIL_SMTPS_PW)) + if (! empty($conf->global->$keyforsmtppw)) { - $loginpass = $conf->global->MAIN_MAIL_SMTPS_PW; + $loginpass = $conf->global->$keyforsmtppw; $this->smtps->setPW($loginpass); } @@ -651,14 +667,14 @@ class CMailFile $from=$this->smtps->getFrom('org'); if (! $from) { - $this->error="Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->MAIN_MAIL_SMTP_PORT."
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 (! $dest) { - $this->error="Failed to send mail with smtps lib to HOST=".$server.", PORT=".$conf->global->MAIN_MAIL_SMTP_PORT."
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; } @@ -666,7 +682,7 @@ class CMailFile if ($res) { if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->smtps->setDebug(true); - + $result=$this->smtps->sendMsg(); //print $result; @@ -684,26 +700,24 @@ class CMailFile } else if ($this->sendmode == 'swiftmailer') { - // Use Swift Mailer library // ------------------------------------------ require_once DOL_DOCUMENT_ROOT.'/includes/swiftmailer/lib/swift_required.php'; - // Forcage parametres - if (empty($conf->global->MAIN_MAIL_SMTP_SERVER)) $conf->global->MAIN_MAIL_SMTP_SERVER=ini_get('SMTP'); - if (empty($conf->global->MAIN_MAIL_SMTP_PORT)) $conf->global->MAIN_MAIL_SMTP_PORT=ini_get('smtp_port'); + // Clean parameters + if (empty($conf->global->$keyforsmtpserver)) $conf->global->$keyforsmtpserver=ini_get('SMTP'); + if (empty($conf->global->$keyforsmtpport)) $conf->global->$keyforsmtpport=ini_get('smtp_port'); // If we use SSL/TLS - $server=$conf->global->MAIN_MAIL_SMTP_SERVER; + $server=$conf->global->$keyforsmtpserver; $secure=''; - //var_dump(stream_get_transports()); - if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $secure='ssl'; - if (! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) && function_exists('openssl_open')) $secure='tls'; + if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $secure='ssl'; + if (! empty($conf->global->$keyforstarttls) && function_exists('openssl_open')) $secure='tls'; - $this->transport = Swift_SmtpTransport::newInstance($server, $conf->global->MAIN_MAIL_SMTP_PORT, $secure); + $this->transport = Swift_SmtpTransport::newInstance($server, $conf->global->$keyforsmtpport, $secure); - if (! empty($conf->global->MAIN_MAIL_SMTPS_ID)) $this->transport->setUsername($conf->global->MAIN_MAIL_SMTPS_ID); - if (! empty($conf->global->MAIN_MAIL_SMTPS_PW)) $this->transport->setPassword($conf->global->MAIN_MAIL_SMTPS_PW); + if (! empty($conf->global->$keyforsmtpid)) $this->transport->setUsername($conf->global->$keyforsmtpid); + if (! empty($conf->global->$keyforsmtppw)) $this->transport->setPassword($conf->global->$keyforsmtppw); //$smtps->_msgReplyTo = 'reply@web.com'; // Create the Mailer using your created Transport @@ -1026,7 +1040,7 @@ class CMailFile $out.= $this->eol; $out.= "--" . $this->related_boundary . $this->eol; } - + if (! $this->atleastoneimage && $strContentAltText && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) // Add plain text message part before html part { $out.= "Content-Type: multipart/alternative; boundary=\"".$this->alternative_boundary."\"".$this->eol; @@ -1036,7 +1050,7 @@ class CMailFile $out.= $this->eol.$strContentAltText.$this->eol; $out.= "--" . $this->alternative_boundary . $this->eol; } - + $out.= "Content-Type: text/html; charset=".$conf->file->character_set_client.$this->eol; $out.= $this->eol.$strContent.$this->eol; @@ -1154,13 +1168,30 @@ class CMailFile function check_server_port($host,$port) { global $conf; + $_retVal=0; $timeout=5; // Timeout in seconds if (function_exists('fsockopen')) { + $keyforsmtpserver='MAIN_MAIL_SMTP_SERVER'; + $keyforsmtpport ='MAIN_MAIL_SMTP_PORT'; + $keyforsmtpid ='MAIN_MAIL_SMTPS_ID'; + $keyforsmtppw ='MAIN_MAIL_SMTPS_PW'; + $keyfortls ='MAIN_MAIL_EMAIL_TLS'; + $keyforstarttls ='MAIN_MAIL_EMAIL_STARTTLS'; + if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default') + { + $keyforsmtpserver='MAIN_MAIL_SMTP_SERVER_EMAILING'; + $keyforsmtpport ='MAIN_MAIL_SMTP_PORT_EMAILING'; + $keyforsmtpid ='MAIN_MAIL_SMTPS_ID_EMAILING'; + $keyforsmtppw ='MAIN_MAIL_SMTPS_PW_EMAILING'; + $keyfortls ='MAIN_MAIL_EMAIL_TLS_EMAILING'; + $keyforstarttls ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING'; + } + // If we use SSL/TLS - if (! empty($conf->global->MAIN_MAIL_EMAIL_TLS) && function_exists('openssl_open')) $host='ssl://'.$host; + if (! empty($conf->global->$keyfortls) && function_exists('openssl_open')) $host='ssl://'.$host; // tls smtp start with no encryption //if (! empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) && function_exists('openssl_open')) $host='tls://'.$host; @@ -1355,7 +1386,7 @@ class CMailFile if ($email) { $i++; - + $newemail=''; if ($format == 4) { diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index c92558bf1d3..cfaa88363a4 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -358,8 +358,11 @@ class SMTPs // This is done here because '@fsockopen' will not give me this // information if it failes to connect because it can't find the HOST $host=$this->getHost(); + $usetls = preg_match('@tls://@i',$host); + $host=preg_replace('@tcp://@i','',$host); // Remove prefix $host=preg_replace('@ssl://@i','',$host); // Remove prefix + $host=preg_replace('@tls://@i','',$host); // Remove prefix // @CHANGE LDR include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; @@ -373,7 +376,7 @@ class SMTPs { //See if we can connect to the SMTP server if ($this->socket = @fsockopen( - $this->getHost(), // Host to 'hit', IP or domain + preg_replace('@tls://@i','',$this->getHost()), // Host to 'hit', IP or domain $this->getPort(), // which Port number to use $this->errno, // actual system level error $this->errstr, // and any text that goes with the error @@ -416,16 +419,17 @@ class SMTPs // This improvment as provided by 'SirSir' to // accomodate both SMTP AND ESMTP capable servers $host=$this->getHost(); + $usetls = preg_match('@tls://@i',$host); + $host=preg_replace('@tcp://@i','',$host); // Remove prefix $host=preg_replace('@ssl://@i','',$host); // Remove prefix - if (!empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS)) - { - $host=preg_replace('@tls://@i','',$host); // Remove prefix - $host='tls://'.$host; - } + $host=preg_replace('@tls://@i','',$host); // Remove prefix + + if ($usetls) $host='tls://'.$host; + if ( $_retVal = $this->socket_send_str('EHLO ' . $host, '250') ) { - if (!empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS)) + if ($usetls) { /* The following dialog illustrates how a client and server can start a TLS STARTTLS session @@ -443,7 +447,7 @@ class SMTPs // Second pass EHLO C: EHLO client-domain.com S: 250-server-domain.com - S: 250 AUTH LOGIN + S: 250 AUTH LOGIN C: socket_send_str('STARTTLS', 220)) @@ -456,7 +460,7 @@ class SMTPs $this->_setErr(132, 'STARTTLS connection failed.'); return $_retVal; } - // Most server servers expect a 2nd pass of EHLO after TLS is established to get another time + // Most server servers expect a 2nd pass of EHLO after TLS is established to get another time // the answer with list of supported AUTH methods. They may differs between non STARTTLS and with STARTTLS. if (!$_retVal = $this->socket_send_str('EHLO '.$host, '250')) { @@ -514,8 +518,12 @@ class SMTPs { // Send the RFC821 specified HELO. $host=$this->getHost(); + $usetls = preg_match('@tls://@i',$host); + $host=preg_replace('@tcp://@i','',$host); // Remove prefix $host=preg_replace('@ssl://@i','',$host); // Remove prefix + $host=preg_replace('@tls://@i','',$host); // Remove prefix + $_retVal = $this->socket_send_str('HELO ' . $host, '250'); } @@ -1237,8 +1245,11 @@ class SMTPs */ $host=$this->getHost(); + $usetls = preg_match('@tls://@i',$host); + $host=preg_replace('@tcp://@i','',$host); // Remove prefix $host=preg_replace('@ssl://@i','',$host); // Remove prefix + $host=preg_replace('@tls://@i','',$host); // Remove prefix $host=dol_getprefix('email'); diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 1e4f1446fa7..a78b7bbc6c8 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -156,4 +156,7 @@ NoContactWithCategoryFound=No contact/address with a category found NoContactLinkedToThirdpartieWithCategoryFound=No contact/address with a category found OutGoingEmailSetup=Outgoing email setup InGoingEmailSetup=Incoming email setup +OutGoingEmailSetupForEmailing=Outgoing email setup (for mass emailing) +DefaultOutgoingEmailSetup=Default outgoing email setup + From 982fca541d3d693c88063d4c129c095bb1a3e8e3 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 24 Aug 2017 08:33:40 +0200 Subject: [PATCH 129/174] Fix: (Agenda) Allowed if link to third party is empty --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index f55f60c7f69..57eefa49018 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -375,7 +375,7 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh $check = array('adherent','banque','user','usergroup','produit','service','produit|service','categorie'); // Test on entity only (Objects with no link to company) $checksoc = array('societe'); // Test for societe object - $checkother = array('contact'); // Test on entity and link to societe. Allowed if link is empty (Ex: contacts...). + $checkother = array('contact','agenda'); // Test on entity and link to third party. Allowed if link is empty (Ex: contacts...). $checkproject = array('projet','project'); // Test for project object $checktask = array('projet_task'); $nocheck = array('barcode','stock','fournisseur'); // No test From 7da6f93d7e5d972fc693c6c6431d9aef63f3d45e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Aug 2017 13:23:15 +0200 Subject: [PATCH 130/174] FIX select of category FIX pb with extrafield list and key '0' --- htdocs/core/class/commonobject.class.php | 12 +++++ htdocs/core/class/extrafields.class.php | 18 ++++---- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/lib/functions.lib.php | 2 +- htdocs/install/mysql/migration/repair.sql | 3 +- htdocs/langs/en_US/admin.lang | 10 ++--- .../modulebuilder/template/myobject_list.php | 2 +- htdocs/societe/list.php | 45 +++++++++++-------- 8 files changed, 57 insertions(+), 37 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 0693b3dd336..50ccf362de6 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4352,6 +4352,12 @@ abstract class CommonObject $this->array_options[$key] = null; } break; + /*case 'select': // Not required, we chosed value='0' for undefined values + if ($value=='-1') + { + $this->array_options[$key] = null; + } + break;*/ case 'price': $this->array_options[$key] = price2num($this->array_options[$key]); break; @@ -4485,6 +4491,12 @@ abstract class CommonObject $this->array_options["options_".$key] = null; } break; + /*case 'select': // Not required, we chosed value='0' for undefined values + if ($value=='-1') + { + $this->array_options[$key] = null; + } + break;*/ case 'price': $this->array_options["options_".$key] = price2num($this->array_options["options_".$key]); break; diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 3fcb909fc51..a66648df2c2 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -348,7 +348,7 @@ class ExtraFields $sql .= " " . $user->id . ","; $sql .= "'" . $this->db->idate(dol_now()) . "'"; $sql.=')'; - + dol_syslog(get_class($this)."::create_label", LOG_DEBUG); if ($this->db->query($sql)) { @@ -721,8 +721,8 @@ class ExtraFields { $array_name_label[$tab->name]=$tab->label; } - - + + // Old usage $this->attribute_type[$tab->name]=$tab->type; @@ -740,8 +740,8 @@ class ExtraFields $this->attribute_list[$tab->name]=$tab->list; $this->attribute_hidden[$tab->name]=$tab->ishidden; $this->attribute_entityid[$tab->name]=$tab->entity; - - + + // New usage $this->attributes[$tab->elementtype]['type'][$tab->name]=$tab->type; @@ -759,8 +759,8 @@ class ExtraFields $this->attributes[$tab->elementtype]['list'][$tab->name]=$tab->list; $this->attributes[$tab->elementtype]['ishidden'][$tab->name]=$tab->ishidden; $this->attributes[$tab->elementtype]['entityid'][$tab->name]=$tab->entity; - - + + if (!empty($conf->multicompany->enabled)) { $sql_entity_name='SELECT label FROM '.MAIN_DB_PREFIX.'entity WHERE rowid='.$tab->entity; $resql_entity_name=$this->db->query($sql_entity_name); @@ -944,10 +944,10 @@ class ExtraFields $out.=''; foreach ($param['options'] as $key => $val) { - if ($key == '') continue; + if ((string) $key == '') continue; list($val, $parent) = explode('|', $val); $out.='
"; + print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]); + print "'; $taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id); print $taskstatic->getNomUrl(1,'withproject'); print ''; + $thirdpartystatic->id=$lines[$i]->socid; + $thirdpartystatic->name=$lines[$i]->thirdparty_name; + print $thirdpartystatic->getNomUrl(1, 'project', 10); + print '"; for ($k = 0 ; $k < $level ; $k++) print "   "; @@ -654,21 +669,6 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr //print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0); print ""; - print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]); - print "'; - $thirdpartystatic->id=$lines[$i]->socid; - $thirdpartystatic->name=$lines[$i]->thirdparty_name; - print $thirdpartystatic->getNomUrl(1, 'project', 10); - print ''; if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload,'allhourmin'); @@ -745,7 +745,13 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr // Warning print ''; if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject")); - else if ($disabledtask) print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $langs->transnoentitiesnoconv("AssignTaskToUser", '...'))); + else if ($disabledtask) + { + $titleassigntask = $langs->trans("AssignTaskToMe"); + if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...'); + + print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $titleassigntask)); + } print '
'; + print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]); + print "'; + $thirdpartystatic->id=$lines[$i]->thirdparty_id; + $thirdpartystatic->name=$lines[$i]->thirdparty_name; + print $thirdpartystatic->getNomUrl(1, 'project'); + print ''; $taskstatic->id=$lines[$i]->id; @@ -864,26 +891,6 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ //print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0); print "'; - $projectstatic->id=$lines[$i]->fk_project; - $projectstatic->ref=$lines[$i]->projectref; - $projectstatic->title=$lines[$i]->projectlabel; - $projectstatic->public=$lines[$i]->public; - $projectstatic->thirdparty_name=$lines[$i]->thirdparty_name; - print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]); - print "'; - $thirdpartystatic->id=$lines[$i]->thirdparty_id; - $thirdpartystatic->name=$lines[$i]->thirdparty_name; - print $thirdpartystatic->getNomUrl(1, 'project'); - print ''; if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload,'allhourmin'); @@ -961,7 +968,13 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ // Warning print ''; if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject")); - else if ($disabledtask) print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $langs->transnoentitiesnoconv("AssignTaskToUser", '...'))); + else if ($disabledtask) + { + $titleassigntask = $langs->trans("AssignTaskToMe"); + if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...'); + + print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $titleassigntask)); + } print '
'."\n"; print ''; -print ''; -print ''; print ''; if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) print ''; +print ''; +print ''; print ''; print ''; print ''; @@ -458,13 +458,13 @@ print ''; print "\n"; print ''; -print ''; -print ''; print ''; if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) { print ''; } +print ''; +print ''; print ''; print ''; /*print ''; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index b4fcd68a3c9..01e4b71eda8 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -434,10 +434,10 @@ print '
'; print '
'.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("ProjectRef").''.$langs->trans("ThirdParty").''.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").'
'."\n"; print ''; -print ''; -print ''; print ''; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) print ''; +print ''; +print ''; print ''; print ''; print ''; @@ -454,13 +454,13 @@ print ''; print "\n"; print ''; -print ''; -print ''; print ''; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) { print ''; } +print ''; +print ''; print ''; print ''; /*print ''; From 99a27162fb2d07dbbfb8389035a84729fd89ada8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Aug 2017 18:28:03 +0200 Subject: [PATCH 139/174] Complete module template --- htdocs/langs/en_US/modulebuilder.lang | 1 + htdocs/modulebuilder/index.php | 60 ++++++++++++- .../template/class/actions_mymodule.class.php | 84 +++++++++++++++---- .../template/core/boxes/README.md | 1 + .../core/modules/modMyModule.class.php | 9 +- .../template/core/triggers/README.md | 1 + 6 files changed, 135 insertions(+), 21 deletions(-) create mode 100644 htdocs/modulebuilder/template/core/boxes/README.md create mode 100644 htdocs/modulebuilder/template/core/triggers/README.md diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 62251069c08..7f986e036c1 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -40,6 +40,7 @@ PathToModuleDocumentation=Path to file of module/application documentation SpaceOrSpecialCharAreNotAllowed=Spaces or special characters are not allowed. FileNotYetGenerated=File not yet generated SpecificationFile=File with business rules +LanguageFile=File for language ConfirmDeleteProperty=Are you sure you want to delete the property %s ? This will change code in PHP class but also remove column from table definition of object. NotNull=Not NULL SearchAll=Used for 'search all' diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 0ba9bbaa071..4ef05cb6e2b 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -146,7 +146,10 @@ if ($dirins && $action == 'initmodule' && $modulename) 'MyModule'=>$modulename, 'MYMODULE'=>strtoupper($modulename), 'My module'=>$modulename, - 'htdocs/modulebuilder/template/'=>strtolower($modulename), + 'my module'=>$modulename, + 'Mon module'=>$modulename, + 'mon module'=>$modulename, + 'htdocs/modulebuilder/template/'=>strtolower($modulename), '---Put here your own copyright and developer email---'=>dol_print_date($now,'%Y').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':'') ); @@ -293,7 +296,10 @@ if ($dirins && $action == 'initobject' && $module && $objectname) 'MyModule'=>$module, 'MYMODULE'=>strtoupper($module), 'My module'=>$module, - 'htdocs/modulebuilder/template/'=>strtolower($modulename), + 'my module'=>$module, + 'mon module'=>$module, + 'Mon module'=>$module, + 'htdocs/modulebuilder/template/'=>strtolower($modulename), 'myobject'=>strtolower($objectname), 'MyObject'=>$objectname ); @@ -908,6 +914,11 @@ elseif (! empty($module)) $head2[$h][2] = 'specifications'; $h++; + $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=languages&module='.$module.($forceddirread?'@'.$dirread:''); + $head2[$h][1] = $langs->trans("Languages"); + $head2[$h][2] = 'languages'; + $h++; + $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:''); $head2[$h][1] = $langs->trans("Objects"); $head2[$h][2] = 'objects'; @@ -1151,6 +1162,51 @@ elseif (! empty($module)) } } + if ($tab == 'languages') + { + if ($action != 'editfile' || empty($file)) + { + $langfiles=dol_dir_list(dol_buildpath($modulelowercase.'/langs', 0), 'files', 1, '\.lang$'); + + foreach ($langfiles as $langfile) + { + $pathtofile = $modulelowercase.'/langs/'.$langfile['relativename']; + print ' '.$langs->trans("LanguageFile").' '.basename(dirname($pathtofile)).' : '.$pathtofile.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + } + } + else + { + // Edit text language file + + //print $langs->trans("UseAsciiDocFormat").'
'; + + $fullpathoffile=dol_buildpath($file, 0); + + $content = file_get_contents($fullpathoffile); + + // New module + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + + $doleditor=new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%'); + print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'text')); + print '
'; + print '
'; + print ''; + print '   '; + print ''; + print '
'; + + print ''; + } + } + if ($tab == 'objects') { $head3 = array(); diff --git a/htdocs/modulebuilder/template/class/actions_mymodule.class.php b/htdocs/modulebuilder/template/class/actions_mymodule.class.php index b8b43f1359d..7b353113c00 100644 --- a/htdocs/modulebuilder/template/class/actions_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/actions_mymodule.class.php @@ -78,13 +78,9 @@ class ActionsMyModule $error = 0; // Error counter - /* - print_r($parameters); - print_r($object); - echo "action: " . $action; - */ - - if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) { // do something only for the context 'somecontext1' or 'somecontext2' + /* print_r($parameters); print_r($object); echo "action: " . $action; */ + if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) // do something only for the context 'somecontext1' or 'somecontext2' + { } @@ -115,14 +111,9 @@ class ActionsMyModule $error = 0; // Error counter - /* - print_r($parameters); - print_r($object); - echo "action: " . $action; - */ - - if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) { // do something only for the context 'somecontext1' or 'somecontext2' - + /* print_r($parameters); print_r($object); echo "action: " . $action; */ + if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) // do something only for the context 'somecontext1' or 'somecontext2' + { foreach($parameters['toselect'] as $objectid) { // Do action on each object id @@ -156,7 +147,8 @@ class ActionsMyModule $error = 0; // Error counter - if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) // do something only for the context 'somecontext' + /* print_r($parameters); print_r($object); echo "action: " . $action; */ + if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) // do something only for the context 'somecontext1' or 'somecontext2' { $this->resprints = ''; } @@ -171,4 +163,64 @@ class ActionsMyModule + /** + * Execute action + * + * @param array $parameters Array of parameters + * @param Object $object Object output on PDF + * @param string $action 'add', 'update', 'view' + * @return int <0 if KO, + * =0 if OK but we want to process standard actions too, + * >0 if OK and we want to replace standard actions. + */ + function beforePDFCreation($parameters, &$object, &$action) + { + global $langs,$conf; + global $hookmanager; + + $outputlangs=$langs; + + $ret=0; $deltemp=array(); + dol_syslog(get_class($this).'::executeHooks action='.$action); + + /* print_r($parameters); print_r($object); echo "action: " . $action; */ + if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) // do something only for the context 'somecontext1' or 'somecontext2' + { + + } + + return $ret; + } + + /** + * Execute action + * + * @param array $parameters Array of parameters + * @param Object $pdfhandler PDF builder handler + * @param string $action 'add', 'update', 'view' + * @return int <0 if KO, + * =0 if OK but we want to process standard actions too, + * >0 if OK and we want to replace standard actions. + */ + function afterPDFCreation($parameters, &$pdfhandler, &$action) + { + global $langs,$conf; + global $hookmanager; + + $outputlangs=$langs; + + $ret=0; $deltemp=array(); + dol_syslog(get_class($this).'::executeHooks action='.$action); + + /* print_r($parameters); print_r($object); echo "action: " . $action; */ + if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) // do something only for the context 'somecontext1' or 'somecontext2' + { + + } + + return $ret; + } + + /* Add here any other hooked methods... */ + } diff --git a/htdocs/modulebuilder/template/core/boxes/README.md b/htdocs/modulebuilder/template/core/boxes/README.md new file mode 100644 index 00000000000..b641e7136bc --- /dev/null +++ b/htdocs/modulebuilder/template/core/boxes/README.md @@ -0,0 +1 @@ +Directory where widgets files are stored. \ No newline at end of file diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 0806bcce8d9..a26f7148142 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -95,7 +95,7 @@ class modMyModule extends DolibarrModules 'models' => 0, // Set this to 1 if module has its own models directory (core/modules/xxx) 'css' => array('/mymodule/css/mymodule.css.php'), // Set this to relative path of css file if module has its own css file 'js' => array('/mymodule/js/mymodule.js.php'), // Set this to relative path of js file if module must load a js on all pages - 'hooks' => array('hookcontext1','hookcontext2') // Set here all hooks context managed by module. You can also set hook context 'all' + 'hooks' => array('hookcontext1','hookcontext2') // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context 'all' ); // Data directories to create when module is enabled. @@ -305,15 +305,18 @@ class modMyModule extends DolibarrModules */ public function init($options='') { - $sql = array(); - $this->_load_tables('/mymodule/sql/'); // Create extrafields include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); + //$result1=$extrafields->addExtraField('myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty'); //$result2=$extrafields->addExtraField('myattr2', "New Attr 2 label", 'string', 1, 10, 'project'); + //$param=array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')); + //$result3=$extrafields->addExtraField('myattr3', "New Attr 3 label", 'select', 1, 3, 'thirdparty', 0, 1, '', $param, 1); + + $sql = array(); return $this->_init($sql, $options); } diff --git a/htdocs/modulebuilder/template/core/triggers/README.md b/htdocs/modulebuilder/template/core/triggers/README.md new file mode 100644 index 00000000000..38d1b1d8961 --- /dev/null +++ b/htdocs/modulebuilder/template/core/triggers/README.md @@ -0,0 +1 @@ +Directory where triggers files are stored. \ No newline at end of file From 999ac8eccd54fe077bc25ab9ff2fd3ea8df15fc3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Aug 2017 23:49:33 +0200 Subject: [PATCH 140/174] Complete module template --- .../mailinglist_mymodule_myobject.modules.php | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php diff --git a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php new file mode 100644 index 00000000000..b3f2a36efab --- /dev/null +++ b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php @@ -0,0 +1,201 @@ + + * + * This file is an example to follow to add your own email selector inside + * the Dolibarr email tool. + * Follow instructions given in README file to know what to change to build + * your own emailing list selector. + * Code that need to be changed in this file are marked by "CHANGE THIS" tag. + */ + +include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; +dol_include_once("/mymodule/class/myobject.class.php"); + + +/** + * mailing_mailinglist_mymodule + */ +class mailing_mailinglist_mymodule_myobject extends MailingTargets +{ + // CHANGE THIS: Put here a name not already used + var $name='mailinglist_mymodule_myobject'; + // CHANGE THIS: Put here a description of your selector module + var $desc='My object emailing target selector'; + // CHANGE THIS: Set to 1 if selector is available for admin users only + var $require_admin=0; + + var $enabled=0; + var $require_module=array(); + var $picto='mymodule@mymodule'; + var $db; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db=$db; + if (is_array($conf->modules)) + { + $this->enabled=in_array('mymodule',$conf->modules); + } + } + + + /** + * Affiche formulaire de filtre qui apparait dans page de selection des destinataires de mailings + * + * @return string Retourne zone select + */ + function formFilter() + { + global $langs; + $langs->load("members"); + + $form=new Form($this->db); + + $arraystatus=array(1=>'Option 1', 2=>'Option 2'); + + $s=''; + $s.=$langs->trans("Status").': '; + $s.=''; + $s.='
'; + + return $s; + } + + + /** + * Renvoie url lien vers fiche de la source du destinataire du mailing + * + * @param int $id ID + * @return string Url lien + */ + function url($id) + { + return ''.img_object('',"generic").''; + } + + + /** + * This is the main function that returns the array of emails + * + * @param int $mailing_id Id of emailing + * @param array $filtersarray Requete sql de selection des destinataires + * @return int <0 if error, number of emails added if ok + */ + function add_to_target($mailing_id,$filtersarray=array()) + { + $target = array(); + $cibles = array(); + $j = 0; + + + $sql = " select rowid as id, email, firstname, lastname, plan, partner"; + $sql.= " from ".MAIN_DB_PREFIX."myobject"; + $sql.= " where email IS NOT NULL AND email != ''"; + if (! empty($_POST['filter']) && $_POST['filter'] != 'none') $sql.= " AND status = '".$this->db->escape($_POST['filter'])."'"; + $sql.= " ORDER BY email"; + + // Stocke destinataires dans cibles + $result=$this->db->query($sql); + if ($result) + { + $num = $this->db->num_rows($result); + $i = 0; + + dol_syslog("mailinglist_mymodule_myobject.modules.php: mailing ".$num." targets found"); + + $old = ''; + while ($i < $num) + { + $obj = $this->db->fetch_object($result); + if ($old <> $obj->email) + { + $cibles[$j] = array( + 'email' => $obj->email, + 'name' => $obj->lastname, + 'id' => $obj->id, + 'firstname' => $obj->firstname, + 'other' => $obj->plan.';'.$obj->partner, + 'source_url' => $this->url($obj->id), + 'source_id' => $obj->id, + 'source_type' => 'dolicloud' + ); + $old = $obj->email; + $j++; + } + + $i++; + } + } + else + { + dol_syslog($this->db->error()); + $this->error=$this->db->error(); + return -1; + } + + // You must fill the $target array with record like this + // $target[0]=array('email'=>'email_0','name'=>'name_0','firstname'=>'firstname_0'); + // ... + // $target[n]=array('email'=>'email_n','name'=>'name_n','firstname'=>'firstname_n'); + + // Example: $target[0]=array('email'=>'myemail@mydomain.com','name'=>'Doe','firstname'=>'John'); + + // ----- Your code end here ----- + + return parent::add_to_target($mailing_id, $cibles); + } + + + /** + * On the main mailing area, there is a box with statistics. + * If you want to add a line in this report you must provide an + * array of SQL request that returns two field: + * One called "label", One called "nb". + * + * @return array + */ + function getSqlArrayForStats() + { + // CHANGE THIS: Optionnal + + //var $statssql=array(); + //$this->statssql[0]="SELECT field1 as label, count(distinct(email)) as nb FROM mytable WHERE email IS NOT NULL"; + + return array(); + } + + + /** + * Return here number of distinct emails returned by your selector. + * For example if this selector is used to extract 500 different + * emails from a text file, this function must return 500. + * + * @param string $filter Filter + * @param string $option Options + * @return int Nb of recipients + */ + function getNbOfRecipients($filter=1,$option='') + { + $a=parent::getNbOfRecipients("select count(distinct(email)) as nb from ".MAIN_DB_PREFIX."myobject as p where email IS NOT NULL AND email != ''"); + + if ($a < 0 || $b < 0) return -1; + if ($option == '') return $a; + return ($a+$b); + } + +} + From 533881e620f500121580380f454f9a7e133a18c7 Mon Sep 17 00:00:00 2001 From: fappels Date: Fri, 25 Aug 2017 11:58:34 +0200 Subject: [PATCH 141/174] Fix supplier prices not shown when best buy hidden only show value if item has supplier --- htdocs/product/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 73911588600..dd98a768c6b 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -834,7 +834,7 @@ else print '
'; - // Multicompany - if (! empty($conf->multicompany->enabled) && is_object($mc)) - { - if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) - { - print "".''; - print "\n"; - } - else - { - print ''; - } - } - // Accountancy code if ($conf->accounting->enabled) { @@ -1109,6 +1094,24 @@ if ($action == 'create' || $action == 'adduserldap') print ""; } + // Multicompany + // This is now done with hook formObjectOptions + /* + if (! empty($conf->multicompany->enabled) && is_object($mc)) + { + if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) // condition must be same for create and edit mode + { + print "".''; + print "\n"; + } + else + { + print ''; + } + } + */ + // Other attributes $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook @@ -1498,6 +1501,24 @@ else print ''; print "\n"; + // Multicompany + // This is now done with hook formObjectOptions (included into /core/tpl/extrafields_view.tpl.php) + /* + if (! empty($conf->multicompany->enabled) && is_object($mc)) + { + if (! empty($conf->multicompany->enabled) && empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + print '\n"; + } + }*/ + // Other attributes include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; @@ -2392,6 +2413,25 @@ else print "\n"; } + // Multicompany + // This is now done with hook formObjectOptions + /* + // TODO check if user not linked with the current entity before change entity (thirdparty, invoice, etc.) !! + if (! empty($conf->multicompany->enabled) && is_object($mc)) + { + if (empty($conf->multicompany->transverse_mode) && $conf->entity == 1 && $user->admin && ! $user->entity) + { + print "".''; + print "\n"; + } + else + { + print ''; + } + } + */ + // Other attributes $parameters=array('colspan' => ' colspan="2"'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook From 98f5fbab5dbb11f6021f96d5746d8d146c2c34ab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 25 Aug 2017 13:50:45 +0200 Subject: [PATCH 143/174] Fix error on contact/address not linked on thirdparty --- htdocs/contact/agenda.php | 40 ++++++++++++++++----------------- htdocs/core/lib/company.lib.php | 26 ++++++++++----------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/htdocs/contact/agenda.php b/htdocs/contact/agenda.php index 7f35c71cd11..cc7f36261cc 100644 --- a/htdocs/contact/agenda.php +++ b/htdocs/contact/agenda.php @@ -211,7 +211,7 @@ else dol_fiche_head($head, 'agenda', $title, -1, 'contact'); $linkback = ''.$langs->trans("BackToList").''; - + $morehtmlref='
'; if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) { @@ -223,42 +223,42 @@ else else $morehtmlref.=$langs->trans("ContactNotLinkedToCompany"); } $morehtmlref.='
'; - + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref); - + print '
'; - + print '
'; - + $object->info($id); print dol_print_object_info($object, 1); - + print '
'; - + print dol_fiche_end(); - + // Actions buttons - + $objcon=$object; $object->fetch_thirdparty(); $objthirdparty=$object->thirdparty; - + $out=''; $permok=$user->rights->agenda->myactions->create; if ((! empty($objthirdparty->id) || ! empty($objcon->id)) && $permok) { //$out.='trans("AddAnAction"),'filenew'); //$out.=""; } - - + + print '
'; - + if (! empty($conf->agenda->enabled)) { if (! empty($user->rights->agenda->myactions->create) || ! empty($user->rights->agenda->allactions->create)) @@ -270,22 +270,22 @@ else print ''.$langs->trans("AddAction").''; } } - + print '
'; - + if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) )) { $param='&id='.$id; if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage; if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; - - + + print load_fiche_titre($langs->trans("TasksHistoryForThisContact"),'',''); - + // List of all actions $filters=array(); $filters['search_agenda_label']=$search_agenda_label; - + show_actions_done($conf,$langs,$db,$objthirdparty,$object,0,$actioncode, '', $filters, $sortfield, $sortorder); } } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index ae4dfe1c2e4..fe36e0e02f4 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1043,7 +1043,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= global $param; // Check parameters - if (! is_object($filterobj)) dol_print_error('','BadParameter'); + if (! is_object($filterobj) && ! is_object($objcon)) dol_print_error('','BadParameter'); $out=''; $histo=array(); @@ -1061,24 +1061,24 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $sql.= " a.fk_user_author, a.fk_contact,"; $sql.= " c.code as acode, c.libelle as alabel, c.picto as apicto,"; $sql.= " u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; - if (get_class($filterobj) == 'Societe') $sql.= ", sp.lastname, sp.firstname"; - if (get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname"; - if (get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref"; + if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql.= ", sp.lastname, sp.firstname"; + if (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname"; + if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u, ".MAIN_DB_PREFIX."actioncomm as a"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action = c.id"; - if (get_class($filterobj) == 'Societe') $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid"; - if (get_class($filterobj) == 'Adherent') $sql.= ", ".MAIN_DB_PREFIX."adherent as m"; - if (get_class($filterobj) == 'CommandeFournisseur') $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseur as o"; + if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid"; + if (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", ".MAIN_DB_PREFIX."adherent as m"; + if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseur as o"; $sql.= " WHERE u.rowid = a.fk_user_action"; $sql.= " AND a.entity IN (".getEntity('agenda').")"; - if (get_class($filterobj) == 'Societe' && $filterobj->id) $sql.= " AND a.fk_soc = ".$filterobj->id; - if (get_class($filterobj) == 'Project' && $filterobj->id) $sql.= " AND a.fk_project = ".$filterobj->id; - if (get_class($filterobj) == 'Adherent') + if (is_object($filterobj) && get_class($filterobj) == 'Societe' && $filterobj->id) $sql.= " AND a.fk_soc = ".$filterobj->id; + if (is_object($filterobj) && get_class($filterobj) == 'Project' && $filterobj->id) $sql.= " AND a.fk_project = ".$filterobj->id; + if (is_object($filterobj) && get_class($filterobj) == 'Adherent') { $sql.= " AND a.fk_element = m.rowid AND a.elementtype = 'member'"; if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; } - if (get_class($filterobj) == 'CommandeFournisseur') + if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') { $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'order_supplier'"; if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; @@ -1239,7 +1239,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $facturestatic=new Facture($db); $out.='
'; - if ($objcon && get_class($objcon) == 'Contact' && get_class($filterobj) == 'Societe') + if ($objcon && get_class($objcon) == 'Contact' && $filterobj && get_class($filterobj) == 'Societe') { $out.=''; } @@ -1247,7 +1247,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= { $out.=''; } - if (get_class($filterobj) == 'Societe') $out.=''; + if ($filterobj && get_class($filterobj) == 'Societe') $out.=''; $out.="\n"; From 7030d0d5962b3160b883589d554917b760b1a3a9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 25 Aug 2017 15:04:55 +0200 Subject: [PATCH 144/174] Add combo on ldap selection --- htdocs/user/card.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 7209b900378..f01915247bf 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -369,7 +369,7 @@ if (empty($reshook)) { $object->default_range = GETPOST('default_range'); $object->default_c_exp_tax_cat = GETPOST('default_c_exp_tax_cat'); - + if (! empty($conf->multicompany->enabled)) { if (! empty($_POST["superadmin"])) @@ -718,6 +718,7 @@ if ($action == 'create' || $action == 'adduserldap') if (is_array($liste) && count($liste)) { print $form->selectarray('users', $liste, '', 1); + print ajax_combobox('users'); } print '
"; } - + if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) { print ''; @@ -1125,7 +1126,7 @@ if ($action == 'create' || $action == 'adduserldap') print $form->selectarray('default_range', range(0, $maxRangeNum), $object->default_range); print ''; } - + // Other attributes $parameters=array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook @@ -1143,7 +1144,7 @@ if ($action == 'create' || $action == 'adduserldap') $doleditor=new DolEditor('note','','',120,'dolibarr_notes','',false,true,$conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_3,'90%'); $doleditor->Create(); print "\n"; - + // Signature print ''; print ''; } - + // Other attributes include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; @@ -2428,14 +2429,14 @@ else print ''; - + print ''; print ''; } - + // Other attributes $parameters=array('colspan' => ' colspan="2"'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook From c9643109dff74491c6d7bd6df88b581161cef289 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 25 Aug 2017 16:21:34 +0200 Subject: [PATCH 145/174] Fix comment doc --- htdocs/compta/facture/class/facture-rec.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 581231ebefa..ddf813db30b 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -1305,7 +1305,7 @@ class FactureLigneRec extends CommonInvoiceLine /** * Recupere les lignes de factures predefinies dans this->lines - * + * @param int $rowid * @return int 1 if OK, < 0 if KO */ function fetch($rowid) From 040071b07b20f9062740493a9eba2701de5b5d56 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 25 Aug 2017 16:25:40 +0200 Subject: [PATCH 146/174] Change copyright comment --- htdocs/compta/facture/admin/facture_rec_cust_extrafields.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/admin/facture_rec_cust_extrafields.php b/htdocs/compta/facture/admin/facture_rec_cust_extrafields.php index c365f59ba37..1bc9272a32f 100644 --- a/htdocs/compta/facture/admin/facture_rec_cust_extrafields.php +++ b/htdocs/compta/facture/admin/facture_rec_cust_extrafields.php @@ -4,7 +4,7 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2012 Regis Houssin * Copyright (C) 2013 Jean-Francois FERRY -* Copyright (C) 2017 ATM-CONSULTING +* Copyright (C) 2017 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 From 9d380a8b8acd5bc1cb4527d906d6c7195634e804 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 25 Aug 2017 16:38:45 +0200 Subject: [PATCH 147/174] NEW Can edit the language into the email templates editor. --- htdocs/admin/mails_templates.php | 95 ++++++++++++---------- htdocs/core/class/html.formadmin.class.php | 7 +- 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index f0cbb91c6c3..5e309eab48c 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -45,6 +45,7 @@ $langs->load("errors"); $langs->load("admin"); $langs->load("main"); $langs->load("mails"); +$langs->load("languages"); $action=GETPOST('action','alpha')?GETPOST('action','alpha'):'view'; $confirm=GETPOST('confirm','alpha'); @@ -85,17 +86,17 @@ $tabsqlsort[25]="label ASC"; // Nom des champs en resultat de select pour affichage du dictionnaire $tabfield=array(); -$tabfield[25]= "label,type_template,private,position,topic,content"; +$tabfield[25]= "label,type_template,lang,private,position,topic,content"; if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) $tabfield[25].=',content_lines'; // Nom des champs d'edition pour modification d'un enregistrement $tabfieldvalue=array(); -$tabfieldvalue[25]= "label,type_template,private,position,topic,content"; +$tabfieldvalue[25]= "label,type_template,lang,private,position,topic,content"; if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) $tabfieldvalue[25].=',content_lines'; // Nom des champs dans la table pour insertion d'un enregistrement $tabfieldinsert=array(); -$tabfieldinsert[25]= "label,type_template,private,position,topic,content"; +$tabfieldinsert[25]= "label,type_template,lang,private,position,topic,content"; if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) $tabfieldinsert[25].=',content_lines'; $tabfieldinsert[25].=',entity'; // Must be at end because not into other arrays @@ -144,16 +145,16 @@ $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->expedition->enabled) $elementList['shipping_send']=$langs->trans('MailToSendShipment'); -if ($conf->ficheinter->enabled) $elementList['fichinter_send']=$langs->trans('MailToSendIntervention'); +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->expedition->enabled) $elementList['shipping_send']=$langs->trans('MailToSendShipment'); +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) $elementList['order_supplier_send']=$langs->trans('MailToSendSupplierOrder'); -if ($conf->fournisseur->enabled) $elementList['invoice_supplier_send']=$langs->trans('MailToSendSupplierInvoice'); -if ($conf->societe->enabled) $elementList['thirdparty']=$langs->trans('MailToThirdparty'); -if ($conf->contrat->enabled) $elementList['contract']=$langs->trans('MailToSendContract'); +if ($conf->fournisseur->enabled) $elementList['order_supplier_send']=$langs->trans('MailToSendSupplierOrder'); +if ($conf->fournisseur->enabled) $elementList['invoice_supplier_send']=$langs->trans('MailToSendSupplierInvoice'); +if ($conf->societe->enabled) $elementList['thirdparty']=$langs->trans('MailToThirdparty'); +if ($conf->contrat->enabled) $elementList['contract']=$langs->trans('MailToSendContract'); $parameters=array('elementList'=>$elementList); $reshook=$hookmanager->executeHooks('emailElementlist',$parameters); // Note that $action and $object may have been modified by some hooks @@ -204,7 +205,7 @@ if (empty($reshook)) if ($value == 'content') $value='content-'.$rowid; if ($value == 'content_lines') $value='content_lines-'.$rowid; - if (! isset($_POST[$value]) || $_POST[$value]=='') + if (! isset($_POST[$value]) || ($_POST[$value]=='' && $value!='lang')) { $ok=0; $fieldnamekey=$listfield[$f]; @@ -434,16 +435,13 @@ if ($action == 'delete') //var_dump($elementList); -$sql="SELECT rowid as rowid, label, type_template, private, position, topic, content_lines, content, active"; +$sql="SELECT rowid as rowid, label, type_template, lang, private, position, topic, content_lines, content, active"; $sql.=" FROM ".MAIN_DB_PREFIX."c_email_templates"; $sql.=" WHERE entity IN (".getEntity('email_template').")"; if ($search_label) $sql.=natural_search('label', $search_label); - -if ($search_country_id > 0) +if (empty($conf->global->MAIN_MULTILANGS)) { - if (preg_match('/ WHERE /',$sql)) $sql.= " AND "; - else $sql.=" WHERE "; - $sql.= " c.rowid = ".$search_country_id; + $sql.= " AND (lang = '".$langs->defaultlang."' OR lang IS NULL)"; } if ($sortfield) @@ -469,21 +467,21 @@ $sql.=$db->plimit($listlimit+1,$offset); $fieldlist=explode(',',$tabfield[$id]); -print ''; -print ''; -print ''; - -print '
'.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("ProjectRef").''.$langs->trans("ThirdParty").''.$langs->trans("RefTask").''.$langs->trans("LabelTask").''.$langs->trans("PlannedWorkload").''.$langs->trans("ProgressDeclared").''.$langs->trans("TimeSpent").''; if ($obj->tobuy) { - if (($productFournList = $product_fourn->list_product_fournisseur_price($product_fourn->id)) > 0) + if (count($productFournList = $product_fourn->list_product_fournisseur_price($obj->rowid)) > 0) { $htmltext=$product_fourn->display_price_product_fournisseur(1, 1, 0, 1, $productFournList); print $form->textwithpicto(count($productFournList),$htmltext); From da34ea6b115f3a7116d5cc94ac7e7c56594fd274 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 25 Aug 2017 13:25:34 +0200 Subject: [PATCH 142/174] FIX field entity "edit" and "view" was in hook but not "create". --- htdocs/user/card.php | 70 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index a2938a89712..eeb1e898736 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1010,21 +1010,6 @@ if ($action == 'create' || $action == 'adduserldap') } print '
'.$langs->trans("Entity").'".$mc->select_entities($conf->entity); - print "
'.$langs->trans("Entity").'".$mc->select_entities($conf->entity); + print "
'.dol_print_date($object->datepreviouslogin,"dayhour").'
' . $langs->trans("Entity") . ''; + if (empty($object->entity)) { + print $langs->trans("AllEntities"); + } else { + $mc->getInfo($object->entity); + print $mc->label; + } + print "
'.$langs->trans("Entity").'".$mc->select_entities($object->entity, 'entity', '', 0, 1); // last parameter 1 means, show also a choice 0=>'all entities' + print "
'; print ''; @@ -1111,7 +1112,7 @@ if ($action == 'create' || $action == 'adduserldap') null, '90%' ); print "
'.$langs->trans("DefaultCategoryCar").'
'.$langs->trans("Signature").''; @@ -1527,7 +1528,7 @@ else print $object->default_range; print '
'; print $form->selectExpenseCategories($object->default_c_exp_tax_cat, 'default_c_exp_tax_cat', 1); print '
'.$langs->trans("DefaultRangeNumber").''; $maxRangeNum = ExpenseReportIk::getMaxRangeNumber($object->default_c_exp_tax_cat); print $form->selectarray('default_range', range(0, $maxRangeNum), $object->default_range); print '
'; - // Form to add a new line $alabelisused=0; $var=false; $fieldlist=explode(',',$tabfield[$id]); -if ($action != 'edit') -{ - // Line for title +//if ($action != 'edit') +//{ + print ''; + print ''; + print ''; + + print '
'; + + // Line for title print ''; foreach ($fieldlist as $field => $value) { @@ -593,12 +591,13 @@ if ($action != 'edit') $colspan=count($fieldlist)+1; //print ''; // Keep   to have a line with enough height -} -print '
 
'; -print ''; + print '
'; -print '
'; + print ''; + + print '
'; +//} print '
'; print ''; @@ -732,15 +731,15 @@ if ($resql) // Show value for field if ($showfield) { - print ''; // To create an artificial CR for the current tr we are on + print ''; + print ''; // To create an artificial CR for the current tr we are on $okforextended = true; - if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) - $okforextended = false; - $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (! empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 140, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%'); - print $doleditor->Create(1); - print ''; - print ''; - + if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) $okforextended = false; + $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (! empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 140, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%'); + print $doleditor->Create(1); + print ''; + print ''; + print ''; } } } @@ -764,12 +763,16 @@ if ($resql) { $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; } + if ($value == 'lang' && $valuetoshow) + { + $valuetoshow = $valuetoshow.' - '.$langs->trans("Language_".$valuetoshow); + } $class='tddict'; // Show value for field if ($showfield) { - print ''.$valuetoshow.''; + print ''.$valuetoshow.''; } } } @@ -884,7 +887,15 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') if ($fieldlist[$field] == 'lang') { print ''; - print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT,'lang'); + if (! empty($conf->global->MAIN_MULTILANGS)) + { + print $formadmin->select_language($langs->defaultlang,'lang'); + } + else + { + //print $langs->defaultlang.' - '.$langs->trans('Language_'.$langs->defaultlang); + print ''; + } print ''; } // Le type de template diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index 16a16719366..459f256918c 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -85,16 +85,11 @@ class FormAdmin asort($langs_available); - $uncompletelanguages=array('da_DA','fi_FI','hu_HU','is_IS','pl_PL','ro_RO','ru_RU','sv_SV','tr_TR','zh_CN'); foreach ($langs_available as $key => $value) { $valuetoshow=$value; if ($showcode) $valuetoshow=$key.' - '.$value; - - if ($showwarning && in_array($key,$uncompletelanguages)) - { - //$value.=' - '.$langs->trans("TranslationUncomplete",$key); - } + if ($filter && is_array($filter)) { if ( ! array_key_exists($key, $filter)) From 7329d21dcd3a727327100ac926df69c6b39a7e9a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 25 Aug 2017 17:13:33 +0200 Subject: [PATCH 148/174] Fix lang selection --- htdocs/admin/mails_templates.php | 44 +++++++++++++--------- htdocs/core/class/html.formadmin.class.php | 2 +- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 5e309eab48c..390c792a879 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -205,7 +205,7 @@ if (empty($reshook)) if ($value == 'content') $value='content-'.$rowid; if ($value == 'content_lines') $value='content_lines-'.$rowid; - if (! isset($_POST[$value]) || ($_POST[$value]=='' && $value!='lang')) + if ((! isset($_POST[$value]) || $_POST[$value]=='') && $value != 'lang') { $ok=0; $fieldnamekey=$listfield[$f]; @@ -254,15 +254,16 @@ if (empty($reshook)) $i=0; foreach ($listfieldinsert as $f => $value) { - //var_dump($i.' - '.$listfieldvalue[$i].' - '.$_POST[$listfieldvalue[$i]].' - '.$value); - if ($value == 'entity') { - $_POST[$listfieldvalue[$i]] = $conf->entity; - } + $keycode=$listfieldvalue[$i]; + if ($value == 'lang') $keycode='langcode'; + + //var_dump($i.' - '.$listfieldvalue[$i].' - '.$_POST[$listfieldvalue[$i]].' - '.$value); + if ($value == 'entity') $_POST[$keycode] = $conf->entity; if ($i) $sql.=","; - if ($value == 'private' && ! is_numeric($_POST[$listfieldvalue[$i]])) $_POST[$listfieldvalue[$i]]='0'; - if ($value == 'position' && ! is_numeric($_POST[$listfieldvalue[$i]])) $_POST[$listfieldvalue[$i]]='1'; - if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; // For vat, we want/accept code = '' - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + if ($value == 'private' && ! is_numeric($_POST[$keycode])) $_POST[$keycode]='0'; + if ($value == 'position' && ! is_numeric($_POST[$keycode])) $_POST[$keycode]='1'; + if ($_POST[$keycode] == '' || ($keycode == 'langcode' && empty($_POST[$keycode]))) $sql.="null"; // For vat, we want/accept code = '' + else $sql.="'".$db->escape($_POST[$keycode])."'"; $i++; } $sql.=",1)"; @@ -302,15 +303,16 @@ if (empty($reshook)) $i = 0; foreach ($listfieldmodify as $field) { + $keycode=$listfieldvalue[$i]; + if ($field == 'lang') $keycode='langcode'; + if ($field == 'content') $_POST['content']=$_POST['content-'.$rowid]; if ($field == 'content_lines') $_POST['content_lines']=$_POST['content_lines-'.$rowid]; - if ($field == 'entity') { - $_POST[$listfieldvalue[$i]] = $conf->entity; - } + if ($field == 'entity') $_POST[$keycode] = $conf->entity; if ($i) $sql.=","; $sql.= $field."="; - if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; // For vat, we want/accept code = '' - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + if ($_POST[$keycode] == '' || ($keycode == 'langcode' && empty($_POST[$keycode]))) $sql.="null"; // For vat, we want/accept code = '' + else $sql.="'".$db->escape($_POST[$keycode])."'"; $i++; } $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; @@ -698,6 +700,7 @@ if ($resql) $obj = $db->fetch_object($resql); //print_r($obj); print ''; + if ($action == 'edit' && ($rowid == (! empty($obj->rowid)?$obj->rowid:$obj->code))) { $tmpaction='edit'; @@ -889,12 +892,19 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') print ''; if (! empty($conf->global->MAIN_MULTILANGS)) { - print $formadmin->select_language($langs->defaultlang,'lang'); + $selectedlang = $langs->defaultlang; + if ($context == 'edit') $selectedlang = $obj->{$fieldlist[$field]}; + print $formadmin->select_language($selectedlang, 'langcode', 0, null, 1); } else { - //print $langs->defaultlang.' - '.$langs->trans('Language_'.$langs->defaultlang); - print ''; + if (! empty($obj->{$fieldlist[$field]})) + { + print $obj->{$fieldlist[$field]}.' - '.$langs->trans('Language_'.$obj->{$fieldlist[$field]}); + } + $keyname=$fieldlist[$field]; + if ($keyname == 'lang') $keyname='langcode'; // Avoid conflict with lang param + print ''; } print ''; } diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index 459f256918c..e2a423e9ca4 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -69,7 +69,7 @@ class FormAdmin $out.= ''; @@ -469,7 +472,7 @@ if ($object->fetch($id) >= 0) print ''; // Other print ''; - print ' '; + print ''; print ''; // Source print ''; From 54cc1ac800bba61f8759e41fac71a1c93fb8f5ef Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 25 Aug 2017 21:12:22 +0200 Subject: [PATCH 150/174] Merge emailing target selectors. --- htdocs/comm/mailing/cibles.php | 25 +- .../modules/mailings/contacts1.modules.php | 231 ++++++++++++++-- .../modules/mailings/contacts2.modules.php | 222 --------------- .../modules/mailings/contacts3.modules.php | 250 ----------------- .../modules/mailings/contacts4.modules.php | 252 ------------------ .../core/modules/mailings/fraise.modules.php | 66 ++++- .../modules/mailings/framboise.modules.php | 234 ---------------- htdocs/install/upgrade2.php | 5 + htdocs/langs/en_US/companies.lang | 1 + 9 files changed, 280 insertions(+), 1006 deletions(-) delete mode 100644 htdocs/core/modules/mailings/contacts2.modules.php delete mode 100644 htdocs/core/modules/mailings/contacts3.modules.php delete mode 100644 htdocs/core/modules/mailings/contacts4.modules.php delete mode 100644 htdocs/core/modules/mailings/framboise.modules.php diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index 6e917010b51..9669d8c0ff3 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -91,8 +91,7 @@ if ($action == 'add') { require_once $file; - // We fill $filtersarray. Using this variable is now deprecated. - // Kept for backward compatibility. + // We fill $filtersarray. Using this variable is now deprecated. Kept for backward compatibility. $filtersarray=array(); if (isset($_POST["filter"])) $filtersarray[0]=$_POST["filter"]; @@ -157,11 +156,13 @@ if ($action == 'delete') } } -if ($_POST["button_removefilter"]) +// Purge search criteria +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') ||GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { $search_lastname=''; $search_firstname=''; $search_email=''; + $search_other=''; $search_dest_status=''; } @@ -304,12 +305,10 @@ if ($object->fetch($id) >= 0) if ($qualified) { $var = !$var; - //print ''; -// print '
'; if ($allowaddtarget) { - print ''; + print ''; print ''; } else @@ -317,13 +316,11 @@ if ($object->fetch($id) >= 0) print '
'; } - //print ''; print '
'; if (empty($obj->picto)) $obj->picto='generic'; - print img_object($langs->trans("Module").': '.get_class($obj),$obj->picto); + print img_object($langs->trans("EmailingTargetSelector").': '.get_class($obj),$obj->picto); print ' '; print $obj->getDesc(); - //print ''; print '
'; try { @@ -334,7 +331,6 @@ if ($object->fetch($id) >= 0) dol_syslog($e->getMessage(), LOG_ERR); } - //print ''; print '
'; if ($nbofrecipient >= 0) { @@ -344,10 +340,8 @@ if ($object->fetch($id) >= 0) { print $langs->trans("Error").' '.img_error($obj->error); } - //print ''; print '
'; - //print ''; print '
'; if ($allowaddtarget) { @@ -361,10 +355,8 @@ if ($object->fetch($id) >= 0) if ($filter) print $filter; else print $langs->trans("None"); } - //print ''; print '
'; - //print ''; print '
'; if ($allowaddtarget) { @@ -376,19 +368,14 @@ if ($object->fetch($id) >= 0) //print $langs->trans("MailNoChangePossible"); print " "; } - //print ''; print '
'; if ($allowaddtarget) print ''; else print '
'; - - //print "\n"; -// print '
'."\n"; } } } // End foreach dir - //print ''; print '
'; print '

'; diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 0e4966a5ada..51cca978ca6 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -28,8 +28,7 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; /** - * \class mailing_contacts1 - * \brief Class to offer a selector of emailing targets with Rule 'Poire'. + * Class to offer a selector of emailing targets from contacts */ class mailing_contacts1 extends MailingTargets { @@ -39,7 +38,7 @@ class mailing_contacts1 extends MailingTargets var $require_module=array("societe"); // Module mailing actif si modules require_module actifs var $require_admin=0; // Module mailing actif pour user admin ou non var $picto='contact'; - + var $db; @@ -101,8 +100,7 @@ class mailing_contacts1 extends MailingTargets $sql.= " AND c.no_email = 0"; $sql.= " AND c.statut = 1"; - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients + // The request must return a field called "nb" to be understandable by parent::getNbOfRecipients return parent::getNbOfRecipients($sql); } @@ -118,10 +116,86 @@ class mailing_contacts1 extends MailingTargets $langs->load("companies"); $langs->load("commercial"); $langs->load("suppliers"); + $langs->load("categories"); $s=''; - $s.=''; + $s.=''; + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $s.=''; + $i++; + } + } + else dol_print_error($this->db); + $s.=''; + + $s.=' '; + + // Filter on contact category + $s .= $langs->trans("ContactCategoriesShort").': '; + $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; + $sql.= " FROM "; + $sql.= " ".MAIN_DB_PREFIX."socpeople as sp,"; + $sql.= " ".MAIN_DB_PREFIX."categorie as c,"; + $sql.= " ".MAIN_DB_PREFIX."categorie_contact as cs"; + $sql.= " WHERE sp.statut = 1"; // Note that null != '' is false + //$sql.= " AND sp.no_email = 0"; + //$sql.= " AND sp.email != ''"; + //$sql.= " AND sp.entity IN (".getEntity('societe').")"; + $sql.= " AND cs.fk_categorie = c.rowid"; + $sql.= " AND cs.fk_socpeople = sp.rowid"; + $sql.= " GROUP BY c.label"; + $sql.= " ORDER BY c.label"; + $resql = $this->db->query($sql); + + $s.=''; + + $s.='
'; + // Add prospect of a particular level + $s.=$langs->trans("NatureOfThirdParty").': '; + $s.=''; + + $s.= ' '; + + // Filter on thirdparty category + $s .= $langs->trans("CustomersProspectsCategoriesShort").': '; + $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; + $sql.= " FROM "; + $sql.= " ".MAIN_DB_PREFIX."socpeople as sp,"; + $sql.= " ".MAIN_DB_PREFIX."categorie as c,"; + $sql.= " ".MAIN_DB_PREFIX."categorie_societe as cs"; + $sql.= " WHERE sp.statut = 1"; // Note that null != '' is false + //$sql.= " AND sp.no_email = 0"; + //$sql.= " AND sp.email != ''"; + //$sql.= " AND sp.entity IN (".getEntity('societe').")"; + $sql.= " AND cs.fk_categorie = c.rowid"; + $sql.= " AND cs.fk_soc = sp.fk_soc"; + $sql.= " GROUP BY c.label"; + $sql.= " ORDER BY c.label"; + $resql = $this->db->query($sql); + + $s.=''; + + $s.= ' '; + + // Filter on thirdparty category + $s .= $langs->trans("SuppliersCategoriesShort").': '; + $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; + $sql.= " FROM "; + $sql.= " ".MAIN_DB_PREFIX."socpeople as sp,"; + $sql.= " ".MAIN_DB_PREFIX."categorie as c,"; + $sql.= " ".MAIN_DB_PREFIX."categorie_fournisseur as cs"; + $sql.= " WHERE sp.statut = 1"; // Note that null != '' is false + //$sql.= " AND sp.no_email = 0"; + //$sql.= " AND sp.email != ''"; + //$sql.= " AND sp.entity IN (".getEntity('societe').")"; + $sql.= " AND cs.fk_categorie = c.rowid"; + $sql.= " AND cs.fk_soc = sp.fk_soc"; + $sql.= " GROUP BY c.label"; + $sql.= " ORDER BY c.label"; + $resql = $this->db->query($sql); + + $s.=''; + return $s; } @@ -168,13 +328,19 @@ class mailing_contacts1 extends MailingTargets * Ajoute destinataires dans table des cibles * * @param int $mailing_id Id of emailing - * @param array $filtersarray Requete sql de selection des destinataires + * @param array $filtersarray Optional filter data (deprecated) * @return int <0 si erreur, nb ajout si ok */ function add_to_target($mailing_id,$filtersarray=array()) { global $conf, $langs; + $filter = GETPOST('filter','alpha'); + $filter_jobposition = GETPOST('filter_jobposition','alpha'); + $filter_category = GETPOST('filter_category','alpha'); + $filter_category_customer = GETPOST('filter_category_customer','alpha'); + $filter_category_supplier = GETPOST('filter_category_supplier','alpha'); + $cibles = array(); // List prospects levels @@ -197,27 +363,43 @@ class mailing_contacts1 extends MailingTargets } else dol_print_error($this->db); - // La requete doit retourner: id, email, fk_contact, name, firstname, other - $sql = "SELECT c.rowid as id, c.email as email, c.rowid as fk_contact,"; - $sql.= " c.lastname, c.firstname, c.civility as civility_id,"; + // Request must return: id, email, fk_contact, lastname, firstname, other + $sql = "SELECT sp.rowid as id, sp.email as email, sp.rowid as fk_contact, sp.lastname, sp.firstname, sp.civility as civility_id, sp.poste as jobposition,"; $sql.= " s.nom as companyname"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc"; - $sql.= " WHERE c.entity IN (".getEntity('societe').")"; - $sql.= " AND c.email <> ''"; - $sql.= " AND c.no_email = 0"; - $sql.= " AND c.statut = 1"; - $sql.= " AND c.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".$mailing_id.")"; - foreach($filtersarray as $key) + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; + if ($filter_category <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie as c"; + if ($filter_category <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie_contact as cs"; + if ($filter_category_customer <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie as c2"; + if ($filter_category_customer <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie_societe as c2s"; + if ($filter_category_supplier <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie as c3"; + if ($filter_category_supplier <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie_fournisseur as c3s"; + $sql.= " WHERE sp.entity IN (".getEntity('societe').")"; + $sql.= " AND sp.email <> ''"; + $sql.= " AND sp.no_email = 0"; + $sql.= " AND sp.statut = 1"; + $sql.= " AND sp.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".$mailing_id.")"; + // Filter on category + if ($filter_category <> 'all') $sql.= " AND cs.fk_categorie = c.rowid AND cs.fk_socpeople = sp.rowid"; + if ($filter_category <> 'all') $sql.= " AND c.label = '".$this->db->escape($filter_category)."'"; + if ($filter_category_customer <> 'all') $sql.= " AND c2s.fk_categorie = c2.rowid AND c2s.fk_soc = sp.fk_soc"; + if ($filter_category_customer <> 'all') $sql.= " AND c2.label = '".$this->db->escape($filter_category_customer)."'"; + if ($filter_category_supplier <> 'all') $sql.= " AND c3s.fk_categorie = c3.rowid AND c3s.fk_soc = sp.fk_soc"; + if ($filter_category_supplier <> 'all') $sql.= " AND c3.label = '".$this->db->escape($filter_category_supplier)."'"; + // Filter on nature + $key = $filter; { - if ($key == 'prospects') $sql.= " AND s.client=2"; //print "xx".$key; + if ($key == 'prospects') $sql.= " AND s.client=2"; foreach($prospectlevel as $codelevel=>$valuelevel) if ($key == 'prospectslevel'.$codelevel) $sql.= " AND s.fk_prospectlevel='".$codelevel."'"; if ($key == 'customers') $sql.= " AND s.client=1"; if ($key == 'suppliers') $sql.= " AND s.fournisseur=1"; } - $sql.= " ORDER BY c.email"; - //print "x".$sql; + // Filter on job position + $key = $filter_jobposition; + if (! empty($key) && $key != 'all') $sql.= " AND sp.poste ='".$this->db->escape($key)."'"; + $sql.= " ORDER BY sp.email"; + //print "wwwwwwx".$sql; // Stocke destinataires dans cibles $result=$this->db->query($sql); @@ -242,8 +424,9 @@ class mailing_contacts1 extends MailingTargets 'firstname' => $obj->firstname, 'other' => ($langs->transnoentities("ThirdParty").'='.$obj->companyname).';'. - ($langs->transnoentities("UserTitle").'='.($obj->civility_id?$langs->transnoentities("Civility".$obj->civility_id):'')), - 'source_url' => $this->url($obj->id), + ($langs->transnoentities("UserTitle").'='.($obj->civility_id?$langs->transnoentities("Civility".$obj->civility_id):'')).';'. + ($langs->transnoentities("JobPosition").'='.$obj->jobposition), + 'source_url' => $this->url($obj->id), 'source_id' => $obj->id, 'source_type' => 'contact' ); diff --git a/htdocs/core/modules/mailings/contacts2.modules.php b/htdocs/core/modules/mailings/contacts2.modules.php deleted file mode 100644 index a9c05434cd3..00000000000 --- a/htdocs/core/modules/mailings/contacts2.modules.php +++ /dev/null @@ -1,222 +0,0 @@ - - * Copyright (C) 2013 Regis Houssin - * - * 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 . - * or see http://www.gnu.org/ - */ - -/** - * \file htdocs/core/modules/mailings/contacts2.modules.php - * \ingroup mailing - * \brief Provides a list of recipients for mailing module - */ - -include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; - - -/** - * \class mailing_contacts2 - * \brief Class to manage a list of personalised recipients for mailing feature - */ -class mailing_contacts2 extends MailingTargets -{ - var $name='ContactsByFunction'; - // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found - var $desc='Add contacts by function'; - var $require_admin=0; - - var $require_module=array(); - var $picto='contact'; - var $db; - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db=$db; - } - - - /** - * Renvoie url lien vers fiche de la source du destinataire du mailing - * - * @param int $id ID - * @return string Url lien - */ - function url($id) - { - return ''.img_object('',"contact").''; - } - - /** - * This is the main function that returns the array of emails - * - * @param int $mailing_id Id of mailing. No need to use it. - * @param array $filtersarray Function - * @return int <0 if error, number of emails added if ok - */ - function add_to_target($mailing_id,$filtersarray=array()) - { - global $conf,$langs; - - $target = array(); - - // La requete doit retourner: id, email, fk_contact, name, firstname, other - $sql = "SELECT sp.rowid as id, sp.email as email, sp.rowid as fk_contact,"; - $sql.= " sp.lastname, sp.firstname as firstname, sp.civility as civility_id,"; - $sql.= " s.nom as companyname"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; - $sql.= " WHERE sp.entity IN (".getEntity('societe').")"; - $sql.= " AND sp.email <> ''"; // Note that null != '' is false - $sql.= " AND sp.no_email = 0"; - $sql.= " AND sp.statut = 1"; - //$sql.= " AND sp.poste != ''"; - $sql.= " AND sp.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".$mailing_id.")"; - if ($filtersarray[0]<>'all') $sql.= " AND sp.poste ='".$this->db->escape($filtersarray[0])."'"; - $sql.= " ORDER BY sp.lastname, sp.firstname"; - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - while ($i < $num) - { - $obj= $this->db->fetch_object($resql); - $target[] = array( - 'email' => $obj->email, - 'fk_contact' => $obj->fk_contact, - 'lastname' => $obj->lastname, - 'firstname' => $obj->firstname, - 'other' => - ($langs->transnoentities("ThirdParty").'='.$obj->companyname).';'. - ($langs->transnoentities("UserTitle").'='.($obj->civility_id?$langs->transnoentities("Civility".$obj->civility_id):'')), - 'source_url' => $this->url($obj->id), - 'source_id' => $obj->id, - 'source_type' => 'contact' - ); - $i++; - } - } - - return parent::add_to_target($mailing_id, $target); - } - - - /** - * On the main mailing area, there is a box with statistics. - * If you want to add a line in this report you must provide an - * array of SQL request that returns two field: - * One called "label", One called "nb". - * - * @return array Array with SQL requests - */ - function getSqlArrayForStats() - { - global $conf; - - $statssql=array(); - /*for ($i=0; $i<5; $i++) { - $statssql[$i] = "SELECT sp.poste as label"; - $statssql[$i].= ", count(distinct(sp.email)) as nb"; - $statssql[$i].= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $statssql[$i].= " ".MAIN_DB_PREFIX."societe as s"; - $statssql[$i].= " WHERE s.rowid = sp.fk_soc"; - $statssql[$i].= " AND sp.email != ''"; // Note that null != '' is false - $statssql[$i].= " AND (sp.poste IS NOT NULL AND sp.poste != '')"; - $statssql[$i].= " AND sp.entity IN (".getEntity('societe').")"; - $statssql[$i].= " GROUP BY label"; - $statssql[$i].= " ORDER BY nb DESC"; - $statssql[$i].= " LIMIT $i,1"; - }*/ - - return $statssql; - } - - - /** - * Return here number of distinct emails returned by your selector. - * - * @param string $sql Requete sql de comptage - * @return int - */ - function getNbOfRecipients($sql='') - { - global $conf; - - // We must report here number of contacts when absolutely no filter selected (so all contacts). - // Number with a filter are show in the combo list for each filter. - // If we want a filter "a position is defined", we must add it into formFilter - $sql = "SELECT count(distinct(sp.email)) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; - $sql.= " WHERE sp.entity IN (".getEntity('societe').")"; - $sql.= " AND sp.email != ''"; // Note that null != '' is false - $sql.= " AND sp.no_email = 0"; - $sql.= " AND sp.statut = 1"; - //$sql.= " AND sp.poste != ''"; - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients - return parent::getNbOfRecipients($sql); - } - - /** - * This is to add a form filter to provide variant of selector - * If used, the HTML select must be called "filter" - * - * @return string A html select zone - */ - function formFilter() - { - global $conf, $langs; - - $langs->load("companies"); - - $sql = "SELECT sp.poste, count(distinct(sp.email)) AS nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; - $sql.= " WHERE sp.entity IN (".getEntity('societe').")"; - $sql.= " AND sp.email != ''"; // Note that null != '' is false - $sql.= " AND sp.no_email = 0"; - $sql.= " AND sp.statut = 1"; - $sql.= " AND (sp.poste IS NOT NULL AND sp.poste != '')"; - $sql.= " GROUP BY sp.poste"; - $sql.= " ORDER BY sp.poste"; - - $resql = $this->db->query($sql); - - $s=''; - $s.=''; - return $s; - } - -} - diff --git a/htdocs/core/modules/mailings/contacts3.modules.php b/htdocs/core/modules/mailings/contacts3.modules.php deleted file mode 100644 index c16f6869668..00000000000 --- a/htdocs/core/modules/mailings/contacts3.modules.php +++ /dev/null @@ -1,250 +0,0 @@ - - * Copyright (C) 2013 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 . - * or see http://www.gnu.org/ - */ - -/** - * \file htdocs/core/modules/mailings/contacts3.modules.php - * \ingroup mailing - * \brief Provides a list of recipients for mailing module - */ - -include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; - - -/** - * Class to manage a list of personalised recipients for mailing feature - */ -class mailing_contacts3 extends MailingTargets -{ - var $name='ContactsByCompanyCategory'; - // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found - var $desc='Add contacts by company category'; - var $require_admin=0; - - var $require_module=array(); - var $picto='contact'; - var $db; - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db=$db; - } - - /** - * Renvoie url lien vers fiche de la source du destinataire du mailing - * - * @param int $id ID - * @return string Url lien - */ - function url($id) - { - return ''.img_object('',"contact").''; - } - - /** - * This is the main function that returns the array of emails - * - * @param int $mailing_id Id of mailing. No need to use it. - * @param array $filtersarray Category - * @return int <0 if error, number of emails added if ok - */ - function add_to_target($mailing_id,$filtersarray=array()) - { - global $conf,$langs; - - $target = array(); - - // La requete doit retourner: id, email, fk_contact, name, firstname, other - $sql = "SELECT sp.rowid as id, sp.email as email, sp.rowid as fk_contact,"; - $sql.= " sp.lastname, sp.firstname, sp.civility as civility_id,"; - $sql.= " s.nom as companyname"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; - if ($filtersarray[0] <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie as c"; - if ($filtersarray[0] <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie_societe as cs"; - $sql.= " WHERE sp.email <> ''"; // Note that null != '' is false - $sql.= " AND sp.no_email = 0"; - $sql.= " AND sp.statut = 1"; - $sql.= " AND sp.entity IN (".getEntity('societe').")"; - $sql.= " AND sp.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".$mailing_id.")"; - if ($filtersarray[0] <> 'all') $sql.= " AND cs.fk_categorie = c.rowid"; - if ($filtersarray[0] <> 'all') $sql.= " AND cs.fk_soc = sp.fk_soc"; - if ($filtersarray[0] <> 'all') $sql.= " AND c.label = '".$this->db->escape($filtersarray[0])."'"; - $sql.= " ORDER BY sp.lastname, sp.firstname"; - - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - - while ($i < $num) - { - $obj= $this->db->fetch_object($resql); - $target[] = array( - 'email' => $obj->email, - 'fk_contact' => $obj->fk_contact, - 'lastname' => $obj->lastname, - 'firstname' => $obj->firstname, - 'other' => - ($langs->transnoentities("ThirdParty").'='.$obj->companyname).';'. - ($langs->transnoentities("UserTitle").'='.($obj->civility_id?$langs->transnoentities("Civility".$obj->civility_id):'')), - 'source_url' => $this->url($obj->id), - 'source_id' => $obj->id, - 'source_type' => 'contact' - ); - $i++; - } - } - - return parent::add_to_target($mailing_id, $target); - } - - - /** - * On the main mailing area, there is a box with statistics. - * If you want to add a line in this report you must provide an - * array of SQL request that returns two field: - * One called "label", One called "nb". - * - * @return array Array with SQL requests - */ - function getSqlArrayForStats() - { - global $conf, $langs; - - $statssql=array(); - /*for ($i=0; $i<5; $i++) { - $statssql[$i] = "SELECT c.label, count(sp.rowid) AS nb"; - $statssql[$i].= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $statssql[$i].= " ".MAIN_DB_PREFIX."societe as s,"; - $statssql[$i].= " ".MAIN_DB_PREFIX."categorie as c,"; - $statssql[$i].= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $statssql[$i].= " WHERE s.rowid = sp.fk_soc"; - $statssql[$i].= " AND sp.email != ''"; // Note that null != '' is false - $statssql[$i].= " AND sp.entity IN (".getEntity('societe').")"; - $statssql[$i].= " AND cs.fk_categorie = c.rowid"; - $statssql[$i].= " AND cs.fk_soc = sp.fk_soc"; - $statssql[$i].= " GROUP BY c.label"; - $statssql[$i].= " ORDER BY nb DESC"; - $statssql[$i].= " LIMIT $i,1"; - }*/ - - return $statssql; - } - - - /** - * Return here number of distinct emails returned by your selector. - * - * @param string $sql Requete sql de comptage - * @return int Number of recipients - */ - function getNbOfRecipients($sql='') - { - global $conf; - - // We must report here number of contacts when absolutely no filter selected (so all contacts). - // Number with a filter are show in the combo list for each filter. - // If we want a filter "is inside at least one category", we must add it into formFilter - $sql = "SELECT count(distinct(c.email)) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc"; - $sql.= " WHERE c.entity IN (".getEntity('societe').")"; - $sql.= " AND c.email != ''"; // Note that null != '' is false - $sql.= " AND c.no_email = 0"; - $sql.= " AND c.statut = 1"; - /* - $sql = "SELECT count(distinct(sp.email)) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s,"; - $sql.= " ".MAIN_DB_PREFIX."categorie as c,"; - $sql.= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $sql.= " WHERE s.rowid = sp.fk_soc"; - $sql.= " AND sp.entity IN (".getEntity('societe').")"; - $sql.= " AND sp.email != ''"; // Note that null != '' is false - $sql.= " AND cs.fk_categorie = c.rowid"; - $sql.= " AND cs.fk_soc = sp.fk_soc"; - */ - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients - return parent::getNbOfRecipients($sql); - } - - /** - * This is to add a form filter to provide variant of selector - * If used, the HTML select must be called "filter". - * - * @return string A html select zone - */ - function formFilter() - { - global $conf, $langs; - - $langs->load("companies"); - - $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $sql.= " ".MAIN_DB_PREFIX."categorie as c,"; - $sql.= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $sql.= " WHERE sp.email != ''"; // Note that null != '' is false - $sql.= " AND sp.no_email = 0"; - $sql.= " AND sp.statut = 1"; - $sql.= " AND sp.entity IN (".getEntity('societe').")"; - $sql.= " AND cs.fk_categorie = c.rowid"; - $sql.= " AND cs.fk_soc = sp.fk_soc"; - $sql.= " GROUP BY c.label"; - $sql.= " ORDER BY c.label"; - - $resql = $this->db->query($sql); - - $s=''; - $s.=''; - - return $s; - } - -} - diff --git a/htdocs/core/modules/mailings/contacts4.modules.php b/htdocs/core/modules/mailings/contacts4.modules.php deleted file mode 100644 index f4c67874bfb..00000000000 --- a/htdocs/core/modules/mailings/contacts4.modules.php +++ /dev/null @@ -1,252 +0,0 @@ - - * Copyright (C) 2013 Florian HENRY - * - * 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 . - * or see http://www.gnu.org/ - */ - -/** - * \file htdocs/core/modules/mailings/contacts4.modules.php - * \ingroup mailing - * \brief Provides a list of recipients for mailing module - */ - -include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; - - -/** - * Class to manage a list of personalised recipients for mailing feature - */ -class mailing_contacts4 extends MailingTargets -{ - var $name='ContactsByCategory'; - // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found - var $desc='Add contacts by category'; - var $require_admin=0; - - var $require_module=array(); - var $picto='contact'; - var $db; - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db=$db; - } - - /** - * Renvoie url lien vers fiche de la source du destinataire du mailing - * - * @param int $id ID - * @return string Url lien - */ - function url($id) - { - return ''.img_object('',"contact").''; - } - - /** - * This is the main function that returns the array of emails - * - * @param int $mailing_id Id of mailing. No need to use it. - * @param array $filtersarray Category - * @return int <0 if error, number of emails added if ok - */ - function add_to_target($mailing_id,$filtersarray=array()) - { - global $conf,$langs; - - $target = array(); - - // La requete doit retourner: id, email, fk_contact, name, firstname, other - $sql = "SELECT sp.rowid as id, sp.email as email, sp.rowid as fk_contact,"; - $sql.= " sp.lastname, sp.firstname, sp.civility as civility_id,"; - $sql.= " s.nom as companyname"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; - if ($filtersarray[0] <> 'all')$sql.= " INNER JOIN ".MAIN_DB_PREFIX."categorie_contact as cs ON cs.fk_socpeople=sp.rowid"; - if ($filtersarray[0] <> 'all') $sql.= " INNER JOIN ".MAIN_DB_PREFIX."categorie as c ON cs.fk_categorie = c.rowid"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; - $sql.= " WHERE sp.email != ''"; // Note that null != '' is false - $sql.= " AND sp.no_email = 0"; - $sql.= " AND sp.statut = 1"; - $sql.= " AND sp.entity IN (".getEntity('societe').")"; - if ($filtersarray[0] <> 'all') $sql.= " AND c.label = '".$this->db->escape($filtersarray[0])."'"; - $sql.= " ORDER BY sp.lastname, sp.firstname"; - - dol_syslog(get_class($this).':: add_to_target',LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - - while ($i < $num) - { - $obj= $this->db->fetch_object($resql); - $target[] = array( - 'email' => $obj->email, - 'fk_contact' => $obj->fk_contact, - 'lastname' => $obj->lastname, - 'firstname' => $obj->firstname, - 'other' => - ($langs->transnoentities("ThirdParty").'='.$obj->companyname).';'. - ($langs->transnoentities("UserTitle").'='.($obj->civility_id?$langs->transnoentities("Civility".$obj->civility_id):'')), - 'source_url' => $this->url($obj->id), - 'source_id' => $obj->id, - 'source_type' => 'contact' - ); - $i++; - } - }else { - $this->error=$this->db->lasterrno(); - return -1; - } - - return parent::add_to_target($mailing_id, $target); - } - - - /** - * On the main mailing area, there is a box with statistics. - * If you want to add a line in this report you must provide an - * array of SQL request that returns two field: - * One called "label", One called "nb". - * - * @return array Array with SQL requests - */ - function getSqlArrayForStats() - { - global $conf, $langs; - - $statssql=array(); - /*for ($i=0; $i<5; $i++) { - $statssql[$i] = "SELECT c.label, count(sp.rowid) AS nb"; - $statssql[$i].= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $statssql[$i].= " ".MAIN_DB_PREFIX."societe as s,"; - $statssql[$i].= " ".MAIN_DB_PREFIX."categorie as c,"; - $statssql[$i].= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $statssql[$i].= " WHERE s.rowid = sp.fk_soc"; - $statssql[$i].= " AND sp.email != ''"; // Note that null != '' is false - $statssql[$i].= " AND sp.entity IN (".getEntity('societe').")"; - $statssql[$i].= " AND cs.fk_categorie = c.rowid"; - $statssql[$i].= " AND cs.fk_soc = sp.fk_soc"; - $statssql[$i].= " GROUP BY c.label"; - $statssql[$i].= " ORDER BY nb DESC"; - $statssql[$i].= " LIMIT $i,1"; - }*/ - - return $statssql; - } - - - /** - * Return here number of distinct emails returned by your selector. - * - * @param string $sql Requete sql de comptage - * @return int Number of recipients - */ - function getNbOfRecipients($sql='') - { - global $conf; - - // We must report here number of contacts when absolutely no filter selected (so all contacts). - // Number with a filter are show in the combo list for each filter. - // If we want a filter "is inside at least one category", we must add it into formFilter - $sql = "SELECT count(distinct(c.email)) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c"; - $sql.= " WHERE c.entity IN (".getEntity('societe').")"; - $sql.= " AND c.email != ''"; // Note that null != '' is false - $sql.= " AND c.no_email = 0"; - $sql.= " AND c.statut = 1"; - /* - $sql = "SELECT count(distinct(sp.email)) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s,"; - $sql.= " ".MAIN_DB_PREFIX."categorie as c,"; - $sql.= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $sql.= " WHERE s.rowid = sp.fk_soc"; - $sql.= " AND sp.entity IN (".getEntity('societe').")"; - $sql.= " AND sp.email != ''"; // Note that null != '' is false - $sql.= " AND cs.fk_categorie = c.rowid"; - $sql.= " AND cs.fk_soc = sp.fk_soc"; - */ - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients - return parent::getNbOfRecipients($sql); - } - - /** - * This is to add a form filter to provide variant of selector - * If used, the HTML select must be called "filter". - * - * @return string A html select zone - */ - function formFilter() - { - global $conf, $langs; - - $langs->load("companies"); - - $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; - $sql.= " INNER JOIN ".MAIN_DB_PREFIX."categorie_contact as cs ON cs.fk_socpeople=sp.rowid"; - $sql.= " INNER JOIN ".MAIN_DB_PREFIX."categorie as c ON cs.fk_categorie = c.rowid"; - $sql.= " WHERE sp.email != ''"; // Note that null != '' is false - $sql.= " AND sp.no_email = 0"; - $sql.= " AND sp.statut = 1"; - $sql.= " AND sp.entity IN (".getEntity('societe').")"; - $sql.= " GROUP BY c.label"; - $sql.= " ORDER BY c.label"; - - $resql = $this->db->query($sql); - - dol_syslog(get_class($this).':: formFilter',LOG_DEBUG); - if ($resql) { - $s=''; - $s.=''; - return $s; - } - else { - $this->error=$this->db->lasterrno(); - return -1; - } - - } - -} - diff --git a/htdocs/core/modules/mailings/fraise.modules.php b/htdocs/core/modules/mailings/fraise.modules.php index 05d9e525652..e0226017ede 100644 --- a/htdocs/core/modules/mailings/fraise.modules.php +++ b/htdocs/core/modules/mailings/fraise.modules.php @@ -34,7 +34,7 @@ class mailing_fraise extends MailingTargets { var $name='FundationMembers'; // Identifiant du module mailing // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found - var $desc='Foundation members with emails (by status)'; + var $desc='Foundation members with emails'; // Set to 1 if selector is available for admin users only var $require_admin=0; @@ -108,10 +108,14 @@ class mailing_fraise extends MailingTargets { global $conf, $langs; $langs->load("members"); + $langs->load("categories"); + $langs->load("companies"); $form=new Form($this->db); $s=''; + + // Status $s.=$langs->trans("Status").': '; $s.=' '; $s.=$langs->trans("Type").': '; - $s.=''; $sql = "SELECT rowid, libelle, statut"; $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type"; $sql.= " WHERE entity = ".$conf->entity; @@ -150,6 +154,47 @@ class mailing_fraise extends MailingTargets } $s.=''; + + $s.=' '; + + $s.=$langs->trans("Category").': '; + $s.=''; + + $s.='
'; $s.=$langs->trans("DateEndSubscription").':  '; $s.=$langs->trans("After").' > '.$form->select_date(-1,'subscriptionafter',0,0,1,'fraise',1,0,1,0); @@ -200,18 +245,29 @@ class mailing_fraise extends MailingTargets $sql = "SELECT a.rowid as id, a.email as email, null as fk_contact, "; $sql.= " a.lastname, a.firstname,"; $sql.= " a.datefin, a.civility as civility_id, a.login, a.societe"; // Other fields - $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a, ".MAIN_DB_PREFIX."adherent_type as ta"; + $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; + if ($_POST['filter_category']) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_member as cm ON cm.fk_member = a.rowid"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = cm.fk_categorie"; + } + $sql.= " , ".MAIN_DB_PREFIX."adherent_type as ta"; $sql.= " WHERE a.email <> ''"; // Note that null != '' is false $sql.= " AND a.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".$mailing_id.")"; + // Filter on status if (isset($_POST["filter"]) && $_POST["filter"] == '-1') $sql.= " AND a.statut=-1"; if (isset($_POST["filter"]) && $_POST["filter"] == '1a') $sql.= " AND a.statut=1 AND a.datefin >= '".$this->db->idate($now)."'"; if (isset($_POST["filter"]) && $_POST["filter"] == '1b') $sql.= " AND a.statut=1 AND (a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."')"; if (isset($_POST["filter"]) && $_POST["filter"] == '0') $sql.= " AND a.statut=0"; + // Filter on date if ($dateendsubscriptionafter > 0) $sql.=" AND datefin > '".$this->db->idate($dateendsubscriptionafter)."'"; if ($dateendsubscriptionbefore > 0) $sql.=" AND datefin < '".$this->db->idate($dateendsubscriptionbefore)."'"; $sql.= " AND a.fk_adherent_type = ta.rowid"; - if ($_POST['filtertype']) $sql.= " AND ta.rowid='".$_POST['filtertype']."'"; - $sql.= " ORDER BY a.email"; + // Filter on type + if ($_POST['filter_type']) $sql.= " AND ta.rowid='".$_POST['filter_type']."'"; + // Filter on category + if ($_POST['filter_category']) $sql.= " AND c.rowid='".$_POST['filter_category']."'"; + $sql.= " ORDER BY a.email"; //print $sql; // Add targets into table diff --git a/htdocs/core/modules/mailings/framboise.modules.php b/htdocs/core/modules/mailings/framboise.modules.php deleted file mode 100644 index 82f7e51e0ef..00000000000 --- a/htdocs/core/modules/mailings/framboise.modules.php +++ /dev/null @@ -1,234 +0,0 @@ - - * Copyright (C) 2005-2009 Regis Houssin - * - * This file is an example to follow to add your own email selector inside - * the Dolibarr email tool. - * Follow instructions given in README file to know what to change to build - * your own emailing list selector. - * Code that need to be changed in this file are marked by "CHANGE THIS" tag. - */ - -/** - * \file htdocs/core/modules/mailings/framboise.modules.php - * \ingroup mailing - * \brief Example file to provide a list of recipients for mailing module - */ - -include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; - - -/** - * Class to manage a list of personalised recipients for mailing feature - */ -class mailing_framboise extends MailingTargets -{ - var $name='MembersCategories'; - // This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found - var $desc="Foundation members with emails (by categories)"; - // Set to 1 if selector is available for admin users only - var $require_admin=0; - - var $require_module=array("adherent","categorie"); - var $picto='user'; - var $db; - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - function __construct($db) - { - $this->db=$db; - } - - - /** - * This is the main function that returns the array of emails. - * - * @param int $mailing_id Id of mailing. No need to use it. - * @param array $filtersarray If you used the formFilter function. Empty otherwise. - * @return int <0 if error, number of emails added if ok - */ - function add_to_target($mailing_id,$filtersarray=array()) - { - global $conf, $langs; - $langs->load("members"); - $langs->load("companies"); - - $cibles = array(); - - // Select the members from category - $sql = "SELECT a.rowid as id, a.email as email, a.lastname, null as fk_contact, a.firstname,"; - $sql.= " a.datefin, a.civility as civility_id, a.login, a.societe,"; // Other fields - if ($_POST['filter']) $sql.= " c.label"; - else $sql.=" null as label"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; - if ($_POST['filter']) - { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_member as cm ON cm.fk_member = a.rowid"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = cm.fk_categorie"; - } - $sql.= " WHERE a.email != ''"; - $sql.= " AND a.entity = ".$conf->entity; - if ($_POST['filter']) $sql.= " AND c.rowid='".$_POST['filter']."'"; - $sql.= " ORDER BY a.email"; - - // Stocke destinataires dans cibles - $result=$this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - $j = 0; - - dol_syslog(get_class($this)."::add_to_target mailing ".$num." targets found"); - - $old = ''; - while ($i < $num) - { - $obj = $this->db->fetch_object($result); - if ($old <> $obj->email) - { - $cibles[$j] = array( - 'email' => $obj->email, - 'fk_contact' => $obj->fk_contact, - 'lastname' => $obj->lastname, - 'firstname' => $obj->firstname, - 'other' => - ($langs->transnoentities("Login").'='.$obj->login).';'. - ($langs->transnoentities("UserTitle").'='.($obj->civility_id?$langs->transnoentities("Civility".$obj->civility_id):'')).';'. - ($langs->transnoentities("DateEnd").'='.dol_print_date($this->db->jdate($obj->datefin),'day')).';'. - ($langs->transnoentities("Company").'='.$obj->societe).';'. - ($obj->label?$langs->transnoentities("Category").'='.$obj->label:''), - 'source_url' => $this->url($obj->id), - 'source_id' => $obj->id, - 'source_type' => 'member' - ); - $old = $obj->email; - $j++; - } - - $i++; - } - } - else - { - dol_syslog($this->db->error()); - $this->error=$this->db->error(); - return -1; - } - - return parent::add_to_target($mailing_id, $cibles); - } - - - /** - * On the main mailing area, there is a box with statistics. - * If you want to add a line in this report you must provide an - * array of SQL request that returns two field: - * One called "label", One called "nb". - * - * @return array Array with SQL requests - */ - function getSqlArrayForStats() - { - // CHANGE THIS: Optionnal - - //var $statssql=array(); - //$this->statssql[0]="SELECT field1 as label, count(distinct(email)) as nb FROM mytable WHERE email IS NOT NULL"; - return array(); - } - - - /** - * Return here number of distinct emails returned by your selector. - * For example if this selector is used to extract 500 different - * emails from a text file, this function must return 500. - * - * @param string $sql Requete sql de comptage - * @return int Nb of recipients - */ - function getNbOfRecipients($sql='') - { - global $conf; - - $sql = "SELECT count(distinct(a.email)) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a"; - $sql.= " WHERE a.email != ''"; - $sql.= " AND a.entity = ".$conf->entity; - - // La requete doit retourner un champ "nb" pour etre comprise - // par parent::getNbOfRecipients - return parent::getNbOfRecipients($sql); - } - - /** - * This is to add a form filter to provide variant of selector - * If used, the HTML select must be called "filter" - * - * @return string A html select zone - */ - function formFilter() - { - global $conf, $langs; - - $langs->load("companies"); - $langs->load("categories"); - - $s=''; - $s.=''; - return $s; - - } - - - /** - * Can include an URL link on each record provided by selector shown on target page. - * - * @param int $id Id of member - * @return string Url link - */ - function url($id) - { - return ''.img_object('',"user").''; - } - -} - diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index 2c032ffa7c0..80162f24b5c 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -4023,6 +4023,10 @@ function migrate_delete_old_files($db,$langs,$conf) DOL_DOCUMENT_ROOT.'/core/menus/standard/auguria_frontoffice.php', DOL_DOCUMENT_ROOT.'/core/menus/standard/eldy_backoffice.php', DOL_DOCUMENT_ROOT.'/core/menus/standard/eldy_frontoffice.php', + DOL_DOCUMENT_ROOT.'/core/modules/mailings/contacts2.modules.php', + DOL_DOCUMENT_ROOT.'/core/modules/mailings/contacts3.modules.php', + DOL_DOCUMENT_ROOT.'/core/modules/mailings/contacts4.modules.php', + DOL_DOCUMENT_ROOT.'/core/modules/mailings/framboise.modules.php', DOL_DOCUMENT_ROOT.'/core/modules/mailings/dolibarr_services_expired.modules.php', DOL_DOCUMENT_ROOT.'/core/modules/mailings/peche.modules.php', DOL_DOCUMENT_ROOT.'/core/modules/mailings/poire.modules.php', @@ -4036,6 +4040,7 @@ function migrate_delete_old_files($db,$langs,$conf) DOL_DOCUMENT_ROOT.'/product/class/api_product.class.php', DOL_DOCUMENT_ROOT.'/societe/class/api_contact.class.php', DOL_DOCUMENT_ROOT.'/societe/class/api_thirdparty.class.php' + ); foreach ($filetodeletearray as $filetodelete) diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index bd7d7983191..a7e7c67ae9c 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -50,6 +50,7 @@ Lastname=Last name Firstname=First name PostOrFunction=Job position UserTitle=Title +NatureOfThirdParty=Nature of Third party Address=Address State=State/Province StateShort=State From a9e7f8b9e6b2b4a7e44af4c71e13f620fd136ef7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 25 Aug 2017 21:27:19 +0200 Subject: [PATCH 151/174] Fix trans --- htdocs/core/modules/mailings/contacts1.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 51cca978ca6..8aae15b9cc8 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -185,7 +185,7 @@ class mailing_contacts1 extends MailingTargets } else { - $s.=''; + $s.=''; } } else dol_print_error($this->db); From 3e7ed752ea2acc56efc439a0bd562ac9efe7720b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 11:54:53 +0200 Subject: [PATCH 152/174] Add changelog --- ChangeLog | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ChangeLog b/ChangeLog index ad00051939c..785e338fe09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,36 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 5.0.5 compared to 5.0.4 ***** +FIX: #7075 : bad path for document +FIX: #7156 +FIX: #7173 +FIX: #7224 +FIX: #7226 +FIX: #7239 +FIX: add supplierproposaldet without price (new product) +FIX: amount overlap other amount when a pagebreak is done due to an image at the bottom of page. +FIX: Bad tax calculation with expense report +FIX: Best buy price calculation +FIX: Buying prices must always be in positive value. +FIX: calculate correct remain to pay for planned bank transactions +FIX: delete linked element on facture rec +FIX: edit sociale was emptying label +FIX: Error when updating thirdparty not returned +FIX: holidays with postgresql like on rowid integer +FIX: id of user not saved when making a payment of expense report +FIX: invoice page list +FIX: invoice situation VAT total rounding into PDF crabe +FIX: PgSQL compatibility. +FIX: remove order rights on invoice page +FIX: status were wrong on product referent list +FIX: supplier id was not passed to hooks +FIX: Support of vat code when using price per customer +FIX: User id correction on holiday request +FIX: value of user id filled to 0 in llx_bank_url when recording an expense report. +FIX: we have to check if contact doesn't already exist on add_contact() function +FIX: We should be able to insert data with value '0' into const + ***** ChangeLog for 5.0.4 compared to 5.0.3 ***** FIX: #5640 Prices of a predefined product/service were incorrect under certain circumstances FIX: #6541 since 4.0.4 to 5.0.0 autofill zip/town not working From f2a437fa891c1e876faa4b82882d15f1aadd9e85 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 15:22:13 +0200 Subject: [PATCH 153/174] Enhance modulebuilder --- htdocs/admin/fichinter.php | 1 - htdocs/admin/limits.php | 19 +++--- htdocs/core/actions_setmoduleoptions.inc.php | 34 +++++++++- htdocs/core/lib/files.lib.php | 12 +++- htdocs/langs/en_US/cron.lang | 2 +- htdocs/langs/en_US/modulebuilder.lang | 4 +- htdocs/modulebuilder/index.php | 65 ++++++++++++------- htdocs/modulebuilder/template/admin/about.php | 7 +- htdocs/modulebuilder/template/admin/setup.php | 57 +++++++++++++++- .../core/modules/modMyModule.class.php | 9 +-- .../template/langs/en_US/mymodule.lang | 5 ++ 11 files changed, 159 insertions(+), 56 deletions(-) diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index 751cbce81e9..62533ced467 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -495,7 +495,6 @@ print "
"; /* * Other options - * */ print load_fiche_titre($langs->trans("OtherOptions"),'',''); diff --git a/htdocs/admin/limits.php b/htdocs/admin/limits.php index 1d4b5cee8d4..36b0d4d0df1 100644 --- a/htdocs/admin/limits.php +++ b/htdocs/admin/limits.php @@ -101,25 +101,24 @@ if ($action == 'edit') print ''; clearstatcache(); - $var=true; print ''; print ''; - + print ''; - + print ''; - + print ''; - + print ''; @@ -135,25 +134,23 @@ if ($action == 'edit') } else { - $var=true; - print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_UNIT"),$langs->trans("ParameterActiveForNextInputOnly")); print '
'; print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_TOT"),$langs->trans("ParameterActiveForNextInputOnly")); print '
'.$langs->trans("MAIN_MAX_DECIMALS_SHOWN").'
'; print $form->textwithpicto($langs->trans("MAIN_ROUNDING_RULE_TOT"),$langs->trans("ParameterActiveForNextInputOnly")); print '
'; print ''; - + print ''; - + print ''; - + print ''; - + print ''; diff --git a/htdocs/core/actions_setmoduleoptions.inc.php b/htdocs/core/actions_setmoduleoptions.inc.php index b8ae96cb920..eadce1dc74c 100644 --- a/htdocs/core/actions_setmoduleoptions.inc.php +++ b/htdocs/core/actions_setmoduleoptions.inc.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2014-2017 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 @@ -17,15 +17,43 @@ */ /** - * \file htdocs/core/actions_setnotes.inc.php + * \file htdocs/core/actions_setmoduleoptions.inc.php * \brief Code for actions on setting notes of object page */ // $action must be defined -// $_FILES may be defined +// $arrayofparameters must be set for action 'update' +// $nomessageinupdate can be set to 1 // $nomessageinsetmoduleoptions can be set to 1 +if ($action == 'update' && is_array($arrayofparameters)) +{ + $db->begin(); + + $ok=True; + foreach($arrayofparameters as $key => $val) + { + $result=dolibarr_set_const($db,$key,GETPOST($key, 'alpha'),'chaine',0,'',$conf->entity); + if ($result < 0) + { + $ok=False; + break; + } + } + + if (! $error) + { + $db->commit(); + if (empty($nomessageinupdate)) setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + if (empty($nomessageinupdate)) setEventMessages($langs->trans("SetupNotSaved"), null, 'errors'); + } +} + // Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) if ($action == 'setModuleOptions') { diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 3fe6d5887f4..8643e951fd4 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -1929,7 +1929,7 @@ function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta function dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser='', $refname='', $mode='read') { global $user, $conf, $db; - global $dolibarr_main_data_root; + global $dolibarr_main_data_root, $dolibarr_main_document_root_alt; if (! is_object($fuser)) $fuser=$user; @@ -1965,6 +1965,16 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $accessallowed=($user->admin && basename($original_file) == $original_file && preg_match('/^dolibarr.*\.log$/', basename($original_file))); $original_file=$dolibarr_main_data_root.'/'.$original_file; } + // Wrapping for *.zip files, like when used with url http://.../document.php?modulepart=packages&file=module_myfile.zip + elseif ($modulepart == 'packages' && !empty($dolibarr_main_data_root)) + { + // Dir for custom dirs + $tmp=explode(',', $dolibarr_main_document_root_alt); + $dirins = $tmp[0]; + + $accessallowed=($user->admin && preg_match('/^module_.*\.zip$/', basename($original_file))); + $original_file=$dirins.'/'.$original_file; + } // Wrapping for some images elseif (($modulepart == 'mycompany' || $modulepart == 'companylogo') && !empty($conf->mycompany->dir_output)) { diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang index 0113b2669c5..7f3385bef12 100644 --- a/htdocs/langs/en_US/cron.lang +++ b/htdocs/langs/en_US/cron.lang @@ -55,7 +55,7 @@ CronSaveSucess=Save successfully CronNote=Comment CronFieldMandatory=Fields %s is mandatory CronErrEndDateStartDt=End date cannot be before start date -StatusAtInstall=Status at installation +StatusAtInstall=Status at module installation CronStatusActiveBtn=Enable CronStatusInactiveBtn=Disable CronTaskInactive=This job is disabled diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 7f986e036c1..034deb7c800 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -58,4 +58,6 @@ SqlFileKey=Sql file for keys AnObjectAlreadyExistWithThisNameAndDiffCase=An object already exists with this name and a different case UseAsciiDocFormat=You can use Markdown format, but it is recommanded to use Asciidoc format (Comparison between .md and .asciidoc: http://asciidoctor.org/docs/user-manual/#compared-to-markdown) IsAMeasure=Is a measure -DirScanned=Directory scanned \ No newline at end of file +DirScanned=Directory scanned +NoTrigger=No trigger +NoWidget=No widget \ No newline at end of file diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 4ef05cb6e2b..d0da95b6947 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -149,7 +149,7 @@ if ($dirins && $action == 'initmodule' && $modulename) 'my module'=>$modulename, 'Mon module'=>$modulename, 'mon module'=>$modulename, - 'htdocs/modulebuilder/template/'=>strtolower($modulename), + 'htdocs/modulebuilder/template'=>strtolower($modulename), '---Put here your own copyright and developer email---'=>dol_print_date($now,'%Y').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':'') ); @@ -508,11 +508,11 @@ if ($dirins && $action == 'generatepackage') $FILENAMEZIP="module_".$modulelowercase.'-'.$arrayversion[0].'.'.$arrayversion[1].($arrayversion[2]?".".$arrayversion[2]:"").".zip"; $dirofmodule = dol_buildpath($modulelowercase, 0).'/bin'; - $outputfile = $dirofmodule.'/'.$FILENAMEZIP; + $outputfilezip = $dirofmodule.'/'.$FILENAMEZIP; if ($dirofmodule) { if (! dol_is_dir($dirofmodule)) dol_mkdir($dirofmodule); - $result = dol_compress_dir($dir, $outputfile, 'zip'); + $result = dol_compress_dir($dir, $outputfilezip, 'zip'); } else { @@ -521,13 +521,13 @@ if ($dirins && $action == 'generatepackage') if ($result > 0) { - setEventMessages($langs->trans("ZipFileGeneratedInto", $outputfile), null); + setEventMessages($langs->trans("ZipFileGeneratedInto", $outputfilezip), null); } else { $error++; $langs->load("errors"); - setEventMessages($langs->trans("ErrorFailToGenerateFile", $outputfile), null, 'errors'); + setEventMessages($langs->trans("ErrorFailToGenerateFile", $outputfilezip), null, 'errors'); } } else @@ -576,7 +576,7 @@ if ($dirins && $action == 'generatedoc') $FILENAMEDOC=$modulelowercase.'.html'; $dirofmodule = dol_buildpath($modulelowercase, 0).'/doc'; - $outputfile = $dirofmodule.'/'.$FILENAMEDOC; + $outputfiledoc = $dirofmodule.'/'.$FILENAMEDOC; if ($dirofmodule) { if (! dol_is_dir($dirofmodule)) dol_mkdir($dirofmodule); @@ -591,13 +591,13 @@ if ($dirins && $action == 'generatedoc') if ($result > 0) { - setEventMessages($langs->trans("DocFileGeneratedInto", $outputfile), null); + setEventMessages($langs->trans("DocFileGeneratedInto", $outputfiledoc), null); } else { $error++; $langs->load("errors"); - setEventMessages($langs->trans("ErrorFailToGenerateFile", $outputfile), null, 'errors'); + setEventMessages($langs->trans("ErrorFailToGenerateFile", $outputfiledoc), null, 'errors'); } } else @@ -1578,14 +1578,21 @@ elseif (! empty($module)) if ($action != 'editfile' || empty($file)) { - foreach ($triggers as $trigger) - { - $pathtofile = $trigger['relpath']; + if (! empty($triggers)) + { + foreach ($triggers as $trigger) + { + $pathtofile = $trigger['relpath']; - print ' '.$langs->trans("TriggersFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; - } + print ' '.$langs->trans("TriggersFile").' : '.$pathtofile.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + } + } + else + { + print $langs->trans("NoTrigger"); + } } else { @@ -1622,13 +1629,20 @@ elseif (! empty($module)) if ($action != 'editfile' || empty($file)) { - foreach ($widgets as $widget) - { - $pathtofile = $widget['relpath']; + if (! empty($widget)) + { + foreach ($widgets as $widget) + { + $pathtofile = $widget['relpath']; - print ' '.$langs->trans("WidgetFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '
'; + print ' '.$langs->trans("WidgetFile").' : '.$pathtofile.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + } + } + else + { + print $langs->trans("NoWidget"); } } else @@ -1811,7 +1825,7 @@ elseif (! empty($module)) if (count($arrayversion)) { $FILENAMEZIP="module_".$modulelowercase.'-'.$arrayversion[0].'.'.$arrayversion[1].($arrayversion[2]?".".$arrayversion[2]:"").".zip"; - $outputfile = dol_buildpath($modulelowercase, 0).'/bin/'.$FILENAMEZIP; + $outputfilezip = dol_buildpath($modulelowercase, 0).'/bin/'.$FILENAMEZIP; $FILENAMEDOC=$modulelowercase.'.html'; $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC; @@ -1820,10 +1834,11 @@ elseif (! empty($module)) print '
'; print ' '. $langs->trans("PathToModulePackage") . ' : '; - if (! dol_is_file($outputfile)) print ''.$langs->trans("FileNotYetGenerated").''; + if (! dol_is_file($outputfilezip)) print ''.$langs->trans("FileNotYetGenerated").''; else { - print ''.$outputfile.''; - print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfile), 'dayhour').')'; + $relativepath = $modulelowercase.'/bin/'.$FILENAMEZIP; + print ''.$outputfilezip.''; + print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfilezip), 'dayhour').')'; } print '
'; diff --git a/htdocs/modulebuilder/template/admin/about.php b/htdocs/modulebuilder/template/admin/about.php index ac21d2810e0..d492f72da79 100644 --- a/htdocs/modulebuilder/template/admin/about.php +++ b/htdocs/modulebuilder/template/admin/about.php @@ -81,16 +81,11 @@ $head = mymoduleAdminPrepareHead(); dol_fiche_head( $head, 'about', - $langs->trans("MyModuleName"), + $langs->trans("ModuleMyModuleName"), 0, 'mymodule@mymodule' ); -// About page goes here -echo $langs->trans("MyModuleAboutPage"); - -echo '
'; - dol_include_once('/mymodule/core/modules/modMyModule.class.php'); $tmpmodule = new modMyModule($db); print $tmpmodule->getDescLong(); diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index d32bd0a1723..46b608efa8e 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -42,8 +42,9 @@ global $langs, $user; require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php"; require_once '../lib/mymodule.lib.php'; //require_once "../class/myclass.class.php"; + // Translations -$langs->load("mymodule@mymodule"); +$langs->loadLangs(array("admin", "mymodule@mymodule")); // Access control if (! $user->admin) accessforbidden(); @@ -51,6 +52,8 @@ if (! $user->admin) accessforbidden(); // Parameters $action = GETPOST('action', 'alpha'); +$arrayofparameters=array('MYMODULE_MYPARAM1'=>'1', 'MYMODULE_MYPARAM2'=>'2'); + /* * Actions @@ -76,14 +79,62 @@ $head = mymoduleAdminPrepareHead(); dol_fiche_head( $head, 'settings', - $langs->trans("Module500000Name"), - 0, + $langs->trans("ModuleMyModuleName"), + -1, "mymodule@mymodule" ); // Setup page goes here echo $langs->trans("MyModuleSetupPage"); + +if ($action == 'edit') +{ + print '
'; + print ''; + print ''; + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_UNIT"),$langs->trans("ParameterActiveForNextInputOnly")); print ''.$conf->global->MAIN_MAX_DECIMALS_UNIT.'
'; print $form->textwithpicto($langs->trans("MAIN_MAX_DECIMALS_TOT"),$langs->trans("ParameterActiveForNextInputOnly")); print ''.$conf->global->MAIN_MAX_DECIMALS_TOT.'
'.$langs->trans("MAIN_MAX_DECIMALS_SHOWN").''.$conf->global->MAIN_MAX_DECIMALS_SHOWN.'
'; print $form->textwithpicto($langs->trans("MAIN_ROUNDING_RULE_TOT"),$langs->trans("ParameterActiveForNextInputOnly")); print ''.$conf->global->MAIN_ROUNDING_RULE_TOT.'
'; + print ''; + + foreach($arrayofparameters as $key => $val) + { + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print $form->textwithpicto($langs->trans($key),$langs->trans($key.'Tooltip')); + print '
'; + + print '
'; + print ''; + print '
'; + + print ''; + print '
'; +} +else +{ + print ''; + print ''; + + foreach($arrayofparameters as $key => $val) + { + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print $form->textwithpicto($langs->trans($key),$langs->trans($key.'Tooltip')); + print '' . $conf->global->$key . '
'; + + print '
'; + print ''.$langs->trans("Modify").''; + print '
'; +} + + // Page end dol_fiche_end(); + llxFooter(); +$db->close(); diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index a26f7148142..77f860ba92c 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -311,10 +311,11 @@ class modMyModule extends DolibarrModules include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); - //$result1=$extrafields->addExtraField('myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty'); - //$result2=$extrafields->addExtraField('myattr2', "New Attr 2 label", 'string', 1, 10, 'project'); - //$param=array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')); - //$result3=$extrafields->addExtraField('myattr3', "New Attr 3 label", 'select', 1, 3, 'thirdparty', 0, 1, '', $param, 1); + $result1=$extrafields->addExtraField('myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty'); + //$result2=$extrafields->addExtraField('myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project'); + //$result3=$extrafields->addExtraField('myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account'); + //$result4=$extrafields->addExtraField('myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1); + //$result5=$extrafields->addExtraField('myattr5', "New Attr 5 label", 'text', 1, 10, 'user'); $sql = array(); diff --git a/htdocs/modulebuilder/template/langs/en_US/mymodule.lang b/htdocs/modulebuilder/template/langs/en_US/mymodule.lang index e09e396dce0..a37d8e0c241 100644 --- a/htdocs/modulebuilder/template/langs/en_US/mymodule.lang +++ b/htdocs/modulebuilder/template/langs/en_US/mymodule.lang @@ -28,6 +28,11 @@ ModuleMyModuleDesc = My module description MyModuleSetup = My module setup Settings = Settings MyModuleSetupPage = My module setup page +MYMODULE_MYPARAM1 = My param 1 +MYMODULE_MYPARAM1Tooltip = My param 1 tooltip +MYMODULE_MYPARAM2=My param 2 +MYMODULE_MYPARAM2Tooltip=My param 2 tooltip + # # About page From 632119a5c509dc0f055fa1fd42b0fc1cdcc18ddf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 15:46:18 +0200 Subject: [PATCH 154/174] Show if module add dictionary data --- htdocs/admin/modulehelp.php | 53 +++++++++++++++++++++-------------- htdocs/langs/en_US/admin.lang | 3 +- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 830b323545f..2110a814b10 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -35,7 +35,8 @@ if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is n require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $langs->load("errors"); $langs->load("admin"); @@ -371,22 +372,7 @@ if ($mode == 'feature') if (count($objMod->requiredby)) $text.=join(',', $objMod->requiredby); else $text.=$langs->trans("None"); - $text.='


'; - - $text.=''.$langs->trans("AddRemoveTabs").': '; - if (isset($objMod->tabs) && is_array($objMod->tabs) && count($objMod->tabs)) - { - $i=0; - foreach($objMod->tabs as $val) - { - $tmp=explode(':',$val,3); - $text.=($i?', ':'').$tmp[0].':'.$tmp[1]; - $i++; - } - } - else $text.=$langs->trans("No"); - - $text.='
'; + $text.='

'; $text.='
'.$langs->trans("AddDictionaries").': '; if (isset($objMod->dictionaries) && isset($objMod->dictionaries['tablib']) && is_array($objMod->dictionaries['tablib']) && count($objMod->dictionaries['tablib'])) @@ -402,13 +388,24 @@ if ($mode == 'feature') $text.='
'; - $text.='
'.$langs->trans("AddBoxes").': '; - if (isset($objMod->boxes) && is_array($objMod->boxes) && count($objMod->boxes)) + $text.='
'.$langs->trans("AddData").': '; + $filedata = dol_buildpath($moduledir.'/sql/data.sql'); + if (dol_is_file($filedata)) + { + $text.=$langs->trans("Yes").' ('.$moduledir.'/sql/data.sql'.')'; + } + else $text.=$langs->trans("No"); + + $text.='
'; + + $text.='
'.$langs->trans("AddRemoveTabs").': '; + if (isset($objMod->tabs) && is_array($objMod->tabs) && count($objMod->tabs)) { $i=0; - foreach($objMod->boxes as $val) + foreach($objMod->tabs as $val) { - $text.=($i?', ':'').($val['file']?$val['file']:$val[0]); + $tmp=explode(':',$val,3); + $text.=($i?', ':'').$tmp[0].':'.$tmp[1]; $i++; } } @@ -474,6 +471,20 @@ if ($mode == 'feature') $text.='
'; + $text.='
'.$langs->trans("AddBoxes").': '; + if (isset($objMod->boxes) && is_array($objMod->boxes) && count($objMod->boxes)) + { + $i=0; + foreach($objMod->boxes as $val) + { + $text.=($i?', ':'').($val['file']?$val['file']:$val[0]); + $i++; + } + } + else $text.=$langs->trans("No"); + + $text.='
'; + $text.='
'.$langs->trans("AddHooks").': '; if (isset($objMod->module_parts) && is_array($objMod->module_parts['hooks']) && count($objMod->module_parts['hooks'])) { diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index a8e373518d2..9362606a6b2 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1696,7 +1696,8 @@ SeeSubstitutionVars=See * note for list of possible substitution variables AllPublishers=All publishers UnknownPublishers=Unknown publishers AddRemoveTabs=Add or remove tabs -AddDictionaries=Add dictionaries +AddDictionaries=Add dictionaries tables +AddData=Add dictionaries data AddBoxes=Add widgets AddSheduledJobs=Add scheduled jobs AddHooks=Add hooks From 5ed22b64fbc260d7134e341346d9c7a20a5fe5c8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 16:04:24 +0200 Subject: [PATCH 155/174] Show if module add objects tables --- htdocs/admin/modulehelp.php | 17 +++++++++++++++++ htdocs/langs/en_US/admin.lang | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 2110a814b10..e0caaba0a93 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -374,6 +374,23 @@ if ($mode == 'feature') $text.='

'; + $text.='
'.$langs->trans("AddDataTables").': '; + $sqlfiles = dol_dir_list(dol_buildpath($moduledir.'/sql/'), 'files', 0, 'llx.*\.sql', array('\.key\.sql')); + if (count($sqlfiles) > 0) + { + $text.=$langs->trans("Yes").' ('; + $i=0; + foreach($sqlfiles as $val) + { + $text.=($i?', ':'').preg_replace('/\.sql$/','',preg_replace('/llx_/','',$val['name'])); + $i++; + } + $text.=')'; + } + else $text.=$langs->trans("No"); + + $text.='
'; + $text.='
'.$langs->trans("AddDictionaries").': '; if (isset($objMod->dictionaries) && isset($objMod->dictionaries['tablib']) && is_array($objMod->dictionaries['tablib']) && count($objMod->dictionaries['tablib'])) { diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 9362606a6b2..99cb1ae95c2 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1696,8 +1696,9 @@ SeeSubstitutionVars=See * note for list of possible substitution variables AllPublishers=All publishers UnknownPublishers=Unknown publishers AddRemoveTabs=Add or remove tabs +AddDataTables=Add object tables AddDictionaries=Add dictionaries tables -AddData=Add dictionaries data +AddData=Add objects or dictionaries data AddBoxes=Add widgets AddSheduledJobs=Add scheduled jobs AddHooks=Add hooks From ebe84b6ac53675922653ea7dcec6b3bb02713e2e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 16:24:55 +0200 Subject: [PATCH 156/174] Fix run sql with large data --- htdocs/core/lib/admin.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index d2c466287ff..e74d1b1e94f 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -143,7 +143,7 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker { while (! feof($fp)) { - $buf = fgets($fp, 4096); + $buf = fgets($fp, 32768); // Test if request must be ran only for particular database or version (if yes, we must remove the -- comment) if (preg_match('/^--\sV(MYSQL|PGSQL)([^\s]*)/i',$buf,$reg)) From 831947b6d12ffc57fd04ee49ba20a528aff3d678 Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Sat, 26 Aug 2017 16:37:32 +0200 Subject: [PATCH 157/174] Little cleaning code $bottomlastpage is same in two case --- .../commande/doc/pdf_einstein.modules.php | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php index 3a2ad2776c5..d1c25ba978f 100644 --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php @@ -562,15 +562,10 @@ class pdf_einstein extends ModelePDFCommandes // Show square if ($pagenb == 1) - { $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code); - $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; - } else - { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); - $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; - } + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; // Affiche zone infos $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); @@ -587,18 +582,18 @@ class pdf_einstein extends ModelePDFCommandes */ // Pied de page - $this->_pagefoot($pdf,$object,$outputlangs); - if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); + $this->_pagefoot($pdf, $object, $outputlangs); + if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages(); $pdf->Close(); - $pdf->Output($file,'F'); + $pdf->Output($file, 'F'); // Add pdfgeneration hook $hookmanager->initHooks(array('pdfgeneration')); - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + $parameters=array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); global $action; - $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + $reshook=$hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); From 77af3b96d382626559ae6daa3089b1cc1a6482db Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 18:45:10 +0200 Subject: [PATCH 158/174] Showempty on language list --- htdocs/admin/mails_templates.php | 2 +- htdocs/langs/en_US/agenda.lang | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 390c792a879..2bf6faf2112 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -912,7 +912,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='') elseif ($fieldlist[$field] == 'type_template') { print ''; - print $form->selectarray('type_template', $elementList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')); + print $form->selectarray('type_template', $elementList, (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), 1); print ''; } elseif (in_array($fieldlist[$field], array('content','content_lines'))) continue; diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index a62db9c7158..25449981587 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -34,6 +34,7 @@ AgendaAutoActionDesc= Define here events for which you want Dolibarr to create a AgendaSetupOtherDesc= This page provides options to allow export of your Dolibarr events into an external calendar (thunderbird, google calendar, ...) AgendaExtSitesDesc=This page allows to declare external sources of calendars to see their events into Dolibarr agenda. ActionsEvents=Events for which Dolibarr will create an action in agenda automatically +EventRemindersByEmailNotEnabled=Event reminders by email was not enabled into Agenda module setup. ##### Agenda event labels ##### NewCompanyToDolibarr=Third party %s created ContractValidatedInDolibarr=Contract %s validated From d9a85e6d3b26774a8501faed2445e092a2a28181 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 19:19:23 +0200 Subject: [PATCH 159/174] FIX Install run_sql function accept -- into sql content. --- htdocs/core/lib/admin.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index e74d1b1e94f..225786898be 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -189,7 +189,7 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker // Add line buf to buffer if not a comment if (! preg_match('/^--/',$buf)) { - $buf=preg_replace('/--.*$/','',$buf); //remove comment from a line that not start with -- before add it to the buffer + $buf=preg_replace('/[,;]\s*--.*$/','',$buf); //remove comment from a line that not start with -- before add it to the buffer $buffer .= trim($buf); } From c64a21f47bcf464af601227b107210bcaae5ba70 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 19:57:22 +0200 Subject: [PATCH 160/174] Fix regression in cleaning sql --- htdocs/core/lib/admin.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 225786898be..b3a7129507b 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -189,7 +189,7 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker // Add line buf to buffer if not a comment if (! preg_match('/^--/',$buf)) { - $buf=preg_replace('/[,;]\s*--.*$/','',$buf); //remove comment from a line that not start with -- before add it to the buffer + $buf=preg_replace('/([,;])\s*--.*$/','\1',$buf); //remove comment from a line that not start with -- before add it to the buffer $buffer .= trim($buf); } From 49a2f4f0c6e9ec164d0f0f9658188511cfb42a6d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 20:13:01 +0200 Subject: [PATCH 161/174] Fix sql --- htdocs/install/mysql/tables/llx_accounting_account.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_accounting_account.sql b/htdocs/install/mysql/tables/llx_accounting_account.sql index b65863afe3f..cffa7624e15 100644 --- a/htdocs/install/mysql/tables/llx_accounting_account.sql +++ b/htdocs/install/mysql/tables/llx_accounting_account.sql @@ -34,7 +34,7 @@ create table llx_accounting_account fk_accounting_category integer DEFAULT 0, fk_user_author integer DEFAULT NULL, fk_user_modif integer DEFAULT NULL, - active tinyint DEFAULT 1 NOT NULL + active tinyint DEFAULT 1 NOT NULL, import_key varchar(14), extraparams varchar(255) -- for other parameters with json format )ENGINE=innodb; From 03eb8705768a847b5e772ca1677664f99438f3cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 20:16:12 +0200 Subject: [PATCH 162/174] Fix sql syntax error --- htdocs/core/lib/admin.lib.php | 2 +- htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql | 4 ++-- htdocs/install/mysql/tables/llx_extrafields.sql | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index b3a7129507b..c97bd21e250 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -189,7 +189,7 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker // Add line buf to buffer if not a comment if (! preg_match('/^--/',$buf)) { - $buf=preg_replace('/([,;])\s*--.*$/','\1',$buf); //remove comment from a line that not start with -- before add it to the buffer + $buf=preg_replace('/([,;ERLT\)])\s*--.*$/i','\1',$buf); //remove comment from a line that not start with -- before add it to the buffer $buffer .= trim($buf); } diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql index 269e73987ee..9ec89aad971 100644 --- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql +++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql @@ -45,12 +45,12 @@ CREATE TABLE llx_accounting_bookkeeping fk_user_modif integer, -- | user making last change date_creation datetime, -- FEC:EcritureDate | creation date tms timestamp, -- | date last modification - fk_user integer NULL -- The id of user that validate the accounting source document + fk_user integer NULL, -- The id of user that validate the accounting source document code_journal varchar(32) NOT NULL, -- FEC:JournalCode journal_label varchar(255), -- FEC:JournalLib piece_num integer NOT NULL, -- FEC:EcritureNum | accounting source document validated tinyint DEFAULT 0 NOT NULL, -- | 0 line not validated / 1 line validated (No deleting / No modification) - date_validated datetime -- FEC:ValidDate + date_validated datetime, -- FEC:ValidDate import_key varchar(14), extraparams varchar(255) -- for other parameters with json format ) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql index 101254ea186..c4f505a978a 100644 --- a/htdocs/install/mysql/tables/llx_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_extrafields.sql @@ -23,7 +23,6 @@ create table llx_extrafields name varchar(64) NOT NULL, -- name of field into extrafields tables entity integer DEFAULT 1 NOT NULL, -- multi company id elementtype varchar(64) NOT NULL DEFAULT 'member', -- for which element this extra fields is for - tms timestamp, -- date of last update label varchar(255) NOT NULL, -- label to show for attribute type varchar(8), size varchar(8) DEFAULT NULL, @@ -41,5 +40,5 @@ create table llx_extrafields fk_user_author integer, -- user making creation fk_user_modif integer, -- user making last change datec datetime, -- date de creation - tms timestamp + tms timestamp -- date of last update )ENGINE=innodb; From c08d0aeda5fa6e28fc1eb3b000d5310d7e3686b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 21:01:26 +0200 Subject: [PATCH 163/174] Clean duplicate accounting account --- htdocs/install/mysql/migration/repair.sql | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index cd55b7b38e2..14d419f3c68 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -228,7 +228,7 @@ update llx_product set barcode = null where barcode in ('', '-1', '0'); update llx_societe set barcode = null where barcode in ('', '-1', '0'); --- Sequence to removed duplicated values of llx_links. Use serveral times if you still have duplicate. +-- Sequence to removed duplicated values of llx_links. Use several times if you still have duplicate. drop table tmp_links_double; --select objectid, label, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_links where label is not null group by objectid, label having count(rowid) >= 2; create table tmp_links_double as (select objectid, label, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_links where label is not null group by objectid, label having count(rowid) >= 2); @@ -237,7 +237,7 @@ delete from llx_links where (rowid, label) in (select max_rowid, label from tmp_ drop table tmp_links_double; --- Sequence to removed duplicated values of barcode in llx_product. Use serveral times if you still have duplicate. +-- Sequence to removed duplicated values of barcode in llx_product. Use several times if you still have duplicate. drop table tmp_product_double; --select barcode, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_product where barcode is not null group by barcode having count(rowid) >= 2; create table tmp_product_double as (select barcode, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_product where barcode is not null group by barcode having count(rowid) >= 2); @@ -246,7 +246,7 @@ update llx_product set barcode = null where (rowid, barcode) in (select max_rowi drop table tmp_product_double; --- Sequence to removed duplicated values of barcode in llx_societe. Use serveral times if you still have duplicate. +-- Sequence to removed duplicated values of barcode in llx_societe. Use several times if you still have duplicate. drop table tmp_societe_double; --select barcode, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_societe where barcode is not null group by barcode having count(rowid) >= 2; create table tmp_societe_double as (select barcode, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_societe where barcode is not null group by barcode having count(rowid) >= 2); @@ -255,6 +255,15 @@ update llx_societe set barcode = null where (rowid, barcode) in (select max_rowi drop table tmp_societe_double; +-- Sequence to removed duplicated values of llx_accounting_account. Use several times if you still have duplicate. +drop table tmp_accounting_account_double; +--select account_number, fk_pcg_version, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_accounting_account where label is not null group by account_number, fk_pcg_version having count(rowid) >= 2; +create table tmp_accounting_account_double as (select account_number, fk_pcg_version, max(rowid) as max_rowid, count(rowid) as count_rowid from llx_accounting_account where label is not null group by account_number, fk_pcg_version having count(rowid) >= 2); +--select * from tmp_accounting_account_double; +delete from llx_accounting_account where (rowid) in (select max_rowid from tmp_accounting_account_double); --update to avoid duplicate, delete to delete +drop table tmp_accounting_account_double; + + UPDATE llx_projet_task SET fk_task_parent = 0 WHERE fk_task_parent = rowid; From 271d0c86c6cb487a899780a0e865b35115b82390 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 21:03:13 +0200 Subject: [PATCH 164/174] Fix sql install --- htdocs/install/mysql/data/llx_c_type_fees.sql | 70 +++++++++++++------ 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_type_fees.sql b/htdocs/install/mysql/data/llx_c_type_fees.sql index 868a210d891..752d6a6dd57 100644 --- a/htdocs/install/mysql/data/llx_c_type_fees.sql +++ b/htdocs/install/mysql/data/llx_c_type_fees.sql @@ -36,26 +36,50 @@ insert into llx_c_type_fees (code,label,active) values ('TF_OTHER', 'Other', insert into llx_c_type_fees (code,label,active) values ('TF_TRIP', 'Transportation', 1); insert into llx_c_type_fees (code,label,active) values ('TF_LUNCH', 'Lunch', 1); -INSERT INTO llx_c_type_fees (code, label, active, accountancy_code) VALUES -('EX_KME', 'ExpLabelKm', 1, '625100'), -('EX_FUE', 'ExpLabelFuelCV', 0, '606150'), -('EX_HOT', 'ExpLabelHotel', 0, '625160'), -('EX_PAR', 'ExpLabelParkingCV', 0, '625160'), -('EX_TOL', 'ExpLabelTollCV', 0, '625160'), -('EX_TAX', 'ExpLabelVariousTaxes', 0, '637800'), -('EX_IND', 'ExpLabelIndemnityTransportationSubscription', 0, '648100'), -('EX_SUM', 'ExpLabelMaintenanceSupply', 0, '606300'), -('EX_SUO', 'ExpLabelOfficeSupplies', 0, '606400'), -('EX_CAR', 'ExpLabelCarRental', 0, '613000'), -('EX_DOC', 'ExpLabelDocumentation', 0, '618100'), -('EX_CUR', 'ExpLabelCustomersReceiving', 0, '625710'), -('EX_OTR', 'ExpLabelOtherReceiving', 0, '625700'), -('EX_POS', 'ExpLabelPostage', 0, '626100'), -('EX_CAM', 'ExpLabelMaintenanceRepairCV', 0, '615300'), -('EX_EMM', 'ExpLabelEmployeesMeal', 0, '625160'), -('EX_GUM', 'ExpLabelGuestsMeal', 0, '625160'), -('EX_BRE', 'ExpLabelBreakfast', 0, '625160'), -('EX_FUE_VP', 'ExpLabelFuelPV', 0, '606150'), -('EX_TOL_VP', 'ExpLabelTollPV', 0, '625160'), -('EX_PAR_VP', 'ExpLabelParkingPV', 0, '625160'), -('EX_CAM_VP', 'ExpLabelMaintenanceRepairPV', 0, '615300'); \ No newline at end of file + +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_KME', 'ExpLabelKm', 1); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_FUE', 'ExpLabelFuelCV', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_HOT', 'ExpLabelHotel', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_PAR', 'ExpLabelParkingCV', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_TOL', 'ExpLabelTollCV', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_TAX', 'ExpLabelVariousTaxes', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_IND', 'ExpLabelIndemnityTransSubscrip', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_SUM', 'ExpLabelMaintenanceSupply', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_SUO', 'ExpLabelOfficeSupplies', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_CAR', 'ExpLabelCarRental', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_DOC', 'ExpLabelDocumentation', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_CUR', 'ExpLabelCustomersReceiving', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_OTR', 'ExpLabelOtherReceiving', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_POS', 'ExpLabelPostage', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_CAM', 'ExpLabelMaintenanceRepairCV', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_EMM', 'ExpLabelEmployeesMeal', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_GUM', 'ExpLabelGuestsMeal', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_BRE', 'ExpLabelBreakfast', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_FUE_VP', 'ExpLabelFuelPV', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_TOL_VP', 'ExpLabelTollPV', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_PAR_VP', 'ExpLabelParkingPV', 0); +INSERT INTO llx_c_type_fees (code, label, active) VALUES('EX_CAM_VP', 'ExpLabelMaintenanceRepairPV', 0); + +-- Set accoutancy_code for french accounting plan +--UPDATE llx_c_type_fees SET accountancy_code = '625100' WHERE code = 'EX_KME'; +--UPDATE llx_c_type_fees SET accountancy_code = '606150' WHERE code = 'EX_FUE'; +--UPDATE llx_c_type_fees SET accountancy_code = '625160' WHERE code = 'EX_HOT'; +--UPDATE llx_c_type_fees SET accountancy_code = '625160' WHERE code = 'EX_PAR'; +--UPDATE llx_c_type_fees SET accountancy_code = '625160' WHERE code = 'EX_TOL'; +--UPDATE llx_c_type_fees SET accountancy_code = '637800' WHERE code = 'EX_TAX'; +--UPDATE llx_c_type_fees SET accountancy_code = '648100' WHERE code = 'EX_IND'; +--UPDATE llx_c_type_fees SET accountancy_code = '606300' WHERE code = 'EX_SUM'; +--UPDATE llx_c_type_fees SET accountancy_code = '606400' WHERE code = 'EX_SUO'; +--UPDATE llx_c_type_fees SET accountancy_code = '613000' WHERE code = 'EX_CAR'; +--UPDATE llx_c_type_fees SET accountancy_code = '618100' WHERE code = 'EX_DOC'; +--UPDATE llx_c_type_fees SET accountancy_code = '625710' WHERE code = 'EX_CUR'; +--UPDATE llx_c_type_fees SET accountancy_code = '625700' WHERE code = 'EX_OTR'; +--UPDATE llx_c_type_fees SET accountancy_code = '626100' WHERE code = 'EX_POS'; +--UPDATE llx_c_type_fees SET accountancy_code = '615300' WHERE code = 'EX_CAM'; +--UPDATE llx_c_type_fees SET accountancy_code = '625160' WHERE code = 'EX_EMM'; +--UPDATE llx_c_type_fees SET accountancy_code = '625160' WHERE code = 'EX_GUM'; +--UPDATE llx_c_type_fees SET accountancy_code = '625160' WHERE code = 'EX_BRE'; +--UPDATE llx_c_type_fees SET accountancy_code = '606150' WHERE code = 'EX_FUE_VP'; +--UPDATE llx_c_type_fees SET accountancy_code = '625160' WHERE code = 'EX_TOL_VP'; +--UPDATE llx_c_type_fees SET accountancy_code = '625160' WHERE code = 'EX_PAR_VP'; +--UPDATE llx_c_type_fees SET accountancy_code = '615300' WHERE code = 'EX_CAM_VP'; From a01bb27d7e892f35337866a55a3d55a4758e9d5a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 21:53:29 +0200 Subject: [PATCH 165/174] FIX install process with DoliWamp --- htdocs/install/step1.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php index 486b156fcaf..339c03a32d3 100644 --- a/htdocs/install/step1.php +++ b/htdocs/install/step1.php @@ -510,7 +510,7 @@ if (! $error && $db->connected && $action == "set") print 'Ok'; // Si creation utilisateur admin demandee, on le cree - if (isset($db_create_user) && $db_create_user == "on") { + if (isset($db_create_user) && ($db_create_user == "1" || $db_create_user == "on")) { dolibarr_install_syslog("step1: create database user: " . $dolibarr_main_db_user); //print $conf->db->host." , ".$conf->db->name." , ".$conf->db->user." , ".$conf->db->port; @@ -614,7 +614,7 @@ if (! $error && $db->connected && $action == "set") // If database creation is asked, we create it - if (!$error && (isset($db_create_database) && $db_create_database == "on")) { + if (!$error && (isset($db_create_database) && ($db_create_database == "1" || $db_create_database == "on"))) { dolibarr_install_syslog("step1: create database: " . $dolibarr_main_db_name . " " . $dolibarr_main_db_character_set . " " . $dolibarr_main_db_collation . " " . $dolibarr_main_db_user); $newdb=getDoliDBInstance($conf->db->type,$conf->db->host,$userroot,$passroot,'',$conf->db->port); //print 'eee'.$conf->db->type." ".$conf->db->host." ".$userroot." ".$passroot." ".$conf->db->port." ".$newdb->connected." ".$newdb->forcecharset;exit; From c8f323b706c7c881611df7d3241bac8c50fd6b9b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 26 Aug 2017 21:55:34 +0200 Subject: [PATCH 166/174] Prepare 5.0.5 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 785e338fe09..e82fdf33d8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,7 @@ FIX: User id correction on holiday request FIX: value of user id filled to 0 in llx_bank_url when recording an expense report. FIX: we have to check if contact doesn't already exist on add_contact() function FIX: We should be able to insert data with value '0' into const +FIX: install process with DoliWamp ***** ChangeLog for 5.0.4 compared to 5.0.3 ***** FIX: #5640 Prices of a predefined product/service were incorrect under certain circumstances From f10e89aa9f2790cad49c7cab5908951ab5671482 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 27 Aug 2017 00:33:50 +0200 Subject: [PATCH 167/174] Fix utf8 bom forbidden --- htdocs/compta/stats/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php index 0c4a16edf7b..1735033cab7 100644 --- a/htdocs/compta/stats/index.php +++ b/htdocs/compta/stats/index.php @@ -1,4 +1,4 @@ - * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin From 3f7eea2e0aba36d94459d910dbe413a32c216f02 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 27 Aug 2017 12:06:46 +0200 Subject: [PATCH 168/174] NEW Can set language on extrafields --- htdocs/compta/bank/card.php | 38 +--------- htdocs/core/class/commonobject.class.php | 3 + htdocs/core/class/extrafields.class.php | 72 +++++++++++-------- htdocs/core/tpl/extrafields_view.tpl.php | 4 ++ .../install/mysql/migration/6.0.0-7.0.0.sql | 2 + .../install/mysql/tables/llx_extrafields.sql | 2 +- .../core/modules/modMyModule.class.php | 10 +-- 7 files changed, 57 insertions(+), 74 deletions(-) diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 1f55698d13f..6aa7a950683 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -560,11 +560,7 @@ else $_GET["id"]=$object->id; } - /* - * Affichage onglets - */ - - // Onglets + // Show tabs $head=bank_prepare_head($object); dol_fiche_head($head, 'bankname', $langs->trans("FinancialAccount"), -1, 'account'); @@ -592,18 +588,6 @@ else print ''; - - // Ref - /* - print ''; - print '';*/ - - // Label - /*print ''; - print '';*/ - // Type print ''; print ''; @@ -616,26 +600,6 @@ else print $langs->trans("Currency".$selectedcode); print ''; - // Status - /*print ''; - print '';*/ - - // Country - /* - print ''; - - // State - print '';*/ - // Conciliate print ''; print '"; } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 7e42e143b6a..3ff082a9ec1 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3401,12 +3401,12 @@ class Form /** * Return list of categories having choosed type * - * @param int $type Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated. - * @param string $selected Id of category preselected or 'auto' (autoselect category if there is only one element) - * @param string $htmlname HTML field name - * @param int $maxlength Maximum length for labels - * @param int $excludeafterid Exclude all categories after this leaf in category tree. - * @param int $outputmode 0=HTML select string, 1=Array + * @param string|int $type Type of category ('customer', 'supplier', 'contact', 'product', 'member'). Old mode (0, 1, 2, ...) is deprecated. + * @param string $selected Id of category preselected or 'auto' (autoselect category if there is only one element) + * @param string $htmlname HTML field name + * @param int $maxlength Maximum length for labels + * @param int $excludeafterid Exclude all categories after this leaf in category tree. + * @param int $outputmode 0=HTML select string, 1=Array * @return string * @see select_categories */ @@ -3449,7 +3449,7 @@ class Form else { $cat = new Categorie($this->db); - $cate_arbo = $cat->get_full_arbo($type,$excludeafterid); + $cate_arbo = $cat->get_full_arbo($type, $excludeafterid); } $output = ' + + + diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 5a9a5b43d93..beb1e34055e 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -54,11 +54,11 @@ ?> // Case of computed field - if (type == 'varchar' || type == 'int' || type == 'double' || type == 'price') { - jQuery("tr.extra_computed_value").show(); + if (type == 'varchar' || type == 'int' || type == 'double' || type == 'price') { + jQuery("tr.extra_computed_value").show(); } else { computed_value.val(''); jQuery("tr.extra_computed_value").hide(); - } + } if (computed_value.val()) { console.log("We enter a computed formula"); @@ -73,7 +73,7 @@ jQuery("#default_value, #unique, #required, #alwayseditable, #ishidden, #list").attr('disabled', false); jQuery("tr.extra_default_value, tr.extra_unique, tr.extra_required, tr.extra_alwayseditable, tr.extra_ishidden, tr.extra_list").show(); } - + if (type == 'date') { size.val('').prop('disabled', true); unique.removeAttr('disabled'); jQuery("#value_choice").hide();jQuery("#helpchkbxlst").hide(); } else if (type == 'datetime') { size.val('').prop('disabled', true); unique.removeAttr('disabled'); jQuery("#value_choice").hide(); jQuery("#helpchkbxlst").hide();} else if (type == 'double') { size.removeAttr('disabled'); unique.removeAttr('disabled'); jQuery("#value_choice").hide(); jQuery("#helpchkbxlst").hide();} @@ -91,19 +91,19 @@ else if (type == 'separate') { size.val('').prop('disabled', true); unique.removeAttr('checked').prop('disabled', true); required.val('').prop('disabled', true); default_value.val('').prop('disabled', true); jQuery("#value_choice").hide();jQuery("#helpselect").hide();jQuery("#helpsellist").hide();jQuery("#helpchkbxlst").hide();jQuery("#helplink").hide();} else { // type = string size.val('').prop('disabled', true); - unique.removeAttr('disabled'); + unique.removeAttr('disabled'); } if (type == 'separate') { - required.removeAttr('checked').prop('disabled', true); alwayseditable.removeAttr('checked').prop('disabled', true); list.val('').prop('disabled', true); - jQuery('#size, #default_value').val('').prop('disabled', true); + required.removeAttr('checked').prop('disabled', true); alwayseditable.removeAttr('checked').prop('disabled', true); list.val('').prop('disabled', true); + jQuery('#size, #default_value').val('').prop('disabled', true); } else { default_value.removeAttr('disabled'); - required.removeAttr('disabled'); alwayseditable.removeAttr('disabled'); list.val('').removeAttr('disabled'); - } + required.removeAttr('disabled'); alwayseditable.removeAttr('disabled'); list.val('').removeAttr('disabled'); + } } init_typeoffields(jQuery("#type").val()); jQuery("#type").change(function() { @@ -113,7 +113,7 @@ // If we enter a formula, we disable other fields jQuery("#computed_value").keyup(function() { init_typeoffields(jQuery('#type').val()); - }); + }); }); @@ -129,23 +129,20 @@
'.$langs->trans("Ref").''; - print $form->showrefnav($object, 'ref', $linkback, 1, 'ref'); - print '
'.$langs->trans("Label").''.$object->label.'
'.$langs->trans("AccountType").''.$object->type_lib[$object->type].'
'.$langs->trans("Status").''.$object->getLibStatut(4).'
'.$langs->trans("BankAccountCountry").''; - if ($object->country_id > 0) - { - $img=picto_from_langcode($object->country_code); - print $img?$img.' ':''; - print getCountry($object->getCountryCode(),0,$db); - } - print '
'.$langs->trans('State').''; - if ($object->state_id > 0) print getState($object->state_id); - print '
'.$langs->trans("Conciliable").''; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 50ccf362de6..450bc4ba393 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4565,6 +4565,9 @@ abstract class CommonObject $e = 0; foreach($extrafields->attribute_label as $key=>$label) { + // Load language if required + if (! empty($extrafields->attributes[$this->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$this->table_element]['langfile'][$key]); + if (is_array($params) && count($params)>0) { if (array_key_exists('colspan',$params)) { $colspan=$params['colspan']; diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index eb04115ca84..7e015d951b1 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -64,7 +64,9 @@ class ExtraFields var $attribute_alwayseditable; // Array to store permission to check var $attribute_perms; - // Array to store permission to check + // Array to store language file to translate label of values + var $attribute_langfile; + // Array to store if field is visible by default on list var $attribute_list; // Array to store if extra field is hidden var $attribute_hidden; // warning, do not rely on this. If your module need a hidden data, it must use its own table. @@ -117,6 +119,7 @@ class ExtraFields $this->attribute_unique = array(); $this->attribute_required = array(); $this->attribute_perms = array(); + $this->attribute_langfile = array(); $this->attribute_list = array(); $this->attribute_hidden = array(); } @@ -124,25 +127,26 @@ class ExtraFields /** * Add a new extra field parameter * - * @param string $attrname Code of attribute - * @param string $label label of attribute - * @param int $type Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...) - * @param int $pos Position of attribute - * @param string $size Size/length of attribute - * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...) - * @param int $unique Is field unique or not - * @param int $required Is field required or not - * @param string $default_value Defaulted value (In database. use the default_value feature for default value on screen. Example: '', '0', 'null', 'avalue') - * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) - * @param int $alwayseditable Is attribute always editable regardless of the document status - * @param string $perms Permission to check - * @param int $list Into list view by default - * @param int $ishidden Is hidden extrafield (warning, do not rely on this. If your module need a hidden data, it must use its own table) - * @param string $computed Computed value - * @param string $entity Entity of extrafields + * @param string $attrname Code of attribute + * @param string $label label of attribute + * @param int $type Type of attribute ('boolean', 'int', 'text', 'varchar', 'date', 'datehour','price','phone','mail','password','url','select','checkbox', ...) + * @param int $pos Position of attribute + * @param string $size Size/length of attribute + * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...) + * @param int $unique Is field unique or not + * @param int $required Is field required or not + * @param string $default_value Defaulted value (In database. use the default_value feature for default value on screen. Example: '', '0', 'null', 'avalue') + * @param array|string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) + * @param int $alwayseditable Is attribute always editable regardless of the document status + * @param string $perms Permission to check + * @param int $list Into list view by default + * @param int $ishidden Is hidden extrafield (warning, do not rely on this. If your module need a hidden data, it must use its own table) + * @param string $computed Computed value + * @param string $entity Entity of extrafields + * @param string $langfile Language file * @return int <=0 if KO, >0 if OK */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param=0, $alwayseditable=0, $perms='', $list=0, $ishidden=0, $computed='', $entity='') + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=0, $ishidden=0, $computed='', $entity='', $langfile='') { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -159,7 +163,7 @@ class ExtraFields if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $ishidden, $default, $computed, $entity); + $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $ishidden, $default, $computed, $entity, $langfile); $err2=$this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { @@ -271,7 +275,7 @@ class ExtraFields * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...) * @param int $unique Is field unique or not * @param int $required Is field required or not - * @param array||string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) + * @param array|string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check * @param int $list Into list view by default @@ -279,9 +283,10 @@ class ExtraFields * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields + * @param string $langfile Language file * @return int <=0 if KO, >0 if OK */ - private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=0, $ishidden=0, $default='', $computed='',$entity='') + private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=0, $ishidden=0, $default='', $computed='',$entity='', $langfile='') { global $conf,$user; @@ -320,6 +325,7 @@ class ExtraFields $sql.= " param,"; $sql.= " alwayseditable,"; $sql.= " perms,"; + $sql.= " langs,"; $sql.= " list,"; $sql.= " ishidden,"; $sql.= " fielddefault,"; @@ -340,6 +346,7 @@ class ExtraFields $sql.= " '".$params."',"; $sql.= " '".$alwayseditable."',"; $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").","; + $sql.= " ".($langfile?"'".$this->db->escape($langfile)."'":"null").","; $sql.= " ".$list.","; $sql.= " ".$ishidden.","; $sql.= " ".($default?"'".$this->db->escape($default)."'":"null").","; @@ -480,9 +487,10 @@ class ExtraFields * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields + * @param string $langfile Language file * @return int >0 if OK, <=0 if KO */ - function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0, $perms='',$list='',$ishidden=0,$default='',$computed='',$entity='') + function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $ishidden=0, $default='', $computed='', $entity='', $langfile='') { if ($elementtype == 'thirdparty') $elementtype='societe'; if ($elementtype == 'contact') $elementtype='socpeople'; @@ -530,7 +538,7 @@ class ExtraFields { if ($label) { - $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$ishidden,$default,$computed,$entity); + $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$ishidden,$default,$computed,$entity,$langfile); } if ($result > 0) { @@ -585,12 +593,13 @@ class ExtraFields * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields + * @param string $langfile Language file * @return int <=0 if KO, >0 if OK */ - private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0,$ishidden=0,$default='',$computed='',$entity='') + private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0,$ishidden=0,$default='',$computed='',$entity='',$langfile='') { global $conf, $user; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$ishidden.", ".$default.", ".$computed.", ".$entity); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$ishidden.", ".$default.", ".$computed.", ".$entity.", ".$langfile); // Clean parameters if ($elementtype == 'thirdparty') $elementtype='societe'; @@ -624,6 +633,7 @@ class ExtraFields $sql.= " fieldunique,"; $sql.= " fieldrequired,"; $sql.= " perms,"; + $sql.= " langs,"; $sql.= " pos,"; $sql.= " alwayseditable,"; $sql.= " param,"; @@ -644,6 +654,7 @@ class ExtraFields $sql.= " '".$unique."',"; $sql.= " '".$required."',"; $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").","; + $sql.= " ".($langfile?"'".$this->db->escape($langfile)."'":"null").","; $sql.= " '".$pos."',"; $sql.= " '".$alwayseditable."',"; $sql.= " '".$param."',"; @@ -702,7 +713,7 @@ class ExtraFields // We should not have several time this log. If we have, there is some optimization to do by calling a simple $object->fetch_optionals() that include cache management. dol_syslog("fetch_name_optionals_label elementtype=".$elementtype); - $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,list,ishidden,fielddefault,fieldcomputed"; + $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,ishidden,fielddefault,fieldcomputed"; $sql .= ",entity"; $sql.= " FROM ".MAIN_DB_PREFIX."extrafields"; $sql.= " WHERE entity IN (0,".$conf->entity.")"; @@ -722,8 +733,6 @@ class ExtraFields $array_name_label[$tab->name]=$tab->label; } - - // Old usage $this->attribute_type[$tab->name]=$tab->type; $this->attribute_label[$tab->name]=$tab->label; @@ -737,12 +746,11 @@ class ExtraFields $this->attribute_pos[$tab->name]=$tab->pos; $this->attribute_alwayseditable[$tab->name]=$tab->alwayseditable; $this->attribute_perms[$tab->name]=$tab->perms; + $this->attribute_langfile[$tab->langs]=$tab->langs; $this->attribute_list[$tab->name]=$tab->list; $this->attribute_hidden[$tab->name]=$tab->ishidden; $this->attribute_entityid[$tab->name]=$tab->entity; - - // New usage $this->attributes[$tab->elementtype]['type'][$tab->name]=$tab->type; $this->attributes[$tab->elementtype]['label'][$tab->name]=$tab->label; @@ -756,6 +764,7 @@ class ExtraFields $this->attributes[$tab->elementtype]['pos'][$tab->name]=$tab->pos; $this->attributes[$tab->elementtype]['alwayseditable'][$tab->name]=$tab->alwayseditable; $this->attributes[$tab->elementtype]['perms'][$tab->name]=$tab->perms; + $this->attributes[$tab->elementtype]['langfile'][$tab->name]=$tab->langs; $this->attributes[$tab->elementtype]['list'][$tab->name]=$tab->list; $this->attributes[$tab->elementtype]['ishidden'][$tab->name]=$tab->ishidden; $this->attributes[$tab->elementtype]['entityid'][$tab->name]=$tab->entity; @@ -820,7 +829,7 @@ class ExtraFields $unique=$this->attribute_unique[$key]; $required=$this->attribute_required[$key]; $param=$this->attribute_param[$key]; - $perms=$this->attribute_perms[$key]; + $langfile=$this->attribute_langfile[$key]; $list=$this->attribute_list[$key]; $hidden=$this->attribute_hidden[$key]; @@ -1352,6 +1361,7 @@ class ExtraFields $required=$this->attribute_required[$key]; $params=$this->attribute_param[$key]; $perms=$this->attribute_perms[$key]; + $langfile=$this->attribute_langfile[$key]; $list=$this->attribute_list[$key]; $hidden=$this->attribute_hidden[$key]; // warning, do not rely on this. If your module need a hidden data, it must use its own table. diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index f553cbdc4f0..56eb8652d2b 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -37,10 +37,14 @@ $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, print $hookmanager->resPrint; if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +//var_dump($extrafields->attributes); if (empty($reshook) && ! empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { + // Load language if required + if (! empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); + if ($action == 'edit_extras') { $value = (isset($_POST["options_" . $key]) ? $_POST["options_" . $key] : $object->array_options["options_" . $key]); diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index 5759423abbb..68cfa63fa16 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -25,6 +25,8 @@ -- -- VMYSQL4.1 DELETE FROM llx_usergroup_user WHERE fk_usergroup NOT IN (SELECT rowid from llx_usergroup); +ALTER TABLE llx_extrafields MODIFY COLUMN langs varchar(64); + ALTER TABLE llx_facture_fourn ADD COLUMN date_pointoftax date DEFAULT NULL; ALTER TABLE llx_facture_fourn ADD COLUMN date_valid date; diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql index c4f505a978a..3b9a9b2d72b 100644 --- a/htdocs/install/mysql/tables/llx_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_extrafields.sql @@ -35,7 +35,7 @@ create table llx_extrafields alwayseditable integer DEFAULT 0, -- 1 if field can be edited whatever is element status param text, -- extra parameters to define possible values of field list integer DEFAULT 0, -- list of values for field that are combo lists - langs varchar(24), -- example: fileofmymodule@mymodule + langs varchar(64), -- example: fileofmymodule@mymodule ishidden integer DEFAULT 0, -- Can be foreign key of external system fk_user_author integer, -- user making creation fk_user_modif integer, -- user making last change diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 77f860ba92c..00199f1d3a4 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -311,11 +311,11 @@ class modMyModule extends DolibarrModules include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; $extrafields = new ExtraFields($this->db); - $result1=$extrafields->addExtraField('myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty'); - //$result2=$extrafields->addExtraField('myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project'); - //$result3=$extrafields->addExtraField('myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account'); - //$result4=$extrafields->addExtraField('myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1); - //$result5=$extrafields->addExtraField('myattr5', "New Attr 5 label", 'text', 1, 10, 'user'); + //$result1=$extrafields->addExtraField('myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule'); + //$result2=$extrafields->addExtraField('myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule'); + //$result3=$extrafields->addExtraField('myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule'); + //$result4=$extrafields->addExtraField('myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1); + //$result5=$extrafields->addExtraField('myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'mymodule@mymodule'); $sql = array(); From 502ac19a0af335ca90021bcf341cb88f8f01ad97 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 27 Aug 2017 12:28:59 +0200 Subject: [PATCH 169/174] Fix regression on categories --- htdocs/categories/class/categorie.class.php | 45 ++++++++++++--------- htdocs/categories/index.php | 2 +- htdocs/compta/bank/card.php | 2 +- htdocs/core/class/html.form.class.php | 14 +++---- 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index d1b8975eaf4..538f07133c5 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -62,14 +62,15 @@ class Categorie extends CommonObject * @note This array should be remove in future, once previous constants are moved to the string value. Deprecated */ private $MAP_ID = array( - 'product' => 0, - 'supplier' => 1, - 'customer' => 2, - 'member' => 3, - 'contact' => 4, - 'account' => 5, - 'project' => 6, - 'user' => 7, + 'product' => 0, + 'supplier' => 1, + 'customer' => 2, + 'member' => 3, + 'contact' => 4, + 'bank_account' => 5, + 'project' => 6, + 'user' => 7, + 'bank_line' => 8, ); public static $MAP_ID_TO_CODE = array( 0 => 'product', @@ -77,9 +78,10 @@ class Categorie extends CommonObject 2 => 'customer', 3 => 'member', 4 => 'contact', - 5 => 'account', + 5 => 'bank_account', 6 => 'project', 7 => 'user', + 8 => 'bank_line', ); /** @@ -94,7 +96,8 @@ class Categorie extends CommonObject 'member' => 'member', 'contact' => 'socpeople', 'user' => 'user', - 'account' => 'account', + 'account' => 'account', // old for bank_account + 'bank_account' => 'account', 'project' => 'project', ); /** @@ -109,7 +112,8 @@ class Categorie extends CommonObject 'member' => 'member', 'contact' => 'contact', 'user' => 'user', - 'account' => 'account', + 'account' => 'account', // old for bank_account + 'bank_account'=> 'account', 'project' => 'project', ); /** @@ -124,7 +128,8 @@ class Categorie extends CommonObject 'member' => 'Adherent', 'contact' => 'Contact', 'user' => 'User', - 'account' => 'Account', + 'account' => 'Account', // old for bank account + 'bank_account' => 'Account', 'project' => 'Project', ); /** @@ -947,8 +952,8 @@ class Categorie extends CommonObject * fulllabel = nom avec chemin complet de la categorie * fullpath = chemin complet compose des id * - * @param string $type Type of categories ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...). - * @param int $markafterid Removed all categories including the leaf $markafterid in category tree. + * @param string $type Type of categories ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...). + * @param int $markafterid Removed all categories including the leaf $markafterid in category tree. * * @return array Array of categories. this->cats and this->motherof are set. */ @@ -1340,11 +1345,11 @@ class Categorie extends CommonObject * Return list of categories (object instances or labels) linked to element of id $id and type $type * Should be named getListOfCategForObject * - * @param int $id Id of element - * @param int $type Type of category ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...) - * @param string $mode 'id'=Get array of category ids, 'object'=Get array of fetched category instances, 'label'=Get array of category - * labels, 'id'= Get array of category IDs - * @return mixed Array of category objects or < 0 if KO + * @param int $id Id of element + * @param string|int $type Type of category ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...) + * @param string $mode 'id'=Get array of category ids, 'object'=Get array of fetched category instances, 'label'=Get array of category + * labels, 'id'= Get array of category IDs + * @return mixed Array of category objects or < 0 if KO */ function containing($id, $type, $mode='object') { @@ -1352,7 +1357,7 @@ class Categorie extends CommonObject if (is_numeric($type)) $type = Categorie::$MAP_ID_TO_CODE[$type]; - if ($type == Categorie::TYPE_BANK_LINE) // TODO Remove this with standard category code + if ($type === Categorie::TYPE_BANK_LINE) // TODO Remove this with standard category code { // Load bank groups $sql = "SELECT c.label, c.rowid"; diff --git a/htdocs/categories/index.php b/htdocs/categories/index.php index c751fad67a7..149eb160a78 100644 --- a/htdocs/categories/index.php +++ b/htdocs/categories/index.php @@ -54,7 +54,7 @@ elseif ($type == Categorie::TYPE_SUPPLIER) { $title=$langs->trans("SuppliersCat elseif ($type == Categorie::TYPE_CUSTOMER) { $title=$langs->trans("CustomersCategoriesArea"); $typetext='customer'; } elseif ($type == Categorie::TYPE_MEMBER) { $title=$langs->trans("MembersCategoriesArea"); $typetext='member'; } elseif ($type == Categorie::TYPE_CONTACT) { $title=$langs->trans("ContactsCategoriesArea"); $typetext='contact'; } -elseif ($type == Categorie::TYPE_ACCOUNT) { $title=$langs->trans("AccountsCategoriesArea"); $typetext='account'; } +elseif ($type == Categorie::TYPE_ACCOUNT) { $title=$langs->trans("AccountsCategoriesArea"); $typetext='bank_account'; } elseif ($type == Categorie::TYPE_PROJECT) { $title=$langs->trans("ProjectsCategoriesArea"); $typetext='project'; } elseif ($type == Categorie::TYPE_USER) { $title=$langs->trans("UsersCategoriesArea"); $typetext='user'; } else { $title=$langs->trans("CategoriesArea"); $typetext='unknown'; } diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 6aa7a950683..7c94e03e339 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -658,7 +658,7 @@ else // Categories if ($conf->categorie->enabled) { print '
'.$langs->trans("Categories").''; - print $form->showCategories($object->id,'account',1); + print $form->showCategories($object->id,'bank_account',1); print "
trans("Position"); ?>
trans("Position"); ?>
trans("LanguageFile"); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>">
attribute_type[$attrname]; -$size=$extrafields->attribute_size[$attrname]; -$computed=$extrafields->attribute_computed[$attrname]; -$default=$extrafields->attribute_default[$attrname]; -$unique=$extrafields->attribute_unique[$attrname]; -$required=$extrafields->attribute_required[$attrname]; -$pos=$extrafields->attribute_pos[$attrname]; -$alwayseditable=$extrafields->attribute_alwayseditable[$attrname]; -$param=$extrafields->attribute_param[$attrname]; -$perms=$extrafields->attribute_perms[$attrname]; -$list=$extrafields->attribute_list[$attrname]; -if (! empty($conf->global->MAIN_CAN_HIDE_EXTRAFIELDS)) { - $ishidden=$extrafields->attribute_hidden[$attrname]; -} -if ($conf->multicompany->enabled) { - $entitycurrentorall=$extrafields->attribute_entityid[$attrname]; -} +$type=$extrafields->attributes[$elementtype]['type'][$attrname]; +$size=$extrafields->attributes[$elementtype]['size'][$attrname]; +$computed=$extrafields->attributes[$elementtype]['computed'][$attrname]; +$default=$extrafields->attributes[$elementtype]['default'][$attrname]; +$unique=$extrafields->attributes[$elementtype]['unique'][$attrname]; +$required=$extrafields->attributes[$elementtype]['required'][$attrname]; +$pos=$extrafields->attributes[$elementtype]['pos'][$attrname]; +$alwayseditable=$extrafields->attributes[$elementtype]['alwayseditable'][$attrname]; +$param=$extrafields->attributes[$elementtype]['param'][$attrname]; +$perms=$extrafields->attributes[$elementtype]['perms'][$attrname]; +$langfile=$extrafields->attributes[$elementtype]['langfile'][$attrname]; +$list=$extrafields->attributes[$elementtype]['list'][$attrname]; +$ishidden=$extrafields->attributes[$elementtype]['hidden'][$attrname]; +$entitycurrentorall=$extrafields->attributes[$elementtype]['entityid'][$attrname]; if((($type == 'select') || ($type == 'checkbox') || ($type == 'radio')) && is_array($param)) { @@ -220,7 +217,9 @@ else - + + + diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 84ee52167a9..b4cce97957a 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -345,6 +345,7 @@ AddCRIfTooLong=There is no automatic wrapping, so if line is out of page on docu ConfirmPurge=Are you sure you want to execute this purge?
This will delete definitely all your data files with no way to restore them (ECM files, attached files...). MinLength=Minimum length LanguageFilesCachedIntoShmopSharedMemory=Files .lang loaded in shared memory +LanguageFile=Language file ExamplesWithCurrentSetup=Examples with current running setup ListOfDirectories=List of OpenDocument templates directories ListOfDirectoriesForModelGenODT=List of directories containing templates files with OpenDocument format.

Put here full path of directories.
Add a carriage return between eah directory.
To add a directory of the GED module, add here DOL_DATA_ROOT/ecm/yourdirectoryname.

Files in those directories must end with .odt or .ods. From 64bbf35812df3d4360115e222d9f3ca7f91e94b7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 27 Aug 2017 13:28:37 +0200 Subject: [PATCH 171/174] Debug modulebuilder --- htdocs/ecm/docfile.php | 6 +- htdocs/langs/en_US/modulebuilder.lang | 3 + htdocs/modulebuilder/index.php | 114 +++++++++++++++----------- 3 files changed, 74 insertions(+), 49 deletions(-) diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/docfile.php index 577ac3e0262..61cce03cc1d 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/docfile.php @@ -268,11 +268,13 @@ $filepath=$relativepath.$file->label; $rellink.='&file='.urlencode($filepath); $fulllink=$urlwithroot.$rellink; print img_picto('','object_globe.png').' '; -print ''; -print ' '.$langs->trans("Download").''; +print ''; +print ' '.$langs->trans("Download").''; print ''; print '
trans("Position"); ?>
trans("Position"); ?>
trans("LanguageFile"); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
'; +print ajax_autoselect('downloadlink'); + dol_fiche_end(); if ($_GET["action"] == 'edit') diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 034deb7c800..1b9b00a28d2 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -35,6 +35,9 @@ ClassFile=File for PHP DAO CRUD class ApiClassFile=File for PHP API class PageForList=PHP page for list of record PageForCreateEditView=PHP page to create/edit/view a record +PageForAgendaTab=PHP page for event tab +PageForDocumentTab=PHP page for document tab +PageForNoteTab=PHP page for note tab PathToModulePackage=Path to zip of module/application package PathToModuleDocumentation=Path to file of module/application documentation SpaceOrSpecialCharAreNotAllowed=Spaces or special characters are not allowed. diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index d0da95b6947..91bf15787ee 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -411,7 +411,7 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname) $filetogenerate = array( 'myobject_card.php'=>strtolower($objectname).'_card.php', 'myobject_note.php'=>strtolower($objectname).'_note.php', - 'myobject_document.php'=>strtolower($objectname).'_note.php', + 'myobject_document.php'=>strtolower($objectname).'_document.php', 'myobject_agenda.php'=>strtolower($objectname).'_agenda.php', 'myobject_list.php'=>strtolower($objectname).'_list.php', 'lib/myobject.lib.php'=>'lib/'.strtolower($objectname).'.lib.php', @@ -1227,6 +1227,7 @@ elseif (! empty($module)) foreach($listofobject as $fileobj) { if (preg_match('/^api_/',$fileobj['name'])) continue; + if (preg_match('/^actions_/',$fileobj['name'])) continue; $tmpcontent=file_get_contents($fileobj['fullname']); if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims',$tmpcontent,$reg)) @@ -1236,7 +1237,7 @@ elseif (! empty($module)) if (empty($firstobjectname)) $firstobjectname = $objectname; } - $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname; + $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname; $head3[$h][1] = $objectname; $head3[$h][2] = $objectname; $h++; @@ -1302,14 +1303,17 @@ elseif (! empty($module)) if ($action != 'editfile' || empty($file)) { try { - $pathtoclass = strtolower($module).'/class/'.strtolower($tabobj).'.class.php'; - $pathtoapi = strtolower($module).'/class/api_'.strtolower($tabobj).'.class.php'; - $pathtolist = strtolower($module).'/'.strtolower($tabobj).'_list.php'; - $pathtocard = strtolower($module).'/'.strtolower($tabobj).'_card.php'; - $pathtophpunit = strtolower($module).'/test/phpunit/'.$tabobj.'Test.php'; - $pathtosql = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.sql'; + $pathtoclass = strtolower($module).'/class/'.strtolower($tabobj).'.class.php'; + $pathtoapi = strtolower($module).'/class/api_'.strtolower($tabobj).'.class.php'; + $pathtoagenda = strtolower($module).'/'.strtolower($tabobj).'_agenda.php'; + $pathtocard = strtolower($module).'/'.strtolower($tabobj).'_card.php'; + $pathtodocument = strtolower($module).'/'.strtolower($tabobj).'_document.php'; + $pathtolist = strtolower($module).'/'.strtolower($tabobj).'_list.php'; + $pathtonote = strtolower($module).'/'.strtolower($tabobj).'_note.php'; + $pathtophpunit = strtolower($module).'/test/phpunit/'.$tabobj.'Test.php'; + $pathtosql = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.sql'; $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($tabobj).'_extrafields.sql'; - $pathtosqlkey = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.key.sql'; + $pathtosqlkey = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.key.sql'; print '
'; print ' '.$langs->trans("ClassFile").' : '.$pathtoclass.''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; @@ -1335,6 +1339,15 @@ elseif (! empty($module)) print '
'; print ' '.$langs->trans("PageForCreateEditView").' : '.$pathtocard.''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + print ' '.$langs->trans("PageForAgendaTab").' : '.$pathtoagenda.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + print ' '.$langs->trans("PageForDocumentTab").' : '.$pathtodocument.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '
'; + print ' '.$langs->trans("PageForNoteTab").' : '.$pathtonote.''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
'; print '


'; @@ -1708,51 +1721,58 @@ elseif (! empty($module)) print_liste_field_titre("Comment",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); print "\n"; - foreach ($cronjobs as $cron) + if (count($cronjobs)) { - print ''; + foreach ($cronjobs as $cron) + { + print ''; - print ''; - print $cron['label']; - print ''; + print ''; + print $cron['label']; + print ''; - print ''; - if ($cron['jobtype']=='method') - { - $text=$langs->trans("CronClass"); - $texttoshow=$langs->trans('CronModule').': '.$module.'
'; - $texttoshow.=$langs->trans('CronClass').': '. $cron['class'].'
'; - $texttoshow.=$langs->trans('CronObject').': '. $cron['objectname'].'
'; - $texttoshow.=$langs->trans('CronMethod').': '. $cron['method']; - $texttoshow.='
'.$langs->trans('CronArgs').': '. $cron['parameters']; - $texttoshow.='
'.$langs->trans('Comment').': '. $langs->trans($cron['comment']); - } - elseif ($cron['jobtype']=='command') - { - $text=$langs->trans('CronCommand'); - $texttoshow=$langs->trans('CronCommand').': '.dol_trunc($cron['command']); - $texttoshow.='
'.$langs->trans('CronArgs').': '. $cron['parameters']; - $texttoshow.='
'.$langs->trans('Comment').': '. $langs->trans($cron['comment']); - } - print $form->textwithpicto($text, $texttoshow, 1); - print ''; + print ''; + if ($cron['jobtype']=='method') + { + $text=$langs->trans("CronClass"); + $texttoshow=$langs->trans('CronModule').': '.$module.'
'; + $texttoshow.=$langs->trans('CronClass').': '. $cron['class'].'
'; + $texttoshow.=$langs->trans('CronObject').': '. $cron['objectname'].'
'; + $texttoshow.=$langs->trans('CronMethod').': '. $cron['method']; + $texttoshow.='
'.$langs->trans('CronArgs').': '. $cron['parameters']; + $texttoshow.='
'.$langs->trans('Comment').': '. $langs->trans($cron['comment']); + } + elseif ($cron['jobtype']=='command') + { + $text=$langs->trans('CronCommand'); + $texttoshow=$langs->trans('CronCommand').': '.dol_trunc($cron['command']); + $texttoshow.='
'.$langs->trans('CronArgs').': '. $cron['parameters']; + $texttoshow.='
'.$langs->trans('Comment').': '. $langs->trans($cron['comment']); + } + print $form->textwithpicto($text, $texttoshow, 1); + print ''; - print ''; - if($cron['unitfrequency'] == "60") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes'); - if($cron['unitfrequency'] == "3600") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours'); - if($cron['unitfrequency'] == "86400") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days'); - if($cron['unitfrequency'] == "604800") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks'); - print ''; + print ''; + if($cron['unitfrequency'] == "60") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes'); + if($cron['unitfrequency'] == "3600") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours'); + if($cron['unitfrequency'] == "86400") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days'); + if($cron['unitfrequency'] == "604800") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks'); + print ''; - print ''; - print $cron['status']; - print ''; + print ''; + print $cron['status']; + print ''; - print ''; - if (!empty($cron['comment'])) {print $cron['comment'];} - print ''; + print ''; + if (!empty($cron['comment'])) {print $cron['comment'];} + print ''; - print ''; + print ''; + } + } + else + { + print ''.$langs->trans("None").''; } print ''; From 6c93c6f6cceab8d9cb7d102058b7f5a05895c254 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 27 Aug 2017 13:38:42 +0200 Subject: [PATCH 172/174] Fix PHPunit --- .../facture/class/facture-rec.class.php | 206 +++++++++--------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index ddf813db30b..a1068a8c691 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -43,7 +43,7 @@ class FactureRec extends CommonInvoice public $table_element_line='facturedet_rec'; public $fk_element='fk_facture'; public $picto='bill'; - + var $entity; var $number; var $date; @@ -58,7 +58,7 @@ class FactureRec extends CommonInvoice var $date_when; var $nb_gen_done; var $nb_gen_max; - + var $rang; var $special_code; @@ -91,20 +91,20 @@ class FactureRec extends CommonInvoice // Clean parameters $this->titre=trim($this->titre); $this->usenewprice=empty($this->usenewprice)?0:$this->usenewprice; - + // No frequency defined then no next date to execution - if (empty($this->frequency)) + if (empty($this->frequency)) { $this->frequency=0; $this->date_when=NULL; } - - + + $this->frequency=abs($this->frequency); $this->nb_gen_done=0; $this->nb_gen_max=empty($this->nb_gen_max)?0:$this->nb_gen_max; $this->auto_validate=empty($this->auto_validate)?0:$this->auto_validate; - + $this->db->begin(); // Charge facture modele @@ -197,7 +197,7 @@ class FactureRec extends CommonInvoice $error++; } } - + // Add object linked if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects)) { @@ -210,7 +210,7 @@ class FactureRec extends CommonInvoice $error++; } } - } + } if ($error) { @@ -268,7 +268,7 @@ class FactureRec extends CommonInvoice if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'"; */ - + $result = $this->db->query($sql); if ($result) { @@ -326,14 +326,14 @@ class FactureRec extends CommonInvoice if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1; - + // Retreive all extrafield for thirdparty // fetch optionals attributes and labels require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); $extrafields=new ExtraFields($this->db); $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true); $this->fetch_optionals($this->id,$extralabels); - + /* * Lines */ @@ -369,8 +369,8 @@ class FactureRec extends CommonInvoice { return $this->fetch_lines(); } - - + + /** * Recupere les lignes de factures predefinies dans this->lines * @@ -394,7 +394,7 @@ class FactureRec extends CommonInvoice $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; $sql.= ' WHERE l.fk_facture = '.$this->id; $sql.= ' ORDER BY l.rang'; - + dol_syslog('FactureRec::fetch_lines', LOG_DEBUG); $result = $this->db->query($sql); if ($result) @@ -439,20 +439,20 @@ class FactureRec extends CommonInvoice $line->special_code = $objp->special_code; $line->fk_unit = $objp->fk_unit; $line->fk_contract_line = $objp->fk_contract_line; - + // Ne plus utiliser $line->price = $objp->price; $line->remise = $objp->remise; - + // Retreive all extrafield for thirdparty // fetch optionals attributes and labels require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'); $extrafieldsline=new ExtraFields($line->db); $extrafieldsline=$extrafieldsline->fetch_name_optionals_label($line->table_element,true); $extralabelsline = $line->fetch_optionals($line->id,$extrafieldsline); - - + + $this->lines[$i] = $line; $i++; @@ -480,12 +480,12 @@ class FactureRec extends CommonInvoice function delete($user, $notrigger=0, $idwarehouse=-1) { $rowid=$this->id; - + dol_syslog(get_class($this)."::delete rowid=".$rowid, LOG_DEBUG); - + $error=0; $this->db->begin(); - + $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet_rec WHERE fk_facture = ".$rowid; dol_syslog($sql); if ($this->db->query($sql)) @@ -498,7 +498,7 @@ class FactureRec extends CommonInvoice $res = $this->deleteObjectLinked(); if ($res < 0) $error=-3; } - else + else { $this->error=$this->db->lasterror(); $error=-1; @@ -509,7 +509,7 @@ class FactureRec extends CommonInvoice $this->error=$this->db->lasterror(); $error=-2; } - + if (! $error) { $this->db->commit(); @@ -548,7 +548,7 @@ class FactureRec extends CommonInvoice function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $info_bits=0, $fk_remise_except='', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $label='', $fk_unit=null) { global $mysoc; - + $facid=$this->id; dol_syslog(get_class($this)."::addline facid=$facid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,txlocaltax1=$txlocaltax1,txlocaltax2=$txlocaltax2,fk_product=$fk_product,remise_percent=$remise_percent,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit", LOG_DEBUG); @@ -601,7 +601,7 @@ class FactureRec extends CommonInvoice $total_ttc = $tabprice[2]; $total_localtax1=$tabprice[9]; $total_localtax2=$tabprice[10]; - + $product_type=$type; if ($fk_product) { @@ -703,12 +703,12 @@ class FactureRec extends CommonInvoice function updateline($rowid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $info_bits=0, $fk_remise_except='', $pu_ttc=0, $type=0, $rang=-1, $special_code=0, $label='', $fk_unit=null) { global $mysoc; - + $facid=$this->id; - + dol_syslog(get_class($this)."::updateline facid=".$facid." rowid=$rowid,desc=$desc,pu_ht=$pu_ht,qty=$qty,txtva=$txtva,txlocaltax1=$txlocaltax1,txlocaltax2=$txlocaltax2,fk_product=$fk_product,remise_percent=$remise_percent,info_bits=$info_bits,fk_remise_except=$fk_remise_except,price_base_type=$price_base_type,pu_ttc=$pu_ttc,type=$type,fk_unit=$fk_unit", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - + // Check parameters if ($type < 0) return -1; @@ -733,7 +733,7 @@ class FactureRec extends CommonInvoice $txtva=price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); - + if ($price_base_type=='HT') { $pu=$pu_ht; @@ -742,7 +742,7 @@ class FactureRec extends CommonInvoice { $pu=$pu_ttc; } - + // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker @@ -754,7 +754,7 @@ class FactureRec extends CommonInvoice $total_ttc = $tabprice[2]; $total_localtax1=$tabprice[9]; $total_localtax2=$tabprice[10]; - + $product_type=$type; if ($fk_product) { @@ -762,7 +762,7 @@ class FactureRec extends CommonInvoice $result=$product->fetch($fk_product); $product_type=$product->type; } - + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET "; $sql.= "fk_facture = '".$facid."'"; $sql.= ", label=".(! empty($label)?"'".$this->db->escape($label)."'":"null"); @@ -802,12 +802,12 @@ class FactureRec extends CommonInvoice return -1; } } - } - - + } + + /** - * Return the next date of - * + * Return the next date of + * * @return timestamp false if KO, timestamp if OK */ function getNextDate() @@ -815,27 +815,27 @@ class FactureRec extends CommonInvoice if (empty($this->date_when)) return false; return dol_time_plus_duree($this->date_when, $this->frequency, $this->unit_frequency); } - + /** * Create all recurrents invoices (for all entities if multicompany is used). * A result may also be provided into this->output. - * - * WARNING: This method change context $conf->entity to be in correct context for each recurring invoice found. - * - * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) + * + * WARNING: This method change context $conf->entity to be in correct context for each recurring invoice found. + * + * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ function createRecurringInvoices() { global $conf, $langs, $db, $user; - + $langs->load("bills"); - + $nb_create=0; - + $now = dol_now(); $tmparray=dol_getdate($now); $today = dol_mktime(23,59,59,$tmparray['mon'],$tmparray['mday'],$tmparray['year']); // Today is last second of current day - + dol_syslog("createRecurringInvoices"); $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'facture_rec'; $sql.= ' WHERE frequency > 0'; // A recurring invoice is an invoice with a frequency @@ -843,30 +843,30 @@ class FactureRec extends CommonInvoice $sql.= ' AND (nb_gen_done < nb_gen_max OR nb_gen_max = 0)'; $sql.= $db->order('entity', 'ASC'); //print $sql;exit; - + $resql = $db->query($sql); if ($resql) { $i=0; $num = $db->num_rows($resql); - + if ($num) $this->output.=$langs->trans("FoundXQualifiedRecurringInvoiceTemplate", $num)."\n"; else $this->output.=$langs->trans("NoQualifiedRecurringInvoiceTemplateFound"); - + $saventity = $conf->entity; - + while ($i < $num) // Loop on each template invoice { $line = $db->fetch_object($resql); $db->begin(); - + $facturerec = new FactureRec($db); $facturerec->fetch($line->rowid); - + // Set entity context $conf->entity = $facturerec->entity; - + dol_syslog("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref.", entity=".$facturerec->entity); $error=0; @@ -874,12 +874,12 @@ class FactureRec extends CommonInvoice $facture = new Facture($db); $facture->fac_rec = $facturerec->id; // We will create $facture from this recurring invoice $facture->fk_fac_rec_source = $facturerec->id; // We will create $facture from this recurring invoice - + $facture->type = self::TYPE_STANDARD; $facture->brouillon = 1; $facture->date = $facturerec->date_when; // We could also use dol_now here but we prefer date_when so invoice has real date when we would like even if we generate later. $facture->socid = $facturerec->socid; - + $invoiceidgenerated = $facture->create($user); if ($invoiceidgenerated <= 0) { @@ -912,16 +912,16 @@ class FactureRec extends CommonInvoice $i++; } - + $conf->entity = $saventity; // Restore entity context } else dol_print_error($db); - + $this->output=trim($this->output); - + return $error?$error:0; } - + /** * Return clicable name (with picto eventually) * @@ -938,13 +938,13 @@ class FactureRec extends CommonInvoice $result=''; $label=$langs->trans("ShowInvoice").': '.$this->ref; - + $url = DOL_URL_ROOT.'/compta/facture/fiche-rec.php?facid='.$this->id; - + if ($short) return $url; - + $picto='bill'; - + $link = ''; $linkend=''; @@ -976,7 +976,7 @@ class FactureRec extends CommonInvoice // Load array of products prodids $num_prods = 0; $prodids = array(); - + $sql = "SELECT rowid"; $sql.= " FROM ".MAIN_DB_PREFIX."product"; $sql.= " WHERE entity IN (".getEntity('product').")"; @@ -1089,7 +1089,7 @@ class FactureRec extends CommonInvoice $this->lines[$xnbp]=$line; $xnbp++; } - + $this->usenewprice = 1; } @@ -1109,7 +1109,7 @@ class FactureRec extends CommonInvoice return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } - + /** * Update frequency and unit * @@ -1133,12 +1133,12 @@ class FactureRec extends CommonInvoice $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; $sql.= ' SET frequency = '.($frequency?$this->db->escape($frequency):'null'); - if (!empty($unit)) + if (!empty($unit)) { $sql.= ', unit_frequency = \''.$this->db->escape($unit).'\''; } $sql.= ' WHERE rowid = '.$this->id; - + dol_syslog(get_class($this)."::setFrequencyAndUnit", LOG_DEBUG); if ($this->db->query($sql)) { @@ -1152,7 +1152,7 @@ class FactureRec extends CommonInvoice return -1; } } - + /** * Update the next date of execution * @@ -1185,7 +1185,7 @@ class FactureRec extends CommonInvoice return -1; } } - + /** * Update the maximum period * @@ -1199,9 +1199,9 @@ class FactureRec extends CommonInvoice dol_syslog(get_class($this)."::setMaxPeriod was called on objet with property table_element not defined",LOG_ERR); return -1; } - + if (empty($nb)) $nb=0; - + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; $sql.= ' SET nb_gen_max = '.$nb; $sql.= ' WHERE rowid = '.$this->id; @@ -1218,7 +1218,7 @@ class FactureRec extends CommonInvoice return -1; } } - + /** * Update the auto validate invoice * @@ -1232,7 +1232,7 @@ class FactureRec extends CommonInvoice dol_syslog(get_class($this)."::setAutoValidate was called on objet with property table_element not defined",LOG_ERR); return -1; } - + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; $sql.= ' SET auto_validate = '.$validate; $sql.= ' WHERE rowid = '.$this->id; @@ -1259,10 +1259,10 @@ class FactureRec extends CommonInvoice */ class FactureLigneRec extends CommonInvoiceLine { - + public $element='facturedetrec'; public $table_element='facturedet_rec'; - + /** * Delete line in database * @@ -1271,12 +1271,12 @@ class FactureLigneRec extends CommonInvoiceLine function delete() { global $conf,$langs,$user; - + $error=0; - + $this->db->begin(); - - + + $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE rowid = ".($this->rowid > 0 ? $this->rowid : $this->id); dol_syslog(get_class($this)."::delete", LOG_DEBUG); if ($this->db->query($sql) ) @@ -1289,7 +1289,7 @@ class FactureLigneRec extends CommonInvoiceLine return -1; } // End call triggers - + $this->db->commit(); return 1; } @@ -1300,17 +1300,17 @@ class FactureLigneRec extends CommonInvoiceLine return -1; } } - - - + + + /** * Recupere les lignes de factures predefinies dans this->lines - * @param int $rowid + * @param int $rowid * @return int 1 if OK, < 0 if KO */ function fetch($rowid) { - + $sql = 'SELECT l.rowid, l.fk_facture ,l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx, '; $sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise, l.remise_percent, l.subprice,'; $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_ttc,'; @@ -1321,14 +1321,14 @@ class FactureLigneRec extends CommonInvoiceLine $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; $sql.= ' WHERE l.rowid = '.$rowid; $sql.= ' ORDER BY l.rang'; - + dol_syslog('FactureRec::fetch_lines', LOG_DEBUG); $result = $this->db->query($sql); if ($result) { - $objp = $this->db->fetch_object($result); - + $objp = $this->db->fetch_object($result); + $this->id = $objp->rowid; $this->label = $objp->custom_label; // Label line $this->desc = $objp->description; // Description line @@ -1363,7 +1363,7 @@ class FactureLigneRec extends CommonInvoiceLine $this->fk_unit = $objp->fk_unit; $this->fk_contract_line = $objp->fk_contract_line; - + $this->db->free($result); return 1; } @@ -1373,8 +1373,8 @@ class FactureLigneRec extends CommonInvoiceLine return -3; } } - - + + /** * Update a line to invoice_rec * @return int <0 if KO, Id of line if OK @@ -1382,16 +1382,16 @@ class FactureLigneRec extends CommonInvoiceLine function update() { include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - + if ($fk_product) { $product=new Product($this->db); $result=$product->fetch($fk_product); $product_type=$product->type; } - + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet_rec SET "; - $sql.= " fk_facture = '".$this->fk_facture."'"; + $sql.= " fk_facture = ".$this->fk_facture; $sql.= ", label=".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null"); $sql.= ", description='".$this->db->escape($this->desc)."'"; $sql.= ", price=".price2num($this->price); @@ -1415,9 +1415,9 @@ class FactureLigneRec extends CommonInvoiceLine $sql.= ", special_code=".$this->special_code; $sql.= ", fk_unit=".($this->fk_unit ?"'".$this->db->escape($this->fk_unit )."'":"null"); $sql.= ", fk_contract_line=".($this->fk_contract_line?$this->fk_contract_line:"null"); - + $sql.= " WHERE rowid = ".$this->id; - + dol_syslog(get_class($this)."::updateline", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) @@ -1430,7 +1430,7 @@ class FactureLigneRec extends CommonInvoiceLine $error++; } } - + if (! $notrigger) { // Call trigger @@ -1451,9 +1451,9 @@ class FactureLigneRec extends CommonInvoiceLine $this->db->rollback(); return -2; } - + } - - - + + + } From a4ea9d9c03f64ef6026e48d7a8fa90af77bf7d76 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 27 Aug 2017 14:33:53 +0200 Subject: [PATCH 173/174] Add login screenshots --- .../dolibarr_screenshot5_1920x1080_a.jpg | Bin 0 -> 227972 bytes .../dolibarr_screenshot5_1920x1080_b.jpg | Bin 0 -> 126498 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/images/dolibarr_screenshot5_1920x1080_a.jpg create mode 100644 doc/images/dolibarr_screenshot5_1920x1080_b.jpg diff --git a/doc/images/dolibarr_screenshot5_1920x1080_a.jpg b/doc/images/dolibarr_screenshot5_1920x1080_a.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1c6e2cbdbdf0c00a5fb4a513e407f9b907fd067c GIT binary patch literal 227972 zcmb5We_T^%mOp-zkRQziNF_T9l1L&9kk52yAweYk@&*);4?iO5&Xjp|yMQr>;txPj z(7Ko3;2?yOwL}7>1%kG22Me9jsWXF;O4I-^__CMiAO7JV1fKus{ZoCL;B{usdk^4{FMgPCs_os-Ld2SJ0ip6-DV7|;?z0CODMu;IQ!DQj($HrhnMh=&U zZK1mGl)In4NNro~V>0>pn2c6kNNBJ^sgMy0d9wTI z3FS)qZfn@ok7Chp*lzTz<$3v6e*TdkwjH!41nLvrY_qM0?Qw)glVR)$W)szNLK+;* zkunXIZYj~jRz~%YdRI`SCXV98F-_viTih=X4%tM$ytqm)rm%*zcpE5DO&}?(f(-1C z&`?>bb*BjkA}o`7eh#Bq%_H-}eFcuQIzA&w$B*l*q$T;g#x#h8y%(BN_6^)R zyCeLtW7L}aMpmI9g%?L;R8$yy2n$Q9$>H%e0x}pwPp}o7+?}N}Lk5AHusuS zu37YM6$(YxwQQxFl%+Th*623{2h&|u3l0!#IDa=-1kp{1D1wo`WpCxY^KHdyaet=T zL)ASix||b7Fp~KhMvIjcT9`tSrCJ&+1nRz?P#J%_JUIi>LaZfW6m0JGp}&_4 zLJ@L;`+m%`>z)DHyg^*Te*LhAI#nMaC48919=Te5bk)CLz}N&<5C#pyZok`TwlNI^ z5iDacnp1m^#lD*_XWaJxG|!dngkAqD;~P0+ZxJ| zihP9Db@C*Qw(?N)D;C!;I5U5sh+FSt_W9c*uDcGovDqr;b`9f+W5?&A=hmkjV5IP} z;!scLpCAPNGqpEbbYSrC&7fcr2*$MZq0OkFcvvgQ+Xk=-9j+i2MT^( z#ke|>NiwcVHgj_&n~KI59z)kz{>P(oD9^r)`+wW`uchS>C0Le%Db-J84@~KGI(_{5 zOYJY)qgpz2g7W$!cDv0|B{vOB<|`F)@&}n1B&-wlgS2wj;qDh-3JE@skP^NP4grr) zUENLxjWPm z`|m~z>u$tXAI!X+vQ;WiwNChFn+6;;33~nTN|EJK@rc{3xa*JxiqhQ7=(A65!|LwF zs{Ek^%NZ#Y@!d~dpP2?`#nKn(4?KW{V&bE3s>I-eN)KWkt{=LTa5S*$7j6?K8yVQed(@$xivF&ZvN-VyMHsMExmQQef`<6yp6OmV!uUq8V>0yIdot*|bV_hQ zugS_Gw<%@Gn!GT>)V5%md)D+eMYxZNX(UK;Nm#sU1m%RBTr%vid^kYTuLQv(VBIPD z-L`OVZ%hv?fZbvdzjFNg9DS4^q9X1R#KPEz6v215wk)G?2v(GnxVfZ<@XI;4Z}(gVu{_s3L}J*S3Wy6ztH5(_O|wz98j5zCuCt1WRQws!1e%Ot)Zp5?{mjJW0|Y zT=LLw2zoRLs0W&FY7NJYpf%Y_GAnpGm_O7uz zw)5cg=q~Bjkkyq;rqIX7+uQdbWw!?EgS=<7uq5V`K9;prI343c}@ zf}0yGRClmjup6zhm|PLgW03UNuvhyWcBH7)>SVzI4Ixj4Q-&$j5CkRcX0zqVCAA4# z@ta^mNU@a0H~apqHU!J-$yLio=hw>Agu+eUXLk$@O=ZC4ibOb*;KfxCBq4|EhS_5z zWmJePBBr627K6Y&2_D^1CKKnn;SHM}7`BQS8mfku;E+A=I5FM2;Rdeu;)*5ZbA3%)Jm=ZDh6@ zFzXi91M~{_LlZ8Ife@PR8XHR$!OA{SLu)z)QjSrR%9Aix__-ZM9_N^RB+V1c>ma&Z zP5W6@;&jt-lZc4dgbRo44iS^J(gcSk`auK&LqHHYq>gY4C72b48WK9oXFP?MK#yV8 zadC_@{@?&!7|8;XlQ0vqHAKdMfu~)&r5mG!Z-d!xQkcQ5kMnSY7fmFp z;w0!#RkDENRsvhF2|MKEk(l~!wj6&6YeH^LF;|Qsr2sexA9MfL+{=!$fJU-<6STn5 zqxj)suD`f8um&#!y=4=kYPO6ddTA|SQW?-v9v}1Mnt-JrStv~6N`r04M(F5;+JpN_ zrTCGY!PgK{C;}%TH*8@HBgp6TXgzSmK6-PPg8P1uqrJg3t)nXLKiqBjf&Yy)d+DDr;9}1 z6roh*UK{_dh`@;Jb?BU{Eja`FEr2qEp;imjYCa)TCo_^XycfQg5?U;OYq|)6Whff6 zu>6(TWJrjN&&S>EOrx-xuyo7#Bth6MOakB~Wh{F*B8#>y3>=%>oqH|4*CcXuV=#1t zf);=ckVQ`@-AD$5ry~fPsM^g9Xcb?(9F`Q4kpxB2rz|!44%UQIM$3?`is<32gP*IG zCu44)C_XSh=s#|~!Ezm^i!4BG&JOCE-cMudzi4x(F5_T^VQJ30@%}}laQh^FmH=xd zj)1Smig_B$BzQEKBzO@2Z=1_#c(=CFquxU>D_0tX1aKe)!^KE~&dHn4tZLtbNfVU! z&6)fAqK416U-+{9!dLC(gATg84j2~-<0Ad>s;)G9*q!iA0tf3lH`O zdRKvU4$X(gLl@OpG;D?Zv?9DsFj_N_*EiSRd`{jxINM%7+1@-YxjHQ#&Niu&b#b(P z`R@(-MDPS^gG&Li4Ef}XGuTr4O*j5$%TgK|u!?yIjgmDvS#hSegH9>!?nQPxVkh3# zRpO0R1?6>cv>J_uhf5&pQ--&i5bm|PTNm>N=h~9Ct8zo`dSp+v-=1ziJ|6B{dQH* zD^pnoje~bQUgjaXpv_HvJ;j;GOV%ot%7VeEe8pARoQHp;$?A6yPrHP{<|G zUc8D}N~M&MlI#Ls_PO@sU-){cEHj4>>ZLZJjU^;W1bay&$rp@{C0Tzb20=Sm;0{<@4QK?4r`i9~-<=?`B9 zW%I6J3FDVl3Q0i{Z40HGiH@?ai4{rDo*ki}8i;IK<;|%zdcA(4;9R))LzBtea;UH| z@2ceJw8V53%Q3mwSswfAJu?%28L@RGr-$MUPmkV8f7h4#I}xxlIa1hgxEdxLP6eUG z>V(M9ZC7I?>-8F75m_BL5|SJCcw|?x^R)u^EW6ESqo^urs2iXszQ&(s1|zk1*WN|L zzC8;B(SvC=08A;ueci1SrFMmUV5%@}gI(3DFUj3PPk2zs(4*ROO`UC?J)Ik3)(_Yb z2tG_4Yx+p?gR1=?s?_B!EmfSgQns7IjZJ*#f_Y0{v*pdr1_hKB8p4OuiP|_Nt{j(? z9XVW5AMNI1sBy5#hO}i?AgQNRiKY-)ghcf zH;gP*CBt%wBQzvzam~za=cVznT$7xZue=$y#^2vRdtf?W-UrI25Z-!hwL~_bW|&1# z|G{2uYd%oCpdlFx`@ziFPHPJF;_g5E!7ZxfYS?`53OGoxKhQx}17-s!XSYy<1`8fg zj*(hxiLENtz8`kDAt_F1>kg6C5tI!OlLP7mU!H6dZ0 zLK$wH+^!7wJyuaXb-W}p5Plhdwqck*N$jN||XJQx&gxlz-A402K3Gd;{&xaBt;;b2_in(v-clUlA^U0UynT`^tbV`>2_h%;< zpRMuh+!Jfj!OZ_{!=fQbejF3v8G1)pEK33+Zqlx7U0x1h`-pf)RFyV z+HrG{x?Yf!BM>C(M6#^v!?n%#j)A+S#WoN8XZfaIHHz$)iZQg+Ol*wGl zIu<$8xFc%uQb*n0M%%ryf~%5dd$`F+Fq#cmy|wfHPt>;?hA>`#+c0&Z!B9Vvu=Pke z2sr5pW+Z1AsU8J~W6@+_l10Mm;7~$D6KKrJPh%LCJE;l85C+j!Fhz0N~*DxxMR;_I}#_tWymRPZT5StUUcv%U={ zNqMuNPQ%-$d$!^E;G7QyOhh;81w92^Rt+mbM>oK7p!n9Xfjk@Re3GXT9LU0 z6GXKe)Br1)=b`?p{p1BPnG?@qF-0~YeS9gEBIKekD>p5SA8YgE?`$#=e4SRAZE8+& zG#t=+W!l1)AMDN9&D9l+I$xQUyff8aKBns3Qski?u&#rG*@>L}n^oLfj|`NL$U zB!KY{6dtfby;fs6~8UErUlFc1tl2jO5*k7sg*JWsP;*z2kY1(CGO5ZOU*T!^O>E ztv=$G4^_^9*|szQki?LCX|}r_1>;f5)DS8Lbs?(^4w`K$ z1U#I{wy&0ykE(ieipGZK+v~@oSOz^9HolG@FVtyI`@Nn1dF>H4J+4^VJcgRYUl|EQ zL=88r75SM^7w_S!N7E zN?1kzn#shn+!i(Qd57(C>G0_CRMPg`=Tz)#8I&L;Ro}IYmECu((B1l|E!CPZQ7|wo zDW3$cFKR3uk76AvIyk?m1a)d9yJgAyvY@f{*$N}BDilE*=+%W`u9nJ@ps%gQA0+mx zQ43O1NTM5tQr%pCtXiIOKobX2%^Tx z#3^1h6pmW;2_%9?dzI{2!+d8qf***=)6njPZY~qfLoga=pj-#!o~LG|oB;S9IX|w_ z-z$>=YXcvRiJ8LHI0498xJg4p5CPcjlRH$k!FRz1W}Xg%{jyxn%3+vH1GDB9V_{kW zFi-Ypk&8zoI9=CST9)6`P;!k+R_jKp(^bqEEb~-=@+hOc+ZNrLz*#Xp|Bo zUNE}a+@IIy=#hhb%Gta|(zzq{1T8shnQO=`5S0l+3&w$$Ljz7%>$}fymGSlY3RyXZP zXKh~P?cHhuAEzU%6Sr#{WAkAR9af#(AQSL(x^3aUqfY7Mc2#e{ym|4ss#ae#mN{u2 zE*(|C>|(*`JXh}jmo=|;oM1v&*)h8VqfDzclv&6ma&#nklBFhM`qem+1kiTO13P#X z0%!OGB)+QHDsFIh#0Y2w#^7X54pj62k0v4XdZ6``@{~GVhR|js;+6i2Ho=gaR2gg8 z)9-|OmBWTRghSpY9}MnH!HHS(aBGpr(A`G(g>t)UBy7&ylHCXD3+BDo?%B}!pN)GE z1OC|PIGaG`?8gJa(lzdep&BXdoRk14pxCgsHjrhevnsbRaR^S_rU;cA2zw737wQQP zmaCyL@SwVFGM-MORS>-Rf+ws~D+JVJNx|h`MMnHbQc?Bcxi7@Op3KQpauOCx~y zk4O0*F5&758||~^#lwXjK%bKuohF0I*}pTg|H(^z)qj=JjU9>s<;4kcb0%$qXlY&3 zk2o3!2!2i+g#}3f{)RYgH05KU;WA%|$Wp%gDVv_{a% z1lz%&8`d;IdqHjKS>-A-0F;aj1`ugwbJnpD%)@%<^gt*^#8WFxL{=6Q<188H%EPYQjQUI!#B3L$Jbt#ZoyzSn!2KG;4m>ys?HB7gSpx@>OhF z_w;tsDK-J+8wv=f6%q8Ct20K$zW(Ux8z(wd(bUIY|0Z6LyN zCZ#JJ{VXC^Ouxrig+L1Yqp46qg9AAPWEanBbOIj9*RB*=rM~0u`TZjL6HtuSbzn3M zZgN0_vmTj~U^2uLhf8v!=fwSoN;ne+eTJ!`QdwXR_wjo<#0Nr#on#)C#3F`KH(r+mG1+*fh{_t70JGnrc1ieLcp1A+rOK1@@} z0d3~$efykluNvalcWPLP3vU2*E1T z!BT(}dWOO91c#gZv+J+4BD92YS1N-!o7hk>q{V5#!vA6Gk-u}fA?iPRZUex^ZbSJD~WjjWrU!d z#(2ua0=8Lf>S)Yc0h-iJT(!cM|HEM(8IF;@>u>@`xziYz=G7Y zJXwE#=zkSNQhG_!{Gi|2yAZ#J9u6aN3N>q`1XZ(^%^|v_P!>`OtZA&4k!&d-EI3W> z^#?TRN5d4zMK^B9tZ8}UAk~fcoCN(Q+Prht1uNmVn@!EBRTzwP491EzC5^w(p1^5J6C_p`s{hw-aoDGIy&x|-Me$eYq#8c^~H$+-%|87<8Lb7{NtA|*H<@}1`g2& z&>|O)M0q`WIJPFm;7fO(wu;?uA#UMB4iAaU zZ?68CTl?ii?r(oLyk`6lX}O;ABj4|X>P1m!pPdqB?C@SeZwD-F;Yaf;U*FRpGf7AD~yWjkAN1~T} z@t=46W?}k%?dj*Q|5r;%=cN}&bz z`d^MNcG7pnY`F>p=-JPr`{mA^nR#6P__~HpUjd{rlC)mSkPFhl<5n=4ttcu09K(B> zJ`N_Txi@G?48w$_4Za&(2!mhbK0l%Cc0(7L6heZvgdH^?h-YE%{QcpGH#|S`Z5F|J z`aN+wwrD|ozxF>KKl|>#zWmqlFaK@R+~e_1qV z{_fM5Pd7c<-?`?}CtrG6pT=BAHy9%kFMV;u)gSsrQaaHY9=l@y$5Bu_47lI`5vt$> zD3FU4FjA6qaV#m$0?>rfBSPHdt>_}3xBq2e5*~iQ6j5{@2r1cDu5DK(CT*4_!Ah|? z`r(zZrnFB?)@7Is4!czs*7-hd249x_vT|M99QCu;w)F4nTGwW=XlOaO=4a#ocJ`k? z{`%k6jV$;tzvBDK=f7}RHw-$1>2K-0y7}qR>zEiO z;}BwJBCfU72PtDC5(J3dY(22zWJZO-uZn~o&~}{xn;I+w;Uby^!s=7i9twl@SU|!I zIBeB0oWV*Ma3B!9cBQwUOC|m)6y7o1vz9*l_)xHkJ!_Pb8_!?0;C>b`7pUWjU)kDP z>A%t&E`|221Q`d*LeXz+78_+}QkY7lFX;>hAAW^StWmyW>-(;iRrW-mq_53MxM`?{ zb_xz4on(hoQ^?(O?+n9={BJFCv3pHWXG-jIO*SR$70E z)5Ga{l6QaTf0Kle6kPB#jDOS#vra(Is^!U9e9TY|$=@1%^f&&6|O46=c+gR(I zq1NUzICGyie z#g#+#{dYP#|2eyNxA%SW$8)*AF7FdoY z$=zN!mhFgQ^~Y?uhO~-8Bou;2vT{YU;ACt1Lj(s%20v%N7sixcc(j$rB(vSZ#a;gX zrC)aDL@u6Mv1`HOC1`)zdgz7`44NHm0j+WBBY*kz-XZ!|uEw}vlw|fzxxZ}vU1IQ8 z#<4e4w}xJP1yl0tJzbAJc^>gRlb?YKM0(yWFh*--SNvjQQ%aSMS%r;5_W_oi0Z0&h z7`1r0{RYVfNI*HQPX)7rwGyz>uZn`jCc3dQscyC#VZr6Ci^weu+-*AA<|*7&E4ooe%XOipdVU6Dv7sD^YtGN5YPbWcLV!>6Ke*VqKy*1 zffb0{IOG={UHbW9LGq5(zG>?RrxDIhnkPC+M#{?iKZsyQY5%06pr;5HNVu6CBuHIy zGLq;KttKcMD5{eHNeArK;nF*ej~8px@>VTR$5ZDkEbo9dxN7`*O?B8nT&BIGMGm1 z_JYNh`P{>iT@5*4OTjZu<*PWueNp~>Q5!#w@-Mh-xZCvF?$f7e7as>JNO&6@-jxqp zVU56W!a>6EOK~m4L(|*k?lr@CqYA|1ZtqTi>?-`J=LbS03Ab@571v-}#1Zdh=Hu)DK<2*k^tB z)|=lwzv_w*d5Ag~jQOUv6~bE{12fBE@~ouYF||D$DdT`S$kJtwCgziPYS;N zL5~0VSCV(3vw8d@zs)F*0Q?3~wR~KP2L?@UU}J<&OhGa1QC@}} zA>qD_nO~uv=+?NVh=Z zp414J?vsH+hot^!vJ zJ}DG&ed2pjtarka>lbBAMJyaML{N8DjSI|e^fMVj`ugiiVbutl&JXa*cNWQ*{;6Wo_EZK5``&A z{irIig^BnkwA*%VbM);a_dI($*Q)~D*z6FwfMf^LU6EoT5;WrheLy0K?uy(5*u>+# z7(>0_0LW`S!ZUg6Dg&WoFjCZlrZhPx>CTcCqsMd{ak8#ykDG8)t1+Qe>%?M#i7&kS+$bMOgdvf`;;e zn&E6@Lw(0G2e0i2MW2S>Dsn&FuRh_Jia$^=Hh6pN*o@(ZxbpmpOMjN1Q@DX6;h@aQ z#HY=4x0^x=;V~;%r6@bXfB1+@%7Hl4;-IF-VqJ&a6qpg@4h=BU<#k{J7z~E#?%4Xp zjoB7!R`=@45Z!ippEXxHwOu|M-j9t-h;$Q+tD_^@XVx>tZG*FY&E4;hkOM z`T8t9a_lSiJ<2^8z5cRU+fdMep#|JeM!fHNLnywEbS>xt- zFQ%mYj;Gb{S8`ZG#xc84SbHOjj`bir$`()sgSCn>6!ZaF3~t+pN!!CspdAgI1kj^c zT69b(s`(i)xmVE{B}bEo5vbJI`ewW8 zXR3L9e_pxCGK&g)&ohaaQO(Da@(acl`=%dZE;ucj$7%xLGx-`+)**@PztYE4>E&hE zrs8mezaA^KhncT}<+LUtA1B2Ngr-*p zUApIL;3m|`$jI@*uJLL34d$Ig3Vp!D7;Ti}+eG05x79v|+2uf0g@V*gsv0Oxqxy7| ze|8_;3oHxhwc}b*%BVAVUSylz9umTqADNT*JbU#o0eep!9{1ii{UAuQd6lrrjlMO2 zCk%o;bb{rNKtx@coq9l>=6Gs<5I^f-adxO9AI~^g7UNB#!LDl z_nPY^35mhtnQVtjpZm(3xw3R%ve1DfkyNi;R@s=(bt*rMeeQW+1-Ur#8VWc`)NlF=8wTs)N;(DWI{aS{oHo(`t zHh@)XXNUWa;I5T-LDhEdbkRox{4@pu-a~5?ojoZ{)e_a`%NfT6)dSH-pe03$D#rGIaRIrvd7?^w3p7s$Zn;nOeem{z2H78uTzA` z0dKKx(PJvk0IW!_-xrMq6oB+ChwO1Nj(oZY@N7nuISK90RkP`ecqJpbng6%1KA4tbQ!a)RtU$ zuvT9@BE6q_Iw)cq>12ljc&ZeG-_jaiYAQcbQ{h`)7uo;l%)&Ttr=28oK>v{>AQDOg zSVB60q7fcyn$4BwlHUBnlMd9oZLo#;j@_Nywpujn_iBt(N_-bUi|AU7w3hs+*iufy zI*c&-ji3bNArrw38$k##4&S|Y!n0Lew5*NqPSsp5JZS^p*XB4_y}AvUb52~@p>5rv zN|-QcTTwoeHe^To_DHoNbd{-+b=t4Zv#_+XD^x1u5pGyg)&z2?It^8EK+fH=dVZlt z<`?Z3&T$epg^4%%m!6X~pHb<9CdV#S|E;t%A^Sr^CGR>qC4JDd;Dk^Wpwu7alb4qem4cghCrT%E zal)I1dv#m6s8rCsxy!-wdSIairI_Y^W5JlL?g!K7I*1W~1%$N88cdzN8<-qskU~xc zERsRo)w(TmqcYQUO8%wf#|zg_1002-5Qck@+ib_BdriVE3T)AssoE@6ao>wImQ6VPRPt`PQTf$2cW3b2 z;j~he?G0z!Rfz%Tk?q${WQEH6mXGEN7CZ)Tjfd^&A8qwU2^Q!wDbbBSfHW`}2-reB z)F(v8io|QD8TD9Ec1PUD*#?}wqO@Ds{ReK|Z?lB>$AGkvjb}$3=LlKng z5cnh1o5m3|4blV8lTnExgLMGK^o|2JqNcy0z`b^R*`m3WrJj`JU81(E!swbOzUWMj zVvVc_v(<)NLzp&mn68b?#5&8B)<#>04;7{kUD_e9ch`4iURmzxy>IjVrtXfar+KrE zBy<41V7md=qPkK<0FC38sCu>r2CfSiS0ZP4eQI+=E$?Dc+O%j&S3*z1cT0wlg)YV+ zI87aim^EvEyK1QuuJ{Q>&)Dk#7=|!UqXz&3ze7|b#tjnRJUm((a(6trgj*lh3KMqZ zvVflU{HV(5j`MdtJ$BWG4NdE|tMrK>b3Wp(w+h{z0h5I&??z!UH{g=HbUJ5CL@x0t zu|2wU&Laf!BSPZ2#t+-`u)&fZGrAfGRl8aIrsGJ7?+E(Pi=4%k2luEK7mmxES{v>~8@#Zny_x(XEz6b-#w z%anuB&8H&toR-F|Qbb}!W3%umS5^!RJ?vdul(zoFwVc8+@WO440O;TYSs$X}GH}tK zr4Vm46r`Npr+a$5-gQT46EYmMi)>4#JJF-$WP!O{2mF()FG|b)Lee~feMJq0jnkGn z?-hgJU3C47*sY)F3L)%{YdgXX=QoGKQm?m#p?}qcXi^W5a6XHK=S@a=4FDz0vT5MB zSYBS4$1Y)0So6TOqA~R?kAhi;hphW@-l|q_lf?9R<1J^uB23(6iB_G9$#kYK%h|4) z??OfL>6s2~X@M{!og%l!YL|C0Ea*oEQwS4&^s>@mXPq z4`djIE@#DoWz-&zuu`}niUBKt6qd@601(F1V_|J$nO~TPyCWAjc&^>+b*Q*XUg>kjz{8+dQBW=gNw5L=X7CtcQ<^+g&8fo;C(}YbPJCxB9zwWHS8R|{ zOg)`zL0u}%27tjLPzGs4rMDs6T=`Md@Q16~3x-s^C54Xh3R)(D@R1y~MP#89JPn}D zO7IV+&mwB1fSC;SfV2HY_Q!Q90jvhiugp6e?wgi5EoS8{G!>R@Tz@tq@wDd~Wm;*5 zSbHq8Bnh=Q zfY!rbI?nFHwhhpHu-)<`Z0Gh@V85+?;&@ccN2?|4Epw8SclNY4c7v?xxnh7jyiM$LvjWd?TW$XW!lPOxWwMJQmqS z6(@3#aNa(uV`=62i=gdVPsmM9s6vQP{$j6%i5xh27YQrw>e>K|TMs$NA zA`y&A*}#?bW;czYW^ItM)bQK1h_>rV&~VII21NO`M;}PQ~Wzlg`lkiN;9c!|228`w9-w zd?gT8L%G@zf?8W&UPfi9J!<0#Rd3o(56833OVX%%BW{S7WT#;z$d_L6Wr7e_ejNE% zaRHH0h>4=|rntQ`Uv|_@#n0t-sVqIjOndf(xpKoydctmQmnuM(DxK1L9V+vx+2?(0 z{GHD9@Q(Z$A8~&HHjGsI?+L-i2={~uuZCUR`NdJtNi;KwL`F^=stPdHZVF{EG7M@G z*bq>Wk~Jd_4X|PYTmHB=Yo~kAnIT#zrl@ykQKRevh4)wx1e+iPqw|SEir5|4^*((D zngyll*pv=aJ8_{iF6Qbrv-ZH2aC6JzNo*k4eLB&5!Q+|y%spTBcIO@3ZnRM0#YPM6@pOsA<+1Ryfz5{FU)fEL?Q&SH~L zdHu0VS&##Xts1ZtNgAX=!N37BIvkFM(a&Vf190&1AF6_eNXP~{O}uzPl6|4oNZ}(6 z5SD6A?khEkJR9q+-6L%wuA_Ky?Pb#EM=gHUNk%OmC^#q;)dan|Z>YCRmH7HjkJ4)$ z=2?PY3TaEq7O&9HA;4zlP|KgQ`)-fdc0@myKkmOIVO(Ju^TSN$uDp7zz!~3zT>E$p z_QjG~<2FuU04L#M1ypa;jRrkzsS>~hxX^-HR{>zNQmM=yn5|T9#@Jyi#!ZSAjfaBj zqmjcOL}byQfVSZvCQG;>Q@er!7DhpVYaJcC=&xLj-cg>rZ|~w)D~yw+tUjfjk(5)= z*f;bjs3WTDlbACngx#S^w+N@hYec7qh7pDeMm z4b0U{_TV+`vNn&>$<9DpHrU4es2Ts?M)onl$CGql2nFg(=R2r}x`@OhQ4`tM$Bwyr z5iCWNn_+6daeusQ_vx+;=VTA!uXJ3RrwSU6-GMH_N}ewXvNukD6BJ-WVP62DEA^TW z+PQn^cFH(ew%Eas$I|ex*|+v#q9t~4@6KJ_;ilF$L8>)yLU~|k)7zb*2nz+mV3LQe zP$14=Smf~g zQLIm6*4t&Nwd0=4%lfaj-@t<=!X)b_+HWit)s$(^cXWd)5cZbrP8>@=C@%WEGb@I1 zI)XEluT;vK>&r)?84tRShPn~G(r!!-y;F0*Dy6)|MH`M)$pwzH8BAdhLD4v@vu&f!Jtcu$;%58tNwfB}WXXil&oc0l zoV=gDv&^5`CdIBg`4OA#(a30;+M#kDiP>PstUA-*Za=e-p0iyx64~Dq+4XJ|>rUWA z>4aZ+%sY1u#4T@dlqZ8HD0bSKytl`kd^~YU?A4G{C}6lJELQDVoCz|9VIy=wvs#b@ z4i&o_Y7!FGV((h2J}@vafT(gKn6!^3P+CtXY)s9A)7t>kVW~6E#YVXLBNX|jP0yM) zcF~`3Hf?Ji&URD%XV|v&JK3B^o$EAAPWvbKnzoer=b0{a%3}}h)+cO|k3`NKjqE>E zHhd(;XD03L*NpnqgqF87?m_1o4Ue7Hh>=%!)pT84F?jD}l78Q7D~^3L5@DlyLL+B- zqAG6(#BRavps~s4d5_}{?{p7b7aFPzlgJ-+&G)+D;R-%&3?3N==0K@fjW{}|Q6bv5 zN*BkL91AwMbWL{HzaFi@Ucu(MrUT-MTe%;FAWeeOAXRQxOlh6UdD5d4si%DGMi5;t zt~JK)FHFn+vg10EFx_s^p*O}8_9`a~wZt8d)`iCI=P%uJc-+0-DT*#Q@;GQBeS4wD zOZ9!#5xsBhDVhyR*c{?UOzLt#)&t%7`=eg5xg4Qfv&o&Fu0W0yMY`CW$z}tC(`%_< zVBWWJ{TcaK>@Qv2piunSe&%XNFjc+OE!z1R=Q~=RX8-phxJfy#qaw+LyXiT*Ih?@U zu-P_&y&(M;`z$jZ-FH1+8jqU!T>KUlC)Um-3ZLYD9JNfid~D!On&ozr#oVtRkCxvZ za|mnQ#5WDSZ|pmExoqR7k&Ev|7X2Y6`^z@9pz+rIbhF=zi2430FwE;uhj0wLMpE_- zJ{S>R%0U%B;ReBhy|q%1bTH5>FztgjF#o+S|XSv>&_1m!rH_iO)<-Yr)iEj6r-YAQg z@&##q&(;qM$0nb>^Kb%$Zf@Gv zHS60SeiqsPncqK0Zfx8dx(ZJL0(YP$0TJQIyd^fP&V*GhNN zq7v0I^;OCB2rfx~pi2dWy<5uS2UR16XbMNzQ7xA{`tC6X9Z#R#9)Ep@JUK6Nv8vel z>o+w{bIVGj0st&}0>lXo|V-MVAl9WZPq2;xmR_WPc%l@0gH>QF!x8<8LL(%n&~+rrq11&{2nRt!$L_v#7- z2MRm}pWRsOABcH&-{D9D18up}cpd0sHtVw4zoD2r-n61PSAbA1 zCx=9psKrXs4}t)W)MSXNVBeAhDLH<3JWH<;2<(iTo*f-^-*S72o01I^64h`_<~@N&_Ds5Huh$iy)>d<2 z+sR~X7E(m{e;7GzDC?gx-^7ExD%y`bqMw}!S=C;8D*EA^=PSjvujj3*+)!T50L~Hh zu-Qa6QBAKfbPNeR7zA_P2=C}7aw1R%3mI{~ zr1zEiwzK;DaKHbvYQ?}4{jmS~%aVdCk_}fohVG4yWbF&NH(pjU8^H}bpQo}uGEU+L z_RE_i5;aAhzbKu!9VD$Agpde0 z5w_DwYC5S%2h}8OJ?a|ia?za>foL=_E4gsHv9wj*_w2%KI=NT-xev?Bf2BD7y~vjS*aO>?A*)z< zkNoFzdty6wCj`jLP3kncEjs&VqYX7rW&H{R(q@*2BjaO_zX^I@5gOUw8(I0EkrTIq zj)j@~og>DWckZSR`S>=dyY2RSjipy4^3#!vA4H#-X~foWkI?#KHT|zi>6L~g4sFLR z)!6Dqku+ZhyN3dbG;ciW0#R?+OnW9p2<=~wov>X8r%ZoOh~_0XZl%r6vGTCduc3S- zL>akw65+VG|Bo^2Cq>q*<)hZbw%9Etx$noEv2(FrkKGwFIy;l15aO*S;>Z17iI!jO zTpx3kkag46#Y6R^>jPC{dt}R$uOlhGA^s2%!9C;f#AZDL-{1GlD#OMMui4r+%DTRg z*xA^mX51YRefx^o|DEWgPLG#Qg)L7>NloYy(o2kfLIf()(IaG<@WQO1lfpFS*l+|h zqhCY;!@vSXOzqAU+%PY>0)k&MVu^Vf&oGcMCORhPj23UPKUM5}{Y|$!jk7l-d3PEP zxMK%qZoss*Zr{*CdQut6>m~B$Tj_6!e_kp(~Ydhusb!2qc>n1;ioZ2r+g|vD=YUzdHqhY%3HkgUDStd{C(6!RX%qAHl7#y zcvsq2@a{LgUbZnSBqDGag*etQznsYaf{PuyzO4K;$Kdmq zzrb=7k{;{76f5VsYj@?Qtk+QGZDq}!)8rJ zyZX_LVRvoBLYjQKWAHu#T4660op-A#zf7}5Dfbw-v|P%k9Vy+)d~0VU3zMz7H?c07@V15k*fU6QGRVI*Fx-EE9ppbV*US*NvyV z9YhLed85ziknnaqq9XG`EB&AYuir-vAJR4!j~os6@mY@NS#;GDJ4KUwmD$*x)9kry z-{ZUKTgoO-1)AY4W__UQt&5yF-~MbN)grP6iRKNGmmf_Wk14p9+DqK>jNO$exHsOr z;;zLay12_(6PvI#=A9?;#yGJ*!UHVAuU7O8IsN`A0zuG+EY|weA(8!I?`Y%Xy~fZh z?GNuYt<5Kdle>aGb02v>=IWHU;c|iF?B?hT&hbx;k9zGMmK$QP%#jGEc<3_8Bhg!W zN^vhHrHQM+{y+ncAetkj!3sQ>Wu~>wom*B?dobcU3nh(MMzya@>9h8-t*W1%GLg)M_zxWvh=Ki zxY_wi{A8m zD@zBhmA{Q%f8@T$a%YYWu^ptJ_kmQTAFB*ma<|cXS*?|L;^m zT`~1n2~7^;RP3*}#HjH|0{+&>uHMLro|u;&zvZ(+`mlE(rhEXoYmKI~WrnkOq2t&> z)Bo8uB7G8Mi8+32tnX>_t;S=E+}DtU6kW<&WjZ{Xfd1k+p;(4&8Utid=p#vzctt}5 zK|cpYUmRpo1#K>I20LLwZo6}a{}^FYL=K-7d!bOx_L#eK8}=TO;pUlw=H&m!*jqrw z5p`R_O$Z(!1a}Ao3BldnJtVjVcX#Um3GVLh8rWyZ%MqH}lrN-kLR2G~HFz zP0`oRJ!hYNcL^8rS-E!Aa6^aLkBPbI16oNOeeZXO*|?^r)7FmQ5p73fF7g4zmKNT< zz(F9r3iN-eS708H^XcQDOy{XsCB!`#H3hLI;P=BTb)`|A$g4Z~t2@F;neqxAj7|f& z3*U80l1uSsZebFD7=e>Qw&fqp4&*_r_yXLrUAN?u(m6T*E`}BCp#uFHRL zW1b^CnD!fH$;^wVTA;j?=lD8-{TQL(Y|zUp1bgrU`M zC57S6q}mqTH`Ffxw1E_*jr>=^h_I#ZrLO>EznF{cm%IL7zo|K*g6(9$gzM%~Cs0Sg ziUMJ{m62r2=!7tW=WF6aOYj=l&EfCA_Q=i;=}Zs4)B z0jv{|`yu0DVwQxM<`1_^9-qT z@PXCTUt^#Z$B8WNTub^d|BlN8omSIh>(2YH44~-+ESc%DJqWK&8U?1zTUa=?ECttXADjd2UdnUX@%G7bS?Ue9I}s)Gv< z3ji2J?YI#+T$^2ZD7#nUW){>kp>V2>ed;!$`3`QvaeCIUhMax6MnX6Q!aeEiY(#&q z{=)Cdq0Cbq6M&IfH(>)3j}`Og-Ga`bM&dYRBip{_O0h_*bVU( zpq2^HgR0Mk6(yZX6FE0l@bowe`*{Utg$nD@e+C-`Fx%h6EZND8U-nJN?atbcBFqvw z04X~Z+>GJ%q}P&q=ZxzL0bT>pfWKJ)kM@6Wya<4lN5u#*gz}}N zirWtGRgX~>+{k+H!WFEj0V>{bh<87?ux;c!S#edDXy$psi2*=30-&7&A?<7OzCV|= zhr?*ImI($(7cc>u3OUpz)3yOt{0unhBE0JfulQ{QXx4SJFU??ogtCw?z#YAT!+7X5 zJq%DIx_?45oAz@nHS=a3jJp2mC(yMCk;_>FQWg$*0QzDpGmI=oQ3WlSGi%QJJ`Ygx z0eoLVs9k2rrOfFW&i2;T(Gk2k8^#8~6uRUvrx-<7Cg~!;vFziS13@3}h#6()aaS>i zn6VQG4-lXOj?!Nzr=8A-T~s_L{~TVZ$N+$%m|z841*n*4yH43Ir-d8?R2I~j6tXs6 z#W5yeX%^gzSlGP03tUU3IFn~H!OW&c__KS#csTXr=7x`&FtJ&;3~O*_2m-TW9a zJPZ)Ia4~@S_8+t@3-@jV2OvN||5zfJOa$^?fXF;6p=%eQhyriM)s@R9;o{rEm*iF% zgRznJ?VM7?vG-yjU6>bbfM@+eY3HvdAba#4@aprrQrz?xh(eB#`xyKH*>_;o5Nxzy zJ4df?IR^}&ncK^;wh1j*Fbt6F#NINp;SIy<>FOcs3OE4zu@(&McmhB=18>ByN`O;Ng`?Hi~!Fo3WUEHnrj3iNtUfVVJcA7J03laMkBV0>i2RM3TE!Xjg4 zVG|_(WJAF!LZD-Y=l_Iv_G821K$qG2l@=AydyWa#|F60M$IE} zp8VWZGVz^O;!~qwvS0=rauy%N>lA~3&hr^ZR+adM@dac(xUjIW>Pbt7)TNDwR*no0 zf$6YSS64q&el6(v!ANe8t)>cQZuz<=%gIHK+Uivkqjk_u1D&|~CkfU$Cw^@3AC(u7 z?8<8;mcTs(ynyO9kE|?w;oNs; z|6{hnJv8U;A>NPEnpwP$*P8qK^l$I~_38ig7r)~Q%6rF+k$V6A^!?}czmERrb00!2 z9u_4dvYN(h_0Ja&{)En^8_lD&C^)pBM9%14m-6iFGrT6-FUdcdMDau&p!!lT{l7F4 zjIeY_L6eX(8HCNqIOPh%l3HV@@YUMO2C|R#b@Qz~#Qw(X!bpd*_gXe>(k1_SNR@q? z;A&p|-A058rWdF)?b51SG&hd|+9AVz&(ucf(>mz~peh>y;cnzFY$Fs9T|KT&ZIdZ#XlRI(mTAjT zG1_P<=xzAE_Qq0YyOezE7~O)1^R%v0SbAg^^Da%SwpjL!x%10s=BtptucG#hzdc++ z9MIN3>y-?JW;;<;uxcd*!^!o^<9e6h%eXW~T+z8neK5EW##N8ypP&YZC1N5H@=m3n z6NSBiVvM>i4REQgF0F+Pa)QYl!=Ht2D{$uEc5NbS2|h`& zQFP4=c7%B`5%^I;LE9_~iV;|8YkJ`}G?1`1iY|W=YYCsyS~TT;Wjss2FJY*aKp zTz^Gjc;nM-Ze<&iwLLL*UDbb(oAuE)*u=yE{5b@aVQz-4SY_+Q~a zpwT104*lG+9`oAq^OFjz2|Z-NV(EWd&^v9s({VkBCoP!Xx~J;2BJTIQ_`O)EC%Vf2 zJeUg9xP_jjPwO@z7hw4}q&U|iK)-u$24#L~iZT;JFGBncCL6d9EtUadY zcUA7h{>(@apQ|-q7gX(kJ1s8s|GfkK`quyN%>Vq%|2_i^`FXie8KY;zhadlId%eNM zN*h1k@4t4?U(ay5$Z7v)=Ra=&XN2Hl!#lOA+d6R_pHYX(PrbCjzUK#zgz;MVziR?b z)sMljO?&UF{Vhp&e)AT4EB58SZsmVvpH>5sxz~9R-y-&v z4qB@(qX~k%fM5y7j%(yXR`)%CH&s2ePt7Y1d6G0$U^>ie+wL*-Z)BhIyZs*;4Lq~Y z_5foK161V;$R9Pdd~WR~{YgF$^~Ry@8kH{|v%^LcE3WNcljxd%<~Gv(vhH5LH7>$z zauQy!N z+3Dk}UMzr@X%s`N5K1)&SNj6G9m6c=e46EV*M9aS8OfXdgcukrC|iP;v_gekuz6{Y zAv+l;mVFb-irQ2DjGGHg*w-|C*{$&~z}ytb>dii1Dwrfd!j`QoD~rgGjmY{TgyI*^ z!V74}*Yfxx9i*svzyr#9m?sJ+XZV`}CWDQ?6?i zy&?`TU0aOSBek?Nb5-l|rvODMMIOIIe}g4U-hCcLL5y}0;~rx868LnPmX_9oqVtAg z0!WMxBwW9x5$ndot3``+8R{1MzEO_mlI!x@B{+$R9?d1VN1IV-Kxos)O0a{StY#Au ziC1kX*D111f#OtXI)VskU)ZXxTYAg0jbCsYs4h5qjE3MR;vye|UH8pJ%Pwb1H zwGFgo(n%jEhLtQE3KJ>c4rkcdGn|E0|$$K+o!4_Wy!MEt>yclMzh=J@w)jGNM?8*rPju$xPjCB8rgJhk@>4WhDR3ggJuSYi;lbUsKx z-D%z3b#2lURcS*|t(q0m*%p^+2XEPrTT+zux9lr`?Yj3ZA~1Q2?dZv-T`J z5!N(tTPZb+IN)}ga11Wbo{T#xaTf0SP#jeL4c6~Y>cGQXHyXkI1%yXwAAV;9G)E|= z{l~)ao%+i93iBUR*dI?8pkpOh%?#RVa zgdtu?$d;kv2E_{7x#yq?uD(l4vq3yX z0oL35nk9yB2GcGbMc@Iz>it|Of781uXn2q;5B?}``AmDgI<}B${42(It1%dZDWQ@N zHbPci7M`SSmx9E<3SG!JD}08vo!V|(*|Mzso$^I(X~sMS$8%Dh!)7BM)r`z{w+v)2 ztETj>?u{4FaD`$s4VYtfy&P+nEk2Y^ugkoT?2c>^><_LKbFgKy3rD|cE3jS7+xBR@ zFa_DD;A&rq#D2s>(ylbzK(u57 z_XshRQ7rM0AO7OXa4e^@bM=FEx^G7x7;_S`&R_8+!>yDZ-HIRi_~zInS>q`gKg1C- zp4m~g6pjni?2o4Btd`t5`+&+8*CL>Pa@atrx{+=W^EaMk@|z>U6)X=72C_-`1pAU( z-tYI9CW;R=tZ(`GuRcI<{zTl~6!opEJR{e%_4L@NKl*R){cFTC{=gs+0t$n(MoOS! zDyU-H=6^2qt`jomh9g^+RDZ)WirQM1)S5AIy(8Hk8b+gua%iVi75l2vXdycIS#*%g z5+MW%Dg$GUKmCetUpCIBu1af)= zM<;=S&0;8Kpe?W4sYDZ%T{50DK0Q6PyIh(V!~4y0LH9BwFORBs$g@uu%yJ%}*Tz}n zoLO}0-`e);4DfDm*GSNXCLwm|s}fG;{fcr~mFe2l-819?#PjN%7b?(totaaSA_ksr zv{h;DzJDD8OSaU0{P`l%O4fL>2t;d`?d9*vkbEwYBD6o!)5HVc!8|HilcE|XH#Y|; zycrD38~h{UCd5z{3aTkh?@QwJV%jIV4-^;i`3IhC{2S@(#+#rdz~mxq+(-BF3ZS`!_xOBK2>|=+h1T~aiPa+EjmI#=#Ld_8ixVzuzd#duPCnRMPg~-YZww4N; zcvwEJUg2JAH}5D3d0-ZXcEN3dc#VA)b4hg)=XKBaL^u!7>&VrjcE08G1^9XDS4_Y&tX42|KK+f zQ8N0+VnlXb-6w4}YUZzn^s>|*O=1cmLy1Q{pql04{9cGQ@socv;6QJ@x{4e1rL?4T z7zDLGW~LgGy0YW6*Lv2?)Mbhf;>X?X$@@udyIyKK>wRwaW+%eao7h{c=YT!PNaD66 z7SRj|j`}yX-|+jtMzRYqE@AK*E;{O$OTJ0T(bNqhOy*bLi6p)9-uJWXlT6#`hwuON zjzYRpK;3T=Cs%AeZ>^N&8k)*mV9I8T4{C@#SPWY8Rck<&fq^w4`Emgk;%=avSU{Gm^fvzN32%YAMu00v#EpP%diBfMT# zxOOTfa5de8d(F~LLo=S7ptb>~X2618w5Fz?&OAX(bb}rf7yDCX3jlQVn1X8l!m!Uc z06>O@+Yakpbt@OkgSizVUDf9t>MTZmy#$c~uTO$>hY zsgBM>Zzfg#gl`dJxWaW3d$-=A9`295 zfE@1@$&yBBo#Ee3ckL(el3mFx=qp^wUjMi})@wkhw;+6o(9R(rdGWy~i)CVlL6^x~BjHNOgDfs2JcB zy?7l@=MVftAYyELo+Q?7E0}fGhr$l_!g8_osMzAi*J;OH(K&jGaFu$!SQ3G#7_QN<)y1zL}%b$E&nEk6*E0)W=kPW@Iiawe!tM z9sm5zkLu;-WnI6M+Iu`2;=I)MFdoIxGA-3nJizY`y{!X^B6^6ezHpy%Bc^g@4Q4ZT z1=p>iMs1J3fX=}DD(o+yfo7&``rl7*GvUKx=}CRP*SwYN_mynmTrw56=&V$G_L*D-{6UfKZyTs>1>Nb?8^i(>H?n%X+iFia-%P zUBJ)!zShqpP5O=4g~SPkvs%)0MmI1|eEZZ{4UqW(Mvl(q@_jKo)o>Z0!2Mv(OU=O@ z6{d#R;W9&en#BKk;Jupm0(y|}tekSeX>)eq;i0~(J4Lm0tve5Rx=Y>0CkBz74bo)3 zfHt1J3awv25tm*@X~g-BQ$>0s;u8*h!dREeXz6W676Avix_|D?xj z2K!zQt_Op0)nf_Cti~&*fo|+w2TcOMrIR71OU0Og2L~hnHEq27=Dup(nSn|gc z@l-y7QZbjhre`w^-_lzVWB$T-bTv=xKP*~oah(+b*e1#}(p z09LTD?NczO;RtyA;yeKH^cpE^f8H8>J{#s}yZGgW^*E}9`~t$d*s~=PerpBxbRsk3 z&<}3X4GjlA>oH-T>0gv;T>S0mufE(bge`j>WBdF38e9Y9GvXq^=$@9pfU1KR?*r+d z88)B=X)lN@dul3+|FXvhoAKcxKDtI;s0fR{&f4h5(JTHx2Ic})=i>W@c zdnx!2*zH>1)*Tto*wA=uBCe^tsmE+DgZZBa(Aw^RIUu{RBm3sw z1ba&06;&Ch&-ecClb8vlmf*yQ7mz9AjE?gqI(X>L{d~)=LSKL2ilBD;K4WW$JkF4V zVl_-)=zYwWv+tGGdj6j$6V0fxp0SCkHAGk18vfkCsHAssG<{TF>FKlMo+j41_$Fs+ zy$uRM`h#Bu`p z3aG~$T5Vb)?@<2r*Sj#TiUGT?o2K$c>a4~Um*b{287BV3a@D2X}#k={1- zl8(fi#_`QDp#**(s8#&q1tmOIzLa#lmhs)(y7be#VHFLte2(pKAA1&wD@NA-88cR? zQ_Xq+?;QNsDTkvMveaKa|; zA}y5;K%J@~rmt8Rr{bKQMVq|^H&_8f`Eu@%V(uykEY+YQrWS9WNN3ufvJ}`*S76Vr zpl0ZOTXT!L#$Us_A}3jCGBGCm-BZ*epaLNfLuxA|pauN`@pbGBr8z14dF5qlE7$Y3 z3Y$?ZgpFb65h>DzpYn^J;8`7YZnR9d=KRaLMnz~%2Cw-nY za*4%Zr5A2Ge9Q+BRG7o9@86GeE0{~S$=#wlsLw6Y@7R1J+_rw@zzz$c$NA0CeW}Vt zZlTZ=CP_4mqO(2nHKWc69N((VPAu2Bg+W~sj^L9mlQt>+2w>6YOO4piw2$~?&!hCp zbH=~jv&g4kKxpS|Y%BXv_!h<%QYWSJ_hF(l`*R=G4tV+V3_i=HHumsQ%s8lO+}76C zdIR2}>~-)AYc5tq?baflo+X6pgi|n*v7*5e%TNpVzue?(x1W7f&&=;z4Pxcd!9*p${`iOSBH8}V4T-aydDgj zJvrmGY4yh5?{Iq6gzJ=SLJnB44=}LzFID!Z{j(==-J zZaJGX66?1#DCfBw&@`gyxW%H7B_$hYOg&dL_5C+$H>b4^6KT*r=ELX;mx7E%9Bf&| z2WxvS(w&nGZ#-buk=d|$dCwyZ84^kci!|dtg^bkN4qcqw0Bsw!dZ_-I8L-t6FvW*csny%MuFBU}w7axtZ&xWt3&YLM;$Gr|N#1=&Fp;n;_^uUpBsNG7*m;WkW0=ee}u5V+I_o!%TMbZXIDx|{J} zLa6SI4x+h~E$i}-lx#>)C+oA7RU=T;=V!ZoXvL!yNPMn-R5Voeg0Kkj{JJ{29idG8 zoJPmm-J>5y0cd%i|L`MLTwHU~`JSmM=+DRth`B_)K4WIcBy2%_!Mr}7j@lb*k2T-e zw4j1r`gs{opA#GE!}E4GdlhVq1(dB|qaw3psQ^U{^HT47=q^yi2&d=By9XtQ>x$x_ z^#R)r0ZlYB3w`aO``;Sfg;U3i6<=?so7}v(6J4l_Qx*Qwa0-*w*);HWXQ_PphbC-b z4wspCYkx+kM>kQUt|Nf9P7Mi^9prph7BEbfaAl=0VFdqf2)K)Q+xHOqf-Ula8n4U_ zrqjd~ZUY%)HwQNn%AdJ>(Q-Tab2{I)jJHzOYt=p@q0*qod#cQ&s0I)68Si+Zcwu>;b$Qy;{Mg zd|{)k%vDgKwcoIk+uyP`8z}cDowCqwH66$+MXg#%N9{EHFUMHH?F{jZpocJO2J;03 z#Wdk&ufo)!4H!FZE5j-}4HyZ`IBL(qg->>qe)^4-Zn}19?|vRSzku54pAH7K%2%8p zV4snc(Vw&{UO<}H&@-kkhHj<|Fvs;VaOD|__mqTbA{0#qZt)_2VPS8DkI7c2Nq*AF z@+gTHdu<=59`im;@hb7{y&*P*HbHG>WuCU31o;k`Jh)}G6Rc_@>K|Thw><8qIN^O2TJSIxLd4N8u!%28x)3lU_g)9n<>Lo*jX$ zXXz?#$Pw4>2avevlxG>f-v#&HE%kfEmKjcAkSjO>;YPg^1jeb`SpRa%`+Ob-?R~^* zwU~WsYf0A5wL6u7;J9aob4xcm$Y$Ry}!z$TyNzrTRA zvfPE8vu2OLW{`#DqcRYCShQy}h@Q+RcsyLR8gd@3uDu;P!ov_pY0pD}eWHxOKOs+Bm9 zQ5iRAl&4@qJ#I6L;OTNJcW|0;y& z>G(xjU6DVqm@nq*h3SK&Gnw4Qeq)#(HggYtu0=F$rYllU!$`|qjevVH#pI&9uI zo`MV40w1!cB%Oxjf$*l)U1#a%xPJAoWFgCsoH%3e3HN!GJeNELK8f%8N}0Rz>(~qF z^Li$}fJE-u=LieBJS6?G-9Um{U7b}?4e>0E7LnXX@y1i1XS9??^mI_mMyf8B^IzdV zVp8d?XxRJ^<8Ael>={hYq={Z4qFX6c>+TG$l0y{ z!36;e@RKRK$vsJeCwp!0Q5wH{O~DxXsxH#Ri-uxGj`rv9N+5v?$c45*-{PU9m0KkjQEqjpl zim{`R%Ce!l2PwInrGGCix+d1TZ7#N~yL0zEt#nZstD;)i z%t5=g^b;S`6}+dZITKMv zIH`YCXtWNJIha|i);F45Q7$_<5qYg)_k)0S1;PYCRl95!94L<3$&NM;uqkIQmJDm8 zQ+d|HnK#(Li%;zAlJjqzZIU@cw7icGA!ek5?Lt4hsNkY}GaK6~xoS2qV98*Md`SxvUSXjeD#hS*%k;FR|7VmI#7>@?TCt)S|EfK`JFl|`d%r#L&*c~-Z-L- z@60_tXiy5?)<|)d-(?ZS}#!<_)M<*{dJ;rcofY-Zxkg6Nd?_a$Fi87*MOGDSU*b zE?3D1#A)-IOhTQ~O%J+}WnwVL0)C)CIqFEWZQ8g59;zD7PWwGOM!qZiev|$X0CXMu z_gN{wK7C>b@|)keb-AM>1@C2S-8u~J9@QrEd;VTXepnhA=>7GX{+eAN0#9H=WpS)>x)^9Q(6*u@j z$mzRx#K+EjYo9Y|e}|(g)$>$o$Uh=yo|KwTh6AmsLQCkA#(l)3*Coz$8^+86@&00u zw9JqE+bO1c%Rrk0a z`A5$EO_@3nYN5SL35ul3!*BT>EbS&e3R3faBT3>s!D&1o=UYjg-j=PulhWWeTZtz> zA^D6?7cf3*GBZ^9gC^q--Q@|%PAfSoV|yNQ8Ufa&Z!~C8ZN7Bj1$6&otNudfQlD+N zf5Beb*J;fOUE?P3%?5;Gk5~lWzW(}JLxYy*<)fhi)dSl6y4g#GbKX zRu$H{p*Lo*-aeDTwtCcGfkmRhMScGeZ8j>0Sw7!QC0t$n?pn32)d%dcAhi zoA(MMO<9Ydmy{@AmTEm@<9);f*TZB5?g>AlZ!V;FmMwY;hm{#0)OMFS8VPO0b?xx~ z@ja`VqsZeeMH{NYNR~I3I&Cp9F87nN>eQbG+c2Jy?4B*)f1~9>_&kU8@fP_;_v}Yl zg&XTU-cEb7GVPyo6sFeHT)Z+dN|cUniaAmwsP%EN%UgogIj7pXbLUl)23)jQZ0mY> z7y^+z7{w(*%cWl<6A75DqvE5m)8BGq#iwqx+XVVWvZ7|llqd)?>Pt3B>Pt6EzI!CE zQb?ja&uu)Y^C+xWz+Im|h=s`TZ+9Ke?(v_X?Y{qcwYW&KumH(0`LVFM*8#RWoiN7c zu($q&=POo|`y?12e)6ChV|OZ(E``h1fT7lp^>KwJ9uwK;trb10@rO^7d_$;6nqc)8!dHyHc7@FNRCJ}|;H1lB6ge{|GMMNhu-mDI-7#PYe+K$6wQ zno82Ry{@f0y;(Gm+G!Rs6g}`#K*z6Mt#P|362x*|AM_NB?$xry%n_QL+$h%nqT$4! zK|5UF@Ey$b3h)qr{Yh$Va8Ilc zSwWDyd5ZA>xmyoQy?_8BRFEA8Tkocgy9^yo$3t#N8NoL@8<`gnBOf6}-4X4jDWubT zfnA)c4R$=@7bPhYO|O1D{8DSGt-C_B^r0JTbe6rxy%5tcX#qN2vX5JJt0ugxk1-Kv zk4>*BtXJ^kb^A{~3&OfVk7lp&h-@{bk$srFpRn=W+Ew!yy#kBUvn7bs#h_>|nQd7* z)tz691a>v*`KULW#J}&h{G#a8g>&g{aRf5~wdYG2H zc9+x3kVA$u?L&N$w`|iLdF~VxWW*S#nSyO5csiG>3VR?KS~u?1EF19$xATZ(EU*#r z7pKtYijf24w09QXYjJV?ljyEi)EuOgEciJm$G0*!CTDtl>G6?5U*G>x2}9&ToHs+K zuM{z-2bIIPSRx%E0a@7*>(g*i^y@rhI1l8~($_59YmN_KuH88#w(NRmB+Xz=LrXqq zImhLtQd$m#(6Ls0Sp0U6WeUR=ll@&3iPWMlX+Z18=*9g>pls{HcG=G2?ZO>Zr3+1h zQrKusC&5p2C8QLk@Q4saEN2z)DLLlNjmg06Rc)jc_pIFOk#TL4{eq0x}=FGIH5ORRs9g;jGHo@5v=D}Wb zaLeryiMx3IZFTxt!E6an{69?Hv!qq%JX=_269ny;9~kcN0f>!tK~b{1(y2i-gTo&Q z&CmN!cD#?Dt`hN$2US>T-g)pQTtqV079?K)(ZR4S!u`PJd6fH&f0bJGqZ8lEAtI0_boI)(z97Nj!+#duV z7!L93^D5S+x)vJuQ?bcnwbODHIS+qvZ8(g9lcN^vSY3|#V%sI56T!ag71akJAzmc} zyA=&IL2WXfGsq^z;dGb9E0b>}mi~(NSz@bq&-Gnl-#IcR>ufD6GnRY174!bjF$fNF#v~6ZY4l~j)N|DWa&Lyj@9+F0NKdK< zI12JFe?Rtl*D$l4w3G!ra-HEKK?O-$PN!3GOGpK)U+$pYk{DCYKaf5}OG~h_F@66+ zTU?Yc%u|%gE0(m=3tCf3?WwKOrjV-1Q?pKzoa>>GfT8`{qR)g}!KakJS&u(i%c;DF z6I0@k`sHiwk1hKyg$QDD=0-B)xZz6Gq4+VE~uO$Mu{blHOyj0(s^=k6*0T@K!38!wdVr5+IPalj!fIkmS$}6 z1*8Wtsx$LL8MzY9BEsZL%M`^;#BxxI_%lRiTr#gEr1~YI$lzD7`{4sxZ|(pn zr}?Ik7S>;9Yk#h(4*83xhs%~XLMW>KR$T0UZHQ5xWb_?D`x>dad;}q0yzh#D&8UNg zQ_M_$CheE04OZrkqjDZ6T>TH^77;CFR)IUGZ^KrzlW|4t1WdqFVaZTbyk$0K8?`F* zB2xPqbLN9iC!IL;w5|f`>Y9prWY@f<*Q;wt(gA`=d_!RnUMlj-a`w5td=$k;D*2_I z+X&`kbHCK{E=i%cJ2;RW?~x7nN^ERGmB7)hlR06wLfz687B|enba};`W@QGhNry7$ zc=M#TAm5LR(?@zaK8uD52IL`uZcV;Pkz^;_t;YHi>ybEYguANDC6M$agQUJ`sW=o zgcZUHW2_xIa(2VOY<*d(^T3M1o6LO{G+hX0ZcS;q<1R+o`2LMmRm%$qTBE!xw`@UO zG+3uPto@p(WsX-s_%UY&GpdW=F~lk5#ILis=?H>QiY$GeumT{Vq)>^iB_5?)GX#K4 zOJ7{V#`utD_}zL@9Ln;AcxK?YKNwV*3oEMP5$3-Bi6aZ10h?b9VwlA}4eo7fM#2tc zI6QvmtfZC7j&~3spVurcuJpJZ^+fFr6g0MqAD6n0Cna(m{w5y|l#Dj{x3^cv_I;<+Tg&Ur|NwO}OQsg7m?O?sneX4S*$=HibRiTitiqaUnjeB?V}J(DEhW>RAw z1$YNUB|psk6uj^;*^BuPG>FnaWt*1DBEpA^lCajzcbc^B1O%rm*FoVcg`;_a@pR&_ zVtHtr2GfP33U#R_#l(JZ(xVM>#tC;j@ufzb$&=g^<_c5|JO_frv2Aan4`^j-EGcbV3>iPj77bOlfDeQDUn?NyZ1}aWJW2 z>f}O)V3^Nd2>&=u_)=>a)uS@dm$+AW=C3JBFdVBDvQHsF)?X=dZ(&c2pKwF?mL>H# z>6F_9V;N>QmnU)q);W6GSMH+j45k`jJ;lXE>M@q_2kUTr@XsQ)y;Mwne_g{q9!e2P zM7lx24u*H1aY{8`Fgo|&s%ey!HMK44z_3=MIR3mjNyV}|*H*2X9<1qf5}m7rY_*?1 zA^NRDF{i;Vn~RQ4c%Y?@aq4$&-8(uT2&NA6brVeuZJk7JB_Neeu#81dYAZN}nUGnI z>2zc8JGkI zABEEN!mSHuE7uxZ8lgZZR!-j6;qVu~92?hn)DJCTlQJ-p834rR<=5 z-+V<-%_4L36Gg5}@PVW-C1J<5XTqxus3W?3pw;W-b626v8))BKSX%4rgYP%gOX}f? zHY5`NfUZ-AN`5MC##1ggBr)5++u=GvbwU48<6I)$fK@gz0H;@+WPh3NZ_!+14c240 zb1=*!ZHh>&bs)0FSedzI*f=C!B4UP4h-!MClc*6)GOH?LVbmzZjo9OACZTqqL`kcn z*BF?qGT8UgU4zNNO3!Sycnd90c7w7Xxa)@+x&?9-Cs9sh!JYpWK$LtXrvV$}Q_Icd zMi69_@Mh5jIl}=Ui-zzgsF!MnI3a1>`=Hx}V|VWwI~WtDZY7dw6B}_%ol9wiyTy&`IZ2>n zv6DG|+v_KFdV0^LIE*C)_oEW?nC-hfg}zK=W!+fL9X?((#q5`OxymlhFPke%$v)PQ z6_)#Nqx<#h4v$Ue?jhweOr3^>rjjtBMQWZug?+BSY6r2>DGo}1+LsPB#WJowq#*d_ zkqAez8i8ZM_9L=KWl%hRui?!2As)N?|D)_Jfa2=5by0#RxVyUtcL?qftZ{c5cMZYa z-Q8&%f)m``X*{@l2$tLb-sjwR-mSW?-tMY3*PLth>gt+nj44CD&-yU`yyB0=syu_77Ysd)HRd#lMBGh!oy{PJ@tTw4q*U!R> zXvYkk2PQ~#X0{{`H2!ilJ1l1A462?fe2BI6_{ujBKc>gsVG5rCl+yRES&BOMW=39J zP^TKx>^er#t7+zH*_`K&QjErj_?=GWQZjLG`Y{v_VHX;%)!+BQOwz2) z`BV49WON#mn#UdoXj^3=7^$EAhH_fS3a&&FJ6|tK5}JPUUUFU~%5k9h!oQ@vocI zn~1i&DQBBbVjV(CIcHZfV_AlSuN1!wo}M39Y?wzd@rdmIIHbcqwKC$G)B0En(zuyD z8&(q`v#&VrgiREEUbP#bi3(=GH7h$e-E4kptu{)lZpeI0HKJV!*9o19rqdl*-%$-H z&REl|@MuyMiqxxJ|I>Lf28r(d1HNjWZ)Yhy4hdIsIl3{m;>P0IGR&lP4j5iH-Umt* z!g!pqJG-y>(NKp;{Bf%`Wzp62`O3JOm5TmJFE(!aH`q{%Hv|3IHI5rztV|57Alm}T z$4$8@8s?cx_~oinQ@s|qASk#UNG}=u<*F89TgNN<5!(=*)FUY@1C+O`QKj8zaqC;a zyw?z2sU1VsC_Q2?Fc!b-tFfhwtCevfDgKW}t_80mce>k~SZ%Fb;ANq(TGwdeSWzK&)^K8(B|5}cf zdW?wrt&`ESJ&a=~RW1EP0ZtE3w`dh9$u{woig(+=)?0EUJaFIb+}8hsfrbC%QFn;y zpr@i?sWLK%=@c#Mz=sPP^~siBXB3O=(%cFOi6@T|8tqDCn>o@9;J@YS9$0A(z`=%dD z*}1Aew_2ZnF;1R_UxM_4e4Rq59+7U*JyO!vODNBN)Dl0#6gF6sO#lYvsRXroxP0HA z%zj!;7mE11b392xYxVsGGy7-p>B#`hF__uQn-&&l@(H(VAEDC@Bwg)|$7Iqq-5d#x zOvKf)G2wB!G4*|_NPqim){*DJ`G7RC+pS~XR zq|pqKLH8aNx`ShIkK>f}Q0YwAmTYxB)%V3Enho5xXd((o@RGW9j%X}EyBxJKfsU{N zX5MxIwe2v-dS+Tp-mu0Xie};SdV}5ca@m?$au&5^KvBrvk{sjM$WrY3iLR(rwCkHN zQpxYseD|j=E#-MJ#E^iXV2DZ0F52D&vf;1YiCFm=2y;T$T^En!mXVe5)#cLzVAbxr z1Hp5?E~3do>!bk3&fRC!#<8ap_#^f=0nHJMhh98YxVtBZD?wC%jGmpz8mlFIJ^&(OAVg#F8H1032?FA*RBlII-J(mn(b9`5byR)M z0qrC+*ABA6Jd)IUz~pKK21-}71FH==H>pNfKyT;X;AR>v?BXIieX4DzmEEiW1Nop% zuGUFws1X^Q!%t>V1FXhXt8vR=;#~8Xf1$`(PNf0vg~89KD3P4{JH1l;8VOW}S;aMQ z?bgJw?M+++Ifrmqyz<=C5PM&r4Q@H7?G%qP#~Y7!)=2?7ICm@~yERO-ta5mC*PP`R zA?Wfi)I-|Iur{<#!!4kml)<94x6LDI(z(*bM-A+|_=B*2!4`b;gg$@56P)6L@{sGD zE8P-EUz*B{>}&4minrZ2E!+ZLv;6#UmCiHFs_n=j$tt}(k?yclm^{YlPlANv^HuZq znkn*Q9gC{&x~m=&JlCAaS%j2aee}1J;)PoA6@oL|Hi;=dRwmiF^>>7x7f5ytj|MfI z2)wWe9_Otl5l?S>?VhEe=OAfiuv}M6zUn*hoQLKY50Av>#Kg@w9U`opOgR}CeE*;4 zcyE?Qf1w(~EM#boN5bQ#b7R!Zxk_4(=+-_6Qk?0Ac2>o)5(ii&WP;Y4m|VD7I`A~Q zCO$Z?U!y*uw4bf0-tN|31i)bz0YXc3qp|k(O9!4rvd`>0T#ljEgi9B;Bwajh3|&1J6q8O@D5-RvFuBN?ef25z<9d zea|O;Vhhh&A^TAMO;E&})?D7MShuX3If@4Jvi^eeFAsI)HNQ*4VeCl=t z)RnOkbyzDD-WWEJQJf;1kM5J11Jl;s@kyLt83r! zF7g3PnS>|vRP|$CVqE79;|cWJ)D|c`39bI@Thmy}(y~UvXDoP$+nFgLEkOvj&q7%8 zgLJb)59~&Aw2||rO5-w}`3F^vUdVo^W&^vh?f{L6GsM|Vtp^5qr;1+^(bI*e1#GL} z46%e@mew0OWyWa*irJt?Lju0sTU4ov>LJlV70(2Gmp=^dvu20?P&W|E>R2qKoD|#} zSXPED)+r7dHZt6A$}T#$;{M@>_RBQPj#|Z161!g8ue3NPz zW+NP8b? zAEtlB>P7dvGDoi9Zu`6d0ePdYbLP%Xy-bqauSkXD`LwfrwKbq5y7u_^W5{WPd{Nox zvLp3)S)An0qSPkdcH&^|$2#fQWKiTSi^V(jm)QhAspL`l*rn4IG zXSbyZ%W{>)DneNMs}@coOX7UxnK*a-1lMY?8+@5u8tz{xYyb&ioaH$6ciEaRkNh{* z<3D#@I=xoECsWBpa&ql$79mpG+hD7{Lm%hO^nU^_&=}bT>4x@LXOG?HVSEv$6ATzw zUc|4)s;FnN4JvV8={0V`>w=%}GWk5YrdLOgPt!xo!zBkHX3)_m{g5TE@-zcw4fZH!M{?ve2z`7Q+=2Sn8^+Y`8@!D8|aA z+s3uZkXPLoi`T`~X?PRvEuh3H0DYCEs$|=dTjA2cwkfNBC>vU0rg|EK&Us+YhX~W@ zXG?pT7S6*eIi@x=uC_IOOnEv!Q^q&Dq>+Nk9}+Z2eO4Ne4FGp`-iYfM&1A+jW;v1b zX|K-opy>E^@=~GfWPX+F+WmNokApzou+NEq4))zVkYg&fR!xC<2uV_+m}BQpSV4(bIc`% zcP;7X>R?Z;tZem`ztzIH4De=%AJUx`09&4)O={Zeg`QE5yg3c%Mo<`OCoc5yN-Qi? zFYhZ{)Z+fMy7WE#>QxAIKOemVm3-n1=-?;U3fM`P*81|dg@Y^pLh(d?HM7hZ2sYEe zE)0QZ6|rYw!qH=L__c`vJ8YaTEr_~sPPb*OD&w*q4y9lHYo~_$ut6s+GjX7&C~nNA z&VH_=^ic(@V6dOrP|0>8=O9zb%)`xm)l>EJQ6n7>dl*^CD@}ZZFRFz@IZl?={9?tb zt2s&k25)ocVmcFqa;Ts}TT#khv5!WmD^)pHX^cwnE!X^{ThKArA<1kX3rdyXctxb`)5HX_J!NIX)^7ml8YR6s~&zf^Ad_;n&jdM-!C_E zt!V$^|8%Gpy%`t>;vyJ zDPd*7I5G0LuDhwe_f2D#_#&v9I;~0;)$dn8}cME^eWH2 zO;iAKaK}^Wo*>a}5?@KS<|CtRZPX^enR+mQi<8gOl1t+Ga*{PibG<~f(k^EV$Eq32 zY=2f&r;skttXPR>Dcey*yEeGoKDg9;Or~~b2dh^v^L_rPmNwT<~&s7Xsf7YO8G~yvD$bK4t7m$kIeY!VmnWZg8!A84)WK?#@i<& z`*Uiowd6jXK?T67OZhkX;WVkV@V%(Mh!H^xz|GCNj-uTXPMAwXoNC4&$|;8882%|1 zNy?U2Jex)vj($|Tz@7k&&njXwW%JRv|pU9h--k=VDM$_%S(7h9;3nyyFzl} zcv$oqn}+tb1JHlUyGC@# zCUwAT9FAMzz(9rOpn}li(E$9Gt}yUPiGBJ3t|CO{+P`e9WXyAIu3>CxE_UjCzB)H) zODV|+k$+<*gDVwRLK`w1 zaG?cY(FEU0!+|Ud=dECkgJLRb?V7Vw#^qnF)3+OO5DVCloW+b9*xcGMX`w-z4O)f| zr@knL-(52r=Qcsnl>XEf>%2BT1u&J`dO?p3Exb0%EByl zB0|%Lc?MnjPxO!b)P_lszUZo0MuQ>XLOVMrJO-?$k{2x>AwJ@iOU4|LIAT4)c7=VY zRFaS8U-xujHNk}F_J~2t2~yRc-&Nu?4c9^?j1{+L61W9+AU&KbkaVY;`M{&3PtV8) zMv_Q2I7~vnNf>0Ha$}9tj34WOL!Qj+o)}QS;;vGtb@3b5kFnF-?M&95bY)L{`xF}s z$iH7Q>t#8b8@o{w3OBp>g-1KQ7a|JO8}yiO05HXjo0Jq%<7s$OhYHd#7wOS&tOpZ$ zoL0^&X*z$_Qtc~QKK34W^~fjej*SAlWPD_3Z?sQ7>D=465NydubU87gRhr`3tpgMiVt*ZqHm8%RZIZW6xkG12ISBr=SZg;X4cg zOZQ{1-8S1bl`}vFZ4+Pld!w|$f}H-8MeQv76cAe%KM1}{R*=6hXxb8AGv~gM!O}0z zm-@P5sVTW7wuF5#Dzh(fEqqvA;@yPI^=;CAAxok)zG|--gRF0$IV9q{7LIbHH!?=! z#;cehJ=Z^7u4+a&hhsUM{RtyAsk2vI;a+8^n!Xo)F=uQ!oGHXK;H@+7A~p{P+j1 z4@63&72L8^*Q8eJ9h|Mes9l`c$m@F>yuUua1KeNp#B)UAwhN}!@;P9LIr7`+jS1-&9H#^U%>uIs|No8(<`1xtc4iyZBv{^BMHYIQ((QP0qa1e`B zZ{Hq>x~f%3GCIU`sQV+ag`3wObJbtkSmfq5vHOw~&M*ytS^<9Uy|9n?GR-xv@e8ng zD}V{+R@>4F{yAFkyiJpdRA`zMJR@R)we^a>=Za;gT-DZacA9NH~5B0GhYh z_<77q)x>^Xv%{y0kTKMLgGgJ=#IMi!>tcS z>PhS5vI>m^N-X1AVR3S-LLy{0wVq9fZAsztr+h)p1r!6)LEWiNe6!c{%DllEa8D8_ zJzC=Cz*u+OU2os%Vg8|r%_3*8t=*sNE~R#GAX7~GpimCfR15@3!Xv$D#TPURd)xLm zIRKRh7Tr5%Lh2EJ*(EnjB|f}zJxxUS&hLmPTZ3qyDL+b5VvzNQ@sFj@`B)NK(eA1{ zr>=*5mX5hFbq5tsi!&h5?*O&FAB;#{V#wgk+)>o8=?XgQd$hro7%oS$K#|xC326M8 z98?F3%C1EdAj^SJ&V_~EC;ZfpP}FqigItc---00FTcx$6;5IV!rm`~Ms{2LNYFcKy zxltO&)Vr|uWkk2dE_3#o%qd6QXa0751oE+b)mfd@@(fsib0N!#;UN)2Ed~~Qkvs9& zH2bVgZt7^F;5sD;%;xTi4Q?^+Y^X?^A7IBr;6ksi>eazkFnILP1qwLP!}uuDqb8_* z##g@5)8DHa8*8798zanVIbZp`T$KwxUZ{a%fK!;|XP@`OHe9~0PQG*-AB)c;4c_;f zL#Ce~cj9=pO~3FDZWiP}Ckmc#;u#l% z;Pez(V-(k*;ERtkE3VWU1UKh8B`LSnmKvkzKW{`LZKVma<)Wu4|lada7|mgK4(oah+#a_-F^AmOD>;nQIw|VzRoLY2sFWaIw<~u|$f->K3q8H3dAn-EpLc zv!*CcZr#^qY}z-_mOHem%bv>ShaSkVM_K{iB~8TgiiwPJxs;#;KYsoKOeA4;SX<<39C&FzlbpRwam(lAi9IoC#Do<}Q69|D}ISb;?@-VRXko0FrA{9P4n5w8u$`-hc!SG>!-%P&$zsaRAIhmQwBS} z3tA3OXp^QH8yw~kQH#Mi|{r}wq!GC3a#7|N@J zQw8F>=!77chAy)c1 z`{PN%GIE6+5Ma3(^u~Im???va`viEg)3~_#=7%mAE3+tewv#o!G=a{{lrHFgcl7ml ziUosxgg_Xu zfqs8Gb!t7YKEb@cwE8l1PNg(*|wzD5suyOdzxh-@r^`Rh7Bbvlrpbt_yAfgPd ztbDIJN-7vsoQV1?$w0Z!!3P+x0VEag<=ckoJS@1}@F}D-0v!`3>_JAF)V0AVF1zLP zHw_viBSx+Ngmv_q%(Ey*%6%F)E@}g7|GBw}TEU*cwPSn}wgp$Yy~ziHkjX-tfJ^Kh zcNZ$jK^-lNA=Ug0Rw@mBZVTty!|Nj>7Bwfffe$xxT8g!0X^b(W?n8{#RLi_qbmK?4 zka*8;2IPaQt;HorQQ8cK)@EiP0*AB+Rw6Z+X)nS<+$V=`U2?->YSOX~ z+ZqwT<37YfJ}tc;fzIb7Ea`$u0&nCB>gKx_%8*oB3Vj4JsRp475&}fZ_VuFL$CX0{Kb}JbDdH!jynEq+iCVZFu`vKw&gqhd(=+3$r$3j>cyf&lU7tTh zdKoi^tN&`4pjc_O1k}wqzd#(wtO>S2^oV5T=rV2}ukhue!7jJ~c^P&`Tj{rXXzaWq zOWY3Wa}kaukO0SV3G3nB3_9+OkhkzPfAkv0u@+1%QxJ>p6RS|}Zaxa)nCUZ{gcA5! z&f{4H7|I`=)4y~dkNPafmoAJW4h-2@OfJm%fvVDX_FwIWM{D@^w|rv zqhwuc@}5P;NzRZeX9$Ie!uCSad)x&_MPRH~X5uk{tWICc2V*gfmMO9zj+SPI%c!H_ z6|ouu&CT?RSk(Hvr)Apgy{l^-{ajEu@E1kQPV=!MfTy_rOHzOw8yBs=W-)@w7-e-> z5C$6US3RZ|C1@aK<`%`tH-Kv2&UD%b5vR5w zPm?8GSk4Z1rlR@OpT=^mcmc<@q6(hAc(3-r)+{^ey`UkQYLU0m8iF2ma5#@FPJ_Zp z84P=Z!_4+QQ?5pJ*bOn(H(?WIHxlt-1&;j1TqyUmHCx0Wi|jTk=NXfN;>?;^aPG+E zwf@4Cjn}u}Ip@{u4LQf!LPf^iebh-{Ye7tfUG+d9XP zrz2&^Q@ls^<|%CCE>ebMyxWQOSC6E4mU-D|IMwd8be?!>EUH%k&#?z89&!rjE!C%F z4AtK|z2=UeOf?(kzAO)vGVRq&yg5r3jk?#0AN$oNP5^d_((0&H zWyd;f-F8gF88yCgY@+`PjU#zD8d>N2BRbT?oF=wrI33$XqDFqG3jBpb!G@zV(pN`x z*2qt4`#sd>z>GZd;ku=u!3dAY>zA#xaTM*C<)kTry%bRc|0m}strM+lj#M+8uJ!w? z7*&JKjn$ixD%co=Ek=tO3mJ*#yasiA#Xhg1hNq_2A_&8<5=Wjtmk_ZzxS{NhfgSWcrp z^`z`es7LjiLi`AGxRG|M-l%rh8wdpY6a3Y5r?Bco5nsn$<|C1YTd+bE_c#x3Qxxhv z3nFeie8L4vITtor3*{cPXOU2j5x#nJR}XHtmp%!#IAG|pT$<3F4H!>ObQ<3aB`#9I zE(?uv?=(lX5MGvEPho@J_J{AC)M01szywo>!cux*uj{k?V|P*y@5gI2LNSa^5@cnEXBKOYEn z0R{{#CIve>C8wCG6PAf{U||C}hxpgTzH6#4YTpYQxlDuV`)B8NZ~nz#0Q2F4=!Z87 zj#BwlMvY3f|Lo*#?*Gnj`u{#eXQz?BwLQa-ARzyl23T}&eeCQ~_f)xM-L6636t?y$ zSU&3x~N#Hp5jG!PbHr~@{NMCUF04Dl2jou<4f zXrEQRNH{u(HxV0?x~!~|K=n6iop2lEMPK|X0-smoT4)w}-+roLo&8?(@-=wfMZob# zT+(CAbo50=e*3{>w)A2(?U?RK>&11=WmKVVHNi2sXhwg*jX1S)4Zu7OYG(Kg)n8@U zk!lH=N8}H+t~ER+uxMpwG=9k=cenM_uJW$4T-H1vtSVuEr>@idcH*axJ@vSxJ?^(_Oo&28byi!@yhK_{6$JueV3s%hThx-*T22pWyRh!wG;p>3zN&rhbpV>mh0-0;m+(|v4nuU>N zX-4{jM8Rc32B$Y?@w6u~4f{n(KCj^oyTq{S@$x!$3x6D4YSuq9AGG~g?J#FWHn|} zj#Og2PC|Q>cf@m<2oSv5Tdl|d*?~5*8x>>Zw#n}p8@bJ_L|0xjUYl#3W9r`>JpSx|1Twk{znPl(KEgliidu}rvJ}Q zB$;Rdd6P1|GnQ1hR&u}P&If&8A5Dedec3<##|r(g2Si61T^D{|KcId>A7NbsXXtRn z-Jj2-Z@UQodNcam*>fY~=S)WJGgyA;yL|1XGWQ{n*uv`LoBBrF`^~eu>5G@#Gws6{ zA@qsAP_T2-#UbB&2bOknMtEz40qU;Lg(BIR%OBIMgnuNMMb}9mleOq4j1) zsx~6l7@#X&e6vxgeFC$<*fX|StMjM?$Wp1)*!(nM#Wi)rq+UDE7&ca4%~RWpg3G)G z`osNot%Vm!w`Ts-9L{Xn%$LS4I=EMgQv-0q_(I17uMAkh4g56H2v{MySwG0)R#F5D z_K6fTL^=ba4x8GUXbQM&w~Lmnk@57h>V4(6lQmJ2HO)L4C{%0L2ax9|+EQ)mYCQ;; zxC?}T7-WIYJ*$qcb7~0q_1;p=*5K^d9|uIbrZZpjOW&yfLdl$7`l{a>#{F1l5mY6F zx02x=vnp_qU|p+TvtBROUkgW+~e4%PB?*D;|&#il;gcc0b23hiL29ZOl;{vj}8v{{HzE;!VCyL z)NNyL4^YV;c!D=R5dDeU7lTKuB9x_ec%He}LYa7JZYdpxCXaxi3&zE&UvA%AUrzCt zmZ8~kA>w4IYy=@>Epw-=_ODU8=C3oRS`K!vZROpur-uc62?cCe(=qkvOB=yNEibTs zIFvNY`$Z+>6{ps6!8gr{>CHECFZ!s-^o=OkV4kAL>!JJ*fm^p)e?8qGkP_j;{Ph-& zz)yA%oog5J&NoaUP5C*c>&p~gQem4vfm6aO3VH9Phd&SIuLqFppUME8!TEHhaeUCQ zu2Vd1aX;kGq+iL+()e!F7z3{t8 z*?u?acX0NUkt6ILVj|dSTuaJW<`NGwc&I|ChoE8LU||uFVPWB5KfwKqdI*C87L$@) z6&*{=gq*`U5RU3Igkv$W5Sx=*+}PA9C@HyNj?1O7k6PWeA4kG%VHe)4_&S(I<9pG+ zr}Pg{@S@Q7&7|t2_ZlV-J%NHvQ|sZY1^d4P>=XS$UGEn#P6pNv&mkB1o|}H3TUjX^W_wy?x1cr1plEAia~^-HWr`ZD ziTW?NrdlS-e}nw~a}{#@@5_){O%#{Q|7`#JwjkfX&-8dLM-6_O#nwgS~p3DNkMog={ z$c`_z68*~@ZYiqI4IQ@>v!4bCWpZ)1V;5Mu6r{tF9lhnI9vJ>0lfcAAb||SBpL`H{Alr z7|Oa~<85)$p_xwEMc~l*(>)K_SEa95XJX^5NZ&3CWo1{j22`R~zcJO0(}$-uer+pdLus8+}iA5Cf%PJhf8wl?Z+essHQ7j>({()d!Tu z%uJizw-l8pJC>=$Ha#^*f7|M1HiRqYu#1_GJnVii(h?04*WZp_2~ci4;-J8tT_aW1|dTGB)?7=t_CK)ZeSv9&rA<7oegs`C@hsClkdWoKWdt7|>TCV%_Bd z)XpweK1;1&mSt=B8F=pMow=HWgP(-vuA_BtVo?1z0Bu0HnEkJi=3M};AA+w<^O~el z2!3t9rL>L{;4c)S9{%wxb6_4#ZKwY<2hN-q?gI44wW>|C0Jf|tRSqIt$K(I`J4Vmu z{q_rl)0845lfM8*{nvhiLOfm~!cXEGgk`U|gUn*hF zq5!vP=_Lme4V>7)DCoD#q|@89w|4UDoyb!+g!P~Fh?bO=!Pd;lW_%exo%U0zbN_h*Uv*$$N+nb-q-@HdvB^vb3DZ%hq(FKX<1Fm!#dC~pI z5UL#h$(Efy>kjQ1fD66Agr$2Hc1K)vz&1Gu07MIZN4idcl@Z{N{9^T`=5e$K1;dXD zE}eIe-P)aoW6iq8gJp9&xPz*02IQkJm>%>O>a;N6D*$MD<=gIlmYlM%o%)O0p~2zG zk7jo2&x6CvZ^age-#>JBJzS3)|HR5MMD^|8#>vI09=RP z0r20+j|7)!zdcxo;zG6Pu%Mts!)7<7Ns_{O(d{VOr_L5jdF)H|96p%Kw+=f74GP-V zViih7Q4zH@@tSwxScfBWKO&lvC|-@`Zz4V#!C#v2$A=Rl72`P)USjQlkVAKN|3aZP zf97CGy-}!>og~`$)Tn2d1_PIXJV{0PaQTN)D`;;ZXnDPcawl3qI16J-^@%rF1OYoU z9r0kGjSW%fhvz%)aO?eZquWYQp+i7mx8A0A&u^FO80$2^aHHOaq8?}Nv>9%p4#jE# z5=!3q#Xb*$A@7^1SG8tg&nG)U_adU*9wsxQwos)tdJiW55Iy65XE#hrdNy(@>jMiEz||>Hr?)oj+ZvwL^rsFaGG#b_(;%-@5MfCLDt$f$kG! zv#UctD#;bx4N;md1A?QDf7H1jO7WX_G1zSc5TSCi8l4(l)+9zP^Kg<5pi#qqCGM8!VbKW_bROyyz(h(xH zn+4n0mu$sM*A%&?JqSH~xQB76czdpm`U7rxfB!!v=fCRzT>^@2 zEzbu#DZGfwU*4+7cpTT~?kwLxWISX*<$o%IQ{qubJl2=l8|V^rxaPnkq~Dttj5v#x5q+gP?$*3MYFRS(A0&*?}H1KrEsHqk2l zf{CI;(lRuNs&h?qFt9>hTpr>?#LapO1N4MWnHoYCx0-^2S7;j54fwj=&oacSTzXda zm$r4}E*dt@^msc+!$ji=K~HHfIL0BS+S6=bL6dT=ja8_`-}-@4=|%KkGqp^i?u{&X zM=FQVcXVZ7j>o!pC@FGx_e&;WlJ@RDZ(e*E9xNF~%^`AyEpuq+s35DiODnZH{#oWE zy>tD;S&!=H*>Q~W2V&1CN~jKup5Hh@L<#J%T!?btQ^nY*$WBMktyXC?kLIe*KF7P9iwIowS&d3$eN&LFMlSdF=b-IP#Ya$9rl4+jE%kNOP=_R z(*E}s7&j$o=c5za6m0yzP&$)$1yvrhjGg9Li^z8OYCwc6nZyhS93La&_@tu~bS&!_ zt*`XzlSBEP)0UdJzVy{nyqYGMcUoQhbKJOeHG2@C!Ft))gA)qu7%FOLTo2ERuL!RV zoa=sj(ZZR`3RR&(Tl{{5MndS4` zEt}4Gu?L5bMf#vSu51(Uo&5Bf=b)B1t@YZp^Q%Dm8U(Muy_a~<1Y8jS_#Jir!JFUY z@0@v6kGohB77H#r9~hktq8C5yGb0-|Fk03E*r!IOZf{|V+1P!jm9SKc2-EpeOg-O1 zp2L%J$~I*ROJJ9zFFI0aH-EJ-5tXxLElRR?I?|{&4K1x#R-?Z=@~6%1%Vg-H;Ta>s z&OPEqHVTCDspQ)Z&I^B_ZEm|YPzctd=yG z(bSM^hTZ;BXc>iCIK5edWcvc$=vw&u_V4=|>6pT?2*Lc-Z@w1%%u2xYp}^N_q>ZI8 z-eyMOP0n)jg_l~<;UE7Q}?)sDDF*2+iL;_m3Z{3lKF-qlLDi3$W@s^QND z8InFzKN;Wjp_xBX{iAl5I#nFDNhDDXpDJ&^4Z*yL3X-}U5r5B$#anS^@_uB>nzF3^ z!O^sqldeO+yn@Lyr|O=rV|B=Ufas$(|4wc2Sb*jImh0bllzbO~&ey(@jKGcT@=V4` zCcph!Ty)ZGat7apDcFj;Iml;7s8ZO~9;QCsxGcLtU~B%vQ|ZsRtP#P!SYDr(CEdo4 zqyfRETWAA<3sNh{GLI$cOQnBK+!9{Bo9TLtwlwxw|FuGA;!VvH>!CRIyIb?cUL=OL zkVzsPWSExN8iAi(?nL*>r|?}b5+GLX{;W$&#;g2T8Qbd}Yi16wL)Uis!xF!fwfkxb zpJ>!%cX!DvrKAVL%VAQS?rniW>L%>QGs^2tgS|V2%E#XA3(aU8!%GFoEQH?Fv-HZ4 zksfV}=f-9R1%N-`VJ2WKiGrDz&rg~mQ9S8gT1H#PA@vu^N=*9l4xyeL0;Xk%Gs(=2%-rch zEI0ta!|@ln1)Jxr?}m&xJ%PlB2+{!aG`8M1hiBCHs}&pPQTiKUE6f;`Mg_d>_aFWU z0iI{Aix4UW>9I4m|8Whn5-|IzM7+rUC};Ze7i#&c;Og?tW39k?e*b62Cc+v`Gz2(b zuPa0r0|YV$5b!s08PRiIcRm{J+B+5JYu45^6{GF82Eup?Ho-Ukg?dx5kDH}x4{}K0 zGJ@HZjMKKjIsen!Vc$b-42IAxM}m{g5pjnHqwZ*1rMnT)!T4W*>wEgf8JP;oOPE+x z5|QZon|&Js&T?4OZc<@f_(}1&L_6FWg$<>vk@*xCT75xNYd`~(sk2OI-~gBQYW-f% z{g-3Pk9dS@%fFo->)@h6sIk7gWE$UHE<_CKDWzNoj=V!=)i)bzb|mL8SyL6;D9w*P z3^K^JZIR0vlG;J~%FaZ96B^+>ZRq!3DA1NfzvyXd5}H{wDTk|K6c3YLxosHj%JaqB zqrQ8`^vZJ?eHN+>s?8oAWTE-mdk)z%-GiSiZg%u)iiowgoT4$M!lRzJ@UBb-(AP=% z_CEdGGlw~pJJ&K^-;wf&i9qc?LZ9VJ848h!o|nWX50M}>cj0>v)cgFF`5oqncc@W=Y1E7qRl)RStM z?7Jd|8Go!U0!#03lwQKatj@Gyv54C8~6Ou2j5tXeCZ;2?+h^dyyQ-DX#g3WRJRTmJ=_1|#u8N-(YndU52i5lQbqAS@L>8$ViJz0+811xZAUN7=APvJ5vvjK5GNo~KL3g-?&) zs)kfD4jjtiAv{Ia|CI8c&*d-PW|$Nmb3+E^5Hmo^>&@GC?da!j&nXGwMU096RxlaX z&^wgUftc#~s-MG6eO*DSY|x^}_h-`%}aJ zda*^prd#DzC$zeSeI9?pOosN)^Kl{zH>+wK8w@+xfHX^l)hkjL<`D^rJN4fMg{C0? zdZMR>r;OtMD!r)2DByYXcnZ&8>tF>UYnzt_p1$e-al_Qd@$&5}AW!<#(Q{#bOC<8& zA~);#`&%aq+cJgv!pXsW87ER!;=S;{UT;q@FzDb#Pg(=?|W5W4|x^QP*xuU{~6-F&w=N_{S#BH9lXJTR|-Ex(fiz54iHGmZCo00gwz8f@44q%(!P>TG%ig4^QxfXacgw=S<{h}|Oo17Ez)O`?fE z_NGm2h}{?aK#smO+0K3VNmfTH@0Y^{D~#N9M>S66W4SJ@uc8<2jB|lp=R{*d&Nb|W zS=}H;OV70r!DRjcXt8=w;;tmKnfHqv;_*mi?*fme0koz_ZWMO^ZhvIgCHm}0>MqJIcR$h)xv5r#_kj1Mw*BXO+R};h)g;*TZTeXd0%+>3GrN<1y zaP=31N9-h0?C8Jz`>Y};J*e*5Xa}7Dl{1A#0MuFRYSAvlqmS6=jzlImZZVC-{2NR4 zrIX5YyTtT?!N92-q2K(rj`J=HOl;)@)P~nT<0;P9N#i{!a_Z+^w%aM*uw~v%e}4sA zm5IGvahMiYoTdum;`qXT>umPQ%pZEo0&Ss4)YZK+br=z8T~qZBW?N5Z0vb29$hcgAsQR&U(6{g&x{=30V<4T@a^U7LE)*K_QH_^i!n z?7F1*6{jCo0@NDR&ciE1oo$MT&QOG(qJVgsi-)|2Q^knG!DURoa%~JkTO_wg@SFF@ z_aJRR8uKs1d!B7erjj&Zx8<`hXI-k1E$xr-d$H4zt9{G+&B<{zGNo-_)Dv7Kn2(=* zKIpHFwyN=)C9Z6y2A$nP?{pJO% zhP76)saxr=R(-3>!it`o&)uyzJ9XM787Z`@g4O zS@@57zuO9IK2v^&_z9f-dH&~r8kzimYh?Dnd&>QC5cde+X><`!9k2)9m%X1lIl+fx`b60{?G){nx1eyAfto-TxWk|8ul55tUBA z4_k9Y-j%Ff$K~G?4I6j-^*6uz;JxVfR}uNM#daF{PNwO{_Orw8*DNl-m*1s!{&lsT zQvE&hE+y(`)N6Xe8=SvFl!y4g!H*Y6e-u0`V7!ue_sDi)?6=)(YSOE?-x}gmjMJE> zh=^zZ`^)(My!o#$6Ab6+l>7#HJ^x@`&{W>XjW4t+k5(6PJsJ#cT8fmmD1%bofrbqA zDA?Cx``@pN#rEhTDOksTG!1SIg1wILW!sb@LG5Gy;o1eR9hM#_CNO@0ZU+kJ)Oyga zA@t3!pCNtq&l_m??-mGM&zJAb_a_}&L328Su*UBk=_B={Ca&Pbe_eUU-trnR1QRqU zsu!O0;ROS(R;%<{*}xy28+)k--*qevyx1&T_`rN)MQ#!eL;Us_APHYKZw@0Yw8_RW%+9!_gHZe8rN6wRu3foMYEYBM2iyVLp^FM&XBVp0n z-8ve|i3)HjwM;kqL#DU&EoL_32dAB4aV{OnKv21slm5EPJsMvcV;fw|i43NdEfboo z8-VGv7gdl1xU%QS2M<6Ptan6rT>ybvD!o68_b7xOq7QvB0N#Ha52H#C-{d|eU zP0?I75|45~HwlW6WBtpSu{~w6`T^g502gy`Y&dmx%??iP@dKqyA_}Nx;93(=YUV1l zMiOsp_~kXfVI&UDV3>jsils?YaE%=ZEA&vTkR=aVaj$DEswzVTntO|-(UHFJ3SrwG z^(qOQF_K-WHWgdd4ZInV(MK5E0doG}8gXiJE|+H@ojWg~3nCW40;$J_oNpTsYCC@g zQ0%VB9@h2e*6lzd2NZ-nCaXwwxd`dSghgYV10d*Yw06`@VsSY5T2%1uPdNQ{=#;82 zC?@5UOD{=@ns?$sQUhW`Q129x7p{$y0IU0W`{2DXqDXrU0cBMbeeD3*b{wXzPK_iZ z3DAjqb^UzbMEBn02Hgk^Xu5PX=y}qI;d>YGQmBai753Q|rCL)I?jVZx>NV0e-Rub` zsRuq+kIGbQ9lNYU5pu4StMldqLOCZ5^?0rBuT9rocwvKrZK>Hm-h(#i!5QA{u3~Ej z*%~4}{tyz^?7WXTI-ne_Jr_4ZE)w_AO5`IR1C-xE{jtJ%MJC$M@;sj+(GeII8voir zlx}9edcHPq(@-bsd|Nd8bB*$V0^b#X{Ne;9+nZn6PUTt-FBI-ucl=E^BsUF{u$_Z+ zBP1VPnS{On{55bI+stBfJa_ZK6jD_Qh)v5u>eY(Hr?hCuKRwRped*J@8zwD@Hg~K^ zqx+!q-gWoFitejuN&Z=hiz38?;yKnVm88}38q<57D^p8B-@Tehn46`@AzjWj+EMn- zt9cB*S--iL)IF+#r@x)K%5UK?Kz%|B^JnMza_nU(m$eomMYb20!g_rt<&dVkKo?$)eh$CRtT%y&HgREPt);dkl=zUw50|sBvpp z^oJjrWlHd*%{GgGkiPZa^KAASbZw4k*nqvwvMVeOd@NV^U zPwMg3%e;;rEFSd(F?k#?+KcVgUqHTdN@>ajMuH{L*$VU~yPeSUBBbI9*6SoMhjr35 z9{_#@&OcbqDey-c4~Z9^#|$|r4dhZS1d$OZ;a zYv{cowRlx0pBf=M9Z9%?Aa$>%`c8+bS}Pg3Qr;t%i&$F%UrTvkQjs1%v<&Gurh1*& z^8mxeZ?m$wbRh6Xq^J3J^|D2sQtDiucLx898Bd zj9h;0B+DYGj9gh*Gzk0)TrXteB$Jct8`MI@fpp4SXzIb-zRLd|+G4I;*bEAGEB0wj zRnJE$kY(gjmE)_#L4=nVOIGVzX+8{xlC7tDPCty&7R$?vGPnl81nU+SE#a={_>rWU zrnwSu=hrsjK@t|RlEXTG>w#w-%tGO7u0eVgE^C`v4V&ftE?}$gSkwu)LvyOXP}#Zq zf5fEn=GL8Lk%p=P{^nawJi;kRBRwiO%p>3@eWD&Z9@q~97ga08FPy++jc=PEHVP+g zWm*xC9}fOh-#$Y&(nJO9OY%&GX;wY64r>|#^e>SHRMC<`C3M@PIQ|;|5^Wh3fg}%^ zEpJoDyhwIEvc0Fd4BVU*w+A(~Z75?=vy^;*x~r%ppl=WbUkxQ@ZkESbBKgZFoKTbj zlMr0oJS3DUhDV%<&CEb*4=zvCcFSqg!Sc!Yuw-3U!$&}{HE6bZUAc5Xp^=$hycBk} zrhf>yFmOYJZJiM~hY4behlBPzRr11x255`PYlb-oR2%XCPG-1KbUo|0Ng>a<%U}qX z7FJ^T8ep$HT$Bl;A+dd`nOu63t?}CFAFQ+zBm27NJRKWk%Y-e5p21BAS0pEGOw9mW zK-Z>3e^sNAFd%jz83~kfKkb#aCA;Kwqw9(3NbcuE8Wj!YWTLQ4YkbOx);VIkiVjnB zER@IJzB$KXZ1nh7)5B(&wqI0On*3DTrTOdnS( z#}ml>NOGZq4Ba0~s70N>{Oyu?yBd*9eLyM0hoq|}@38EgU z!x>(w%OtI$a3qC;+48%T0J{J_nR1g+nYVH}dwr$y@CHZqNoLb1^_cBZJ^ru;FjfDx z=^E}N1+Q^KszQvk_0v`_t2MVy1mhX36Jq_c*GWIm&)O@t)H;)+Z}zQ6auNlZy8iN2_;^!JZ1Idp za#f0}508W+ZHqGK0YxyGq0$S4lj6E;b>`b64bF2{I08u}x``$`LJD^4ae7UPEVT(m zMg*eCbPrp{d?-=&FVD>l_&Q-#STv6(YmJhXtZ)W0*4O~z!uP7KotF48d`I!d&D9h3m8RUjvr3uj2s9C%A{pT0+(MB?l5cOWFFDO0Ej${%!COI^`&K&zsY zK=y<0Z^OI_i5)2JWh+m}y&#ok4b@BzCB4~#TVEVBrXxkP);VqyD@`09?7W4k^6;Y* z>iR0?gh8(e>B)#peuo4d6AA?w&_4W(Sw&d#EeV8qj*`N?tjr-X(^tuhUQsAj)7#^3LX zOdM6wUfwvdQVG8*Ek&%oErfT17X68Kt4RFk3I$IFLh906dAR{a+7u*qdXOsEsfk-B z+R$cg7T?_3Xh#XTm1DIpiMdXsm)_u5D>T3xua4oCD@d_i<%sV_xIx>uiDnVN{GK}Xq$z(mly+bJ{kK%1F^pw$)c1&o zyh`f%-E)ZSC}nU94b1d{Bno3^@W_!U)Yfnl2uONjtBt-FIs-nn9(vJ6>9({1gKX#r znBD;hI2b})ludS|^GkO3O}lm^B~4yz%|7uCT%r%HYaq0HtyRiNJmn>%q0f%5D4J!w z_d0*1YPx%QSDp^{+5q9G492Dlsx>H&ZEmLw%MZ)US=5ZM8eo7xXW(u?Xk%jrAqPA| z?J#l4ZoH%TF_p=px5jw}r7^W_792!~ytpD3zEiW2-N%c;s~w z-fK?A19-~2UBE`8J|X;aU=)q2hY>W;d88j5Th^`&c@O$`XYkPN2tQS5oC>cl3l#)7 zKsVnHN@%Tvp^s=*Nr8yp2Bt4D7_eC*{9CXSKmDW+`ACCc9R7|oOy1p;9i!Zo>fKmD z0f5y*jkH}{&XCgy5}F}I6}^PAOY7OsJT)A5(vFhWRJxwrKF(d5dFDA z7CyXR;5yYCbNub2X-%&Bx;epqKUIpxTcRB`U-n-7r{EW#n#f5raCc5M8n=E>R5KHH z<0!@H|6;%vTeZ{RnBcOj*Bp$BZS-p84Cx^SOTF|>wsHdF@yW!Tq~|=a^dW~op}d>x zeydo~&lFg-KAE#NKklS`W1;cOELfY@^juZihF>$9{o-+RZ~ME6sfSJck^u%M-M?$2 zNP)@rAARLtzX^13lgW`APdL^c+0PB|DZ}h5eJ(&k{r+I^rtlmj*sTnx5uS5z&{5}a zo;r}(!g9+ES%B-6!E~$}ZHIw=Ww|%T=K#VbM>x73K0idEzBC9X%xrFm>Y7F&DKbX%4! z-{0AFCU_xbHDm8DCK#zc2nH5b6&nR>jvp4?mi&03o~j&YmAvAMvo4;hvX->_zGmss zE7+BBufbhO>()61hJm%I)2^=GHiYM;qpVXGtk|W9`pC~7TL>9fO2%`1LSc)n9ioVn z$Z}nyzw~sRZDwI~|Fi9I#l|<{ekMk^x9rdPk|ix~Ksg!fpt>*wrHo723}<`2dPmqT zW$BLw3ZM08f)!S|lW|&MJS^*`lXo2z5Om%*C58w5a4HXAP!m!H6z~dGq^JJr1(hKV8RD$lAvtvUIq!paS17 zGJ+!V#Z}orc%+cf5X_&@&YSMCl36hP-sjwuYp5S?mB-ruvtolbp>*M>L#I~?l~1XF zIZWCu8TXA_-18^nfCH>O75|f((gBV)PBJ!Sl|~!2p^W2<(xe~Unnw?7F)76KP}P@f zHmTpW{c;36U0z)Cyr=Vi9;KOyEn0b;~O5mQeOJcPe127 zS=H5iCMo@7KT3u-1^pyN5?ngwD)Yk@KE%#e>k|Gm?CF1zP!DNwHA~Va@i#mxjlrMxQ*nsu8 z0hGxLM(NM^Yjv5|J`wywbkqU$2jSGGC!4~uozsWiv}SzeqqvVs^1(s@{D);iq=|QF zIHgr0!_6|Xqj(QXumeTI=&dVrD|)gFNAHO`vNbCP>T^ig#8&~;3H~*b3g~8|+Eoeq z@+d2#f(bisQ$dqzRD#$7NdAhiv27ugRRhl}>AvY(gU)AopN;EU1QZlUawPLtNO}g@ zghyovw;GJE2BhlAGCrgPyAtGJ0_&IN4zGBDY5lur781>dMLDMxni(AOr8)qVd*qLC zKDp>Io+ikWW{?zLh`ckke}o4GB`bANv3^dOacj_muvlsd|8AqEpy6u;HkH^z#+fN#7{wwOdT1PJ_MTC0R6JNq548_J=!-}1H^UQ{rFF- z7MGgq*)Gx}qkwd>ooxXZT25bDsd_Wo)$fX8Y~yAWYF#hQtCL1VxUO?9(t%DpU#$}M z?S05W-Iz2+Y-Qv2H{b~l)BTBYas-}3N7O%9GQeQllUp5saetEI(v_SCIs2YLb}5n@ zUo}NXnAdtjRV1{hT7%mTr*XX_(fN+jH+N`(zu6Hywu`NH~#e3 z7N_*z75^NhPlt;(o|J(V$QAc^K2^AH23z>uvME!R&HAc_jwe+Awqmr#tS5nzH)4X6 zqbCdjD^>d7e@ykcRqb9-zbmK$-Ri$YRq8@chJ_ufACN%Paj~5G(&KF^s4@Cpc(MFO{-CBLp)&~3Ce%Y$7UkyvDh@Y;TvKeU8 zb8DkJ$0z7x*A3J8vDz@6(Ylg6eqFD#H2>6xeU2jb<35tyw2Ee`5&fv3TZ@W0C?4LW z9H4Gx2UT%#j1ipN{LXA zY}xIZuww%3CDSEF>9c1PD|26BRo7Nkr;?5M#2Lwq%*`u~TsWoCOQ!=GEVNs7LW;^x z3A>#T!DWx-9V$d@mt)0v@-LL-ChdxUpyt_0qXMBs1*GGPaA-ru8#2#h>GYiAUGsZ1gA$>{H;e{6J)r3)pD)e2!d1(V@WFIf z`kwxcjrB_koqR=Wn86U$AI-RU7LuWt$w#G9&-=LcLj%O0yxX&b)Oziw)PFE9h)k3f zWoykWPQ3S!2R@I1`0dBGs!jY_B{y4-3S=l-8 z8Rs1CY=}x@cnwMP`XbF{7%7M4=$JZ+af*~OT3R8fM@GK-^G0Hj$d%Dp4Hz)P? z5Wq`=1oEgPim z7pQtY*9a~58UN+gM&_Y7uf)Wg0=L|DU8)!zuGlwmyX)7QsmDO}R+<58PDqz(4=7a-(g3s5-g!S^{Up4j?Z*-B7~ ztu%W$moO|7{hkTe+{92s_uB2sr)bx`JVTW2Ma|Sb63A^L+Q14~|7GR|Co$f#LR68y zLX=i3lg28$&Z{Y~ko`l0scCXxhLuZ3*4}u#P^|-jQYDyOn9r(_ z>;m*9AlLK*t#{vfSKg5lL)hPDnj5;=v!R+A>X|u%|2-5G;p(_=LOJHMus5s^umkEC z=u5Jj;j~!#^s>$!i1@qpxtIaRx>o6>N_80p;-EF7Be!~!zlqOumAF(e@>R*07HTqWKTL)B=SwrXyQ`L;*~bfne~Y3BQx%*xm*?CX z7exy-7fzOF12no;jFU;;_mOm$EwI9 zLmSijn}uaSHM0ZRX5!zz-6>Q-<%TwgerY8?#lYKqUv$L?u=Ap(&Z{uNE70u6)rA>F z)?9zIp`UrN4V#GZ=(z>wo3t#`H0th$O6wp2w_jw_0N5{0C`5&gHbVC|Ym&zdXa-$F zwp|H!2Q=l{;0(A#qiZQ+HK07D^Mb3eELY36)YALF{nzNiO$VPdRQT>N<`w^aY1yZ^?A|81k z6#!Wfs)tnjVwY6o@j{|(Y8RYA(@JYL(Y>xivEI#g7q6lOEBet!6 zAd5QT8v0OC?(7E_WkGLHe37r(LU7msbM*&P0tY8o23D7>Mf5={?QRNGKK%d=NboOv z+1|o2+2#MaBX14`J$Ill?XyCSV0H_VK%>yDSbtiZcdb>MvD=M-&J{503&}W4%J3_8 zS78ypH6m%vRPooEaXS!K{BA$SlhOq%&lo>5g*L~XL-1ulK1Ji?6Y!R)CR7#UH7TBi zqTe8Y7lNIziYTW~lrxaxyb;^u3NA9z5$lAMFJYw0P^~id<(Nccht+Qu8 zxbg&*!DU&&#;vFy;6!Kt`7Say9$q58+$?5AXkX|z@qmVJe$HNK`q0ozkkT}$v|5C# z6;oxWIWgAz!Q3Vut}#k&4E9az#eyPZei! z07eWwQgKDAb*T}ClP039QsTLa|HDwLpOnp4t~~W03>Dq(5SWP3MyJ?IBY^tRx;9U? zdt3!#cJ_fevIG>?%+#oNgm~8U^Qyd6i3;gOCNVgM!x2ZHC&r|l4PO{2!7VG1h{>bZ!PC*rWy}(&^o9w zqiNzR%@r!<17=KwiZc>*Bl>N+G~V3-$X<|py}`I$sjDhGEa|zNcj&e|JS)G`*Yhf7 zFV&WYif-Z@uQ96AD1j5}Wptc$n|FF4@>kyU(Nve1LcrUOm)^kBVrg3fM;9?6qbekL zR<~d=%|?g;lRD4lmTG%vhMC5nlm3;uSvQgkTi_Ad6dXqM+2bOLIfX^f&+pi{X-)0Y?M)C6hl<{!6S zlOBr=6ESk?2k-&XE>k;D={h>1oL3+96MmOd`Xj>?0q}PlhZxaa`f52JA59uC&*VO< zq{p`No1aPbm##SUh?fk&_38fQ6f3;J9$cl!QP;uKbmegK1@ z5$IU?5KC#ajq5*H)FjQEUi-*;h-@K!5FevEsv=(tPP@!EmPZQ{kBNH_{TNjCzV*qB zq!=d*!)LNFSxwqh0tGgUoQl6=Cf(rQxJm$$FYh_jy;zf_XdjqNAhAerz=2zxVuPSy zxroFLa}Mc8>y5TH3O8t|y(K*#1GNDJy;RQ8*4=sSCxg#8`djFAi5%~BNbMN+NH)*D#csA zms@R!tFH$R_}N4eE-7SX%GGcsm(&QGs>4ku)?uR@->Dm_=nb{YS zSFOu)Fw=T|2>py8CI4E+Vf@wP$LO(TMYXnpx$F`yHfE|y!pd@B6O0}wej{|EOq5Dg z66BkW;4}3%^n`rLj(4|7s_-x{Sr8?mhp60@-pqzH1cx?#C>WYcB`gHjyXZvot&CLD z;4Q70+fexf$&z2)Z&4&z(awgni@DQgWEOsA{E;qJjQv?D{!d?uYod>NkrNN+bmix- zN)Le*V7XuPJg8YoR#S@&H3$})8IJ0?jf!w0N`=Gmf_Rm4K*0z7RVJ;2IR@2F-Izx+EZgjV9sH90Qd8pMP^qh98T z$$=1rAwUzEUE|eEE_CWG&PH|5H!fN{Qwn~A<#)W!or$Kwakl;}$Y#4zr zKxOpOyv5g18XV7l4$PooML6H6+rlK9=+YT6Vz!*z9QH?%&I%Ib;6rq=9dctZcq|*r zHxcjsWRoqP`*~{kiq-gc(^lCt-Gc@vAsv_z`Yl*U@GMwQkiyMdu3tnHx8JA=b#nG~ zxe;tBgwWY(wa;ea4O_mxgwbz!l4FukxcE{EWM|jh2Ip>tYJ|E>d0j%TLD4(g%E3)h z>%00Nzh+gX(YFjAN*5zq&dhB>1tfX3VD{B7g*7MG0zriXRaj2T{q&v7O$+nJ@Zoe* zhZ&11nlv*kD+sd%)sxcD7x7BXWusdun@P!Kov3qX*(O1rzdz~mWTDcz1KCEL8Qfee zf)|*r5j$!c{&Y+UGf#F#XisKiajB;i3$wC`wKM^&jtvz5}F%CCbd=1w9Znq`bj=cH;tT4#3-wgyGyv0mXNDe zvgPw-C*e*YK(Zp5fb#^+{@(ml-yzs}~7HTUa~bxE+(J`&)_ zNYvtZIS*zd`ySxx2uGy<36s+)4$u-Uhsz6R{%KH17^D}dzQotf)mKjT5;7e;$H5^J zj)A;FF*K1$7}i();6Ebf=H6S|9=jg%d4S~vmFXw0J0ZQB`(1ebB!rvWQs!~lc*tCW z@pwjb_8>Tg6&l{bOLul_44Ydb=j)QKnu+N2wMlhc4rl!i13u01M8ljfMo(@`-{MgD zVB#8VbElP*M_?|8!)9Bx29g@dCXRMxbH=c0oDA@$+`=^}E|%$rl^=3{8v2n6PZw2WT!+=ob5H8PZW9IaoV$n^_k>8*)m=(*CSBg=4{~9#oraRO zOu}wvTY4mi--C7SH~I*U1U>297FgN5ZvFgZOJcxt1RQ<)NF6MnRX$k$gA_=5Oj zZeeXIIt(samJRuF_VUhOpl6!E)`tIVFd&%vB(-N1B@O+^sxuYoXiYo`_in1{XK-4{ z-7hc-XuL6uV<(Ig056m@+D!PXW~$$klIlXLrY`Mg*w^AJT|1#LQF^xy^is0uy5lI? zxuFXp4B_jxNj;Vc=^=P4$n(W$M<+P$&%H6$JEtJO_Yn~>7kBW&p!!QIeccc4imq)% z#~s={&pF`V?q|(F`$!fm#)`(`b-C4xu8TujP?nRwygDSFB6qmMOH@%N!1b#*R34Jti) zspaNNIZavi^S-jDI5~XZt0Sj?rnCS)LZib3dxKqMMqecfDefcL-8Aa9?WSbW&bBQ! zxPj)t&cZV@HoDouV+p{|)hr58ve#>Z>u=yM7Zg|%Re`aG>8H<3Y)|I0L67RQ=B$|? z+|n#QHV7kK>t!$(4j7`$U}@WRyWx6Q1&fUrhDnv~J?{?K__95}LAw5hS4$t}nu@#G8f<<_0 zDMPQDC>m0v@CZ%|HBnUv&WGulQSJ|>pX2xd^kdE?qk`yIb>JcGd>`F22-k%|E~LC( z5>{2O)dz8FpvxP=4SkZWc+Y=^B_gw#n*Esi=W%gx+8;``5rap+ALkV@1}i zYNqn(*ZNl3=q?T8tUZc$2s0bZ3ox!_vXpZ$d<*3g-fo8ttH}ky0r5b`aEDawqk+%L z)cn%y2lmkE9djEVV}CYY{%*Kpt9iS@B8cEums`#wb3$o0_Y@U9+^0(!8SHC`!EgB` z9jQIO$D(64qd95K*;fJsfdj;GhEMvaMk8)i38FfuwcRP3Cav2?%GZ;AaSx^MQ6dS- zKrCGfFj@m()yaUmro<^SKa9^W0yfRwX1Fuh5%Ixa5tf!cu~Fn>AeE{3@Tv;}8{6p= zauDaV?iMm=1pIZ0MwvM_V)NSMrT;6pY7E74ft;1ju(p&*lU{7o)a$*rHu4T0M(M$&ULzj_gE%Ln{iQ4E+_sIdM)}jA>$Y9t18qqs^8S{_iC1z z6+%TRU{$U^Nrn;PblXEsEVB@yyUO~OHzhNma5d9@89sIL%`o9@aztMvbjwrhUWOsD zI6kaxb+&MQ&V*%5)qRo-#|a4Ddi_h<@_vCVXG&*T=Nq`F`FU)_d#XHGqH%(dsM2ZC z$**sRHlaN-`v>+3#FlmSov{}?N@x)K9#g(o9 z)=5{ya8OZ0!O6g!R|2vg4k4!p)|&Z2{IY#T$TE~5KQ1pUnE7G#fE$4TsLoIQOb#YN z#gt~uY)v}()*4E+VjTLn5oODO(#fc(N|}2XOf-F{A!4Siwa_7ibW&~*Hc=O)-){#S zSr3{e>UsMp5>z7~>!teJ(Y9ydqS>5#^e-qxAU+U0(k5Mz-d zY7_Yx}d`L+rEE zCe^2E3s%8W{$Ic7KkNl;>|RS6&=7=C^I&C;hZH7J+yzL{UChe9me&`CS7ugl6ydRA zaTJ=2R0vwteBpI{^+S5hE^-#!ARgeknW|@((m8LRDM(9n&vlvO<9Lm;YZwK=;~B=_3wO|X$lY8qg0tLq$T=%!9HGFDH2 z3L{=K){UUAQtRf`T_Z`T6&K`UAPH)HbbK!<aQ~$6GaN9K{scl~|QRWE7~xgO0){ z(Ebgyubx9r$aU)uKbceg$ePD*;36YnJXhlHymzotddc{{wsQN_TERW`~P&jQd1xreuPKkOzus~{H z$uN)Mpb3q}^(^2qA!Pv0KJnxZ^c1$68M>LiYAZ-v?iT0bK`1dU<^DapwOwlfOOnTZ zVA{|>pO;FOep*A6&%1zT*~g@41BbSn3Y|WrFkhdyCH#KYEWt^z!?8-%#Ia_oad6h0 zrXpW;UNmS177!vW8ng-%97Nf8X*(9n$S-A`?4EDjM==G zTQu;7NV4+$mS8A38dzUBubF^M^nt@#Fxj^rd7jISZRw^JqTvTL-;N9zsHH^PK z3!*uCm+{2lx@L;tY>4_ie#go&G3Ke>Pm_l3Rw||%89Am>qnueR!Z4OG<~Pk_6;%uM zvY>o=OF_c{9=CXAe^5cuL1HOgOyiWD*Q6i>Qi2w)n&@v4K zNcdQbtTQf}U4A=@=?mB3m+2_K{OaCQYhusx1Y#U;02o|yUUXL!3h)QfZ-Tm2clt>| zG18_SLII~`uu9!IJDnqp9}Ccw^YJrWH6Hy|5uf@#RV?Wy;ASf~R;chNaU8dHsAZuD zSL6VXYnUdSmS{36FZmP=IaJgnn5@1#Hn_wF(z+}(8%bigs^-_Ic%bjjM@$yYy5p^e zqU_cFp*l>oW88z`VVc^!S~EcX?rm-cNlU?jF>mFRtvp|MOW&fTHH1rJ?C=f8y369F z#-itPC5Z8&3B(8)?+SQ=cY-okaqF=2vtZ8EYvAkdY(Vk)PgZ~Ax-t}HOX>5vMX?F#>)ws8ui>Mx z=yreiy?Zb*ft?#$O3nr#vOD|*+1miw2uf`BN(&`MdYH!#G~;%HB}=Ia`M|Ipgp#)U zo!&x*!`{#WlQbfVKt*_WG~4QgV|_AwOOhhs>k0XOeP-*}JxbuyW4m@GDVWmu)c*}wH`;q&;*WIUPCn?opV z$Ro6qHVQOcsBpVBw*)+HRX=Xk1RlRCM*CB3fBI#x`!|0%AW|Ge^)XZv{97PQH9dF_KY zoBImn{hz>f;*N{ruup4Y8HF`lH=Z)#Kn7 zDElAUr`@lXyCx;Hix+m;6y7%6ee46Gfw^)hXD8s@x^b*c?qld`vEF{@tCiPi_Ij;@ zo~H7&_h08@Ii@R7x8O+T{P#!HVQT^d zkN1;@p8S8Xc%Mz|c)Nx&pniub*bnovcyBpGr!(cujTQtHJS=GfbA?fU^&5~)rhxmA2wqJUn5fiULQ1Ft%&UD#soJNWjuGV> z7P8MY-pt*C8*OWj8khgUTHw5$+D-daNgi=wV(dJ%*tNwjP}1{f?^*0fL0JAB_It#q z>YvXv3-r<~mh}=NwZA((PFS{RcgH~xUW`2!ndhBCOPA|uJ*(yDBgR0EpGXhh+BWEk z*@<$^p$El9Z^1tM}0RtauHk_A=PaBm9pQu+&rRjNmIicgU(`ZeN!? z6Lf9RO8!LP1I|Zwl``(=Q4g<-&haD=m<2W0q_(Tm&3B{0^8W5 zbG_=%&4-aKdk>p=I^2mDJ4*Z@vXN6z#l$)-CD1okqz5u8nUtfbdY`Y)hR=!TP$epP zw`K8`)-aaISMS7Wegf(v`qy4b4WK57vTbht2MgDx_*L55np>*acjh-?W}RH|MxXW7 zNZC1srA#PqeBQ6L&GR(d*3pf1q6qBN%h@A|17~tova*xL+YA;ApOH9?5@qb=) zV&DU%1Okq}5V3X;#`y$Y3r50u@U`IiX6C%njp>O~P*)a7T`3 z>M}(D{><=nNR?2G)VeX!A^}^SFCG7zCU!UMK9t|S7MUiAs(Yz`z5`Y2$D$XqYPwD5 zpjv&RZVgM~-gsxNp7sQ#2<`Zy++6w_p!j~?2^LtyW9q9|v!Rikm;=R$tnOvuqCUqp zLU6MxYqc}{ZM_S%w3En0{^U*w?5&T@UI3l;XsX)vi-KfR66**prkKe|=p!K$bzQfS zoUJqe-f!T1Xn$nIWb;hJYB>M)UG|E@OtFL*eJ;tS z$@|dIs5iYjF%2jkVuF6*mJh7cnsw)Ez@q`i1~LyfSc|h2tCr}yr~2Ob{(Wour%&}* zF(_kv9u194#-0kW#5bxmTg!#4wp}Dtd zs8uY?elO~`&2ekjIFrn|$33WAXwCU|no;hr-{*?+`*6NwRUMgGYp=FL&*NKmRVPtB zJoTQJ?%RZq5}&^cD%d4C@<%XS$>R)4H5ef%xn`E9l=cX_-4)=YiIcrYFVjB5gDJxN zx}*Dq=Ej{R8U*Q-I}QLA4boJBNv}ZGN;l(?^#srTZoQFh>yr#O{<`8uA5978m51I= z4Vig0B{i?xPO~pM35^`@;}X{ma}T-yn%Ty5o+{vvthiGcLgvydoRHVcfbN<%o4R{( z{tshs8P&%3eGk*(?(U_y1S!ScTHK{bkm4;)(Ljqk6+(dG5L`-u;%RqJ>jyS)K&zM> z*#oH9Y>5mufG-q!H9(_`YFDXWyg;AKYPX4nL@Cu=`jfz0(WW7x*k%I{2O6+C~Z#17lq<0nW#zc#wG|tS}<-#rtv(MFu2!UL?2HT$9Q@f*Q;{FSM@t*HC+S zx4Kp-U1?;U<+47O63f@fV5Y&$I4IQBJ*qp=yhQSCu#^?vld~So7FA zlT**D)?2$fVYS7Q?f*v7)y7H=XU?DA)#7Gia5F7&8JiHD~tl8glF12IJbtKo_R)>uZI zKY_WN>woRQpeu#c^?S&z%a2hw3YMY6EH|5DfTduOJ~==wiJsTYa>foKgk`Pl=)+|) zsd@K;>qx0Se0dhAE@45%A5!G5kL5qFHSdc$a{7n@iP%6#YaLBygJqZc8!@uXC(Nc$z9dnrXTOu|U zj;t|thqz1VV;=I89eQfaSU4ruE}p;Lp^240ljTLZYSlWuT`7E6Ic}wOK7|I>g70%B zs~LCumSObfn>qlqARn9Ze|Qe(yi^VD7^-AMt)r1Hwf(teO=uS=R0255n4(5{#=lzE*^LxMooJa-h*vf*23Ck98#I@{`ZKDVTw3(+6O701V- zR7B{d_pp|5#SLWheC+iosiW;gqalbB6FQ4B<<~Eqc86gY5g0cTF~cAy-y@rv0_^tC zN}cnN=v)Fgfh7m$XEk=2_h;&3&d-m5ckXwIuj1cRO3$jBfi_g*tNQfHsH&S~93`L| z`Y51I%v+o{iZM0nRV1ogI?Q(DkNv(4DJ82;cuHc~N&1vh@5h48rkh%Uhoq9yshYPhf z^ELb)Ay@Ii$2q4$nimBH@4YFfkXSm_?7Ik{E(Z6Q(I!T?ZXB!R39La_Q7}qH4q2lq zjb#RKYh%bT-W#22+DAD%o*rCowV`k;CpTS|6UoKV29_H`^C8)gB$^Ji56%m-9{Ag2 zV|5hsp%KLX4{xnTv0o7<-r{I=E`TL|2A=DFzc-bNYBu3YM=u*Isty!yCJ(_E;&(@dlGP5&QWZLs7a$529uUaXFJ8RL2LIR}Od!U{C+RVAusN5$%SS_2mc)Qv&-@Wv{@Q0Y7V zym@!=2d+ZQVIV3{Vo(1gZVfqrFef;dpQ2eOv{?(;p9DySSdx+%T09aJGa7DPC*K*B z{Cy(a#;Vr`SMCNgQl;fT&0uoi%_~P+s@;m?Ztf2_pwL-s8K`mC{*5k%FZ_m+tFDc> z&Daot9xN(vgurc&XC%eAqo^ZJ%sgX#Q@_mQ{fW;kb8A`W8~eL(oET(me>pm5%>NU> z05d5zUpZwpFY9tjD-3Z#+f@Oo9p0y?TaqVG8X`1jeoHeDBeAhP}t2t8)p~gl@zBkUC!ccSt?V$+^bgyf2^&<)gUgW$|WpXC32W^g- zZA0a1I7}}xRiFo74T-uS#|D(&#@+W7^Zd@{VmpXr(oVb9`_Bq>dlZUt!irA9_&uIU z-|em2I2-7gZDRM5vs(4^;lGgB`Ggp22+Y0FyW0T>b;qZ^9CPC% zkpWFiS5X6hOPs)fq;Etc<;054%Ruo6^vkm2PT13ThSU9 zZr3TAa#QOGF&Ek_!@MGzKy#acISr5>XSW;6Sb);L3`c(pccwVd8wPsV|F41cfFO~$~ zi5D8SzkkR{`CsOL*pPO!NSJ=f=wNyjSV^B-URRNx|HNmSWWlO}E#K;6%^#JY!!LiY zfpdA>K|^eibxq))j0d-Oxd7$lkc`@ODDDf=#qCr}n6-i1pF^LH-z3lWw;wGqGXM-3 z;-_{pI(nybmtEy@EWSMMNiVsBrDu#)$(p?^Km|<(oip!SI=~>efckTUSM| z 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 EEVlz_q{%zuW;! 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 literal 0 HcmV?d00001 diff --git a/doc/images/dolibarr_screenshot5_1920x1080_b.jpg b/doc/images/dolibarr_screenshot5_1920x1080_b.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f7d8a5b573d9e7b3e055a62890cb02fa37e1ae0 GIT binary patch literal 126498 zcmb@t2V4`&+b_Ne0h0h4s(_#YLhlfeZls3*La3oAEp$+t3d%VF5$V!P5TrwBQbYk! zLFq_uqTo>w0kI<%^c?>aJ->GEd*6HipU*p+%+Aj4&dxmhl<)J*?2m^(oLm=9hCEFSERB>^l$Dh|v^gvqBsw$Pr-2Yf%|3Wl0JYh{fW>JFk zf&N3mArWC@Qv<9M#TmP25n_Q3KztAmI^^LMeu{a`|B}GH|45(anPZ2b83kr8^F{B; zwGZ}9XAO3rk6h5=WY+yR3FA!-_X6ZI0@p-&f`@~04=D3`+K~-Gc@~0@9Nxj+-VlU( z3hEPme_n(3V_xI?Z`TAx2Kz%0`aH8fnCcM@${C=H^9(!{0m|2z^`=GN4?D z4qb&RAqLb0wL&+cZm1U;fJUK7XbyS|J%!ewE$AKe3HkOqhxx)nV3Dx%unVvhSQd;9D}ym$EwD~lFKie#1zUtYgKfe-z;@v* za1J;xTm&u&SAuK8kHSfCJGdL%7aj_ahR4Ix;RWz=cmwMw%&LU=a!k9fTRe z9^r)uMf`?HMbHtoh#QDL#0=sY;vM2IR!&x7RykH}RwAntt1s&r)&$l()@s&v)_&GG z)-~2oY;0`&Y*K88+057|YyoWN*izYw*{-qmuuZY8vhD2Ivqx}`+#bC>$M$&aiP)2{ zr*Kchp1XUd_pI&tf@DV?LaHK7kj}^uWE?UNS%M_qkVjSa`&F40*hGF7QHzNnodaG6k`J^Vcq9xL zmK7!opA)VSejvOfa!|xnY4h9^|Ie6#b<{_R#`iJ}vOX|t1jy&TO>On2ba^3^Oq}@o04ah*OCvBFPC3X;7~ZKa9W{W;h7@8qJ?6d;!VXj zN;oBFrA(zkrN5Nbm4lQkl^?5ctC*|AsdTA)P?c5nQY})QRpV4MQTtu3L+w3Y4o}6G z;2)~6t6S@9W1wshX3%c%*-+as#<0hT#mLks*=XFD+t}WiZv4bV%*5BE-sGLBy6HL7 z9y3-ml3AwN0#StMMPv})nIATfG4CUBkZehG(u#$wMVLjGCEU{7GTU;=O2R6{>gF-% z81Y#4v1My1>rm@kHf%Q5Hbpis$SUOX@M3qwwJb#w7=)D&%xD! z;qckf$T7?DsgsgZjMFGZh~iJ_aNgtW;9Tvz<6`WR>$2vm?wa5_?(D9(- zw@>Ul;c=qPoz>mZz0Uo+$1#s`j~!2<=M~R)UWQ)zUR&M-?;P(7o0)eg-KeHTUws}6^SyM=c|@B#z#AW}N=V&t>a`lpLde>vlDrtK`(*^sjj zqGY3zqSm8LqN~m!&Uu}?cV6^-?D=OgM`Ox#*W1) z$7RKRyx@4DD_$g?7QcGY^kRL&-h{A(g-be@t|lT9{S(KN)RGF5{z~>v9!XJ7$xHd3 z>XkZ@rjk~W_9NXVef+Y<<&q4xjF61^%p;k#SzKAsS*zKW**9{qImtO6b5GNM}X*QL|deoOIIO}A)w(QUrlm+zqO#NYXGH~Q{Q hQy}rGx_fFhk`G*Ux3r`< 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

r-nSMh5pl+f>u=M7e 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 literal 0 HcmV?d00001 From e04dd3c80798516a570af6f81e6294557da9f82b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 27 Aug 2017 15:05:35 +0200 Subject: [PATCH 174/174] Fix php unit --- .../compta/facture/class/facture-rec.class.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index a1068a8c691..967fdc908bc 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -1276,7 +1276,6 @@ class FactureLigneRec extends CommonInvoiceLine $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE rowid = ".($this->rowid > 0 ? $this->rowid : $this->id); dol_syslog(get_class($this)."::delete", LOG_DEBUG); if ($this->db->query($sql) ) @@ -1302,15 +1301,14 @@ class FactureLigneRec extends CommonInvoiceLine } - /** * Recupere les lignes de factures predefinies dans this->lines - * @param int $rowid - * @return int 1 if OK, < 0 if KO + * + * @param int $rowid Id of invoice + * @return int 1 if OK, < 0 if KO */ function fetch($rowid) { - $sql = 'SELECT l.rowid, l.fk_facture ,l.fk_product, l.product_type, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx, '; $sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise, l.remise_percent, l.subprice,'; $sql.= ' l.info_bits, l.total_ht, l.total_tva, l.total_ttc,'; @@ -1322,7 +1320,7 @@ class FactureLigneRec extends CommonInvoiceLine $sql.= ' WHERE l.rowid = '.$rowid; $sql.= ' ORDER BY l.rang'; - dol_syslog('FactureRec::fetch_lines', LOG_DEBUG); + dol_syslog('FactureRec::fetch', LOG_DEBUG); $result = $this->db->query($sql); if ($result) { @@ -1376,11 +1374,14 @@ class FactureLigneRec extends CommonInvoiceLine /** - * Update a line to invoice_rec + * Update a line to invoice_rec. + * * @return int <0 if KO, Id of line if OK */ function update() { + global $user; + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; if ($fk_product) @@ -1454,6 +1455,4 @@ class FactureLigneRec extends CommonInvoiceLine } - - }