diff --git a/.travis.yml b/.travis.yml
index 4b17ebaf0c8..96a238e6ad4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@
# from Dolibarr GitHub repository.
# For syntax, see http://about.travis-ci.org/docs/user/languages/php/
-# We use dist: trusty to have php 5.4+ available
+# We use dist: trusty to have php 5.4+ available
dist: trusty
sudo: required
diff --git a/ChangeLog b/ChangeLog
index e516382f62f..f61d3a4820d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -284,6 +284,68 @@ Following changes may create regressions for some external modules, but were nec
where {TYPE} is contact type code (BILLING, SHIPPING, CUSTOMER, ... see contact type dictionnary).
+
+***** ChangeLog for 7.0.4 compared to 7.0.3 *****
+FIX: #8984 button create expense report
+FIX: #9032
+FIX: #9161
+FIX: #9328
+FIX: According to french law, if seller is in France and buyer isn't in UE and isn't a company, TVA used = TVA product
+FIX: Add calls to fetchComments function
+FIX: better compatibility with multicompany
+FIX: case when we valid form with keyboard
+FIX: character making error on bill list
+FIX: check !empty exclude select element
+FIX: combo into popup become crazy with IE10
+FIX: combo of stock in popup are crazy in IE
+FIX: Deletion of files in migration
+FIX: exclude element of the select
+FIX: extrafieldkey
+FIX: Fetch function will fetch comments
+FIX: Fetch task will now fetch comments
+FIX: filter supplier invoice list by societe name.
+FIX: $fk_account is always empty, must be $soc->fk_account
+FIX: Force stripe api version to avoid trouble if we update stripe api
+FIX: getEntity project and not projet
+FIX: Get templates in a forced language
+FIX: global $mysoc missing (to avoid php notice on lines 279, 280 & 281)
+FIX: Injection
+FIX: invoice stats: situation invoices were not counted
+FIX: keep context filter on contact list on change column displayed
+FIX: Keep same project when creating shipping from order
+FIX: langs fr
+FIX: Lose filter on payment type or category after a sort on invoice list
+FIX: Missing behavior
+FIX: missing hook to edit sql
+FIX: multicompany compatibility !
+FIX: need to filter on current entity on replenish
+FIX: Option MAIN_DISABLE_NOTES_TAB #9611
+FIX: page must always be 0 when we search (to avoid case : when we're on page 3 and we're looking for a precise thirdparty, we stay on page 3 and nothing's displaied)
+FIX: Pagination on related item pages
+FIX: Pagination on withdraw request list
+FIX: PDF address: handle when contact thirdparty different from document thirdparty
+FIX: PHP warning, undefined index notnull
+FIX: Product marge tabs on product card
+FIX: Product margin tab and credit note
+FIX: propal: correctly preset project when creating with origin/originid
+FIX: remain to pay for credit note was wrong on invoice list
+FIX: remove debug
+FIX: Remove fetchComments from project and task fetch function
+FIX: remove rowid for multicompany compatibility
+FIX: Search on Ref project on order list
+FIX: search on ref project on propal list
+FIX: showOptionals: column mismatches
+FIX: SQL Injections reported by mu shcor (ADLab of Venustech)
+FIX: stock replenish with multientity
+FIX: table llx_chargessociales doesn't exists
+FIX: we must see number of all shared projects
+FIX: when stock is empty for current entity but > 0 in other entity, until this commit product wasn't displaied on replenishment, it must depends on multientity stock sharing
+FIX: when we're just admin and not super admin, if we create new user with transverse mode, we don't see it then we can't add him in usergroup
+FIX: wrong function name
+FIX: Wrong position of firstname lastname
+FIX: wrong value for module part and return access denied
+FIX: Wrong variable and trigger name
+
***** ChangeLog for 7.0.3 compared to 7.0.2 *****
FIX: 7.0 task contact card without withproject parameters
FIX: #8722
@@ -766,6 +828,32 @@ Following changes may create regressions for some external modules, but were nec
multicompany module to a version that support Dolibarr v7, everything should work as expected.
+***** ChangeLog for 6.0.8 compared to 6.0.7 *****
+FIX: #8762
+FIX: #9032
+FIX: case when we valid form with keyboard
+FIX: clause must not be there
+FIX: dol_delete_file must work in a context without db handler loaded
+FIX: entity test must be on product_fourn_price table and not product table
+FIX: Fetch shipping will now fetch project id
+FIX: $fk_account is always empty, must be $soc->fk_account
+FIX: getEntity project and not projet
+FIX: If we enable 3 steps for supplier order approbation, we must not delete all fourn rights def.
+FIX: Keep supplier proposal price for supplier order
+FIX: langs fr
+FIX: missing filters during reordering
+FIX: need to filter on aa.entity for same accounting accounts available in several entities
+FIX: page must always be 0 when we search (to avoid case : when we're on page 3 and we're looking for a precise thirdparty, we stay on page 3 and nothing's displaied)
+FIX: PDF address: handle when contact thirdparty different from document thirdparty
+FIX: propal: correctly preset project when creating with origin/originid
+FIX: pu_ht_devise was not converted to numeric so decimals were lost when calculating total_ht_devise
+FIX: remain to pay for credit note was wrong on invoice list
+FIX: shipment: fk_proje(c)t not handled in fetch() and update() methods
+FIX: showOptionals: column mismatches
+FIX: sometimes amounts are identical but php find them different.
+FIX: test is_erasable() must be done before call function delete() too to avoid delete invoice with &action=delete in url
+FIX: we must see number of all shared projects
+FIX: wrong var name
***** ChangeLog for 6.0.7 compared to 6.0.6 *****
FIX: #8023
diff --git a/README-FR.md b/README-FR.md
index a9745bb8dbb..19d4ae25df9 100644
--- a/README-FR.md
+++ b/README-FR.md
@@ -16,8 +16,8 @@ Dolibarr est distribué sous les termes de la licence GNU General Public License
## INSTALLER DOLIBARR
Si vous n'avez pas de connaissances techniques, et que vous recherchez
-un programme d'installation qui install Dolibarr ERP/CRM en quelques clics,
-vous devez vous réorienter vers DoliWamp (la version tout-en-un
+un programme d'installation qui installe Dolibarr ERP/CRM en quelques clics,
+vous devez vous ré-orienter vers DoliWamp (la version tout-en-un
de Dolibarr pour Windows), DoliDeb (la version tout-en-un pour Debian ou
Ubuntu) ou DoliRpm (la version tout-en-un de Dolibarr pour Fedora, Redhat,
OpenSuse, Mandriva ou Mageia).
@@ -25,39 +25,39 @@ OpenSuse, Mandriva ou Mageia).
Vous pouvez les télécharger depuis la rubrique *download* du portail officiel:
https://www.dolibarr.org/
-Si vous avez déjà installé un serveur Web avec PHP et une base de donnée (MariaDb/MySql/PostgreSql),
+Si vous avez déjà installé un serveur Web avec PHP et une base de données (MariaDb/MySql/PostgreSql),
vous pouvez installer Dolibarr avec cette version de la manière suivante:
-- Copier le répertoire "dolibarr" et son contenu dans la racine de votre serveur
- web, ou bien copier le répertoire sur le serveur et configurer ce serveur pour
+- Copiez le répertoire "dolibarr" et son contenu dans la racine de votre serveur
+ web, ou bien copiez le répertoire sur le serveur et configurez ce serveur pour
utiliser "dolibarr/htdocs" comme racine d'un nouveau virtual host (ce second
choix requiert des compétences et habilitations en administration du serveur
web).
-- Créer un fichier vide "htdocs/conf/conf.php" et attribuer les permissions
+- Créez un fichier vide "htdocs/conf/conf.php" et attribuez les permissions
en lecture et écriture pour le user du serveur web (les permissions en
écriture seront supprimées une fois l'installation terminée).
-- Depuis votre navigateur, appeler la page "install/" de dolibarr. L'url dépend
- du choix fait à la première etape:
+- Depuis votre navigateur, appelez la page "install/" de dolibarr. L'url dépend
+ du choix fait à la première étape:
http://localhost/dolibarr/htdocs/install/
ou
http://yourdolibarrvirtualhost/install/
-- Suivez les instructions fournies par l'installeur...
+- Suivez les instructions fournies par l'installateur...
## METTRE A JOUR DOLIBARR
-Pour mettre a jour Dolibarr depuis une vieille version vers celle ci:
-- Ecraser les vieux fichiers dans le vieux repertoire 'dolibarr' par les fichiers
+Pour mettre à jour Dolibarr depuis une vieille version vers celle ci:
+- Ecrasez les vieux fichiers dans le vieux répertoire 'dolibarr' par les fichiers
fournis dans ce nouveau package.
-- Au prochain accès, Dolibarr proposera la page de "mise a jour" des données (si necessaire).
- Si un fichier install.lock existe pour vérouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transféré sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents")
-
-*Note: Le processus de migration peut etre lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/*
+- Au prochain accès, Dolibarr proposera la page de "mise à jour" des données (si nécessaire).
+ Si un fichier install.lock existe pour verrouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transférés sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents")
+
+*Note: Le processus de migration peut être lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/*
## CE QUI EST NOUVEAU
@@ -94,14 +94,15 @@ Voir fichier ChangeLog.
- Gestion de marque-pages
- Gestion des promesses de dons
-- Gestion de la TVA NPR (non perçue récupérable - pour les utilisateurs français des DOM-TOM)
- Rapports
- Imports/Exports des données
+- Support des codes barres
+- Calcul des marges
- Connectivité LDAP
- Intégratn de ClickToDial
- Intégration RSS
- Intégation Skype
-- Intégration de système de paiements (Paypal, Strip, Paybox...)
+- Intégration de système de paiements (Paypal, Stripe, Paybox...)
- …
### Divers:
@@ -114,9 +115,18 @@ Voir fichier ChangeLog.
- Application simple à utiliser.
- Requiert PHP et MariaDb, Mysql ou Postgresql (Voir versions exactes sur https://wiki.dolibarr.org/index.php/Prérequis).
- Compatible avec toutes les offres Cloud du marché respectant les prérequis de base de données et PHP.
-- Code simple et facilement personnalisable (pas de framework lourd; mécanisme de hook et triggers).
- APIs.
- Génération PDF et ODT des éléments (factures, propositions commerciales, commandes, bons expéditions, etc...)
+- Code simple et facilement personnalisable (pas de framework lourd; mécanisme de hook et triggers).
+- Support natif de nombreuses fonctions spécifiques aux pays comme:
+ - La tax espagnole TE et ISPF
+ - Gestion de la TVA NPR (non perçue récupérable - pour les utilisateurs français des DOM-TOM)
+ - La loi française Finance 2016 et logiciels de caisse
+ - La double taxe canadienne
+ - Le timbre fiscal tunisien
+ - Numérotation de facture de l'argentines (avec type A,B,C...)
+ - Compatible avec vos processus RGPD
+ - ...
- …
### Extension
@@ -126,7 +136,7 @@ Dolibarr peut aussi être étendu à volonté avec l'ajout de module/application
## CE QUE DOLIBARR NE PEUT PAS (ENCORE) FAIRE
-Voici un liste de fonctionnalites pas encore gérées par Dolibarr:
+Voici un liste de fonctionnalités pas encore gérées par Dolibarr:
- Dolibarr ne contient pas de module de Gestion de la paie.
- Les tâches du module de gestion de projets n'ont pas de dépendances entre elle.
- Dolibarr n'embarque pas de Webmail intégré nativement.
@@ -135,7 +145,7 @@ Voici un liste de fonctionnalites pas encore gérées par Dolibarr:
## DOCUMENTATION
-Les documentations utilisateur, développeur et traducteur sont disponible sous forme de ressources de la communautés via la site [Wiki](https://wiki.dolibarr.org).
+La documentation utilisateur, développeur et traducteur est disponible sous forme de ressources de la communauté via le site [Wiki](https://wiki.dolibarr.org).
## CONTRIBUER
diff --git a/README.md b/README.md
index dfd9d70ab7c..c38d0ca7dd1 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# DOLIBARR ERP & CRM

+[](https://houndci.com)
|6|7|8|develop|
|----------|----------|----------|----------|
@@ -129,7 +130,6 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Donations management
- Reporting
- Data export/import
-- Thirdparties and/or products categories
- Barcodes support
- Margin calculations
- LDAP connectivity
@@ -151,13 +151,15 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Compatible with all Cloud solutions that match MySQL, PHP or PostgreSQL prerequisites.
- APIs.
- An easy to understand, maintain and develop code (PHP with no heavy framework; trigger and hook architecture)
-- Support for country specific features:
+- Support a lot of country specific features:
- Spanish Tax RE and ISPF
- French NPR VAT rate (VAT called "Non Perçue Récupérable" for DOM-TOM)
- Canadian double taxes (federal/province) and other countries using cumulative VAT
- Tunisian tax stamp
- Argentina invoice numbering using A,B,C...
- Compatible with [European directives](http://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE)
+ - Compatible with European GDPR rules
+ - ...
- PDF or ODT generation for invoice, proposals, orders...
- …
diff --git a/build/aps/APP-META-1.1.xml b/build/aps/APP-META-1.1.xml
deleted file mode 100644
index 1394da4d4be..00000000000
--- a/build/aps/APP-META-1.1.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
This document is addressed to independent software -vendors who plan to distribute web applications among the Panel users. -The aim of the document is to help vendors find out whether they can -package their applications to APS to make them available through the -Panel.
-The document does not contain information about -Application Packaging Standard itself or give application packaging -instructions. It focuses on how the Panel implements APS and what APS -packages are not supported by this implementation.
- -Application Packaging Standard (APS) - is a set of rules that defines a web application packaging format. This - standard is designed to ease the integration of applications in a -service provider's infrastructure. It covers provisioning, management, -and integration of cloud-based services and applications.
-The Panel uses APS to offer third-party applications to hosting customers. These applications are presented in APS catalog, where the customers can buy or download them.
-Currently, the Panel does not support all aspects of - APS. Therefore, customers may have problems trying to install certain -applications. To find out whether your application is compatible with -the Panel, see section Plesk Panel Restrictions.
-You can find more information about APS at http://www.apsstandard.org/.
-APS specification and supporting documents are available at http://www.apsstandard.org/isv/documentation/.
- -The current Panel version has restrictions on APS -applications processing. If an application requires performing -restricted actions, the Panel will not install it. Particularly, these -actions are the following:
-See Mail aspect of APS in APS Format Specification v1.2, section 8.8. Mail at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.aspects.mail
-See DNS aspect in APS Format Specification v1.2, section 8.10. DNS Zone at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.aspects.dns
-See DLL aspect in APS Format Specification v1.2, section 8.11. DLL Content Processing Method at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.aspects.dll
-If - you need you application to perform these actions, consider other ways -of integration with the Panel: API RPC, modules or Panel Notifications.
-Also, the Panel does not support the following actions defined in the application package:
-Parallels Holdings, Ltd.
-c/o Parallels International GmbH
-Vordergasse 59
-CH-Schaffhausen
-Switzerland
-Phone: +41-526320-411
-Fax: +41-52672-2010
--
Copyright © 1999-2011 Parallels Holdings, Ltd. and its affiliates. All rights reserved.
--
This product is protected by United States and -international copyright laws. The product's underlying technology, -patents, and trademarks are listed at -http://www.parallels.com/trademarks.
--
Microsoft, Windows, Windows Server, Windows NT, Windows Vista, and MS-DOS are registered trademarks of Microsoft Corporation.
-Linux is a registered trademark of Linus Torvalds.
-Mac is a registered trademark of Apple, Inc.
-All other marks and names mentioned herein may be trademarks of their respective owners.
- - - - - - - - -- * Usage:
} and {@code } tags in your source with
- * {@code class=prettyprint.}
- * You can also use the (html deprecated) {@code } tag, but the pretty
- * printer needs to do more substantial DOM manipulations to support that, so
- * some css styles may not be preserved.
- * } or {@code } element to specify the
- * language, as in {@code }. Any class that
- * starts with "lang-" followed by a file extension, specifies the file type.
- * See the "lang-*.js" files in this directory for code that implements
- * per-language file handlers.
- *
- * Change log:
- * cbeust, 2006/08/22
- *
- * Java annotations (start with "@") are now captured as literals ("lit")
- *
- * @requires console
- */
-
-// JSLint declarations
-/*global console, document, navigator, setTimeout, window */
-
-/**
- * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
- * UI events.
- * If set to {@code false}, {@code prettyPrint()} is synchronous.
- */
-window['PR_SHOULD_USE_CONTINUATION'] = true;
-
-/** the number of characters between tab columns */
-window['PR_TAB_WIDTH'] = 8;
-
-/** Walks the DOM returning a properly escaped version of innerHTML.
- * @param {Node} node
- * @param {Array.} out output buffer that receives chunks of HTML.
- */
-window['PR_normalizedHtml']
-
-/** Contains functions for creating and registering new language handlers.
- * @type {Object}
- */
- = window['PR']
-
-/** Pretty print a chunk of code.
- *
- * @param {string} sourceCodeHtml code as html
- * @return {string} code as html, but prettier
- */
- = window['prettyPrintOne']
-/** Find all the {@code } and {@code } tags in the DOM with
- * {@code class=prettyprint} and prettify them.
- * @param {Function?} opt_whenDone if specified, called when the last entry
- * has been finished.
- */
- = window['prettyPrint'] = void 0;
-
-/** browser detection. @extern @returns false if not IE, otherwise the major version. */
-window['_pr_isIE6'] = function () {
- var ieVersion = navigator && navigator.userAgent &&
- navigator.userAgent.match(/\bMSIE ([678])\./);
- ieVersion = ieVersion ? +ieVersion[1] : false;
- window['_pr_isIE6'] = function () { return ieVersion; };
- return ieVersion;
-};
-
-
-(function () {
- // Keyword lists for various languages.
- var FLOW_CONTROL_KEYWORDS =
- "break continue do else for if return while ";
- var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
- "double enum extern float goto int long register short signed sizeof " +
- "static struct switch typedef union unsigned void volatile ";
- var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
- "new operator private protected public this throw true try typeof ";
- var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
- "concept concept_map const_cast constexpr decltype " +
- "dynamic_cast explicit export friend inline late_check " +
- "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
- "template typeid typename using virtual wchar_t where ";
- var JAVA_KEYWORDS = COMMON_KEYWORDS +
- "abstract boolean byte extends final finally implements import " +
- "instanceof null native package strictfp super synchronized throws " +
- "transient ";
- var CSHARP_KEYWORDS = JAVA_KEYWORDS +
- "as base by checked decimal delegate descending event " +
- "fixed foreach from group implicit in interface internal into is lock " +
- "object out override orderby params partial readonly ref sbyte sealed " +
- "stackalloc string select uint ulong unchecked unsafe ushort var ";
- var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
- "debugger eval export function get null set undefined var with " +
- "Infinity NaN ";
- var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
- "goto if import last local my next no our print package redo require " +
- "sub undef unless until use wantarray while BEGIN END ";
- var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
- "elif except exec finally from global import in is lambda " +
- "nonlocal not or pass print raise try with yield " +
- "False True None ";
- var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
- " defined elsif end ensure false in module next nil not or redo rescue " +
- "retry self super then true undef unless until when yield BEGIN END ";
- var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
- "function in local set then until ";
- var ALL_KEYWORDS = (
- CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
- PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
-
- // token style names. correspond to css classes
- /** token style for PHP variables */
- var PR_VAR = 'vr';
- /** token style for a string literal */
- var PR_STRING = 'str';
- /** token style for a keyword */
- var PR_KEYWORD = 'kwd';
- /** token style for a comment */
- var PR_COMMENT = 'com';
- /** token style for a type */
- var PR_TYPE = 'typ';
- /** token style for a literal value. e.g. 1, null, true. */
- var PR_LITERAL = 'lit';
- /** token style for a punctuation string. */
- var PR_PUNCTUATION = 'pun';
- /** token style for a punctuation string. */
- var PR_PLAIN = 'pln';
-
- /** token style for an sgml tag. */
- var PR_TAG = 'tag';
- /** token style for a markup declaration such as a DOCTYPE. */
- var PR_DECLARATION = 'dec';
- /** token style for embedded source. */
- var PR_SOURCE = 'src';
- /** token style for an sgml attribute name. */
- var PR_ATTRIB_NAME = 'atn';
- /** token style for an sgml attribute value. */
- var PR_ATTRIB_VALUE = 'atv';
-
- /**
- * A class that indicates a section of markup that is not code, e.g. to allow
- * embedding of line numbers within code listings.
- */
- var PR_NOCODE = 'nocode';
-
- /** A set of tokens that can precede a regular expression literal in
- * javascript.
- * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
- * list, but I've removed ones that might be problematic when seen in
- * languages that don't support regular expression literals.
- *
- * Specifically, I've removed any keywords that can't precede a regexp
- * literal in a syntactically legal javascript program, and I've removed the
- * "in" keyword since it's not a keyword in many languages, and might be used
- * as a count of inches.
- *
- *
The link a above does not accurately describe EcmaScript rules since
- * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
- * very well in practice.
- *
- * @private
- */
- var REGEXP_PRECEDER_PATTERN = function () {
- var preceders = [
- "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
- "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
- "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
- "<", "<<", "<<=", "<=", "=", "==", "===", ">",
- ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
- "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
- "||=", "~" /* handles =~ and !~ */,
- "break", "case", "continue", "delete",
- "do", "else", "finally", "instanceof",
- "return", "throw", "try", "typeof"
- ];
- var pattern = '(?:^^|[+-]';
- for (var i = 0; i < preceders.length; ++i) {
- pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
- }
- pattern += ')\\s*'; // matches at end, and matches empty string
- return pattern;
- // CAVEAT: this does not properly handle the case where a regular
- // expression immediately follows another since a regular expression may
- // have flags for case-sensitivity and the like. Having regexp tokens
- // adjacent is not valid in any language I'm aware of, so I'm punting.
- // TODO: maybe style special characters inside a regexp as punctuation.
- }();
-
- // Define regexps here so that the interpreter doesn't have to create an
- // object each time the function containing them is called.
- // The language spec requires a new object created even if you don't access
- // the $1 members.
- var pr_amp = /&/g;
- var pr_lt = //g;
- var pr_quot = /\"/g;
- /** like textToHtml but escapes double quotes to be attribute safe. */
- function attribToHtml(str) {
- return str.replace(pr_amp, '&')
- .replace(pr_lt, '<')
- .replace(pr_gt, '>')
- .replace(pr_quot, '"');
- }
-
- /** escapest html special characters to html. */
- function textToHtml(str) {
- return str.replace(pr_amp, '&')
- .replace(pr_lt, '<')
- .replace(pr_gt, '>');
- }
-
-
- var pr_ltEnt = /</g;
- var pr_gtEnt = />/g;
- var pr_aposEnt = /'/g;
- var pr_quotEnt = /"/g;
- var pr_ampEnt = /&/g;
- var pr_nbspEnt = / /g;
- /** unescapes html to plain text. */
- function htmlToText(html) {
- var pos = html.indexOf('&');
- if (pos < 0) { return html; }
- // Handle numeric entities specially. We can't use functional substitution
- // since that doesn't work in older versions of Safari.
- // These should be rare since most browsers convert them to normal chars.
- for (--pos; (pos = html.indexOf('', pos + 1)) >= 0;) {
- var end = html.indexOf(';', pos);
- if (end >= 0) {
- var num = html.substring(pos + 3, end);
- var radix = 10;
- if (num && num.charAt(0) === 'x') {
- num = num.substring(1);
- radix = 16;
- }
- var codePoint = parseInt(num, radix);
- if (!isNaN(codePoint)) {
- html = (html.substring(0, pos) + String.fromCharCode(codePoint) +
- html.substring(end + 1));
- }
- }
- }
-
- return html.replace(pr_ltEnt, '<')
- .replace(pr_gtEnt, '>')
- .replace(pr_aposEnt, "'")
- .replace(pr_quotEnt, '"')
- .replace(pr_nbspEnt, ' ')
- .replace(pr_ampEnt, '&');
- }
-
- /** is the given node's innerHTML normally unescaped? */
- function isRawContent(node) {
- return 'XMP' === node.tagName;
- }
-
- var newlineRe = /[\r\n]/g;
- /**
- * Are newlines and adjacent spaces significant in the given node's innerHTML?
- */
- function isPreformatted(node, content) {
- // PRE means preformatted, and is a very common case, so don't create
- // unnecessary computed style objects.
- if ('PRE' === node.tagName) { return true; }
- if (!newlineRe.test(content)) { return true; } // Don't care
- var whitespace = '';
- // For disconnected nodes, IE has no currentStyle.
- if (node.currentStyle) {
- whitespace = node.currentStyle.whiteSpace;
- } else if (window.getComputedStyle) {
- // Firefox makes a best guess if node is disconnected whereas Safari
- // returns the empty string.
- whitespace = window.getComputedStyle(node, null).whiteSpace;
- }
- return !whitespace || whitespace === 'pre';
- }
-
- function normalizedHtml(node, out, opt_sortAttrs) {
- switch (node.nodeType) {
- case 1: // an element
- var name = node.tagName.toLowerCase();
-
- out.push('<', name);
- var attrs = node.attributes;
- var n = attrs.length;
- if (n) {
- if (opt_sortAttrs) {
- var sortedAttrs = [];
- for (var i = n; --i >= 0;) { sortedAttrs[i] = attrs[i]; }
- sortedAttrs.sort(function (a, b) {
- return (a.name < b.name) ? -1 : a.name === b.name ? 0 : 1;
- });
- attrs = sortedAttrs;
- }
- for (var i = 0; i < n; ++i) {
- var attr = attrs[i];
- if (!attr.specified) { continue; }
- out.push(' ', attr.name.toLowerCase(),
- '="', attribToHtml(attr.value), '"');
- }
- }
- out.push('>');
- for (var child = node.firstChild; child; child = child.nextSibling) {
- normalizedHtml(child, out, opt_sortAttrs);
- }
- if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
- out.push('<\/', name, '>');
- }
- break;
- case 3: case 4: // text
- out.push(textToHtml(node.nodeValue));
- break;
- }
- }
-
- /**
- * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
- * matches the union o the sets o strings matched d by the input RegExp.
- * Since it matches globally, if the input strings have a start-of-input
- * anchor (/^.../), it is ignored for the purposes of unioning.
- * @param {Array.} regexs non multiline, non-global regexs.
- * @return {RegExp} a global regex.
- */
- function combinePrefixPatterns(regexs) {
- var capturedGroupIndex = 0;
-
- var needToFoldCase = false;
- var ignoreCase = false;
- for (var i = 0, n = regexs.length; i < n; ++i) {
- var regex = regexs[i];
- if (regex.ignoreCase) {
- ignoreCase = true;
- } else if (/[a-z]/i.test(regex.source.replace(
- /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
- needToFoldCase = true;
- ignoreCase = false;
- break;
- }
- }
-
- function decodeEscape(charsetPart) {
- if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
- switch (charsetPart.charAt(1)) {
- case 'b': return 8;
- case 't': return 9;
- case 'n': return 0xa;
- case 'v': return 0xb;
- case 'f': return 0xc;
- case 'r': return 0xd;
- case 'u': case 'x':
- return parseInt(charsetPart.substring(2), 16)
- || charsetPart.charCodeAt(1);
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7':
- return parseInt(charsetPart.substring(1), 8);
- default: return charsetPart.charCodeAt(1);
- }
- }
-
- function encodeEscape(charCode) {
- if (charCode < 0x20) {
- return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
- }
- var ch = String.fromCharCode(charCode);
- if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
- ch = '\\' + ch;
- }
- return ch;
- }
-
- function caseFoldCharset(charSet) {
- var charsetParts = charSet.substring(1, charSet.length - 1).match(
- new RegExp(
- '\\\\u[0-9A-Fa-f]{4}'
- + '|\\\\x[0-9A-Fa-f]{2}'
- + '|\\\\[0-3][0-7]{0,2}'
- + '|\\\\[0-7]{1,2}'
- + '|\\\\[\\s\\S]'
- + '|-'
- + '|[^-\\\\]',
- 'g'));
- var groups = [];
- var ranges = [];
- var inverse = charsetParts[0] === '^';
- for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
- var p = charsetParts[i];
- switch (p) {
- case '\\B': case '\\b':
- case '\\D': case '\\d':
- case '\\S': case '\\s':
- case '\\W': case '\\w':
- groups.push(p);
- continue;
- }
- var start = decodeEscape(p);
- var end;
- if (i + 2 < n && '-' === charsetParts[i + 1]) {
- end = decodeEscape(charsetParts[i + 2]);
- i += 2;
- } else {
- end = start;
- }
- ranges.push([start, end]);
- // If the range might intersect letters, then expand it.
- if (!(end < 65 || start > 122)) {
- if (!(end < 65 || start > 90)) {
- ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
- }
- if (!(end < 97 || start > 122)) {
- ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
- }
- }
- }
-
- // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
- // -> [[1, 12], [14, 14], [16, 17]]
- ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); });
- var consolidatedRanges = [];
- var lastRange = [NaN, NaN];
- for (var i = 0; i < ranges.length; ++i) {
- var range = ranges[i];
- if (range[0] <= lastRange[1] + 1) {
- lastRange[1] = Math.max(lastRange[1], range[1]);
- } else {
- consolidatedRanges.push(lastRange = range);
- }
- }
-
- var out = ['['];
- if (inverse) { out.push('^'); }
- out.push.apply(out, groups);
- for (var i = 0; i < consolidatedRanges.length; ++i) {
- var range = consolidatedRanges[i];
- out.push(encodeEscape(range[0]));
- if (range[1] > range[0]) {
- if (range[1] + 1 > range[0]) { out.push('-'); }
- out.push(encodeEscape(range[1]));
- }
- }
- out.push(']');
- return out.join('');
- }
-
- function allowAnywhereFoldCaseAndRenumberGroups(regex) {
- // Split into character sets, escape sequences, punctuation strings
- // like ('(', '(?:', ')', '^'), and runs of characters that do not
- // include any of the above.
- var parts = regex.source.match(
- new RegExp(
- '(?:'
- + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]' // a character set
- + '|\\\\u[A-Fa-f0-9]{4}' // a unicode escape
- + '|\\\\x[A-Fa-f0-9]{2}' // a hex escape
- + '|\\\\[0-9]+' // a back-reference or octal escape
- + '|\\\\[^ux0-9]' // other escape sequence
- + '|\\(\\?[:!=]' // start of a non-capturing group
- + '|[\\(\\)\\^]' // start/emd of a group, or line start
- + '|[^\\x5B\\x5C\\(\\)\\^]+' // run of other characters
- + ')',
- 'g'));
- var n = parts.length;
-
- // Maps captured group numbers to the number they will occupy in
- // the output or to -1 if that has not been determined, or to
- // undefined if they need not be capturing in the output.
- var capturedGroups = [];
-
- // Walk over and identify back references to build the capturedGroups
- // mapping.
- for (var i = 0, groupIndex = 0; i < n; ++i) {
- var p = parts[i];
- if (p === '(') {
- // groups are 1-indexed, so max group index is count of '('
- ++groupIndex;
- } else if ('\\' === p.charAt(0)) {
- var decimalValue = +p.substring(1);
- if (decimalValue && decimalValue <= groupIndex) {
- capturedGroups[decimalValue] = -1;
- }
- }
- }
-
- // Renumber groups and reduce capturing groups to non-capturing groups
- // where possible.
- for (var i = 1; i < capturedGroups.length; ++i) {
- if (-1 === capturedGroups[i]) {
- capturedGroups[i] = ++capturedGroupIndex;
- }
- }
- for (var i = 0, groupIndex = 0; i < n; ++i) {
- var p = parts[i];
- if (p === '(') {
- ++groupIndex;
- if (capturedGroups[groupIndex] === undefined) {
- parts[i] = '(?:';
- }
- } else if ('\\' === p.charAt(0)) {
- var decimalValue = +p.substring(1);
- if (decimalValue && decimalValue <= groupIndex) {
- parts[i] = '\\' + capturedGroups[groupIndex];
- }
- }
- }
-
- // Remove any prefix anchors so that the output will match anywhere.
- // ^^ really does mean an anchored match though.
- for (var i = 0, groupIndex = 0; i < n; ++i) {
- if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
- }
-
- // Expand letters to groupts to handle mixing of case-sensitive and
- // case-insensitive patterns if necessary.
- if (regex.ignoreCase && needToFoldCase) {
- for (var i = 0; i < n; ++i) {
- var p = parts[i];
- var ch0 = p.charAt(0);
- if (p.length >= 2 && ch0 === '[') {
- parts[i] = caseFoldCharset(p);
- } else if (ch0 !== '\\') {
- // TODO: handle letters in numeric escapes.
- parts[i] = p.replace(
- /[a-zA-Z]/g,
- function (ch) {
- var cc = ch.charCodeAt(0);
- return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
- });
- }
- }
- }
-
- return parts.join('');
- }
-
- var rewritten = [];
- for (var i = 0, n = regexs.length; i < n; ++i) {
- var regex = regexs[i];
- if (regex.global || regex.multiline) { throw new Error('' + regex); }
- rewritten.push(
- '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
- }
-
- return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
- }
-
- var PR_innerHtmlWorks = null;
- function getInnerHtml(node) {
- // inner html is hopelessly broken in Safari 2.0.4 when the content is
- // an html description of well formed XML and the containing tag is a PRE
- // tag, so we detect that case and emulate innerHTML.
- if (null === PR_innerHtmlWorks) {
- var testNode = document.createElement('PRE');
- testNode.appendChild(
- document.createTextNode('\n '));
- PR_innerHtmlWorks = !/)[\r\n]+/g, '$1')
- .replace(/(?:[\r\n]+[ \t]*)+/g, ' ');
- }
- return content;
- }
-
- var out = [];
- for (var child = node.firstChild; child; child = child.nextSibling) {
- normalizedHtml(child, out);
- }
- return out.join('');
- }
-
- /** returns a function that expand tabs to spaces. This function can be fed
- * successive chunks of text, and will maintain its own internal state to
- * keep track of how tabs are expanded.
- * @return {function (string) : string} a function that takes
- * plain text and return the text with tabs expanded.
- * @private
- */
- function makeTabExpander(tabWidth) {
- var SPACES = ' ';
- var charInLine = 0;
-
- return function (plainText) {
- // walk over each character looking for tabs and newlines.
- // On tabs, expand them. On newlines, reset charInLine.
- // Otherwise increment charInLine
- var out = null;
- var pos = 0;
- for (var i = 0, n = plainText.length; i < n; ++i) {
- var ch = plainText.charAt(i);
-
- switch (ch) {
- case '\t':
- if (!out) { out = []; }
- out.push(plainText.substring(pos, i));
- // calculate how much space we need in front of this part
- // nSpaces is the amount of padding -- the number of spaces needed
- // to move us to the next column, where columns occur at factors of
- // tabWidth.
- var nSpaces = tabWidth - (charInLine % tabWidth);
- charInLine += nSpaces;
- for (; nSpaces >= 0; nSpaces -= SPACES.length) {
- out.push(SPACES.substring(0, nSpaces));
- }
- pos = i + 1;
- break;
- case '\n':
- charInLine = 0;
- break;
- default:
- ++charInLine;
- }
- }
- if (!out) { return plainText; }
- out.push(plainText.substring(pos));
- return out.join('');
- };
- }
-
- var pr_chunkPattern = new RegExp(
- '[^<]+' // A run of characters other than '<'
- + '|<\!--[\\s\\S]*?--\>' // an HTML comment
- + '|' // a CDATA section
- // a probable tag that should not be highlighted
- + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>'
- + '|<', // A '<' that does not begin a larger chunk
- 'g');
- var pr_commentPrefix = /^<\!--/;
- var pr_cdataPrefix = /^) into their textual equivalent.
- *
- * @param {string} s html where whitespace is considered significant.
- * @return {Object} source code and extracted tags.
- * @private
- */
- function extractTags(s) {
- // since the pattern has the 'g' modifier and defines no capturing groups,
- // this will return a list of all chunks which we then classify and wrap as
- // PR_Tokens
- var matches = s.match(pr_chunkPattern);
- var sourceBuf = [];
- var sourceBufLen = 0;
- var extractedTags = [];
- if (matches) {
- for (var i = 0, n = matches.length; i < n; ++i) {
- var match = matches[i];
- if (match.length > 1 && match.charAt(0) === '<') {
- if (pr_commentPrefix.test(match)) { continue; }
- if (pr_cdataPrefix.test(match)) {
- // strip CDATA prefix and suffix. Don't unescape since it's CDATA
- sourceBuf.push(match.substring(9, match.length - 3));
- sourceBufLen += match.length - 12;
- } else if (pr_brPrefix.test(match)) {
- //
tags are lexically significant so convert them to text.
- // This is undone later.
- sourceBuf.push('\n');
- ++sourceBufLen;
- } else {
- if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {
- // A will start a section that should be
- // ignored. Continue walking the list until we see a matching end
- // tag.
- var name = match.match(pr_tagNameRe)[2];
- var depth = 1;
- var j;
- end_tag_loop:
- for (j = i + 1; j < n; ++j) {
- var name2 = matches[j].match(pr_tagNameRe);
- if (name2 && name2[2] === name) {
- if (name2[1] === '/') {
- if (--depth === 0) { break end_tag_loop; }
- } else {
- ++depth;
- }
- }
- }
- if (j < n) {
- extractedTags.push(
- sourceBufLen, matches.slice(i, j + 1).join(''));
- i = j;
- } else { // Ignore unclosed sections.
- extractedTags.push(sourceBufLen, match);
- }
- } else {
- extractedTags.push(sourceBufLen, match);
- }
- }
- } else {
- var literalText = htmlToText(match);
- sourceBuf.push(literalText);
- sourceBufLen += literalText.length;
- }
- }
- }
- return { source: sourceBuf.join(''), tags: extractedTags };
- }
-
- /** True if the given tag contains a class attribute with the nocode class. */
- function isNoCodeTag(tag) {
- return !!tag
- // First canonicalize the representation of attributes
- .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,
- ' $1="$2$3$4"')
- // Then look for the attribute we want.
- .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/);
- }
-
- /**
- * Apply the given language handler to sourceCode and add the resulting
- * decorations to out.
- * @param {number} basePos the index of sourceCode within the chunk of source
- * whose decorations are already present on out.
- */
- function appendDecorations(basePos, sourceCode, langHandler, out) {
- if (!sourceCode) { return; }
- var job = {
- source: sourceCode,
- basePos: basePos
- };
- langHandler(job);
- out.push.apply(out, job.decorations);
- }
-
- /** Given triples of [style, pattern, context] returns a lexing function,
- * The lexing function interprets the patterns to find token boundaries and
- * returns a decoration list of the form
- * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
- * where index_n is an index into the sourceCode, and style_n is a style
- * constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
- * all characters in sourceCode[index_n-1:index_n].
- *
- * The stylePatterns is a list whose elements have the form
- * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
- *
- * Style is a style constant like PR_PLAIN, or can be a string of the
- * form 'lang-FOO', where FOO is a language extension describing the
- * language of the portion of the token in $1 after pattern executes.
- * E.g., if style is 'lang-lisp', and group 1 contains the text
- * '(hello (world))', then that portion of the token will be passed to the
- * registered lisp handler for formatting.
- * The text before and after group 1 will be restyled using this decorator
- * so decorators should take care that this doesn't result in infinite
- * recursion. For example, the HTML lexer rule for SCRIPT elements looks
- * something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
- * '';
- $desc = $form->textwithpicto($tmp.$langs->trans("InvoiceDeposit"), $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
+ $tmp = $tmp.'';
+ $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
print '';
print $desc;
print ' ';
@@ -2920,8 +2929,9 @@ if ($action == 'create')
{
// First situation invoice
print '';
- $tmp=' ';
- $desc = $form->textwithpicto($tmp.$langs->trans("InvoiceFirstSituationAsk"), $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3);
+ $tmp=' ';
+ $tmp = $tmp.'';
+ $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3);
print $desc;
print '';
@@ -2931,7 +2941,7 @@ if ($action == 'create')
$tmp='' . $langs->trans('NoSituations') . '') || (GETPOST('origin') && GETPOST('origin') != 'facture' && GETPOST('origin') != 'commande')) $tmp.=' disabled';
$tmp.= '> ';
- $text = $tmp.$langs->trans("InvoiceSituationAsk") . ' ';
+ $text = ' ';
$text .= '';
@@ -2955,7 +2965,7 @@ if ($action == 'create')
});
});
';
- $text = $tmp.$langs->trans("InvoiceReplacementAsk") . ' ';
+ $text = '';
$text .= ' ';
if ($socid > 0)
@@ -3147,7 +3193,14 @@ if ($action == 'create')
print '';
include_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php';
$liste = ModelePDFFactures::liste_modeles($db);
- print $form->selectarray('model', $liste, $conf->global->FACTURE_ADDON_PDF);
+ if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)){ // Hidden conf
+ $paramkey='FACTURE_ADDON_PDF_'.$object->type;
+ $curent = !empty($conf->global->$paramkey)?$conf->global->$paramkey:$conf->global->FACTURE_ADDON_PDF;
+ }
+ else{
+ $curent = $conf->global->FACTURE_ADDON_PDF;
+ }
+ print $form->selectarray('model', $liste, $curent);
print " ";
// Multicurrency
@@ -3253,8 +3306,7 @@ if ($action == 'create')
print '' . $langs->trans($newclassname) . ' ' . $objectsrc->getNomUrl(1);
// We check if Origin document (id and type is known) has already at least one invoice attached to it
$objectsrc->fetchObjectLinked($originid,$origin,'','facture');
- $cntinvoice=count($objectsrc->linkedObjects['facture']);
- if ($cntinvoice>=1)
+ if (is_array($objectsrc->linkedObjects['facture']) && count($objectsrc->linkedObjects['facture']) >= 1)
{
setEventMessages('WarningBillExist', null, 'warnings');
echo ' ('.$langs->trans('LatestRelatedBill').end($objectsrc->linkedObjects['facture'])->getNomUrl(1).')';
diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php
index 1c97b82d926..ad33432484f 100644
--- a/htdocs/compta/facture/class/facture-rec.class.php
+++ b/htdocs/compta/facture/class/facture-rec.class.php
@@ -64,7 +64,11 @@ class FactureRec extends CommonInvoice
*/
public $picto='bill';
+ /**
+ * @var int Entity
+ */
public $entity;
+
public $number;
public $date;
public $amount;
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index dd207af57ec..20983ebd3c9 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -98,11 +98,18 @@ class Facture extends CommonInvoice
public $socid;
public $author;
+
+ /**
+ * @var int ID
+ */
public $fk_user_author;
+
+ /**
+ * @var int ID
+ */
public $fk_user_valid;
+
public $date; // Date invoice
- public $date_creation; // Creation date
- public $date_validation; // Validation date
public $datem;
public $ref_client;
public $ref_int;
@@ -128,6 +135,8 @@ class Facture extends CommonInvoice
public $paye;
//! key of module source when invoice generated from a dedicated module ('cashdesk', 'takepos', ...)
public $module_source;
+ //! key of pos source ('0', '1', ...)
+ public $pos_source;
//! id of template invoice when generated from a template invoice
public $fk_fac_rec_source;
//! id of source invoice if replacement invoice or credit note
@@ -136,7 +145,11 @@ class Facture extends CommonInvoice
public $date_lim_reglement;
public $cond_reglement_code; // Code in llx_c_paiement
public $mode_reglement_code; // Code in llx_c_paiement
- public $fk_bank; // Field to store bank id to use when payment mode is withdraw
+
+ /**
+ * @var int ID Field to store bank id to use when payment mode is withdraw
+ */
+ public $fk_bank;
/**
* @deprecated
@@ -155,7 +168,11 @@ class Facture extends CommonInvoice
public $fac_rec;
// Multicurrency
+ /**
+ * @var int ID
+ */
public $fk_multicurrency;
+
public $multicurrency_code;
public $multicurrency_tx;
public $multicurrency_total_ht;
@@ -447,7 +464,7 @@ class Facture extends CommonInvoice
$sql.= ", note_public";
$sql.= ", ref_client, ref_int";
$sql.= ", fk_account";
- $sql.= ", module_source, fk_fac_rec_source, fk_facture_source, fk_user_author, fk_projet";
+ $sql.= ", module_source, pos_source, fk_fac_rec_source, fk_facture_source, fk_user_author, fk_projet";
$sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf";
$sql.= ", situation_cycle_ref, situation_counter, situation_final";
$sql.= ", fk_incoterms, location_incoterms";
@@ -472,6 +489,7 @@ class Facture extends CommonInvoice
$sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null");
$sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL');
$sql.= ", ".($this->module_source ? "'".$this->db->escape($this->module_source)."'" : "null");
+ $sql.= ", ".($this->pos_source != '' ? "'".$this->db->escape($this->pos_source)."'" : "null");
$sql.= ", ".($this->fk_fac_rec_source?"'".$this->db->escape($this->fk_fac_rec_source)."'":"null");
$sql.= ", ".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null");
$sql.= ", ".($user->id > 0 ? "'".$user->id."'":"null");
@@ -972,6 +990,7 @@ class Facture extends CommonInvoice
$this->user_valid = '';
$this->fk_facture_source = 0;
$this->date_creation = '';
+ $this->date_modification = '';
$this->date_validation = '';
$this->ref_client = '';
$this->close_code = '';
@@ -1209,6 +1228,10 @@ class Facture extends CommonInvoice
if ($user->rights->facture->lire) {
$label = '' . $langs->trans("ShowInvoice") . '';
+ if ($this->type == self::TYPE_REPLACEMENT) $label='' . $langs->transnoentitiesnoconv("ShowInvoiceReplace") . '';
+ if ($this->type == self::TYPE_CREDIT_NOTE) $label='' . $langs->transnoentitiesnoconv("ShowInvoiceAvoir") . '';
+ if ($this->type == self::TYPE_DEPOSIT) $label='' . $langs->transnoentitiesnoconv("ShowInvoiceDeposit") . '';
+ if ($this->type == self::TYPE_SITUATION) $label='' . $langs->transnoentitiesnoconv("ShowInvoiceSituation") . '';
if (! empty($this->ref))
$label .= '
'.$langs->trans('Ref') . ': ' . $this->ref;
if (! empty($this->ref_client))
@@ -1223,10 +1246,6 @@ class Facture extends CommonInvoice
$label.= '
' . $langs->trans('LT2') . ': ' . price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency);
if (! empty($this->total_ttc))
$label.= '
' . $langs->trans('AmountTTC') . ': ' . price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
- if ($this->type == self::TYPE_REPLACEMENT) $label=$langs->transnoentitiesnoconv("ShowInvoiceReplace").': '.$this->ref;
- if ($this->type == self::TYPE_CREDIT_NOTE) $label=$langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref;
- if ($this->type == self::TYPE_DEPOSIT) $label=$langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref;
- if ($this->type == self::TYPE_SITUATION) $label=$langs->transnoentitiesnoconv("ShowInvoiceSituation").': '.$this->ref;
if ($moretitle) $label.=' - '.$moretitle;
}
@@ -1341,6 +1360,7 @@ class Facture extends CommonInvoice
$this->date_pointoftax = $this->db->jdate($obj->date_pointoftax);
$this->date_creation = $this->db->jdate($obj->datec);
$this->date_validation = $this->db->jdate($obj->datev);
+ $this->date_modification = $this->db->jdate($obj->datem);
$this->datem = $this->db->jdate($obj->datem);
$this->remise_percent = $obj->remise_percent;
$this->remise_absolue = $obj->remise_absolue;
@@ -1751,9 +1771,9 @@ class Facture extends CommonInvoice
$facligne->total_ttc = -$remise->amount_ttc;
$facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
- $facligne->multicurrency_total_ht = -$remise->multicurrency_total_ht;
- $facligne->multicurrency_total_tva = -$remise->multicurrency_total_tva;
- $facligne->multicurrency_total_ttc = -$remise->multicurrency_total_ttc;
+ $facligne->multicurrency_total_ht = -$remise->multicurrency_amount_ht;
+ $facligne->multicurrency_total_tva = -$remise->multicurrency_amount_tva;
+ $facligne->multicurrency_total_ttc = -$remise->multicurrency_amount_ttc;
$lineid=$facligne->insert();
if ($lineid > 0)
@@ -4087,7 +4107,7 @@ class Facture extends CommonInvoice
* @param int $hidedetails Hide details of lines
* @param int $hidedesc Hide description
* @param int $hideref Hide ref
- * @param null|array $moreparams Array to provide more information
+ * @param null|array $moreparams Array to provide more information
* @return int <0 if KO, >0 if OK
*/
public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
@@ -4096,12 +4116,15 @@ class Facture extends CommonInvoice
$langs->load("bills");
- if (! dol_strlen($modele)) {
-
+ if (! dol_strlen($modele))
+ {
$modele = 'crabe';
+ $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$this->type;
if ($this->modelpdf) {
$modele = $this->modelpdf;
+ } elseif (! empty($conf->global->$thisTypeConfName)) {
+ $modele = $conf->global->$thisTypeConfName;
} elseif (! empty($conf->global->FACTURE_ADDON_PDF)) {
$modele = $conf->global->FACTURE_ADDON_PDF;
}
@@ -4315,42 +4338,42 @@ class FactureLigne extends CommonInvoiceLine
*/
public $table_element='facturedet';
- var $oldline;
+ public $oldline;
//! From llx_facturedet
//! Id facture
- var $fk_facture;
+ public $fk_facture;
//! Id parent line
- var $fk_parent_line;
+ public $fk_parent_line;
/**
* @deprecated
*/
- var $label;
+ public $label;
//! Description ligne
- var $desc;
+ public $desc;
- var $localtax1_type; // Local tax 1 type
- var $localtax2_type; // Local tax 2 type
- var $fk_remise_except; // Link to line into llx_remise_except
- var $rang = 0;
+ public $localtax1_type; // Local tax 1 type
+ public $localtax2_type; // Local tax 2 type
+ public $fk_remise_except; // Link to line into llx_remise_except
+ public $rang = 0;
- var $fk_fournprice;
- var $pa_ht;
- var $marge_tx;
- var $marque_tx;
+ public $fk_fournprice;
+ public $pa_ht;
+ public $marge_tx;
+ public $marque_tx;
- var $special_code; // Liste d'options non cumulabels:
+ public $special_code; // Liste d'options non cumulabels:
// 1: frais de port
// 2: ecotaxe
// 3: ??
- var $origin;
- var $origin_id;
+ public $origin;
+ public $origin_id;
- var $fk_code_ventilation = 0;
+ public $fk_code_ventilation = 0;
- var $date_start;
- var $date_end;
+ public $date_start;
+ public $date_end;
// Ne plus utiliser
//var $price; // P.U. HT apres remise % de ligne (exemple 80)
@@ -4361,17 +4384,17 @@ class FactureLigne extends CommonInvoiceLine
* @deprecated
* @see product_ref
*/
- var $ref; // Product ref (deprecated)
- var $product_ref; // Product ref
+ public $ref; // Product ref (deprecated)
+ public $product_ref; // Product ref
/**
* @deprecated
* @see product_label
*/
- var $libelle; // Product label (deprecated)
- var $product_label; // Product label
- var $product_desc; // Description produit
+ public $libelle; // Product label (deprecated)
+ public $product_label; // Product label
+ public $product_desc; // Description produit
- var $skip_update_total; // Skip update price total for special lines
+ public $skip_update_total; // Skip update price total for special lines
/**
* @var int Situation advance percentage
@@ -4384,12 +4407,12 @@ class FactureLigne extends CommonInvoiceLine
public $fk_prev_id;
// Multicurrency
- var $fk_multicurrency;
- var $multicurrency_code;
- var $multicurrency_subprice;
- var $multicurrency_total_ht;
- var $multicurrency_total_tva;
- var $multicurrency_total_ttc;
+ public $fk_multicurrency;
+ public $multicurrency_code;
+ public $multicurrency_subprice;
+ public $multicurrency_total_ht;
+ public $multicurrency_total_tva;
+ public $multicurrency_total_ttc;
/**
* Load invoice line from database
diff --git a/htdocs/compta/facture/class/facturestats.class.php b/htdocs/compta/facture/class/facturestats.class.php
index ef54a6ffa5f..1201c429a2a 100644
--- a/htdocs/compta/facture/class/facturestats.class.php
+++ b/htdocs/compta/facture/class/facturestats.class.php
@@ -88,8 +88,8 @@ class FactureStats extends Stats
$this->where.=" AND f.fk_soc = ".$this->socid;
}
if ($this->userid > 0) $this->where.=' AND f.fk_user_author = '.$this->userid;
- if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $this->where.= " AND f.type IN (0,1,2)";
- else $this->where.= " AND f.type IN (0,1,2,3)";
+ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $this->where.= " AND f.type IN (0,1,2,5)";
+ else $this->where.= " AND f.type IN (0,1,2,3,5)";
}
diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
index 2e5cb83883f..35338722353 100644
--- a/htdocs/compta/facture/list.php
+++ b/htdocs/compta/facture/list.php
@@ -422,7 +422,7 @@ if ($filtre)
}
if ($search_ref) $sql .= natural_search('f.facnumber', $search_ref);
if ($search_refcustomer) $sql .= natural_search('f.ref_client', $search_refcustomer);
-if ($search_type != '') $sql.=" AND f.type IN (".$db->escape($search_type).")";
+if ($search_type != '' && $search_type != '-1') $sql.=" AND f.type IN (".$db->escape($search_type).")";
if ($search_project) $sql .= natural_search('p.ref', $search_project);
if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
if ($search_town) $sql.= natural_search('s.town', $search_town);
@@ -458,7 +458,7 @@ if ($search_month > 0)
if ($search_year > 0 && empty($search_day))
$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,$search_month,false))."' AND '".$db->idate(dol_get_last_day($search_year,$search_month,false))."'";
else if ($search_year > 0 && ! empty($search_day))
- $sql.= " AND f.datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $serch_year))."'";
+ $sql.= " AND f.datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $search_year))."'";
else
$sql.= " AND date_format(f.datef, '%m') = '".$search_month."'";
}
diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php
index ea43c270b5f..eec0c640b67 100644
--- a/htdocs/compta/index.php
+++ b/htdocs/compta/index.php
@@ -162,7 +162,6 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire)
if ( $resql )
{
- $var = false;
$num = $db->num_rows($resql);
print '';
@@ -350,7 +349,6 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire)
$resql = $db->query($sql);
if ($resql)
{
- $var=false;
$num = $db->num_rows($resql);
$i = 0;
@@ -473,7 +471,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture-
$resql=$db->query($sql);
if ($resql)
{
- $var=false;
$num = $db->num_rows($resql);
print '';
@@ -520,7 +517,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture-
$total_ttc += $obj->total_ttc;
$totalam += $obj->am;
$i++;
- $var = !$var;
}
}
else
@@ -1069,7 +1065,7 @@ if ($resql)
$obj = $db->fetch_object($resql);
- print "".dol_print_date($db->jdate($obj->da),"day")." ";
+ print ''.dol_print_date($db->jdate($obj->da),"day").' ';
print ''.$obj->libelle.' '.$obj->label.' ';
$i++;
}
@@ -1080,7 +1076,6 @@ if ($resql)
print '';
-
+// End of page
llxFooter();
-
$db->close();
diff --git a/htdocs/compta/localtax/class/localtax.class.php b/htdocs/compta/localtax/class/localtax.class.php
index 6838f9a65b2..49c95c26c2e 100644
--- a/htdocs/compta/localtax/class/localtax.class.php
+++ b/htdocs/compta/localtax/class/localtax.class.php
@@ -55,8 +55,19 @@ class Localtax extends CommonObject
*/
public $label;
+ /**
+ * @var int ID
+ */
public $fk_bank;
+
+ /**
+ * @var int ID
+ */
public $fk_user_creat;
+
+ /**
+ * @var int ID
+ */
public $fk_user_modif;
/**
diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
index 764ca818f7f..94cd53b5424 100644
--- a/htdocs/compta/paiement.php
+++ b/htdocs/compta/paiement.php
@@ -526,7 +526,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
*/
$sql = 'SELECT f.rowid as facid, f.facnumber, f.total_ttc, f.multicurrency_code, f.multicurrency_total_ttc, f.type,';
- $sql.= ' f.datef as df, f.fk_soc as socid';
+ $sql.= ' f.datef as df, f.fk_soc as socid, f.date_lim_reglement as dlr';
$sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
$sql.= ' WHERE f.entity IN ('.getEntity('facture', $conf->entity).')';
$sql.= ' AND (f.fk_soc = '.$facture->socid;
@@ -578,6 +578,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
print '';
print ''.$arraytitle.' ';
print ''.$langs->trans('Date').' ';
+ print ''.$langs->trans('DateMaxPayment').' ';
if (!empty($conf->multicurrency->enabled)) print ''.$langs->trans('Currency').' ';
if (!empty($conf->multicurrency->enabled)) print ''.$langs->trans('MulticurrencyAmountTTC').' ';
if (!empty($conf->multicurrency->enabled)) print ''.$multicurrencyalreadypayedlabel.' ';
@@ -629,7 +630,25 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
// Date
print ''.dol_print_date($db->jdate($objp->df),'day')." \n";
-
+
+ // Date Max Payment
+ if ($objp->dlr > 0 )
+ {
+ print '';
+ print dol_print_date($db->jdate($objp->dlr), 'day');
+
+ if ($invoice->hasDelay())
+ {
+ print img_warning($langs->trans('Late'));
+ }
+
+ print ' ';
+ }
+ else
+ {
+ print '-- ';
+ }
+
// Currency
if (!empty($conf->multicurrency->enabled)) print ''.$objp->multicurrency_code." \n";
diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php
index ade6895ac41..64d0f8601fa 100644
--- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php
+++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php
@@ -152,6 +152,8 @@ class RemiseCheque extends CommonObject
$now=dol_now();
+ dol_syslog("RemiseCheque::Create start", LOG_DEBUG);
+
$this->db->begin();
$sql = "INSERT INTO ".MAIN_DB_PREFIX."bordereau_cheque (";
@@ -178,7 +180,6 @@ class RemiseCheque extends CommonObject
$sql.= ", ''";
$sql.= ")";
- dol_syslog("RemiseCheque::Create", LOG_DEBUG);
$resql = $this->db->query($sql);
if ( $resql )
{
@@ -195,7 +196,6 @@ class RemiseCheque extends CommonObject
$sql.= " SET ref='(PROV".$this->id.")'";
$sql.= " WHERE rowid=".$this->id."";
- dol_syslog("RemiseCheque::Create", LOG_DEBUG);
$resql = $this->db->query($sql);
if (! $resql)
{
@@ -242,13 +242,12 @@ class RemiseCheque extends CommonObject
if($linetoremise==$lineid) $checkremise=true;
}
- if($checkremise==true)
+ if ($checkremise)
{
$sql = "UPDATE ".MAIN_DB_PREFIX."bank";
$sql.= " SET fk_bordereau = ".$this->id;
$sql.= " WHERE rowid = ".$lineid;
- dol_syslog("RemiseCheque::Create", LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql)
{
@@ -284,11 +283,13 @@ class RemiseCheque extends CommonObject
if (! $this->errno)
{
$this->db->commit();
+ dol_syslog("RemiseCheque::Create end", LOG_DEBUG);
return $this->id;
}
else
{
$this->db->rollback();
+ dol_syslog("RemiseCheque::Create end", LOG_DEBUG);
return $this->errno;
}
}
diff --git a/htdocs/compta/paiement/cheque/index.php b/htdocs/compta/paiement/cheque/index.php
index ecb035caeb8..c3cf1634557 100644
--- a/htdocs/compta/paiement/cheque/index.php
+++ b/htdocs/compta/paiement/cheque/index.php
@@ -91,7 +91,7 @@ $max=10;
$sql = "SELECT bc.rowid, bc.date_bordereau as db, bc.amount, bc.ref as ref,";
$sql.= " bc.statut, bc.nbcheque,";
-$sql.= " ba.ref, ba.label, ba.rowid as bid, ba.number, ba.currency_code, ba.account_number, ba.fk_accountancy_journal,";
+$sql.= " ba.ref as bref, ba.label, ba.rowid as bid, ba.number, ba.currency_code, ba.account_number, ba.fk_accountancy_journal,";
$sql.= " aj.code";
$sql.= " FROM ".MAIN_DB_PREFIX."bordereau_cheque as bc, ".MAIN_DB_PREFIX."bank_account as ba";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_journal as aj ON aj.rowid = ba.fk_accountancy_journal";
@@ -120,7 +120,7 @@ if ($resql)
$checkdepositstatic->statut=$objp->statut;
$accountstatic->id=$objp->bid;
- $accountstatic->ref=$objp->ref;
+ $accountstatic->ref=$objp->bref;
$accountstatic->label=$objp->label;
$accountstatic->number=$objp->number;
$accountstatic->currency_code=$objp->currency_code;
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index 952f478087b..18dabbcf980 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -1,12 +1,14 @@
- * Copyright (C) 2004-2010 Laurent Destailleur
- * Copyright (C) 2005 Marc Barilley / Ocebo
+/* Copyright (C) 2002-2004 Rodolphe Quiedeville
+ * Copyright (C) 2004-2010 Laurent Destailleur
+ * Copyright (C) 2005 Marc Barilley / Ocebo
* Copyright (C) 2012 Cédric Salvador
* Copyright (C) 2014 Raphaël Doursenaud
* Copyright (C) 2014 Marcos García
* Copyright (C) 2015 Juanjo Menent
* Copyright (C) 2018 Ferran Marcet
+ * Copyright (C) 2018 Thibault FOUCART
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -72,14 +74,69 @@ class Paiement extends CommonObject
public $author;
public $paiementid; // Type de paiement. Stocke dans fk_paiement
// de llx_paiement qui est lie aux types de
- //paiement de llx_c_paiement
- public $num_paiement; // Numero du CHQ, VIR, etc...
- public $num_payment; // Numero du CHQ, VIR, etc...
- public $bank_account; // Id compte bancaire du paiement
- public $bank_line; // Id de la ligne d'ecriture bancaire
+ //paiement de llx_c_paiement
+
+ /**
+ * @var string type libelle
+ */
+ public $type_libelle;
+
+ /**
+ * @var string type code
+ */
+ public $type_code;
+
+ /**
+ * @var string Numero du CHQ, VIR, etc...
+ * @deprecated
+ * @see num_payment
+ */
+ public $numero;
+
+ /**
+ * @var string Numero du CHQ, VIR, etc...
+ * @deprecated
+ * @see num_payment
+ */
+ public $num_paiement;
+
+ /**
+ * @var string Numero du CHQ, VIR, etc...
+ */
+ public $num_payment;
+
+ /**
+ * @var string Id of external payment mode
+ */
+ public $ext_payment_id;
+
+ /**
+ * @var string Name of external payment mode
+ */
+ public $ext_payment_site;
+
+ /**
+ * @var int bank account id of payment
+ * @deprecated
+ */
+ public $bank_account;
+
+ /**
+ * @var int bank account id of payment
+ */
+ public $fk_account;
+
+ /**
+ * @var int id of payment line in bank account
+ */
+ public $bank_line;
+
// fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...)
- // fk_paiement dans llx_paiement_facture est le rowid du paiement
- public $fk_paiement; // Type of paiment
+ // fk_paiement dans llx_paiement_facture est le rowid du paiement
+ /**
+ * @var int payment id
+ */
+ public $fk_paiement; // Type of payment
/**
@@ -87,7 +144,7 @@ class Paiement extends CommonObject
*
* @param DoliDB $db Database handler
*/
- function __construct($db)
+ public function __construct($db)
{
$this->db = $db;
}
@@ -100,9 +157,9 @@ class Paiement extends CommonObject
* @param int $fk_bank Id of bank line associated to payment
* @return int <0 if KO, 0 if not found, >0 if OK
*/
- function fetch($id, $ref='', $fk_bank='')
+ public function fetch($id, $ref='', $fk_bank='')
{
- $sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.fk_bank,';
+ $sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank,';
$sql.= ' c.code as type_code, c.libelle as type_libelle,';
$sql.= ' p.num_paiement as num_payment, p.note,';
$sql.= ' b.fk_account';
@@ -135,6 +192,8 @@ class Paiement extends CommonObject
$this->type_libelle = $obj->type_libelle;
$this->type_code = $obj->type_code;
$this->statut = $obj->statut;
+ $this->ext_payment_id = $obj->ext_payment_id;
+ $this->ext_payment_site = $obj->ext_payment_site;
$this->bank_account = $obj->fk_account; // deprecated
$this->fk_account = $obj->fk_account;
@@ -229,8 +288,8 @@ class Paiement extends CommonObject
}
$note = ($this->note_public?$this->note_public:$this->note);
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, fk_user_creat)";
- $sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', ".$user->id.")";
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)";
+ $sql.= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($this->num_paiement)."', '".$this->db->escape($note)."', ".($this->ext_payment_id?"'".$this->db->escape($this->ext_payment_id)."'":"null").", ".($this->ext_payment_site?"'".$this->db->escape($this->ext_payment_site)."'":"null").", ".$user->id.")";
dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
$resql = $this->db->query($sql);
diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php
index 0d07c341458..3dccc0ff912 100644
--- a/htdocs/compta/prelevement/create.php
+++ b/htdocs/compta/prelevement/create.php
@@ -46,7 +46,7 @@ $result = restrictedArea($user, 'prelevement', '', '', 'bons');
$action = GETPOST('action','alpha');
$mode = GETPOST('mode','alpha')?GETPOST('mode','alpha'):'real';
$format = GETPOST('format','aZ09');
-$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
+$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
$page = GETPOST("page",'int');
if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
$offset = $limit * $page;
diff --git a/htdocs/compta/salaries/class/paymentsalary.class.php b/htdocs/compta/salaries/class/paymentsalary.class.php
index ea67873c2ee..4da78cb492d 100644
--- a/htdocs/compta/salaries/class/paymentsalary.class.php
+++ b/htdocs/compta/salaries/class/paymentsalary.class.php
@@ -56,7 +56,12 @@ class PaymentSalary extends CommonObject
public $datep;
public $datev;
public $amount;
+
+ /**
+ * @var int ID
+ */
public $fk_project;
+
public $type_payment;
public $num_payment;
@@ -67,8 +72,20 @@ class PaymentSalary extends CommonObject
public $datesp;
public $dateep;
+
+ /**
+ * @var int ID
+ */
public $fk_bank;
+
+ /**
+ * @var int ID
+ */
public $fk_user_author;
+
+ /**
+ * @var int ID
+ */
public $fk_user_modif;
diff --git a/htdocs/compta/sociales/class/cchargesociales.class.php b/htdocs/compta/sociales/class/cchargesociales.class.php
index 9013edee195..a8f5c430691 100644
--- a/htdocs/compta/sociales/class/cchargesociales.class.php
+++ b/htdocs/compta/sociales/class/cchargesociales.class.php
@@ -48,7 +48,12 @@ class Cchargesociales
public $deductible;
public $active;
public $code;
+
+ /**
+ * @var int ID
+ */
public $fk_pays;
+
public $module;
public $accountancy_code;
diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php
index aa5786d0eb5..e44d02f83e2 100644
--- a/htdocs/compta/sociales/class/chargesociales.class.php
+++ b/htdocs/compta/sociales/class/chargesociales.class.php
@@ -64,7 +64,15 @@ class ChargeSociales extends CommonObject
public $date_creation;
public $date_modification;
public $date_validation;
+
+ /**
+ * @var int ID
+ */
public $fk_account;
+
+ /**
+ * @var int ID
+ */
public $fk_project;
diff --git a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
index 442e63efe11..b6ff4a49337 100644
--- a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
+++ b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
@@ -46,7 +46,11 @@ class PaymentSocialContribution extends CommonObject
*/
public $picto = 'payment';
+ /**
+ * @var int ID
+ */
public $fk_charge;
+
public $datec='';
public $tms='';
public $datep='';
@@ -59,10 +63,27 @@ class PaymentSocialContribution extends CommonObject
public $amount; // Total amount of payment
public $amounts=array(); // Array of amounts
+
+ /**
+ * @var int ID
+ */
public $fk_typepaiement;
+
public $num_paiement;
+
+ /**
+ * @var int ID
+ */
public $fk_bank;
+
+ /**
+ * @var int ID
+ */
public $fk_user_creat;
+
+ /**
+ * @var int ID
+ */
public $fk_user_modif;
/**
diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php
index 8b407c9be61..c78e0d8dd7a 100644
--- a/htdocs/compta/tva/class/tva.class.php
+++ b/htdocs/compta/tva/class/tva.class.php
@@ -1,8 +1,9 @@
- * Copyright (C) 2004-2008 Laurent Destailleur
- * Copyright (C) 2011-2017 Alexandre Spangaro
- * Copyright (C) 2018 Philippe Grand
+/* Copyright (C) 2002-2003 Rodolphe Quiedeville
+ * Copyright (C) 2004-2008 Laurent Destailleur
+ * Copyright (C) 2011-2017 Alexandre Spangaro
+ * Copyright (C) 2018 Philippe Grand
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -60,8 +61,19 @@ class Tva extends CommonObject
*/
public $label;
+ /**
+ * @var int ID
+ */
public $fk_bank;
+
+ /**
+ * @var int ID
+ */
public $fk_user_creat;
+
+ /**
+ * @var int ID
+ */
public $fk_user_modif;
/**
@@ -92,9 +104,9 @@ class Tva extends CommonObject
$this->amount=trim($this->amount);
$this->label=trim($this->label);
$this->note=trim($this->note);
- $this->fk_bank=trim($this->fk_bank);
- $this->fk_user_creat=trim($this->fk_user_creat);
- $this->fk_user_modif=trim($this->fk_user_modif);
+ $this->fk_bank = (int) $this->fk_bank;
+ $this->fk_user_creat = (int) $this->fk_user_creat;
+ $this->fk_user_modif = (int) $this->fk_user_modif;
// Check parameters
// Put here code to add control on parameters values
@@ -171,9 +183,9 @@ class Tva extends CommonObject
$this->amount=trim($this->amount);
$this->label=trim($this->label);
$this->note=trim($this->note);
- $this->fk_bank=trim($this->fk_bank);
- $this->fk_user_creat=trim($this->fk_user_creat);
- $this->fk_user_modif=trim($this->fk_user_modif);
+ $this->fk_bank = (int) $this->fk_bank;
+ $this->fk_user_creat = (int) $this->fk_user_creat;
+ $this->fk_user_modif = (int) $this->fk_user_modif;
// Check parameters
// Put here code to add control on parameters values
@@ -508,9 +520,9 @@ class Tva extends CommonObject
$this->amount=price2num(trim($this->amount));
$this->label=trim($this->label);
$this->note=trim($this->note);
- $this->fk_bank=trim($this->fk_bank);
- $this->fk_user_creat=trim($this->fk_user_creat);
- $this->fk_user_modif=trim($this->fk_user_modif);
+ $this->fk_bank = (int) $this->fk_bank;
+ $this->fk_user_creat = (int) $this->fk_user_creat;
+ $this->fk_user_modif = (int) $this->fk_user_modif;
if (empty($this->datec)) $this->datec = dol_now();
// Check parameters
@@ -652,8 +664,8 @@ class Tva extends CommonObject
function update_fk_bank($id_bank)
{
// phpcs:enable
- $sql = 'UPDATE '.MAIN_DB_PREFIX.'tva SET fk_bank = '.$id_bank;
- $sql.= ' WHERE rowid = '.$this->id;
+ $sql = 'UPDATE '.MAIN_DB_PREFIX.'tva SET fk_bank = '.(int) $id_bank;
+ $sql.= ' WHERE rowid = '.(int) $this->id;
$result = $this->db->query($sql);
if ($result)
{
@@ -758,7 +770,7 @@ class Tva extends CommonObject
{
$sql = "SELECT t.rowid, t.tms, t.fk_user_modif, t.datec, t.fk_user_creat";
$sql.= " FROM ".MAIN_DB_PREFIX."tva as t";
- $sql.= " WHERE t.rowid = ".$id;
+ $sql.= " WHERE t.rowid = ".(int) $id;
dol_syslog(get_class($this)."::info", LOG_DEBUG);
$result=$this->db->query($sql);
diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
index b8cadaa4632..b5d17676d8d 100644
--- a/htdocs/contact/class/contact.class.php
+++ b/htdocs/contact/class/contact.class.php
@@ -47,7 +47,11 @@ class Contact extends CommonObject
*/
public $table_element='socpeople';
- public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
+ /**
+ * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
+ * @var int
+ */
+ public $ismultientitymanaged = 1;
/**
* @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
@@ -889,6 +893,7 @@ class Contact extends CommonObject
$sql.=" FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc";
$sql.=" WHERE ec.fk_c_type_contact = tc.rowid";
$sql.=" AND fk_socpeople = ". $this->id;
+ $sql.=" AND tc.source = 'external'";
$sql.=" GROUP BY tc.element";
dol_syslog(get_class($this)."::load_ref_elements", LOG_DEBUG);
diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php
index 04132fa9b75..52a2c4bbe7f 100644
--- a/htdocs/contact/list.php
+++ b/htdocs/contact/list.php
@@ -68,6 +68,8 @@ $search_phone_mobile=GETPOST("search_phone_mobile",'alpha');
$search_fax=GETPOST("search_fax",'alpha');
$search_email=GETPOST("search_email",'alpha');
$search_skype=GETPOST("search_skype",'alpha');
+$search_twitter=GETPOST("search_twitter",'alpha');
+$search_facebook=GETPOST("search_facebook",'alpha');
$search_priv=GETPOST("search_priv",'alpha');
$search_categ=GETPOST("search_categ",'int');
$search_categ_thirdparty=GETPOST("search_categ_thirdparty",'int');
@@ -156,7 +158,9 @@ $arrayfields=array(
'p.phone_mobile'=>array('label'=>"PhoneMobile", 'checked'=>1),
'p.fax'=>array('label'=>"Fax", 'checked'=>0),
'p.email'=>array('label'=>"EMail", 'checked'=>1),
- 'p.skype'=>array('label'=>"Skype", 'checked'=>1, 'enabled'=>(! empty($conf->skype->enabled))),
+ 'p.skype'=>array('label'=>"Skype", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
+ 'p.twitter'=>array('label'=>"Twitter", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
+ 'p.facebook'=>array('label'=>"Facebook", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
'p.thirdparty'=>array('label'=>"ThirdParty", 'checked'=>1, 'enabled'=>empty($conf->global->SOCIETE_DISABLE_CONTACTS)),
'p.priv'=>array('label'=>"ContactVisibility", 'checked'=>1, 'position'=>200),
'p.datec'=>array('label'=>"DateCreationShort", 'checked'=>0, 'position'=>500),
@@ -198,7 +202,7 @@ if (empty($reshook))
include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
// Did we click on purge search criteria ?
- if (GETPOST('button_removefilter_x') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter')) // All tests are required to be compatible with all browsers
+ 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
{
$sall="";
$search_id='';
@@ -217,6 +221,8 @@ if (empty($reshook))
$search_fax="";
$search_email="";
$search_skype="";
+ $search_twitter="";
+ $search_facebook="";
$search_priv="";
$search_status=-1;
$search_categ='';
@@ -311,6 +317,8 @@ if (strlen($search_phone_pro)) $sql.= natural_search('p.phone', $search_pho
if (strlen($search_phone_mobile)) $sql.= natural_search('p.phone_mobile', $search_phone_mobile);
if (strlen($search_fax)) $sql.= natural_search('p.fax', $search_fax);
if (strlen($search_skype)) $sql.= natural_search('p.skype', $search_skype);
+if (strlen($search_twitter)) $sql.= natural_search('p.twitter', $search_twitter);
+if (strlen($search_facebook)) $sql.= natural_search('p.facebook', $search_facebook);
if (strlen($search_email)) $sql.= natural_search('p.email', $search_email);
if (strlen($search_zip)) $sql.= natural_search("p.zip",$search_zip);
if ($search_status != '' && $search_status >= 0) $sql.= " AND p.statut = ".$db->escape($search_status);
@@ -601,6 +609,18 @@ if (! empty($arrayfields['p.skype']['checked']))
print '';
print '';
}
+if (! empty($arrayfields['p.twitter']['checked']))
+{
+ print '';
+ print '';
+ print ' ';
+}
+if (! empty($arrayfields['p.facebook']['checked']))
+{
+ print '';
+ print '';
+ print ' ';
+}
if (! empty($arrayfields['p.thirdparty']['checked']))
{
print '';
@@ -671,6 +691,8 @@ if (! empty($arrayfields['p.phone_mobile']['checked'])) print_liste_field
if (! empty($arrayfields['p.fax']['checked'])) print_liste_field_titre($arrayfields['p.fax']['label'],$_SERVER["PHP_SELF"],"p.fax", $begin, $param, '', $sortfield,$sortorder);
if (! empty($arrayfields['p.email']['checked'])) print_liste_field_titre($arrayfields['p.email']['label'],$_SERVER["PHP_SELF"],"p.email", $begin, $param, '', $sortfield,$sortorder);
if (! empty($arrayfields['p.skype']['checked'])) print_liste_field_titre($arrayfields['p.skype']['label'],$_SERVER["PHP_SELF"],"p.skype", $begin, $param, '', $sortfield,$sortorder);
+if (! empty($arrayfields['p.twitter']['checked'])) print_liste_field_titre($arrayfields['p.twitter']['label'],$_SERVER["PHP_SELF"],"p.twitter", $begin, $param, '', $sortfield,$sortorder);
+if (! empty($arrayfields['p.facebook']['checked'])) print_liste_field_titre($arrayfields['p.facebook']['label'],$_SERVER["PHP_SELF"],"p.facebook", $begin, $param, '', $sortfield,$sortorder);
if (! empty($arrayfields['p.thirdparty']['checked'])) print_liste_field_titre($arrayfields['p.thirdparty']['label'],$_SERVER["PHP_SELF"],"s.nom", $begin, $param, '', $sortfield,$sortorder);
if (! empty($arrayfields['p.priv']['checked'])) print_liste_field_titre($arrayfields['p.priv']['label'],$_SERVER["PHP_SELF"],"p.priv", $begin, $param, 'align="center"', $sortfield,$sortorder);
// Extra fields
@@ -801,7 +823,19 @@ while ($i < min($num,$limit))
// Skype
if (! empty($arrayfields['p.skype']['checked']))
{
- if (! empty($conf->skype->enabled)) { print ' '.dol_print_skype($obj->skype,$obj->rowid,$obj->socid,'AC_SKYPE',18).' '; }
+ if (! empty($conf->socialnetworks->enabled)) { print ''.dol_print_socialnetworks($obj->skype,$obj->rowid,$obj->socid,'skype').' '; }
+ if (! $i) $totalarray['nbfield']++;
+ }
+ // Twitter
+ if (! empty($arrayfields['p.twitter']['checked']))
+ {
+ if (! empty($conf->socialnetworks->enabled)) { print ''.dol_print_socialnetworks($obj->twitter,$obj->rowid,$obj->socid,'twitter').' '; }
+ if (! $i) $totalarray['nbfield']++;
+ }
+ // Facebook
+ if (! empty($arrayfields['p.facebook']['checked']))
+ {
+ if (! empty($conf->socialnetworks->enabled)) { print ''.dol_print_socialnetworks($obj->facebook,$obj->rowid,$obj->socid,'facebook').' '; }
if (! $i) $totalarray['nbfield']++;
}
// Company
diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
index 2bcb802000f..7e0c2d13ca5 100644
--- a/htdocs/contrat/class/contrat.class.php
+++ b/htdocs/contrat/class/contrat.class.php
@@ -10,6 +10,7 @@
* Copyright (C) 2014-2015 Marcos García
* Copyright (C) 2015-2017 Ferran Marcet
* Copyright (C) 2018 Nicolas ZABOURI
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -2519,8 +2520,16 @@ class ContratLigne extends CommonObjectLine
public $tms;
+ /**
+ * @var int ID
+ */
public $fk_contrat;
+
+ /**
+ * @var int ID
+ */
public $fk_product;
+
public $statut; // 0 inactive, 4 active, 5 closed
public $type; // 0 for product, 1 for service
@@ -2563,6 +2572,10 @@ class ContratLigne extends CommonObjectLine
public $qty;
public $remise_percent;
public $remise;
+
+ /**
+ * @var int ID
+ */
public $fk_remise_except;
public $subprice; // Unit price HT
@@ -2582,13 +2595,30 @@ class ContratLigne extends CommonObjectLine
public $total_localtax2;
public $total_ttc;
+ /**
+ * @var int ID
+ */
public $fk_fournprice;
+
public $pa_ht;
public $info_bits;
+
+ /**
+ * @var int ID
+ */
public $fk_user_author;
+
+ /**
+ * @var int ID
+ */
public $fk_user_ouverture;
+
+ /**
+ * @var int ID
+ */
public $fk_user_cloture;
+
public $commentaire;
const STATUS_INITIAL = 0;
@@ -2858,9 +2888,9 @@ class ContratLigne extends CommonObjectLine
$error=0;
// Clean parameters
- $this->fk_contrat=trim($this->fk_contrat);
- $this->fk_product=trim($this->fk_product);
- $this->statut=(int) $this->statut;
+ $this->fk_contrat = (int) $this->fk_contrat;
+ $this->fk_product = (int) $this->fk_product;
+ $this->statut = (int) $this->statut;
$this->label=trim($this->label);
$this->description=trim($this->description);
$this->vat_src_code=trim($this->vat_src_code);
@@ -2870,7 +2900,7 @@ class ContratLigne extends CommonObjectLine
$this->qty=trim($this->qty);
$this->remise_percent=trim($this->remise_percent);
$this->remise=trim($this->remise);
- $this->fk_remise_except=trim($this->fk_remise_except);
+ $this->fk_remise_except = (int) $this->fk_remise_except;
$this->subprice=price2num($this->subprice);
$this->price_ht=price2num($this->price_ht);
$this->total_ht=trim($this->total_ht);
@@ -2879,9 +2909,9 @@ class ContratLigne extends CommonObjectLine
$this->total_localtax2=trim($this->total_localtax2);
$this->total_ttc=trim($this->total_ttc);
$this->info_bits=trim($this->info_bits);
- $this->fk_user_author=trim($this->fk_user_author);
- $this->fk_user_ouverture=trim($this->fk_user_ouverture);
- $this->fk_user_cloture=trim($this->fk_user_cloture);
+ $this->fk_user_author = (int) $this->fk_user_author;
+ $this->fk_user_ouverture = (int) $this->fk_user_ouverture;
+ $this->fk_user_cloture = (int) $this->fk_user_cloture;
$this->commentaire=trim($this->commentaire);
//if (empty($this->subprice)) $this->subprice = 0;
if (empty($this->price_ht)) $this->price_ht = 0;
diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php
index 297f7821599..58f96b7faf1 100644
--- a/htdocs/core/actions_linkedfiles.inc.php
+++ b/htdocs/core/actions_linkedfiles.inc.php
@@ -50,13 +50,17 @@ if (GETPOST('sendit','alpha') && ! empty($conf->global->MAIN_UPLOAD_DOC))
if (! $error)
{
+ // Define if we have to generate thumbs or not
+ $generatethumbs = 1;
+ if (GETPOST('section_dir')) $generatethumbs=0;
+
if (! empty($upload_dirold) && ! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
{
- $result = dol_add_file_process($upload_dirold, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'));
+ $result = dol_add_file_process($upload_dirold, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'), null, '', $generatethumbs);
}
elseif (! empty($upload_dir))
{
- $result = dol_add_file_process($upload_dir, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'));
+ $result = dol_add_file_process($upload_dir, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'), null, '', $generatethumbs);
}
}
}
@@ -69,7 +73,7 @@ elseif (GETPOST('linkit','none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
if (substr($link, 0, 7) != 'http://' && substr($link, 0, 8) != 'https://' && substr($link, 0, 7) != 'file://') {
$link = 'http://' . $link;
}
- dol_add_file_process($upload_dir, 0, 1, 'userfile', null, $link);
+ dol_add_file_process($upload_dir, 0, 1, 'userfile', null, $link, '', 0);
}
}
@@ -77,20 +81,23 @@ elseif (GETPOST('linkit','none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
// Delete file/link
if ($action == 'confirm_deletefile' && $confirm == 'yes')
{
- $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
- if (GETPOST('section', 'alpha')) $file = $upload_dir . "/" . $urlfile; // For a delete of GED module urlfile contains full path from upload_dir
- else // For documents pages, upload_dir contains already path to file from module dir, so we clean path into urlfile.
+ $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
+ if (GETPOST('section', 'alpha')) // For a delete from the ECM module, upload_dir is ECM root dir and urlfile contains relative path from upload_dir
+ {
+ $file = $upload_dir . (preg_match('/\/$/', $upload_dir) ? '' : '/') . $urlfile;
+ }
+ else // For a delete from the file manager into another module, or from documents pages, upload_dir contains already path to file from module dir, so we clean path into urlfile.
{
$urlfile=basename($urlfile);
- $file = $upload_dir . "/" . $urlfile;
+ $file = $upload_dir . (preg_match('/\/$/', $upload_dir) ? '' : '/') . $urlfile;
if (! empty($upload_dirold)) $fileold = $upload_dirold . "/" . $urlfile;
}
- $linkid = GETPOST('linkid', 'int'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
+ $linkid = GETPOST('linkid', 'int');
- if ($urlfile)
+ if ($urlfile) // delete of a file
{
- $dir = dirname($file).'/'; // Chemin du dossier contenant l'image d'origine
- $dirthumb = $dir.'/thumbs/'; // Chemin du dossier contenant la vignette
+ $dir = dirname($file).'/'; // Chemin du dossier contenant l'image d'origine
+ $dirthumb = $dir.'/thumbs/'; // Chemin du dossier contenant la vignette (if file is an image)
$ret = dol_delete_file($file, 0, 0, 0, (is_object($object)?$object:null));
if (! empty($fileold)) dol_delete_file($fileold, 0, 0, 0, (is_object($object)?$object:null)); // Delete file using old path
@@ -114,7 +121,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes')
if ($ret) setEventMessages($langs->trans("FileWasRemoved", $urlfile), null, 'mesgs');
else setEventMessages($langs->trans("ErrorFailToDeleteFile", $urlfile), null, 'errors');
}
- elseif ($linkid)
+ elseif ($linkid) // delete of external link
{
require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
$link = new Link($db);
@@ -143,7 +150,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes')
}
else
{
- header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id.(!empty($withproject)?'&withproject=1':''));
+ header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.(GETPOST('section_dir','alpha')?'§ion_dir='.urlencode(GETPOST('section_dir','alpha')):'').(!empty($withproject)?'&withproject=1':''));
exit;
}
}
@@ -208,13 +215,20 @@ elseif ($action == 'renamefile' && GETPOST('renamefilesave','alpha'))
$result = dol_move($srcpath, $destpath);
if ($result)
{
- if ($object->id)
- {
- $object->addThumbs($destpath);
- }
+ // Define if we have to generate thumbs or not
+ $generatethumbs = 1;
+ if (GETPOST('section_dir')) $generatethumbs=0;
- // TODO Add revert function of addThumbs to remove for old name
- //$object->delThumbs($srcpath);
+ if ($generatethumbs)
+ {
+ if ($object->id)
+ {
+ $object->addThumbs($destpath);
+ }
+
+ // TODO Add revert function of addThumbs to remove thumbs with old name
+ //$object->delThumbs($srcpath);
+ }
setEventMessages($langs->trans("FileRenamed"), null);
}
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index 2bb55264cf9..6621ffaeb8a 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -1098,6 +1098,18 @@ if (! $error && ($massaction == 'delete' || ($action == 'delete' && $confirm ==
continue;
}
+ if ($objectclass == "Task" && $objecttmp->hasChildren() > 0)
+ {
+ $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task SET fk_task_parent = 0 WHERE fk_task_parent = ".$objecttmp->id;
+ $res = $db->query($sql);
+
+ if (!$res)
+ {
+ setEventMessage('ErrorRecordParentingNotModified', 'errors');
+ $error++;
+ }
+ }
+
if (in_array($objecttmp->element, array('societe', 'member'))) $result = $objecttmp->delete($objecttmp->id, $user, 1);
else $result = $objecttmp->delete($user);
diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php
index d2d34cd523a..d5c40c17ad0 100644
--- a/htdocs/core/actions_printing.inc.php
+++ b/htdocs/core/actions_printing.inc.php
@@ -47,11 +47,21 @@ if ($action == 'print_file' && $user->rights->printing->read) {
{
$printerfound++;
- $subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':'');
+ $subdir='';
$module = GETPOST('printer', 'alpha');
- if ($module =='commande_fournisseur') {
- $module = 'fournisseur';
- $subdir = 'commande';
+ switch ($module )
+ {
+ case 'livraison' :
+ $subdir = 'receipt';
+ $module = 'expedition';
+ break;
+ case 'expedition' :
+ $subdir = 'sending';
+ break;
+ case 'commande_fournisseur' :
+ $module = 'fournisseur';
+ $subdir = 'commande';
+ break;
}
try {
$ret = $printer->printFile(GETPOST('file', 'alpha'), $module, $subdir);
diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php
index 6afd6b1e354..153c5ca9364 100644
--- a/htdocs/core/actions_sendmails.inc.php
+++ b/htdocs/core/actions_sendmails.inc.php
@@ -425,7 +425,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
if (empty($actiontypecode)) $actiontypecode='AC_OTH_AUTO'; // Event insert into agenda automatically
$object->socid = $sendtosocid; // To link to a company
- $object->sendtoid = $sendtoid; // To link to contacts/addresses. This is an array.
+ $object->sendtoid = $sendtoid; // To link to contact addresses. This is an array.
$object->actiontypecode = $actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
$object->actionmsg = $actionmsg; // Long text
$object->actionmsg2 = $actionmsg2; // Short text
diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php
index 8d1c5cd712c..82f83595537 100644
--- a/htdocs/core/ajax/ajaxdirpreview.php
+++ b/htdocs/core/ajax/ajaxdirpreview.php
@@ -82,9 +82,16 @@ else // For no ajax call
dol_print_error($db,$ecmdir->error);
exit;
}
+
+ $relativepath=$ecmdir->getRelativePath(); // Example 'mydir/'
}
- $relativepath=$ecmdir->getRelativePath();
- $upload_dir = $rootdirfordoc.'/'.$relativepath;
+ elseif (GETPOST('section_dir'))
+ {
+ $relativepath=GETPOST('section_dir');
+ }
+ //var_dump($section.'-'.GETPOST('section_dir').'-'.$relativepath);
+
+ $upload_dir = $rootdirfordoc.'/'.$relativepath;
}
if (empty($url))
@@ -226,7 +233,18 @@ if ($type == 'directory')
{
if ($module == 'medias')
{
- $relativepath=GETPOST('file','alpha');
+ /*
+ $_POST is array like
+ 'token' => string '062380e11b7dcd009d07318b57b71750' (length=32)
+ 'action' => string 'file_manager' (length=12)
+ 'website' => string 'template' (length=8)
+ 'pageid' => string '124' (length=3)
+ 'section_dir' => string 'mydir/' (length=3)
+ 'section_id' => string '0' (length=1)
+ 'max_file_size' => string '2097152' (length=7)
+ 'sendit' => string 'Envoyer fichier' (length=15)
+ */
+ $relativepath=GETPOST('file','alpha')?GETPOST('file','alpha'):GETPOST('section_dir','alpha');
if ($relativepath && $relativepath!= '/') $relativepath.='/';
$upload_dir = $dolibarr_main_data_root.'/'.$module.'/'.$relativepath;
if (GETPOSTISSET('website') || GETPOSTISSET('file_manager'))
diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php
index 4b588751829..a1fafa80559 100644
--- a/htdocs/core/ajax/ajaxdirtree.php
+++ b/htdocs/core/ajax/ajaxdirtree.php
@@ -1,5 +1,6 @@
+/* Copyright (C) 2007-2018 Laurent Destailleur
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +31,7 @@ if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1');
if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
+
if (! isset($mode) || $mode != 'noajax') // For ajax call
{
$res=@include '../../main.inc.php';
@@ -39,16 +41,26 @@ if (! isset($mode) || $mode != 'noajax') // For ajax call
include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
+ //if (GETPOST('preopened')) { $_GET['dir'] = $_POST['dir'] = '/bbb/'; }
+
$openeddir = GETPOST('openeddir');
$modulepart= GETPOST('modulepart');
$selecteddir = jsUnEscape(GETPOST('dir')); // relative path. We must decode using same encoding function used by javascript: escape()
+
+ $preopened = GETPOST('preopened');
+
if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir); // We removed last '/' except if it is '/'
}
else // For no ajax call
{
+ //if (GETPOST('preopened')) { $_GET['dir'] = $_POST['dir'] = GETPOST('preopened'); }
+
$openeddir = GETPOST('openeddir');
$modulepart= GETPOST('modulepart');
$selecteddir = GETPOST('dir');
+
+ $preopened = GETPOST('preopened');
+
if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir); // We removed last '/' except if it is '/'
if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
}
@@ -58,8 +70,16 @@ $langs->load("ecm");
// Define fullpathselecteddir.
$fullpathselecteddir='';
-if ($modulepart == 'ecm') $fullpathselecteddir=$conf->ecm->dir_output.'/'.($selecteddir != '/' ? $selecteddir : '');
-if ($modulepart == 'medias') $fullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($selecteddir != '/' ? $selecteddir : '');
+if ($modulepart == 'ecm')
+{
+ $fullpathselecteddir=$conf->ecm->dir_output.'/'.($selecteddir != '/' ? $selecteddir : '');
+ $fullpathpreopened=$conf->ecm->dir_output.'/'.($preopened != '/' ? $preopened : '');
+}
+elseif ($modulepart == 'medias')
+{
+ $fullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($selecteddir != '/' ? $selecteddir : '');
+ $fullpathpreopened=$dolibarr_main_data_root.'/medias/'.($preopened != '/' ? $preopened : '');
+}
// Security:
@@ -77,7 +97,7 @@ if ($modulepart == 'ecm')
{
if (! $user->rights->ecm->read) accessforbidden();
}
-if ($modulepart == 'medias')
+elseif ($modulepart == 'medias')
{
// Always allowed
}
@@ -87,20 +107,20 @@ if ($modulepart == 'medias')
* View
*/
-if (! isset($mode) || $mode != 'noajax')
+if (! isset($mode) || $mode != 'noajax') // if ajax mode
{
top_httphead();
}
-//print ''."\n";
+//print ''."\n";
$userstatic=new User($db);
$form=new Form($db);
$ecmdirstatic = new EcmDirectory($db);
-// Load full tree from database. We will use it to define nbofsubdir and nboffilesinsubdir
+// Load full tree of ECM module from database. We will use it to define nbofsubdir and nboffilesinsubdir
if (empty($sqltree)) $sqltree=$ecmdirstatic->get_full_arbo(0);
-// Try to find key into $sqltree
+// Try to find selected dir id into $sqltree and save it into $current_ecmdir_id
$current_ecmdir_id=-1;
foreach($sqltree as $keycursor => $val)
{
@@ -113,131 +133,13 @@ foreach($sqltree as $keycursor => $val)
if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))
{
- if (file_exists($fullpathselecteddir))
- {
- $files = @scandir($fullpathselecteddir);
+ treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened);
- if ($files)
- {
- natcasesort($files);
- if (count($files) > 2) /* The 2 accounts for . and .. */
- {
- echo '\n";
-
- }
- }
- else print "PermissionDenied";
- }
-
// This ajax service is called only when a directory $selecteddir is opened but not when closed.
//print '';
- $formconfirm.= "\n";
+ $formconfirm.= "\n";
}
else
{
- $formconfirm.= "\n\n";
+ $formconfirm.= "\n\n";
if (empty($disableformtag)) $formconfirm.= '\n";
$formconfirm.= '
';
- $formconfirm.= "\n";
+ $formconfirm.= "\n";
}
return $formconfirm;
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index 4a59e28f044..bfc67880a96 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -310,7 +310,7 @@ class FormFile
$param.= 'entity='.(!empty($object->entity)?$object->entity:$conf->entity);
$printer=0;
- if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport'))) // The direct print feature is implemented only for such elements
+ if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport','livraison'))) // The direct print feature is implemented only for such elements
{
$printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false;
}
@@ -1139,7 +1139,6 @@ class FormFile
//var_dump($sortfield.' - '.$sortorder);
if ($sortfield && $sortorder) // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
{
- //var_dump($sortfield);
$filearray=dol_sort_array($filearray, $sortfield, $sortorder);
}
}
@@ -1162,7 +1161,7 @@ class FormFile
print ''."\n";
// Do we have entry into database ?
print ''."\n";
- print '';
+ print ' ';
// File name
print '';
@@ -1258,12 +1257,9 @@ class FormFile
if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1';
$fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:'');
- //if (! empty($object->ref)) $fulllink.='&hashn='.$object->ref; // Hash of file path
- //elseif (! empty($object->label)) $fulllink.='&hashc='.$object->label; // Hash of file content
print img_picto($langs->trans("FileSharedViaALink"),'object_globe.png').' ';
print '';
- //print ' '.$langs->trans("Download").''; // No target here
}
else
{
@@ -1299,17 +1295,12 @@ class FormFile
if ($permtoeditline)
{
- print ''.img_edit('default',0,'class="paddingrightonly"').'';
+ $paramsectiondir=(in_array($modulepart, array('medias','ecm'))?'§ion_dir='.urlencode($relativepath):'');
+ print ''.img_edit('default',0,'class="paddingrightonly"').'';
}
}
if ($permonobject)
{
- /*
- if ($file['level1name'] <> $object->id)
- $filepath=$file['level1name'].'/'.$file['name'];
- else
- $filepath=$file['name'];
- */
$useajax=1;
if (! empty($conf->dol_use_jmobile)) $useajax=0;
if (empty($conf->use_javascript_ajax)) $useajax=0;
diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
index c80358315c6..68da2dce777 100644
--- a/htdocs/core/class/html.formmail.class.php
+++ b/htdocs/core/class/html.formmail.class.php
@@ -4,6 +4,7 @@
* Copyright (C) 2010-2011 Juanjo Menent
* Copyright (C) 2015-2017 Marcos García
* Copyright (C) 2015-2017 Nicolas ZABOURI
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,7 +45,28 @@ class FormMail extends Form
public $fromname;
public $frommail;
- public $replytoname;
+
+ /**
+ * @var string user, company, robot
+ */
+ public $fromtype;
+
+ /**
+ * @var int ID
+ */
+ public $fromid;
+
+ /**
+ * @var string thirdparty etc
+ */
+ public $totype;
+
+ /**
+ * @var int ID
+ */
+ public $toid;
+
+ public $replytoname;
public $replytomail;
public $toname;
public $tomail;
@@ -91,11 +113,6 @@ class FormMail extends Form
public $withtouser=array();
public $withtoccuser=array();
- /**
- * @var string Error code (or message)
- */
- public $error='';
-
public $lines_model;
diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php
index 04cc6705623..b2166453bbd 100644
--- a/htdocs/core/class/html.formprojet.class.php
+++ b/htdocs/core/class/html.formprojet.class.php
@@ -235,7 +235,7 @@ class FormProjets
}
else if ($obj->fk_statut == 2)
{
- if ($discard_close == 2) $disabled=1;
+ if ($discard_closed == 2) $disabled=1;
$labeltoshow.=' - '.$langs->trans("Closed");
}
else if ( empty($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY) && $socid > 0 && (! empty($obj->fk_soc) && $obj->fk_soc != $socid))
diff --git a/htdocs/core/class/html.formsms.class.php b/htdocs/core/class/html.formsms.class.php
index a04da7caf08..4ef6208723d 100644
--- a/htdocs/core/class/html.formsms.class.php
+++ b/htdocs/core/class/html.formsms.class.php
@@ -1,20 +1,21 @@
- * Copyright (C) 2010 Juanjo Menent
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-*/
+/* Copyright (C) 2005-2011 Laurent Destailleur
+ * Copyright (C) 2010 Juanjo Menent
+ * Copyright (C) 2018 Frédéric France
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
/**
* \file htdocs/core/class/html.formsms.class.php
@@ -37,33 +38,38 @@ class FormSms
*/
public $db;
- var $fromname;
- var $fromsms;
- var $replytoname;
- var $replytomail;
- var $toname;
- var $tomail;
+ public $fromname;
+ public $fromsms;
+ public $replytoname;
+ public $replytomail;
+ public $toname;
+ public $tomail;
- var $withsubstit; // Show substitution array
- var $withfrom;
- var $withto;
- var $withtopic;
- var $withbody;
+ public $withsubstit; // Show substitution array
+ public $withfrom;
+ public $withto;
+ public $withtopic;
+ public $withbody;
- var $withfromreadonly;
- var $withreplytoreadonly;
- var $withtoreadonly;
- var $withtopicreadonly;
- var $withcancel;
+ public $withfromreadonly;
+ public $withreplytoreadonly;
+ public $withtoreadonly;
+ public $withtopicreadonly;
+ public $withcancel;
- var $substit=array();
- var $param=array();
+ public $substit=array();
+ public $param=array();
/**
* @var string Error code (or message)
*/
public $error='';
+ /**
+ * @var string[] Array of error strings
+ */
+ public $errors=array();
+
/**
* Constructor
diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php
index 5d2136bd236..6c4a9703014 100644
--- a/htdocs/core/class/html.formticket.class.php
+++ b/htdocs/core/class/html.formticket.class.php
@@ -45,6 +45,10 @@ class FormTicket
public $db;
public $track_id;
+
+ /**
+ * @var int ID
+ */
public $fk_user_create;
public $message;
diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php
index 7db88051e5e..1ca10d9dd9b 100644
--- a/htdocs/core/class/menubase.class.php
+++ b/htdocs/core/class/menubase.class.php
@@ -1,6 +1,7 @@
* Copyright (C) 2009-2012 Regis Houssin
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -52,9 +53,25 @@ class Menubase
public $module;
public $type;
public $mainmenu;
+
+ /**
+ * @var int ID
+ */
public $fk_menu;
+
+ /**
+ * @var string fk_mainmenu
+ */
public $fk_mainmenu;
+
+ /**
+ * @var string fk_leftmenu
+ */
public $fk_leftmenu;
+
+ /**
+ * @var int position
+ */
public $position;
public $url;
public $target;
@@ -98,10 +115,10 @@ class Menubase
$this->type=trim($this->type);
$this->mainmenu=trim($this->mainmenu);
$this->leftmenu=trim($this->leftmenu);
- $this->fk_menu=trim($this->fk_menu); // If -1, fk_mainmenu and fk_leftmenu must be defined
+ $this->fk_menu = (int) $this->fk_menu; // If -1, fk_mainmenu and fk_leftmenu must be defined
$this->fk_mainmenu=trim($this->fk_mainmenu);
$this->fk_leftmenu=trim($this->fk_leftmenu);
- $this->position=trim($this->position);
+ $this->position = (int) $this->position;
$this->url=trim($this->url);
$this->target=trim($this->target);
$this->titre=trim($this->titre);
@@ -109,7 +126,7 @@ class Menubase
$this->perms=trim($this->perms);
$this->enabled=trim($this->enabled);
$this->user=trim($this->user);
- $this->position=trim($this->position);
+ if (empty($this->position)) $this->position=0;
if (! $this->level) $this->level=0;
// Check parameters
@@ -142,7 +159,7 @@ class Menubase
$sql = "SELECT count(*)";
$sql.= " FROM ".MAIN_DB_PREFIX."menu";
$sql.= " WHERE menu_handler = '".$this->db->escape($this->menu_handler)."'";
- $sql.= " AND fk_menu = ".((int) $this->db->escape($this->fk_menu));
+ $sql.= " AND fk_menu = ".((int) $this->fk_menu);
$sql.= " AND position = ".((int) $this->position);
$sql.= " AND url = '".$this->db->escape($this->url)."'";
$sql.= " AND entity = ".$conf->entity;
@@ -239,10 +256,10 @@ class Menubase
$this->type=trim($this->type);
$this->mainmenu=trim($this->mainmenu);
$this->leftmenu=trim($this->leftmenu);
- $this->fk_menu=trim($this->fk_menu);
+ $this->fk_menu = (int) $this->fk_menu;
$this->fk_mainmenu=trim($this->fk_mainmenu);
$this->fk_leftmenu=trim($this->fk_leftmenu);
- $this->position=trim($this->position);
+ $this->position = (int) $this->position;
$this->url=trim($this->url);
$this->target=trim($this->target);
$this->titre=trim($this->titre);
@@ -261,7 +278,7 @@ class Menubase
$sql.= " type='".$this->db->escape($this->type)."',";
$sql.= " mainmenu='".$this->db->escape($this->mainmenu)."',";
$sql.= " leftmenu='".$this->db->escape($this->leftmenu)."',";
- $sql.= " fk_menu='".$this->db->escape($this->fk_menu)."',";
+ $sql.= " fk_menu=".$this->fk_menu.",";
$sql.= " fk_mainmenu=".($this->fk_mainmenu?"'".$this->db->escape($this->fk_mainmenu)."'":"null").",";
$sql.= " fk_leftmenu=".($this->fk_leftmenu?"'".$this->db->escape($this->fk_leftmenu)."'":"null").",";
$sql.= " position=".($this->position > 0 ? $this->position : 0).",";
diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php
index fb6c94b00f7..7a24e4928c7 100644
--- a/htdocs/core/class/notify.class.php
+++ b/htdocs/core/class/notify.class.php
@@ -51,11 +51,11 @@ class Notify
*/
public $errors = array();
- var $author;
- var $ref;
- var $date;
- var $duree;
- var $note;
+ public $author;
+ public $ref;
+ public $date;
+ public $duree;
+ public $note;
/**
* @var int Project ID
@@ -65,6 +65,7 @@ class Notify
// Les codes actions sont definis dans la table llx_notify_def
// codes actions supported are
+ // @TODO defined also into interface_50_modNotificiation_Notificiation.class.php
public $arrayofnotifsupported = array(
'BILL_VALIDATE',
'BILL_PAYED',
@@ -76,7 +77,11 @@ class Notify
'ORDER_SUPPLIER_VALIDATE',
'ORDER_SUPPLIER_APPROVE',
'ORDER_SUPPLIER_REFUSE',
- 'SHIPPING_VALIDATE'
+ 'SHIPPING_VALIDATE',
+ 'EXPENSE_REPORT_VALIDATE',
+ 'EXPENSE_REPORT_APPROVE',
+ 'HOLIDAY_VALIDATE',
+ 'HOLIDAY_APPROVE'
);
@@ -340,22 +345,27 @@ class Notify
$oldref=(empty($object->oldref)?$object->ref:$object->oldref);
$newref=(empty($object->newref)?$object->ref:$object->newref);
+ $sql = '';
+
// Check notification per third party
- $sql = "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
- $sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
- $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,";
- $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
- $sql.= " ".MAIN_DB_PREFIX."notify_def as n,";
- $sql.= " ".MAIN_DB_PREFIX."societe as s";
- $sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
- $sql.= " AND n.fk_soc = s.rowid";
- if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage
- else $sql.= " AND a.code = '".$notifcode."'"; // New usage
- $sql .= " AND s.rowid = ".$object->socid;
+ if ($object->socid > 0)
+ {
+ $sql.= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
+ $sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
+ $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,";
+ $sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
+ $sql.= " ".MAIN_DB_PREFIX."notify_def as n,";
+ $sql.= " ".MAIN_DB_PREFIX."societe as s";
+ $sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
+ $sql.= " AND n.fk_soc = s.rowid";
+ if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage
+ else $sql.= " AND a.code = '".$notifcode."'"; // New usage
+ $sql .= " AND s.rowid = ".$object->socid;
+
+ $sql.= "\nUNION\n";
+ }
// Check notification per user
- $sql.= "\nUNION\n";
-
$sql.= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
$sql.= " FROM ".MAIN_DB_PREFIX."user as c,";
@@ -363,7 +373,7 @@ class Notify
$sql.= " ".MAIN_DB_PREFIX."notify_def as n";
$sql.= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action";
if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage
- else $sql.= " AND a.code = '".$notifcode."'"; // New usage
+ else $sql.= " AND a.code = '".$this->db->escape($notifcode)."'"; // New usage
$result = $this->db->query($sql);
if ($result)
@@ -396,6 +406,7 @@ class Notify
{
$outputlangs = new Translate('', $conf);
$outputlangs->setDefaultLang($obj->default_lang);
+ $outputlangs->loadLangs(array("main","other"));
}
$subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification").($projtitle?' '.$projtitle:'');
@@ -405,72 +416,92 @@ class Notify
$link='/compta/facture/card.php?facid='.$object->id;
$dir_output = $conf->facture->dir_output;
$object_type = 'facture';
- $mesg = $langs->transnoentitiesnoconv("EMailTextInvoiceValidated",$newref);
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoiceValidated",$newref);
break;
case 'BILL_PAYED':
$link='/compta/facture/card.php?facid='.$object->id;
$dir_output = $conf->facture->dir_output;
$object_type = 'facture';
- $mesg = $langs->transnoentitiesnoconv("EMailTextInvoicePayed",$newref);
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoicePayed",$newref);
break;
case 'ORDER_VALIDATE':
$link='/commande/card.php?id='.$object->id;
$dir_output = $conf->commande->dir_output;
$object_type = 'order';
- $mesg = $langs->transnoentitiesnoconv("EMailTextOrderValidated",$newref);
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextOrderValidated",$newref);
break;
case 'PROPAL_VALIDATE':
$link='/comm/propal/card.php?id='.$object->id;
$dir_output = $conf->propal->multidir_output[$object->entity];
$object_type = 'propal';
- $mesg = $langs->transnoentitiesnoconv("EMailTextProposalValidated",$newref);
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalValidated",$newref);
break;
case 'PROPAL_CLOSE_SIGNED':
$link='/comm/propal/card.php?id='.$object->id;
$dir_output = $conf->propal->multidir_output[$object->entity];
$object_type = 'propal';
- $mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref);
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref);
break;
case 'FICHINTER_ADD_CONTACT':
$link='/fichinter/card.php?id='.$object->id;
$dir_output = $conf->ficheinter->dir_output;
$object_type = 'ficheinter';
- $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$object->ref);
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$newref);
break;
case 'FICHINTER_VALIDATE':
$link='/fichinter/card.php?id='.$object->id;
$dir_output = $conf->ficheinter->dir_output;
$object_type = 'ficheinter';
- $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionValidated",$object->ref);
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionValidated",$newref);
break;
case 'ORDER_SUPPLIER_VALIDATE':
$link='/fourn/commande/card.php?id='.$object->id;
$dir_output = $conf->fournisseur->commande->dir_output;
$object_type = 'order_supplier';
- $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
- $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$object->ref,$user->getFullName($langs));
- $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
+ $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
+ $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$newref,$user->getFullName($langs));
+ $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
break;
case 'ORDER_SUPPLIER_APPROVE':
$link='/fourn/commande/card.php?id='.$object->id;
$dir_output = $conf->fournisseur->commande->dir_output;
$object_type = 'order_supplier';
- $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
- $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$newref,$user->getFullName($langs));
- $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
+ $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
+ $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$newref,$user->getFullName($langs));
+ $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
break;
case 'ORDER_SUPPLIER_REFUSE':
$link='/fourn/commande/card.php?id='.$object->id;
$dir_output = $conf->fournisseur->commande->dir_output;
$object_type = 'order_supplier';
- $mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
- $mesg.= $langs->transnoentitiesnoconv("EMailTextOrderRefusedBy",$newref,$user->getFullName($langs));
- $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
+ $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
+ $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderRefusedBy",$newref,$user->getFullName($langs));
+ $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
break;
case 'SHIPPING_VALIDATE':
$dir_output = $conf->expedition->dir_output.'/sending/';
$object_type = 'order_supplier';
- $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
+ break;
+ case 'EXPENSE_REPORT_VALIDATE':
+ $dir_output = $conf->expensereport->dir_output;
+ $object_type = 'expensereport';
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
+ break;
+ case 'EXPENSE_REPORT_APPROVE':
+ $dir_output = $conf->expensereport->dir_output;
+ $object_type = 'expensereport';
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
+ break;
+ case 'HOLIDAY_VALIDATE':
+ $dir_output = $conf->holiday->dir_output;
+ $object_type = 'holiday';
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
+ break;
+ case 'HOLIDAY_APPROVE':
+ $dir_output = $conf->holiday->dir_output;
+ $object_type = 'holiday';
+ $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
break;
}
$ref = dol_sanitizeFileName($newref);
@@ -662,6 +693,26 @@ class Notify
$object_type = 'order_supplier';
$mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
break;
+ case 'EXPENSE_REPORT_VALIDATE':
+ $dir_output = $conf->expensereport->dir_output;
+ $object_type = 'expensereport';
+ $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
+ break;
+ case 'EXPENSE_REPORT_APPROVE':
+ $dir_output = $conf->expensereport->dir_output;
+ $object_type = 'expensereport';
+ $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
+ break;
+ case 'HOLIDAY_VALIDATE':
+ $dir_output = $conf->holiday->dir_output;
+ $object_type = 'holiday';
+ $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
+ break;
+ case 'HOLIDAY_APPROVE':
+ $dir_output = $conf->holiday->dir_output;
+ $object_type = 'holiday';
+ $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
+ break;
}
$ref = dol_sanitizeFileName($newref);
$pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
@@ -679,6 +730,8 @@ class Notify
$message.= $langs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n";
$message.= "\n";
$message.= $mesg;
+ //if ($link) $message.= "\n" . $urlwithroot . $link; // link already added around the ref into the text
+
$message = nl2br($message);
// Replace keyword __SUPERVISOREMAIL__
diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
index 17f83452ba5..2e489f6ba65 100644
--- a/htdocs/core/class/translate.class.php
+++ b/htdocs/core/class/translate.class.php
@@ -655,11 +655,12 @@ class Translate
* @param string $param2 chaine de param2
* @param string $param3 chaine de param3
* @param string $param4 chaine de param4
+ * @param string $param5 chaine de param5
* @return string Translated string (encoded into UTF8)
*/
- function transnoentities($key, $param1='', $param2='', $param3='', $param4='')
+ function transnoentities($key, $param1='', $param2='', $param3='', $param4='', $param5='')
{
- return $this->convToOutputCharset($this->transnoentitiesnoconv($key, $param1, $param2, $param3, $param4));
+ return $this->convToOutputCharset($this->transnoentitiesnoconv($key, $param1, $param2, $param3, $param4, $param5));
}
@@ -675,9 +676,10 @@ class Translate
* @param string $param2 chaine de param2
* @param string $param3 chaine de param3
* @param string $param4 chaine de param4
+ * @param string $param5 chaine de param5
* @return string Translated string
*/
- function transnoentitiesnoconv($key, $param1='', $param2='', $param3='', $param4='')
+ function transnoentitiesnoconv($key, $param1='', $param2='', $param3='', $param4='', $param5='')
{
global $conf;
@@ -700,7 +702,7 @@ class Translate
if (! preg_match('/^Format/',$key))
{
//print $str;
- $str=sprintf($str,$param1,$param2,$param3,$param4); // Replace %s and %d except for FormatXXX strings.
+ $str=sprintf($str, $param1, $param2, $param3, $param4, $param5); // Replace %s and %d except for FormatXXX strings.
}
return $str;
diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php
index 9f680ef4990..7904f485d6a 100644
--- a/htdocs/core/class/utils.class.php
+++ b/htdocs/core/class/utils.class.php
@@ -284,8 +284,9 @@ class Utils
}
$errormsg='';
+ $handle = '';
- // Debut appel methode execution
+ // Start call method to execute dump
$fullcommandcrypted=$command." ".$paramcrypted." 2>&1";
$fullcommandclear=$command." ".$paramclear." 2>&1";
if ($compression == 'none') $handle = fopen($outputfile, 'w');
diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
index 8a39043a680..bb08018b7f6 100644
--- a/htdocs/core/lib/ajax.lib.php
+++ b/htdocs/core/lib/ajax.lib.php
@@ -546,7 +546,7 @@ function ajax_constantonoff($code, $input=array(), $entity=null, $revertonoff=0,
* @param string $text_on Text if on
* @param string $text_off Text if off
* @param array $input Array of type->list of CSS element to switch. Example: array('disabled'=>array(0=>'cssid'))
- * @return void
+ * @return string html for button on/off
*/
function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input=array())
{
diff --git a/htdocs/core/lib/asset.lib.php b/htdocs/core/lib/asset.lib.php
index 7a4fd80158c..b0a4a6b81a9 100644
--- a/htdocs/core/lib/asset.lib.php
+++ b/htdocs/core/lib/asset.lib.php
@@ -26,7 +26,7 @@
*
* @return array head array with tabs
*/
-function AssetsAdminPrepareHead()
+function asset_admin_prepare_head()
{
global $langs, $conf;
@@ -70,7 +70,7 @@ function AssetsAdminPrepareHead()
*
* @return array head array with tabs
*/
-function AssetsPrepareHead()
+function asset_prepare_head()
{
global $langs, $conf;
diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php
index a23474e1104..46e3922a0d0 100644
--- a/htdocs/core/lib/company.lib.php
+++ b/htdocs/core/lib/company.lib.php
@@ -6,11 +6,11 @@
* Copyright (C) 2013-2014 Florian Henry
* Copyright (C) 2013-2014 Juanjo Menent
* Copyright (C) 2013 Christophe Battarel
- * Copyright (C) 2013 Alexandre Spangaro
+ * Copyright (C) 2013-2018 Alexandre Spangaro
* Copyright (C) 2015-2018 Frédéric France
* Copyright (C) 2015 Raphaël Doursenaud
- * Copyright (C) 2017 Rui Strecht
- * Copyright (C) 2018 Ferran Marcet
+ * Copyright (C) 2017 Rui Strecht
+ * Copyright (C) 2018 Ferran Marcet
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -154,18 +154,18 @@ function societe_prepare_head(Societe $object)
// Tab to accountancy
if (! empty($conf->accounting->enabled) && $object->client>0)
{
- $head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettrage.php?socid='.$object->id;
- $head[$h][1] = $langs->trans("TabAccountingCustomer");
- $head[$h][2] = 'accounting';
+ $head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettering_customer.php?socid='.$object->id;
+ $head[$h][1] = $langs->trans("TabLetteringCustomer");
+ $head[$h][2] = 'lettering_customer';
$h++;
}
// Tab to accountancy
if (! empty($conf->accounting->enabled) && $object->fournisseur>0)
{
- $head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettrage_supplier.php?socid='.$object->id;
- $head[$h][1] = $langs->trans("TabAccountingSupplier");
- $head[$h][2] = 'accounting_supplier';
+ $head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettering_supplier.php?socid='.$object->id;
+ $head[$h][1] = $langs->trans("TabLetteringSupplier");
+ $head[$h][2] = 'lettering_supplier';
$h++;
}
}
@@ -1303,6 +1303,8 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
global $param;
+ dol_include_once('/comm/action/class/actioncomm.class.php');
+
// Check parameters
if (! is_object($filterobj) && ! is_object($objcon)) dol_print_error('','BadParameter');
@@ -1358,6 +1360,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
$sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'product'";
if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
}
+ //TODO check how ot work with new table actioncomm_resources and multiple contact affectation
if (is_object($objcon) && $objcon->id) $sql.= " AND a.fk_contact = ".$objcon->id;
// Condition on actioncode
if (! empty($actioncode))
@@ -1394,6 +1397,14 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
{
$obj = $db->fetch_object($resql);
+ $contactaction = new ActionComm($db);
+ $contactaction->id=$obj->id;
+ $result = $contactaction->fetchResources();
+ if ($result<0) {
+ dol_print_error($db);
+ setEventMessage("company.lib::show_actions_done Error fetch ressource",'errors');
+ }
+
//if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
//elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
$tododone='';
@@ -1415,6 +1426,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
'userphoto'=>$obj->user_photo,
'contact_id'=>$obj->fk_contact,
+ 'socpeopleassigned' => $contactaction->socpeopleassigned,
'lastname'=>$obj->lastname,
'firstname'=>$obj->firstname,
'fk_element'=>$obj->fk_element,
@@ -1559,7 +1571,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
$out.=getTitleFieldOfList($langs->trans("Label"), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder);
$out.=getTitleFieldOfList($langs->trans("Date"), 0, $_SERVER["PHP_SELF"], 'a.datep,a.id', '', $param, 'align="center"', $sortfield, $sortorder);
$out.=getTitleFieldOfList('');
- $out.=getTitleFieldOfList($langs->trans("ActionOnContact"), 0, $_SERVER["PHP_SELF"], 'a.fk_contact', '', $param, '', $sortfield, $sortorder);
+ $out.=getTitleFieldOfList($langs->trans("ActionOnContact"), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder);
$out.=getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], 'a.percent', '', $param, 'align="center"', $sortfield, $sortorder);
$out.=getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'maxwidthsearch ');
$out.=' ';
@@ -1678,10 +1690,28 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
$contactstatic->firstname=$histo[$key]['firstname'];
$contactstatic->id=$histo[$key]['contact_id'];
$out.=''.$contactstatic->getNomUrl(1,'',10).' ';
- }
- else
- {
- $out.=' ';
+ } elseif (isset($histo[$key]['socpeopleassigned']) && is_array($histo[$key]['socpeopleassigned']) && count($histo[$key]['socpeopleassigned']) > 0) {
+ $out .= '';
+ foreach ( $histo[$key]['socpeopleassigned'] as $cid => $Tab ) {
+ $contact = new Contact($db);
+ $result = $contact->fetch($cid);
+
+ if ($result < 0)
+ dol_print_error($db, $contact->error);
+
+ if ($result > 0) {
+ $out .= $contact->getNomUrl(1);
+ if (isset($histo[$key]['acode']) && $histo[$key]['acode'] == 'AC_TEL') {
+ if (! empty($contact->phone_pro))
+ $out .= '(' . dol_print_phone($contact->phone_pro) . ')';
+ }
+ $out .= '';
+ }
+ }
+ $out .= ' ';
+ }
+ else {
+ $out.=' ';
}
// Status
diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php
index 8f01ea6aebe..84048ac9c66 100644
--- a/htdocs/core/lib/date.lib.php
+++ b/htdocs/core/lib/date.lib.php
@@ -572,6 +572,8 @@ function dol_get_first_day_week($day,$month,$year,$gm=false)
*/
function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $lastday=0)
{
+ global $conf;
+
$nbFerie = 0;
// Check to ensure we use correct parameters
@@ -583,10 +585,31 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
{
$ferie=false;
$countryfound=0;
+ $includesaturdayandsunday=1;
$jour = date("d", $timestampStart);
$mois = date("m", $timestampStart);
$annee = date("Y", $timestampStart);
+
+
+ // Check into var $conf->global->HOLIDAY_MORE_DAYS MM-DD,YYYY-MM-DD, ...
+ if (! empty($conf->global->HOLIDAY_MORE_PUBLIC_HOLIDAYS))
+ {
+ $arrayofdaystring=explode(',',$conf->global->HOLIDAY_MORE_PUBLIC_HOLIDAYS);
+ foreach($arrayofdaystring as $daystring)
+ {
+ $tmp=explode('-',$daystring);
+ if ($tmp[2])
+ {
+ if ($tmp[0] == $annee && $tmp[1] == $mois && $tmp[2] == $jour) $ferie=true;
+ }
+ else
+ {
+ if ($tmp[0] == $mois && $tmp[1] == $jour) $ferie=true;
+ }
+ }
+ }
+
if ($countrycode == 'FR')
{
$countryfound=1;
@@ -649,12 +672,6 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
$mois_pentecote = date("m", $date_pentecote);
if($jour_pentecote == $jour && $mois_pentecote == $mois) $ferie=true;
// "Pentecote"
-
- // Calul des samedis et dimanches
- $jour_julien = unixtojd($timestampStart);
- $jour_semaine = jddayofweek($jour_julien, 0);
- if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
- // Samedi (6) et dimanche (0)
}
// Pentecoste and Ascensione in Italy go to the sunday after: isn't holiday.
@@ -681,12 +698,18 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
$mois_paques = date("m", $date_paques);
if($jour_paques == $jour && $mois_paques == $mois) $ferie=true;
// Paques
+ }
- // Calul des samedis et dimanches
- $jour_julien = unixtojd($timestampStart);
- $jour_semaine = jddayofweek($jour_julien, 0);
- if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
- //Samedi (6) et dimanche (0)
+ if ($countrycode == 'IN')
+ {
+ $countryfound=1;
+
+ if($jour == 1 && $mois == 1) $ferie=true; // New Year's Day
+ if($jour == 26 && $mois == 1) $ferie=true; // Republic Day
+ if($jour == 1 && $mois == 5) $ferie=true; // May Day
+ if($jour == 15 && $mois == 8) $ferie=true; // Independence Day
+ if($jour == 2 && $mois == 10) $ferie=true; // Gandhi Jayanti
+ if($jour == 25 && $mois == 12) $ferie=true; // Christmas
}
if ($countrycode == 'ES')
@@ -724,12 +747,6 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
$mois_viernes = date("m", $date_viernes);
if($jour_viernes == $jour && $mois_viernes == $mois) $ferie=true;
//Viernes Santo
-
- // Calul des samedis et dimanches
- $jour_julien = unixtojd($timestampStart);
- $jour_semaine = jddayofweek($jour_julien, 0);
- if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
- //Samedi (6) et dimanche (0)
}
if ($countrycode == 'AT')
@@ -811,22 +828,15 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
$mois_fronleichnam = date("m", $date_fronleichnam);
if($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) $ferie=true;
// Fronleichnam
-
- // Calul des samedis et dimanches
- $jour_julien = unixtojd($timestampStart);
- $jour_semaine = jddayofweek($jour_julien, 0);
- if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
- //Samedi (6) et dimanche (0)
}
- // Cas pays non defini
- if (! $countryfound)
+ // If we have to include saturday and sunday
+ if ($includesaturdayandsunday)
{
- // Calul des samedis et dimanches
$jour_julien = unixtojd($timestampStart);
$jour_semaine = jddayofweek($jour_julien, 0);
if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
- //Samedi (6) et dimanche (0)
+ //Saturday (6) and Sunday (0)
}
// On incremente compteur
diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
index 5aff804b4da..7897041ebbf 100644
--- a/htdocs/core/lib/files.lib.php
+++ b/htdocs/core/lib/files.lib.php
@@ -2496,7 +2496,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
//$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
}
// Wrapping pour les propales
- else if ($modulepart == 'propal' && !empty($conf->propal->multidir_output[$entity]))
+ else if (($modulepart == 'propal' || $modulepart == 'propale') && !empty($conf->propal->multidir_output[$entity]))
{
if ($fuser->rights->propale->{$lire} || preg_match('/^specimen/i',$original_file))
{
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index d53e20fdc7d..7888338cdc2 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -13,6 +13,7 @@
* Copyright (C) 2014 Cédric GROSS
* Copyright (C) 2014-2015 Marcos García
* Copyright (C) 2015 Jean-François Ferry
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -2189,50 +2190,52 @@ function dol_print_email($email,$cid=0,$socid=0,$addlink=0,$max=64,$showinvalid=
}
/**
- * Show Skype link
+ * Show social network link
*
- * @param string $skype Skype to show (only skype, without 'Name of recipient' before)
+ * @param string $value Skype to show (only skype, without 'Name of recipient' before)
* @param int $cid Id of contact if known
* @param int $socid Id of third party if known
- * @param int $addlink 0=no link to create action
- * @param int $max Max number of characters to show
+ * @param string $type 'skype','facebook',...
* @return string HTML Link
*/
-function dol_print_skype($skype,$cid=0,$socid=0,$addlink=0,$max=64)
+function dol_print_socialnetworks($value,$cid,$socid,$type)
{
global $conf,$user,$langs;
- $newskype=$skype;
+ $newskype=$value;
- if (empty($skype)) return ' ';
+ if (empty($value)) return ' ';
- if (! empty($addlink))
+ if (! empty($type))
{
- $newskype =img_picto($langs->trans("Skype"), 'object_skype.png');
- $newskype.= ' ';
- $newskype.=dol_trunc($skype,$max);
- $newskype.= ' ';
- $newskype.='';
- $newskype.='
';
- $newskype.=' ';
- $newskype.='
';
- $newskype.='';
-
- if (($cid || $socid) && ! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create)
+ $newskype ='';
}
else
{
$langs->load("errors");
- $newskype.=img_warning($langs->trans("ErrorBadSkype",$skype));
+ $newskype.=img_warning($langs->trans("ErrorBadSocialNetworkValue",$value));
}
return $newskype;
}
@@ -3151,11 +3154,13 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
//if (in_array($picto, array('switch_off', 'switch_on', 'off', 'on')))
if (empty($srconly) && in_array($pictowithoutext, array(
'bank', 'close_title', 'delete', 'edit', 'ellipsis-h', 'filter', 'grip', 'grip_title', 'list', 'listlight', 'off', 'on', 'play', 'playdisabled', 'printer', 'resize',
- 'note','switch_off', 'switch_on', 'unlink', 'uparrow', '1downarrow', '1uparrow')
- )) {
+ 'note','switch_off', 'switch_on', 'unlink', 'uparrow', '1downarrow', '1uparrow',
+ 'skype','twitter','facebook'
+ )
+ )) {
$fakey = $pictowithoutext;
$facolor = ''; $fasize = '';
- $marginleftonlyshort = 0;
+ $marginleftonlyshort = 2;
if ($pictowithoutext == 'switch_off') {
$fakey = 'fa-toggle-off';
$facolor = '#999';
@@ -3237,12 +3242,13 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
else {
$fakey = 'fa-'.$pictowithoutext;
$facolor = '#444';
+ $marginleftonlyshort=0;
}
if (preg_match('/class="([^"]+)"/', $moreatt, $reg)) {
$morecss.= ($morecss?' ':'').$reg[1];
}
- $enabledisablehtml = '';
+ $enabledisablehtml = '';
if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
$enabledisablehtml.= $titlealt;
}
@@ -4565,6 +4571,7 @@ function price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerou
* 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT)
* 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT)
* 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK)
+ * Numeric = Nb of digits for rounding
* @param int $alreadysqlnb Put 1 if you know that content is already universal format number
* @return string Amount with universal numeric format (Example: '99.99999') or unchanged text if conversion fails. If amount is null or '', it returns ''.
*
@@ -4615,7 +4622,7 @@ function price2num($amount,$rounding='',$alreadysqlnb=0)
if ($rounding == 'MU') $nbofdectoround=$conf->global->MAIN_MAX_DECIMALS_UNIT;
elseif ($rounding == 'MT') $nbofdectoround=$conf->global->MAIN_MAX_DECIMALS_TOT;
elseif ($rounding == 'MS') $nbofdectoround=empty($conf->global->MAIN_MAX_DECIMALS_STOCK)?5:$conf->global->MAIN_MAX_DECIMALS_STOCK;
- elseif (is_numeric($rounding)) $nbofdectoround=$rounding; // For admin info page
+ elseif (is_numeric($rounding)) $nbofdectoround=$rounding;
//print "RR".$amount.' - '.$nbofdectoround.'
';
if (dol_strlen($nbofdectoround)) $amount = round($amount,$nbofdectoround); // $nbofdectoround can be 0.
else return 'ErrorBadParameterProvidedToFunction';
@@ -5982,6 +5989,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob
$substitutionarray['__THIRDPARTY_ID__'] = '__THIRDPARTY_ID__';
$substitutionarray['__THIRDPARTY_NAME__'] = '__THIRDPARTY_NAME__';
+ $substitutionarray['__THIRDPARTY_NAME_ALIAS__'] = '__THIRDPARTY_NAME_ALIAS__';
$substitutionarray['__THIRDPARTY_EMAIL__'] = '__THIRDPARTY_EMAIL__';
if (is_object($object) && $object->element == 'member')
@@ -6044,6 +6052,12 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob
$substitutionarray['__MEMBER_PHONE__']=$msgishtml?dol_htmlentitiesbr($object->phone):$object->phone;
$substitutionarray['__MEMBER_PHONEPRO__']=$msgishtml?dol_htmlentitiesbr($object->phone_perso):$object->phone_perso;
$substitutionarray['__MEMBER_PHONEMOBILE__']=$msgishtml?dol_htmlentitiesbr($object->phone_mobile):$object->phone_mobile;
+ $substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE__'] = dol_print_date($object->first_subscription_date, 'dayrfc');
+ $substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE_START__'] = dol_print_date($object->first_subscription_date_start, 'dayrfc');
+ $substitutionarray['__MEMBER_FIRST_SUBSCRIPTION_DATE_END__'] = dol_print_date($object->first_subscription_date_end, 'dayrfc');
+ $substitutionarray['__MEMBER_LAST_SUBSCRIPTION_DATE__'] = dol_print_date($object->last_subscription_date, 'dayrfc');
+ $substitutionarray['__MEMBER_LAST_SUBSCRIPTION_DATE_START__'] = dol_print_date($object->last_subscription_date_start, 'dayrfc');
+ $substitutionarray['__MEMBER_LAST_SUBSCRIPTION_DATE_END__'] = dol_print_date($object->last_subscription_date_end, 'dayrfc');
if (is_object($object) && $object->element == 'societe')
{
@@ -6212,7 +6226,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob
* @param array $substitutionarray Array with key->val to substitute. Example: array('__MYKEY__' => 'MyVal', ...)
* @param Translate $outputlangs Output language
* @return string Output string after substitutions
- * @see complete_substitutions_array
+ * @see complete_substitutions_array, getCommonSubstitutionArray
*/
function make_substitutions($text, $substitutionarray, $outputlangs=null)
{
@@ -7013,11 +7027,12 @@ function complete_head_from_modules($conf,$langs,$object,&$head,&$h,$type,$mode=
// No need to make a return $head. Var is modified as a reference
if (! empty($hookmanager))
{
- $parameters=array('object' => $object, 'mode' => $mode, 'head'=>$head);
- $reshook=$hookmanager->executeHooks('completeTabsHead',$parameters);
+ $parameters=array('object' => $object, 'mode' => $mode, 'head' => $head);
+ $reshook=$hookmanager->executeHooks('completeTabsHead', $parameters);
if ($reshook > 0)
{
$head = $hookmanager->resArray;
+ $h = count($head);
}
}
}
diff --git a/htdocs/core/lib/import.lib.php b/htdocs/core/lib/import.lib.php
index 89847d69c11..ea700c38845 100644
--- a/htdocs/core/lib/import.lib.php
+++ b/htdocs/core/lib/import.lib.php
@@ -1,8 +1,9 @@
- * Copyright (C) 2007 Rodolphe Quiedeville
- * Copyright (C) 2010 Regis Houssin
- * Copyright (C) 2010 Juanjo Menent
+/* Copyright (C) 2006-2009 Laurent Destailleur
+ * Copyright (C) 2007 Rodolphe Quiedeville
+ * Copyright (C) 2010 Regis Houssin
+ * Copyright (C) 2010 Juanjo Menent
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +21,9 @@
*/
/**
- * \file htdocs/core/lib/order.lib.php
- * \brief Ensemble de fonctions de base pour le module commande
- * \ingroup commande
- */
+ * \file htdocs/core/lib/import.lib.php
+ * \brief Ensemble de fonctions de base pour le module import
+ * \ingroup import
/**
* Function to return list of tabs for import pages
diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php
index ecbdfad82f5..0119b0f0ee5 100644
--- a/htdocs/core/lib/payments.lib.php
+++ b/htdocs/core/lib/payments.lib.php
@@ -1,6 +1,7 @@
+ * Copyright (C) 2013 Marcos García
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -164,7 +165,7 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
else $out.='&securekey='.dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2);
}
}
- if ($type == 'order')
+ elseif ($type == 'order')
{
$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=order&ref='.($mode?'':'');
if ($mode == 1) $out.='order_ref';
@@ -182,7 +183,7 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
}
}
}
- if ($type == 'invoice')
+ elseif ($type == 'invoice')
{
$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=invoice&ref='.($mode?'':'');
if ($mode == 1) $out.='invoice_ref';
@@ -200,7 +201,7 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
}
}
}
- if ($type == 'contractline')
+ elseif ($type == 'contractline')
{
$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=contractline&ref='.($mode?'':'');
if ($mode == 1) $out.='contractline_ref';
@@ -218,7 +219,7 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
}
}
}
- if ($type == 'member' || $type == 'membersubscription')
+ elseif ($type == 'member' || $type == 'membersubscription')
{
$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=membersubscription&ref='.($mode?'':'');
if ($mode == 1) $out.='member_ref';
@@ -335,14 +336,14 @@ function htmlPrintOnlinePaymentFooter($fromcompany, $langs, $addformmessage=0, $
$parammessageform='ONLINE_PAYMENT_MESSAGE_FORM_'.$suffix;
if (! empty($conf->global->$parammessageform)) print $langs->transnoentities($conf->global->$parammessageform);
- else if (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORM)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORM);
+ elseif (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORM)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORM);
// Add other message if VAT exists
if ($object->total_vat != 0 || $object->total_tva != 0)
{
$parammessageform='ONLINE_PAYMENT_MESSAGE_FORMIFVAT_'.$suffix;
if (! empty($conf->global->$parammessageform)) print $langs->transnoentities($conf->global->$parammessageform);
- else if (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORMIFVAT)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORMIFVAT);
+ elseif (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORMIFVAT)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORMIFVAT);
}
}
diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
index e112c0a279c..5b8a5d6d4c4 100644
--- a/htdocs/core/lib/pdf.lib.php
+++ b/htdocs/core/lib/pdf.lib.php
@@ -1395,7 +1395,7 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl
if ($detail->eatby) $dte[]=$outputlangs->transnoentitiesnoconv('printEatby',dol_print_date($detail->eatby, $format, false, $outputlangs));
if ($detail->sellby) $dte[]=$outputlangs->transnoentitiesnoconv('printSellby',dol_print_date($detail->sellby, $format, false, $outputlangs));
if ($detail->batch) $dte[]=$outputlangs->transnoentitiesnoconv('printBatch',$detail->batch);
- $dte[]=$outputlangs->transnoentitiesnoconv('printQty',$detail->dluo_qty);
+ $dte[]=$outputlangs->transnoentitiesnoconv('printQty',$detail->qty);
$libelleproduitservice.= "__N__ ".implode(" - ", $dte);
}
}
diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php
index c01026b445d..38660cc272a 100644
--- a/htdocs/core/lib/sendings.lib.php
+++ b/htdocs/core/lib/sendings.lib.php
@@ -364,7 +364,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='')
$detail.= $langs->trans("Batch").': '.$dbatch->batch;
$detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day");
$detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day");
- $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty;
+ $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->qty;
$detail.= '
';
}
print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"),$detail);
diff --git a/htdocs/core/lib/stock.lib.php b/htdocs/core/lib/stock.lib.php
index ac59ab230c7..579944117ab 100644
--- a/htdocs/core/lib/stock.lib.php
+++ b/htdocs/core/lib/stock.lib.php
@@ -39,7 +39,7 @@ function stock_prepare_head($object)
$head[$h][2] = 'card';
$h++;
- $head[$h][0] = DOL_URL_ROOT.'/product/stock/mouvement.php?id='.$object->id;
+ $head[$h][0] = DOL_URL_ROOT.'/product/stock/movement_list.php?id='.$object->id;
$head[$h][1] = $langs->trans("StockMovements");
$head[$h][2] = 'movements';
$h++;
diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
index 9f848fb68ee..350014b3eb9 100644
--- a/htdocs/core/lib/website.lib.php
+++ b/htdocs/core/lib/website.lib.php
@@ -305,9 +305,9 @@ function redirectToContainer($containerref, $containeraliasalt='',$containerid=0
*/
function includeContainer($containerref)
{
- global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $weblangs; // Very important. Required to have var available when running inluded containers.
+ global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs; // Very important. Required to have var available when running inluded containers.
global $includehtmlcontentopened;
- global $websitekey;
+ global $websitekey, $websitepagefile;
$MAXLEVEL=20;
@@ -607,7 +607,7 @@ function dolSavePageContent($filetpl, $object, $objectpage)
$tplcontent ='';
$tplcontent.= "title, 0, 'UTF-8').'" />'."\n";
$tplcontent.= ''."\n";
$tplcontent.= ''."\n";
+ $tplcontent.= ''."\n";
$tplcontent.= ''."\n";
$tplcontent.= ''."\n";
$tplcontent.= ''."\n";
@@ -672,7 +673,7 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
dol_delete_file($fileindex);
$indexcontent = 'SetIdentity($_GET['openid_identity']);
$openid_validation_result = $openid->ValidateWithServer();
- if ($openid_validation_result == true)
+ if ($openid_validation_result === true)
{
// OK HERE KEY IS VALID
@@ -90,7 +90,7 @@ function check_user_password_openid($usertotest,$passwordtotest,$entitytotest)
}
}
}
- else if($openid->IsError() == true)
+ else if($openid->IsError() === true)
{
// ON THE WAY, WE GOT SOME ERROR
$error = $openid->GetError();
diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql
index 806960aaa34..682746b3412 100644
--- a/htdocs/core/menus/init_menu_auguria.sql
+++ b/htdocs/core/menus/init_menu_auguria.sql
@@ -63,10 +63,16 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="admintools"', __HANDLER__, 'left', 320__+MAX_llx_menu__, 'home', '', 300__+MAX_llx_menu__, '/product/admin/product_tools.php?mainmenu=home&leftmenu=admintools', 'ProductVatMassChange', 1, 'products', '', '', 2, 15, __ENTITY__);
-- Home - Menu users and groups
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '1', __HANDLER__, 'left', 400__+MAX_llx_menu__, 'home', 'users', 1__+MAX_llx_menu__, '/user/home.php?leftmenu=users', 'MenuUsersAndGroups', 0, 'users', '', '', 2, 4, __ENTITY__);
+
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 401__+MAX_llx_menu__, 'home', '', 400__+MAX_llx_menu__, '/user/list.php?leftmenu=users', 'Users', 1, 'users', '$user->rights->user->user->lire || $user->admin', '', 2, 0, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 402__+MAX_llx_menu__, 'home', '', 401__+MAX_llx_menu__, '/user/card.php?leftmenu=users&action=create', 'NewUser', 2, 'users', '($user->rights->user->user->creer || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)', '', 2, 0, __ENTITY__);
-insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 403__+MAX_llx_menu__, 'home', '', 400__+MAX_llx_menu__, '/user/group/list.php?leftmenu=users', 'Groups', 1, 'users', '(($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->read:$user->rights->user->user->lire) || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)', '', 2, 1, __ENTITY__);
-insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 404__+MAX_llx_menu__, 'home', '', 403__+MAX_llx_menu__, '/user/group/card.php?leftmenu=users&action=create', 'NewGroup', 2, 'users', '(($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->write:$user->rights->user->user->creer) || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)', '', 2, 0, __ENTITY__);
+
+insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 404__+MAX_llx_menu__, 'home', '', 401__+MAX_llx_menu__, '/user/hierarchy.php?leftmenu=users', 'HierarchicView', 1, 'users', '$user->rights->user->user->lire || $user->admin', '', 2, 0, __ENTITY__);
+insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 405__+MAX_llx_menu__, 'home', '', 401__+MAX_llx_menu__, '/categories/index.php?leftmenu=users&type=7', 'UsersCategoriesShort', 1, 'categories', '$user->rights->user->user->lire || $user->admin', '', 2, 0, __ENTITY__);
+
+insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 407__+MAX_llx_menu__, 'home', '', 400__+MAX_llx_menu__, '/user/group/list.php?leftmenu=users', 'Groups', 1, 'users', '(($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->read:$user->rights->user->user->lire) || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)', '', 2, 1, __ENTITY__);
+insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="users"', __HANDLER__, 'left', 408__+MAX_llx_menu__, 'home', '', 407__+MAX_llx_menu__, '/user/group/card.php?leftmenu=users&action=create', 'NewGroup', 2, 'users', '(($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->write:$user->rights->user->user->creer) || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE)', '', 2, 0, __ENTITY__);
+
-- Third parties
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 500__+MAX_llx_menu__, 'companies', 'thirdparties', 2__+MAX_llx_menu__, '/societe/index.php?leftmenu=thirdparties', 'ThirdParty', 0, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 501__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/card.php?action=create', 'MenuNewThirdParty', 1, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__);
@@ -114,7 +120,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3100__+MAX_llx_menu__, 'products', 'stock', 3__+MAX_llx_menu__, '/product/stock/index.php?leftmenu=stock', 'Stock', 0, 'stocks', '$user->rights->stock->lire', '', 2, 3, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3101__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/card.php?action=create', 'MenuNewWarehouse', 1, 'stocks', '$user->rights->stock->creer', '', 2, 0, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3102__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/list.php', 'List', 1, 'stocks', '$user->rights->stock->lire', '', 2, 1, __ENTITY__);
-insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3104__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/mouvement.php', 'Movements', 1, 'stocks', '$user->rights->stock->mouvement->lire', '', 2, 3, __ENTITY__);
+insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3104__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/movement_list.php', 'Movements', 1, 'stocks', '$user->rights->stock->mouvement->lire', '', 2, 3, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled && $conf->supplier_order->enabled', __HANDLER__, 'left', 3105__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/replenish.php', 'Replenishments', 1, 'stocks', '$user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire', '', 2, 4, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3106__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/massstockmove.php', 'MassStockTransferShort', 1, 'stocks', '$user->rights->stock->mouvement->creer', '', 2, 5, __ENTITY__);
diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
index 3a7e6ae784b..562ed99a020 100644
--- a/htdocs/core/menus/standard/eldy.lib.php
+++ b/htdocs/core/menus/standard/eldy.lib.php
@@ -616,6 +616,11 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
$newmenu->add("/user/card.php?leftmenu=users&action=create", $langs->trans("NewUser"),2, ($user->rights->user->user->creer || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE), '', 'home');
$newmenu->add("/user/list.php?leftmenu=users", $langs->trans("ListOfUsers"), 2, $user->rights->user->user->lire || $user->admin);
$newmenu->add("/user/hierarchy.php?leftmenu=users", $langs->trans("HierarchicView"), 2, $user->rights->user->user->lire || $user->admin);
+ if (! empty($conf->categorie->enabled))
+ {
+ $langs->load("categories");
+ $newmenu->add("/categories/index.php?leftmenu=users&type=7", $langs->trans("UsersCategoriesShort"), 2, $user->rights->categorie->lire, '', $mainmenu, 'cat');
+ }
$newmenu->add("", $langs->trans("Groups"), 1, ($user->rights->user->user->lire || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE));
$newmenu->add("/user/group/card.php?leftmenu=users&action=create", $langs->trans("NewGroup"), 2, (($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->write:$user->rights->user->user->creer) || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE));
$newmenu->add("/user/group/list.php?leftmenu=users", $langs->trans("ListOfGroups"), 2, (($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->read:$user->rights->user->user->lire) || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE));
@@ -679,6 +684,25 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
$newmenu->add("/societe/card.php?leftmenu=suppliers&action=create&type=f",$langs->trans("MenuNewSupplier"), 2, $user->rights->societe->creer && ($user->rights->fournisseur->lire || $user->rights->supplier_proposal->lire));
}
+ // Categories
+ if (! empty($conf->categorie->enabled))
+ {
+ $langs->load("categories");
+ if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))
+ {
+ // Categories prospects/customers
+ $menutoshow=$langs->trans("CustomersProspectsCategoriesShort");
+ if (! empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) $menutoshow=$langs->trans("CustomersCategoriesShort");
+ if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $menutoshow=$langs->trans("ProspectsCategoriesShort");
+ $newmenu->add("/categories/index.php?leftmenu=cat&type=2", $menutoshow, 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
+ }
+ // Categories suppliers
+ if (! empty($conf->fournisseur->enabled))
+ {
+ $newmenu->add("/categories/index.php?leftmenu=catfournish&type=1", $langs->trans("SuppliersCategoriesShort"), 1, $user->rights->categorie->lire);
+ }
+ }
+
// Contacts
$newmenu->add("/societe/index.php?leftmenu=thirdparties", (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")), 0, $user->rights->societe->contact->lire, '', $mainmenu, 'contacts');
$newmenu->add("/contact/card.php?leftmenu=contacts&action=create", (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("NewContact") : $langs->trans("NewContactAddress")), 1, $user->rights->societe->contact->creer);
@@ -693,25 +717,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
if (! empty($conf->categorie->enabled))
{
$langs->load("categories");
- if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))
- {
- // Categories prospects/customers
- $menutoshow=$langs->trans("CustomersProspectsCategoriesShort");
- if (! empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) $menutoshow=$langs->trans("CustomersCategoriesShort");
- if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $menutoshow=$langs->trans("ProspectsCategoriesShort");
- $newmenu->add("/categories/index.php?leftmenu=cat&type=2", $menutoshow, 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
- $newmenu->add("/categories/card.php?action=create&type=2", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
- }
// Categories Contact
- $newmenu->add("/categories/index.php?leftmenu=catcontact&type=4", $langs->trans("ContactCategoriesShort"), 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
- $newmenu->add("/categories/card.php?action=create&type=4", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
- // Categories suppliers
- if (! empty($conf->fournisseur->enabled))
- {
- $newmenu->add("/categories/index.php?leftmenu=catfournish&type=1", $langs->trans("SuppliersCategoriesShort"), 0, $user->rights->categorie->lire);
- $newmenu->add("/categories/card.php?action=create&type=1", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
- }
- //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
+ $newmenu->add("/categories/index.php?leftmenu=catcontact&type=4", $langs->trans("ContactCategoriesShort"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
}
}
@@ -1206,10 +1213,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
if (! empty($conf->categorie->enabled)) {
$langs->load("categories");
- $newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags');
- $newmenu->add("/categories/card.php?action=create&type=5",$langs->trans("NewCategory"),1,$user->rights->categorie->creer);
- $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags');
- $newmenu->add("/compta/bank/categ.php",$langs->trans("NewCategory"),1,$user->rights->categorie->creer, '', $mainmenu, 'tags');
+ $newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),1,$user->rights->categorie->creer, '', $mainmenu, 'tags');
+ $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),1,$user->rights->categorie->creer, '', $mainmenu, 'tags');
}
// Prelevements
@@ -1269,6 +1274,14 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
{
$newmenu->add("/product/stats/card.php?id=all&leftmenu=stats&type=0", $langs->trans("Statistics"), 1, $user->rights->produit->lire && $user->rights->propale->lire);
}
+
+ // Categories
+ if (! empty($conf->categorie->enabled))
+ {
+ $langs->load("categories");
+ $newmenu->add("/categories/index.php?leftmenu=cat&type=0", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
+ //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
+ }
}
// Services
@@ -1281,15 +1294,13 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
{
$newmenu->add("/product/stats/card.php?id=all&leftmenu=stats&type=1", $langs->trans("Statistics"), 1, $user->rights->service->lire && $user->rights->propale->lire);
}
- }
-
- // Categories
- if (! empty($conf->categorie->enabled))
- {
- $langs->load("categories");
- $newmenu->add("/categories/index.php?leftmenu=cat&type=0", $langs->trans("Categories"), 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
- $newmenu->add("/categories/card.php?action=create&type=0", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
- //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
+ // Categories
+ if (! empty($conf->categorie->enabled))
+ {
+ $langs->load("categories");
+ $newmenu->add("/categories/index.php?leftmenu=cat&type=0", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
+ //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
+ }
}
// Warehouse
@@ -1299,7 +1310,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
$newmenu->add("/product/stock/index.php?leftmenu=stock", $langs->trans("Warehouses"), 0, $user->rights->stock->lire, '', $mainmenu, 'stock');
$newmenu->add("/product/stock/card.php?action=create", $langs->trans("MenuNewWarehouse"), 1, $user->rights->stock->creer);
$newmenu->add("/product/stock/list.php", $langs->trans("List"), 1, $user->rights->stock->lire);
- $newmenu->add("/product/stock/mouvement.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire);
+ $newmenu->add("/product/stock/movement_list.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire);
$newmenu->add("/product/stock/massstockmove.php", $langs->trans("MassStockTransferShort"), 1, $user->rights->stock->mouvement->creer);
if ($conf->supplier_order->enabled) $newmenu->add("/product/stock/replenish.php", $langs->trans("Replenishment"), 1, $user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire);
@@ -1405,9 +1416,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
if (! empty($conf->categorie->enabled))
{
$langs->load("categories");
- $newmenu->add("/categories/index.php?leftmenu=cat&type=6", $langs->trans("Categories"), 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
- $newmenu->add("/categories/card.php?action=create&type=6", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
- //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
+ $newmenu->add("/categories/index.php?leftmenu=cat&type=6", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
}
}
}
@@ -1539,23 +1548,21 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
$newmenu->add("/adherents/list.php?leftmenu=members&statut=1&filter=outofdate",$langs->trans("MenuMembersNotUpToDate"),2,$user->rights->adherent->lire);
$newmenu->add("/adherents/list.php?leftmenu=members&statut=0",$langs->trans("MenuMembersResiliated"),2,$user->rights->adherent->lire);
$newmenu->add("/adherents/stats/index.php?leftmenu=members",$langs->trans("MenuMembersStats"),1,$user->rights->adherent->lire);
- if (! empty($conf->global->MEMBER_LINK_TO_HTPASSWDFILE) && ($usemenuhider || empty($leftmenu) || $leftmenu=='none' || $leftmenu=="members" || $leftmenu=="export")) $newmenu->add("/adherents/htpasswd.php?leftmenu=export",$langs->trans("Filehtpasswd"),1,$user->rights->adherent->export);
+
$newmenu->add("/adherents/cartes/carte.php?leftmenu=export",$langs->trans("MembersCards"),1,$user->rights->adherent->export);
+ if (! empty($conf->global->MEMBER_LINK_TO_HTPASSWDFILE) && ($usemenuhider || empty($leftmenu) || $leftmenu=='none' || $leftmenu=="members" || $leftmenu=="export")) $newmenu->add("/adherents/htpasswd.php?leftmenu=export",$langs->trans("Filehtpasswd"),1,$user->rights->adherent->export);
+
+ if (! empty($conf->categorie->enabled))
+ {
+ $langs->load("categories");
+ $newmenu->add("/categories/index.php?leftmenu=cat&type=3", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
+ }
$newmenu->add("/adherents/index.php?leftmenu=members&mainmenu=members",$langs->trans("Subscriptions"),0,$user->rights->adherent->cotisation->lire);
$newmenu->add("/adherents/list.php?leftmenu=members&statut=-1,1&mainmenu=members",$langs->trans("NewSubscription"),1,$user->rights->adherent->cotisation->creer);
$newmenu->add("/adherents/subscription/list.php?leftmenu=members",$langs->trans("List"),1,$user->rights->adherent->cotisation->lire);
$newmenu->add("/adherents/stats/index.php?leftmenu=members",$langs->trans("MenuMembersStats"),1,$user->rights->adherent->lire);
-
- if (! empty($conf->categorie->enabled))
- {
- $langs->load("categories");
- $newmenu->add("/categories/index.php?leftmenu=cat&type=3", $langs->trans("Categories"), 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
- $newmenu->add("/categories/card.php?action=create&type=3", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
- //if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
- }
-
//$newmenu->add("/adherents/index.php?leftmenu=export&mainmenu=members",$langs->trans("Tools"),0,$user->rights->adherent->export, '', $mainmenu, 'export');
//if (! empty($conf->export->enabled) && ($usemenuhider || empty($leftmenu) || $leftmenu=="export")) $newmenu->add("/exports/index.php?leftmenu=export",$langs->trans("Datas"),1,$user->rights->adherent->export);
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 3839edb85c1..dff597c5593 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
@@ -4,21 +4,22 @@
* Copyright (C) 2014 Marcos García
* Copyright (C) 2016 Charlie Benke
* Copyright (C) 2018 Philippe Grand
-*
-* 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/
-*/
+ * Copyright (C) 2018 Frédéric France
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
/**
* \file htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
@@ -46,7 +47,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
public $emetteur;
/**
- * @var array() Minimum version of PHP required by module.
+ * @var array Minimum version of PHP required by module.
* e.g.: PHP ≥ 5.4 = array(5, 4)
*/
public $phpmin = array(5, 4);
@@ -351,6 +352,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
catch(Exception $e)
{
$this->error=$e->getMessage();
+ dol_syslog($e->getMessage(), LOG_INFO);
return -1;
}
// After construction $odfHandler->contentXml contains content and
@@ -366,6 +368,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
}
catch(OdfException $e)
{
+ dol_syslog($e->getMessage(), LOG_INFO);
}
// Define substitution array
@@ -402,6 +405,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
}
catch(OdfException $e)
{
+ dol_syslog($e->getMessage(), LOG_INFO);
}
}
// Replace tags of lines
@@ -434,9 +438,11 @@ class doc_generic_order_odt extends ModelePDFCommandes
}
catch(OdfException $e)
{
+ dol_syslog($e->getMessage(), LOG_INFO);
}
catch(SegmentException $e)
{
+ dol_syslog($e->getMessage(), LOG_INFO);
}
}
$listlines->merge();
@@ -460,6 +466,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
}
catch(OdfException $e)
{
+ dol_syslog($e->getMessage(), LOG_INFO);
}
}
@@ -473,7 +480,8 @@ class doc_generic_order_odt extends ModelePDFCommandes
try {
$odfHandler->exportAsAttachedPDF($file);
}catch (Exception $e){
- $this->error=$e->getMessage();
+ $this->error=$e->getMessage();
+ dol_syslog($e->getMessage(), LOG_INFO);
return -1;
}
}
@@ -481,7 +489,8 @@ class doc_generic_order_odt extends ModelePDFCommandes
try {
$odfHandler->saveToDisk($file);
}catch (Exception $e){
- $this->error=$e->getMessage();
+ $this->error=$e->getMessage();
+ dol_syslog($e->getMessage(), LOG_INFO);
return -1;
}
}
diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
index d3b5d12d620..ad77e9bea32 100644
--- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
+++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
@@ -27,7 +27,7 @@
/**
* \file htdocs/core/modules/commande/doc/pdf_einstein.modules.php
* \ingroup commande
- * \brief Fichier de la classe permettant de generer les commandes au modele Einstein
+ * \brief File of Class to generate PDF orders with template Einstein
*/
require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
@@ -38,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
/**
- * Classe to generate PDF orders with template Einstein
+ * Class to generate PDF orders with template Einstein
*/
class pdf_einstein extends ModelePDFCommandes
{
@@ -149,13 +149,13 @@ class pdf_einstein extends ModelePDFCommandes
$this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
$this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
- $this->option_logo = 1; // Affiche logo
- $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION
- $this->option_modereg = 1; // Affiche mode reglement
- $this->option_condreg = 1; // Affiche conditions reglement
- $this->option_codeproduitservice = 1; // Affiche code produit-service
- $this->option_multilang = 1; // Dispo en plusieurs langues
- $this->option_escompte = 0; // Affiche si il y a eu escompte
+ $this->option_logo = 1; // Display logo
+ $this->option_tva = 1; // Manage the vat option FACTURE_TVAOPTION
+ $this->option_modereg = 1; // Display payment mode
+ $this->option_condreg = 1; // Display payment terms
+ $this->option_codeproduitservice = 1; // Display product-service code
+ $this->option_multilang = 1; // Available in several languages
+ $this->option_escompte = 0; // Displays if there has been a discount
$this->option_credit_note = 0; // Support credit notes
$this->option_freetext = 1; // Support add of a personalised text
$this->option_draft_watermark = 1; // Support add of a watermark on drafts
@@ -1261,27 +1261,30 @@ class pdf_einstein extends ModelePDFCommandes
$pdf->SetXY($this->marge_gauche,$posy);
// Logo
- $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
- if ($this->emetteur->logo)
+ if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
{
- if (is_readable($logo))
+ $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
+ if ($this->emetteur->logo)
{
- $height=pdf_getHeightForLogo($logo);
- $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ if (is_readable($logo))
+ {
+ $height=pdf_getHeightForLogo($logo);
+ $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ }
+ else
+ {
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B', $default_font_size -2);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ }
}
else
{
- $pdf->SetTextColor(200,0,0);
- $pdf->SetFont('','B', $default_font_size -2);
- $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
- $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ $text=$this->emetteur->name;
+ $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
}
}
- else
- {
- $text=$this->emetteur->name;
- $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
- }
$pdf->SetFont('','B', $default_font_size + 3);
$pdf->SetXY($posx,$posy);
diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
new file mode 100644
index 00000000000..1c85adddfcc
--- /dev/null
+++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
@@ -0,0 +1,1675 @@
+
+ * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2008 Raphael Bertrand
+ * Copyright (C) 2010-2013 Juanjo Menent
+ * Copyright (C) 2012 Christophe Battarel
+ * Copyright (C) 2012 Cedric Salvador
+ * Copyright (C) 2015 Marcos García
+ * Copyright (C) 2017 Ferran Marcet
+ * Copyright (C) 2018 Frédéric France
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
+ * \ingroup commande
+ * \brief Fichier de la classe permettant de generer les commandes au modele Eratosthène
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
+require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
+
+
+/**
+ * Classe to generate PDF orders with template Eratosthene
+ */
+class pdf_eratosthene extends ModelePDFCommandes
+{
+ /**
+ * @var DoliDb Database handler
+ */
+ public $db;
+
+ /**
+ * @var string model name
+ */
+ public $name;
+
+ /**
+ * @var string model description (short text)
+ */
+ public $description;
+
+ /**
+ * @var int Save the name of generated file as the main doc when generating a doc with this template
+ */
+ public $update_main_doc_field;
+
+ /**
+ * @var string document type
+ */
+ public $type;
+
+ /**
+ * @var array Minimum version of PHP required by module.
+ * e.g.: PHP ≥ 5.3 = array(5, 3)
+ */
+ public $phpmin = array(5, 2);
+
+ /**
+ * Dolibarr version of the loaded document
+ * @public string
+ */
+ public $version = 'development';
+
+ public $page_largeur;
+ public $page_hauteur;
+ public $format;
+ public $marge_gauche;
+ public $marge_droite;
+ public $marge_haute;
+ public $marge_basse;
+
+ public $emetteur; // Objet societe qui emet
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $conf,$langs,$mysoc;
+
+ // Translations
+ $langs->loadLangs(array("main", "bills", "products"));
+
+ $this->db = $db;
+ $this->name = "eratosthene";
+ $this->description = $langs->trans('PDFEratostheneDescription');
+ $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
+
+ // Dimension page
+ $this->type = 'pdf';
+ $formatarray=pdf_getFormat();
+ $this->page_largeur = $formatarray['width'];
+ $this->page_hauteur = $formatarray['height'];
+ $this->format = array($this->page_largeur,$this->page_hauteur);
+ $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10;
+ $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10;
+ $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
+ $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
+
+ $this->option_logo = 1; // Affiche logo
+ $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION
+ $this->option_modereg = 1; // Affiche mode reglement
+ $this->option_condreg = 1; // Affiche conditions reglement
+ $this->option_codeproduitservice = 1; // Affiche code produit-service
+ $this->option_multilang = 1; // Dispo en plusieurs langues
+ $this->option_escompte = 0; // Affiche si il y a eu escompte
+ $this->option_credit_note = 0; // Support credit notes
+ $this->option_freetext = 1; // Support add of a personalised text
+ $this->option_draft_watermark = 1; // Support add of a watermark on drafts
+
+ $this->franchise=!$mysoc->tva_assuj;
+
+ // Get source company
+ $this->emetteur=$mysoc;
+ if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined
+
+ // Define position of columns
+ $this->posxdesc=$this->marge_gauche+1;
+
+
+ $this->tva=array();
+ $this->localtax1=array();
+ $this->localtax2=array();
+ $this->atleastoneratenotnull=0;
+ $this->atleastonediscount=0;
+ }
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * Function to build pdf onto disk
+ *
+ * @param Object $object Object to generate
+ * @param Translate $outputlangs Lang output object
+ * @param string $srctemplatepath Full path of source filename for generator using a template file
+ * @param int $hidedetails Do not show line details
+ * @param int $hidedesc Do not show desc
+ * @param int $hideref Do not show ref
+ * @return int 1=OK, 0=KO
+ */
+ public function write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
+ {
+ // phpcs:enable
+ global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblignes;
+
+ if (! is_object($outputlangs)) $outputlangs=$langs;
+ // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
+ if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
+
+ // Translations
+ $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries"));
+
+ $nblignes = count($object->lines);
+
+ if ($conf->commande->dir_output)
+ {
+ $object->fetch_thirdparty();
+
+ $deja_regle = 0;
+
+ // Definition of $dir and $file
+ if ($object->specimen)
+ {
+ $dir = $conf->commande->dir_output;
+ $file = $dir . "/SPECIMEN.pdf";
+ }
+ else
+ {
+ $objectref = dol_sanitizeFileName($object->ref);
+ $dir = $conf->commande->dir_output . "/" . $objectref;
+ $file = $dir . "/" . $objectref . ".pdf";
+ }
+
+ if (! file_exists($dir))
+ {
+ if (dol_mkdir($dir) < 0)
+ {
+ $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
+ return 0;
+ }
+ }
+
+ if (file_exists($dir))
+ {
+ // Add pdfgeneration hook
+ if (! is_object($hookmanager))
+ {
+ include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
+ $hookmanager=new HookManager($this->db);
+ }
+ $hookmanager->initHooks(array('pdfgeneration'));
+ $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
+ global $action;
+ $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
+
+ // Create pdf instance
+ $pdf=pdf_getInstance($this->format);
+ $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
+ $pdf->SetAutoPageBreak(1,0);
+
+ $heightforinfotot = 40; // Height reserved to output the info and total part
+ $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page
+ $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22); // Height reserved to output the footer (value include bottom margin)
+
+ if (class_exists('TCPDF'))
+ {
+ $pdf->setPrintHeader(false);
+ $pdf->setPrintFooter(false);
+ }
+ $pdf->SetFont(pdf_getPDFFont($outputlangs));
+ // Set path to the background PDF File
+ if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
+ {
+ $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
+ $tplidx = $pdf->importPage(1);
+ }
+
+ $pdf->Open();
+ $pagenb=0;
+ $pdf->SetDrawColor(128,128,128);
+
+ $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
+ $pdf->SetSubject($outputlangs->transnoentities("PdfOrderTitle"));
+ $pdf->SetCreator("Dolibarr ".DOL_VERSION);
+ $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
+ $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfOrderTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
+ if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
+
+ $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
+
+ /// Does we have at least one line with discount $this->atleastonediscount
+ foreach ($object->lines as $line) {
+ if ($line->remise_percent){
+ $this->atleastonediscount = true;
+ break;
+ }
+ }
+
+ if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS))
+ {
+ $this->posxpicture+=($this->postotalht - $this->posxdiscount);
+ $this->posxtva+=($this->postotalht - $this->posxdiscount);
+ $this->posxup+=($this->postotalht - $this->posxdiscount);
+ $this->posxqty+=($this->postotalht - $this->posxdiscount);
+ $this->posxdiscount+=($this->postotalht - $this->posxdiscount);
+ //$this->postotalht;
+ }
+
+ // New page
+ $pdf->AddPage();
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ $pagenb++;
+ $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->MultiCell(0, 3, ''); // Set interline to 3
+ $pdf->SetTextColor(0,0,0);
+
+
+ $tab_top = 90+$top_shift;
+ $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
+
+ // Incoterm
+ if ($conf->incoterm->enabled)
+ {
+ $desc_incoterms = $object->getIncotermsForPDF();
+ if ($desc_incoterms)
+ {
+ $tab_top -= 2;
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
+ $nexY = $pdf->GetY();
+ $height_incoterms=$nexY-$tab_top;
+
+ // Rect prend une longueur en 3eme param
+ $pdf->SetDrawColor(192,192,192);
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
+
+ $tab_top = $nexY+6;
+ }
+ }
+
+ // Affiche notes
+ $notetoshow=empty($object->note_public)?'':$object->note_public;
+ if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
+ {
+ // Get first sale rep
+ if (is_object($object->thirdparty))
+ {
+ $salereparray=$object->thirdparty->getSalesRepresentatives($user);
+ $salerepobj=new User($this->db);
+ $salerepobj->fetch($salereparray[0]['id']);
+ if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
+ }
+ }
+
+ $pagenb = $pdf->getPage();
+ if ($notetoshow)
+ {
+ $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
+ $pageposbeforenote = $pagenb;
+
+ $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
+ complete_substitutions_array($substitutionarray, $outputlangs, $object);
+ $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
+
+ $tab_top -= 2;
+
+ $pdf->startTransaction();
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
+ // Description
+ $pageposafternote=$pdf->getPage();
+ $posyafter = $pdf->GetY();
+
+ if($pageposafternote>$pageposbeforenote )
+ {
+ $pdf->rollbackTransaction(true);
+
+ // prepar pages to receive notes
+ while ($pagenb < $pageposafternote) {
+ $pdf->AddPage();
+ $pagenb++;
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ // $this->_pagefoot($pdf,$object,$outputlangs,1);
+ $pdf->setTopMargin($tab_top_newpage);
+ // The only function to edit the bottom margin of current page to set it.
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ }
+
+ // back to start
+ $pdf->setPage($pageposbeforenote);
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
+ $pageposafternote=$pdf->getPage();
+
+ $posyafter = $pdf->GetY();
+
+ if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20))) // There is no space left for total+free text
+ {
+ $pdf->AddPage('','',true);
+ $pagenb++;
+ $pageposafternote++;
+ $pdf->setPage($pageposafternote);
+ $pdf->setTopMargin($tab_top_newpage);
+ // The only function to edit the bottom margin of current page to set it.
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ //$posyafter = $tab_top_newpage;
+ }
+
+
+ // apply note frame to previus pages
+ $i = $pageposbeforenote;
+ while ($i < $pageposafternote) {
+ $pdf->setPage($i);
+
+
+ $pdf->SetDrawColor(128,128,128);
+ // Draw note frame
+ if($i>$pageposbeforenote){
+ $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
+ $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1);
+ }
+ else{
+ $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
+ }
+
+ // Add footer
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+
+ $i++;
+ }
+
+ // apply note frame to last page
+ $pdf->setPage($pageposafternote);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ $height_note=$posyafter-$tab_top_newpage;
+ $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
+
+ }
+ else // No pagebreak
+ {
+ $pdf->commitTransaction();
+ $posyafter = $pdf->GetY();
+ $height_note=$posyafter-$tab_top;
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
+
+
+ if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
+ {
+ // not enough space, need to add page
+ $pdf->AddPage('','',true);
+ $pagenb++;
+ $pageposafternote++;
+ $pdf->setPage($pageposafternote);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+
+ $posyafter = $tab_top_newpage;
+ }
+
+ }
+
+ $tab_height = $tab_height - $height_note;
+ $tab_top = $posyafter +6;
+ }
+ else
+ {
+ $height_note=0;
+ }
+
+ $iniY = $tab_top + 7;
+ $curY = $tab_top + 7;
+ $nexY = $tab_top + 7;
+
+ // Use new auto collum system
+ $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
+
+ // Loop on each lines
+ $pageposbeforeprintlines=$pdf->getPage();
+ $pagenb = $pageposbeforeprintlines;
+ for ($i = 0 ; $i < $nblignes ; $i++)
+ {
+ $curY = $nexY;
+ $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage
+ $pdf->SetTextColor(0,0,0);
+
+ $pdf->setTopMargin($tab_top_newpage);
+ $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot); // The only function to edit the bottom margin of current page to set it.
+ $pageposbefore=$pdf->getPage();
+
+ // Description of product line
+ $curX = $this->posxdesc-1;
+
+ $showpricebeforepagebreak=1;
+
+ if($this->getColumnStatus('desc'))
+ {
+ $pdf->startTransaction();
+ pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
+ $pageposafter=$pdf->getPage();
+ if ($pageposafter > $pageposbefore) // There is a pagebreak
+ {
+ $pdf->rollbackTransaction(true);
+ $pageposafter=$pageposbefore;
+ //print $pageposafter.'-'.$pageposbefore;exit;
+ $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
+ pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
+ $pageposafter=$pdf->getPage();
+ $posyafter=$pdf->GetY();
+ if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text
+ {
+ if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new page
+ {
+ $pdf->AddPage('','',true);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ //if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ $pdf->setPage($pageposafter+1);
+ }
+ }
+ else
+ {
+ // We found a page break
+ $showpricebeforepagebreak=0;
+ }
+ }
+ else // No pagebreak
+ {
+ $pdf->commitTransaction();
+ }
+ $posYAfterDescription=$pdf->GetY();
+ }
+
+ $nexY = $pdf->GetY();
+ $pageposafter=$pdf->getPage();
+
+ $pdf->setPage($pageposbefore);
+ $pdf->setTopMargin($this->marge_haute);
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+
+ // We suppose that a too long description is moved completely on next page
+ if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
+ $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
+ }
+
+ $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut
+
+ // VAT Rate
+ if ($this->getColumnStatus('vat'))
+ {
+ $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Unit price before discount
+ if ($this->getColumnStatus('subprice'))
+ {
+ $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Quantity
+ // Enough for 6 chars
+ if ($this->getColumnStatus('qty'))
+ {
+ $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+
+ // Unit
+ if ($this->getColumnStatus('unit'))
+ {
+ $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
+ $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Discount on line
+ if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
+ {
+ $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Total HT line
+ if ($this->getColumnStatus('totalexcltax'))
+ {
+ $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+
+ $parameters=array(
+ 'object' => $object,
+ 'i' => $i,
+ 'pdf' =>& $pdf,
+ 'curY' =>& $curY,
+ 'nexY' =>& $nexY,
+ 'outputlangs' => $outputlangs,
+ 'hidedetails' => $hidedetails
+ );
+ $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this); // Note that $object may have been modified by hook
+
+
+ // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
+ if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
+ else $tvaligne=$object->lines[$i]->total_tva;
+
+ $localtax1ligne=$object->lines[$i]->total_localtax1;
+ $localtax2ligne=$object->lines[$i]->total_localtax2;
+ $localtax1_rate=$object->lines[$i]->localtax1_tx;
+ $localtax2_rate=$object->lines[$i]->localtax2_tx;
+ $localtax1_type=$object->lines[$i]->localtax1_type;
+ $localtax2_type=$object->lines[$i]->localtax2_type;
+
+ if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
+ if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
+ if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
+
+ $vatrate=(string) $object->lines[$i]->tva_tx;
+
+ // Retrieve type from database for backward compatibility with old records
+ if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
+ && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
+ {
+ $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0,$object->thirdparty,$mysoc);
+ $localtax1_type = $localtaxtmp_array[0];
+ $localtax2_type = $localtaxtmp_array[2];
+ }
+
+ // retrieve global local tax
+ if ($localtax1_type && $localtax1ligne != 0)
+ $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
+ if ($localtax2_type && $localtax2ligne != 0)
+ $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
+
+ if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
+ if (! isset($this->tva[$vatrate])) $this->tva[$vatrate]=0;
+ $this->tva[$vatrate] += $tvaligne;
+
+ // Add line
+ if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
+ {
+ $pdf->setPage($pageposafter);
+ $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
+ //$pdf->SetDrawColor(190,190,200);
+ $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
+ $pdf->SetLineStyle(array('dash'=>0));
+ }
+
+ $nexY+=2; // Passe espace entre les lignes
+
+ // Detect if some page were added automatically and output _tableau for past pages
+ while ($pagenb < $pageposafter)
+ {
+ $pdf->setPage($pagenb);
+ if ($pagenb == $pageposbeforeprintlines)
+ {
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
+ }
+ else
+ {
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
+ }
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+ $pagenb++;
+ $pdf->setPage($pagenb);
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ }
+ if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+ {
+ if ($pagenb == $pageposafter)
+ {
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
+ }
+ else
+ {
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
+ }
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+ // New page
+ $pdf->AddPage();
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ $pagenb++;
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ }
+ }
+
+ // Show square
+ if ($pagenb == $pageposbeforeprintlines)
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
+ 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;
+
+ // Affiche zone infos
+ $posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
+
+ // Affiche zone totaux
+ $posy=$this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
+
+ // Affiche zone versements
+ /*
+ if ($deja_regle)
+ {
+ $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
+ }
+ */
+
+ // Pied de page
+ $this->_pagefoot($pdf, $object, $outputlangs);
+ if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages();
+
+ $pdf->Close();
+
+ $pdf->Output($file, 'F');
+
+ // Add pdfgeneration hook
+ $hookmanager->initHooks(array('pdfgeneration'));
+ $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
+
+ if (! empty($conf->global->MAIN_UMASK))
+ @chmod($file, octdec($conf->global->MAIN_UMASK));
+
+ $this->result = array('fullpath'=>$file);
+
+ return 1; // Pas d'erreur
+ }
+ else
+ {
+ $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
+ return 0;
+ }
+ }
+ else
+ {
+ $this->error=$langs->transnoentities("ErrorConstantNotDefined","COMMANDE_OUTPUTDIR");
+ return 0;
+ }
+ }
+
+ /**
+ * Show payments table
+ *
+ * @param TCPDF $pdf Object PDF
+ * @param Object $object Object order
+ * @param int $posy Position y in PDF
+ * @param Translate $outputlangs Object langs for output
+ * @return int <0 if KO, >0 if OK
+ */
+ private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
+ {
+ }
+
+ /**
+ * Show miscellaneous information (payment mode, payment term, ...)
+ *
+ * @param TCPDF $pdf Object PDF
+ * @param Object $object Object to show
+ * @param int $posy Y
+ * @param Translate $outputlangs Langs object
+ * @return void
+ */
+ private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
+ {
+ global $conf;
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // If France, show VAT mention if not applicable
+ if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
+
+ $posy=$pdf->GetY()+4;
+ }
+
+ $posxval=52;
+
+ // Show payments conditions
+ if ($object->cond_reglement_code || $object->cond_reglement)
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("PaymentConditions").':';
+ $pdf->MultiCell(43, 4, $titre, 0, 'L');
+
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc);
+ $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement);
+ $pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L');
+
+ $posy=$pdf->GetY()+3;
+ }
+
+ // Check a payment mode is defined
+ /* Not used with orders
+ if (empty($object->mode_reglement_code)
+ && ! $conf->global->FACTURE_CHQ_NUMBER
+ && ! $conf->global->FACTURE_RIB_NUMBER)
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->MultiCell(80, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
+ $pdf->SetTextColor(0,0,0);
+
+ $posy=$pdf->GetY()+1;
+ }
+ */
+ /* TODO
+ else if (! empty($object->availability_code))
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0);
+ $pdf->SetTextColor(0,0,0);
+
+ $posy=$pdf->GetY()+1;
+ }*/
+
+ // Show planed date of delivery
+ if (! empty($object->date_livraison))
+ {
+ $outputlangs->load("sendings");
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
+ $pdf->MultiCell(80, 4, $titre, 0, 'L');
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $dlp=dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true);
+ $pdf->MultiCell(80, 4, $dlp, 0, 'L');
+
+ $posy=$pdf->GetY()+1;
+ }
+ elseif ($object->availability_code || $object->availability) // Show availability conditions
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
+ $pdf->MultiCell(80, 4, $titre, 0, 'L');
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $lib_availability=$outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset(isset($object->availability)?$object->availability:'');
+ $lib_availability=str_replace('\n',"\n",$lib_availability);
+ $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
+
+ $posy=$pdf->GetY()+1;
+ }
+
+ // Show payment mode
+ if ($object->mode_reglement_code
+ && $object->mode_reglement_code != 'CHQ'
+ && $object->mode_reglement_code != 'VIR')
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("PaymentMode").':';
+ $pdf->MultiCell(80, 5, $titre, 0, 'L');
+
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement);
+ $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L');
+
+ $posy=$pdf->GetY()+2;
+ }
+
+ // Show payment mode CHQ
+ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
+ {
+ // Si mode reglement non force ou si force a CHQ
+ if (! empty($conf->global->FACTURE_CHQ_NUMBER))
+ {
+ if ($conf->global->FACTURE_CHQ_NUMBER > 0)
+ {
+ $account = new Account($this->db);
+ $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
+
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','B', $default_font_size - 3);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0);
+ $posy=$pdf->GetY()+1;
+
+ if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','', $default_font_size - 3);
+ $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
+ $posy=$pdf->GetY()+2;
+ }
+ }
+ if ($conf->global->FACTURE_CHQ_NUMBER == -1)
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','B', $default_font_size - 3);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0);
+ $posy=$pdf->GetY()+1;
+
+ if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','', $default_font_size - 3);
+ $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
+ $posy=$pdf->GetY()+2;
+ }
+ }
+ }
+ }
+
+ // If payment mode not forced or forced to VIR, show payment with BAN
+ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
+ {
+ if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER))
+ {
+ $bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account);
+ if (! empty($object->fk_bank)) $bankid=$object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
+ $account = new Account($this->db);
+ $account->fetch($bankid);
+
+ $curx=$this->marge_gauche;
+ $cury=$posy;
+
+ $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size);
+
+ $posy+=2;
+ }
+ }
+
+ return $posy;
+ }
+
+
+ /**
+ * Show total to pay
+ *
+ * @param TCPDF $pdf Object PDF
+ * @param Facture $object Object invoice
+ * @param int $deja_regle Montant deja regle
+ * @param int $posy Position depart
+ * @param Translate $outputlangs Objet langs
+ * @return int Position pour suite
+ */
+ private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
+ {
+ global $conf,$mysoc;
+
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ $tab2_top = $posy;
+ $tab2_hl = 4;
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // Tableau total
+ $col1x = 120; $col2x = 170;
+ if ($this->page_largeur < 210) // To work with US executive format
+ {
+ $col2x-=20;
+ }
+ $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
+
+ $useborder=0;
+ $index = 0;
+
+ // Total HT
+ $pdf->SetFillColor(255,255,255);
+ $pdf->SetXY($col1x, $tab2_top + 0);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
+
+ $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
+ $pdf->SetXY($col2x, $tab2_top + 0);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1);
+
+ // Show VAT by rates and total
+ $pdf->SetFillColor(248,248,248);
+
+ $total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
+
+ $this->atleastoneratenotnull=0;
+ if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
+ {
+ $tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
+ if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
+ {
+ // Nothing to do
+ }
+ else
+ {
+ //Local tax 1 before VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
+ //{
+ foreach( $this->localtax1 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('1','3','5'))) continue;
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey!=0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ }
+ //}
+ //Local tax 2 before VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
+ //{
+ foreach( $this->localtax2 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('1','3','5'))) continue;
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey!=0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+
+ }
+ }
+ }
+ //}
+ // VAT
+ foreach($this->tva as $tvakey => $tvaval)
+ {
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ $this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' ';
+ $totalvat.=vatrate($tvakey,1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+
+ //Local tax 1 after VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
+ //{
+ foreach( $this->localtax1 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('2','4','6'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
+
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ }
+ //}
+ //Local tax 2 after VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
+ //{
+ foreach( $this->localtax2 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('2','4','6'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
+
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ }
+ //}
+
+ // Total TTC
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFillColor(224,224,224);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
+ }
+ }
+
+ $pdf->SetTextColor(0,0,0);
+
+ $creditnoteamount=0;
+ $depositsamount=0;
+ //$creditnoteamount=$object->getSumCreditNotesUsed();
+ //$depositsamount=$object->getSumDepositsUsed();
+ //print "x".$creditnoteamount."-".$depositsamount;exit;
+ $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
+ if (! empty($object->paye)) $resteapayer=0;
+
+ if ($deja_regle > 0)
+ {
+ // Already paid + Deposits
+ $index++;
+
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
+
+ $index++;
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFillColor(224,224,224);
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->SetTextColor(0,0,0);
+ }
+
+ $index++;
+ return ($tab2_top + ($tab2_hl * $index));
+ }
+
+ /**
+ * Show table for lines
+ *
+ * @param TCPDF $pdf Object PDF
+ * @param string $tab_top Top position of table
+ * @param string $tab_height Height of table (rectangle)
+ * @param int $nexY Y (not used)
+ * @param Translate $outputlangs Langs object
+ * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
+ * @param int $hidebottom Hide bottom bar of array
+ * @param string $currency Currency code
+ * @return void
+ */
+ private function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
+ {
+ global $conf;
+
+ // Force to disable hidetop and hidebottom
+ $hidebottom=0;
+ if ($hidetop) $hidetop=-1;
+
+ $currency = !empty($currency) ? $currency : $conf->currency;
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ // Amount in (at tab_top - 1)
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+
+ if (empty($hidetop))
+ {
+ $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency));
+ $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
+ $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
+
+ //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
+ if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
+ }
+
+ $pdf->SetDrawColor(128,128,128);
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // Output Rect
+ $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param
+
+
+ foreach ($this->cols as $colKey => $colDef)
+ {
+ if(!$this->getColumnStatus($colKey)) continue;
+
+ // get title label
+ $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
+
+ // Add column separator
+ if(!empty($colDef['border-left'])){
+ $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
+ }
+
+ if (empty($hidetop))
+ {
+ $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
+
+ $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
+ $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
+ }
+ }
+
+ if (empty($hidetop)){
+ $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line prend une position y en 2eme param et 4eme param
+ }
+ }
+
+ /**
+ * Show top header of page.
+ *
+ * @param TCPDF $pdf Object PDF
+ * @param Object $object Object to show
+ * @param int $showaddress 0=no, 1=yes
+ * @param Translate $outputlangs Object lang for output
+ * @param string $titlekey Translation key to show as title of document
+ * @return void
+ */
+ private function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey="PdfOrderTitle")
+ {
+ global $conf,$langs,$hookmanager;
+
+ // Translations
+ $outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies"));
+
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
+
+ // Show Draft Watermark
+ if($object->statut==0 && (! empty($conf->global->COMMANDE_DRAFT_WATERMARK)) )
+ {
+ pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->COMMANDE_DRAFT_WATERMARK);
+ }
+
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFont('','B', $default_font_size + 3);
+
+ $posy=$this->marge_haute;
+ $posx=$this->page_largeur-$this->marge_droite-100;
+
+ $pdf->SetXY($this->marge_gauche,$posy);
+
+ // Logo
+ if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
+ {
+ $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
+ if ($this->emetteur->logo)
+ {
+ if (is_readable($logo))
+ {
+ $height=pdf_getHeightForLogo($logo);
+ $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ }
+ else
+ {
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B', $default_font_size -2);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ }
+ }
+ else
+ {
+ $text=$this->emetteur->name;
+ $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
+ }
+ }
+
+ $pdf->SetFont('','B', $default_font_size + 3);
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $title=$outputlangs->transnoentities($titlekey);
+ $pdf->MultiCell(100, 3, $title, '', 'R');
+
+ $pdf->SetFont('','B',$default_font_size);
+
+ $posy+=5;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref), '', 'R');
+
+ $posy+=1;
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ if ($object->ref_client)
+ {
+ $posy+=5;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
+ }
+
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("OrderDate")." : " . dol_print_date($object->date,"%d %b %Y",false,$outputlangs,true), '', 'R');
+
+ // Get contact
+ if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
+ {
+ $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
+ if (count($arrayidcontact) > 0)
+ {
+ $usertmp=new User($this->db);
+ $usertmp->fetch($arrayidcontact[0]);
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
+ }
+ }
+
+ $posy+=2;
+
+ $top_shift = 0;
+ // Show list of linked objects
+ $current_y = $pdf->getY();
+ $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
+ if ($current_y < $pdf->getY())
+ {
+ $top_shift = $pdf->getY() - $current_y;
+ }
+
+ if ($showaddress)
+ {
+ // Sender properties
+ $carac_emetteur='';
+ // Add internal contact of proposal if defined
+ $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
+ if (count($arrayidcontact) > 0)
+ {
+ $object->fetch_user($arrayidcontact[0]);
+ $labelbeforecontactname=($outputlangs->transnoentities("FromContactName")!='FromContactName'?$outputlangs->transnoentities("FromContactName"):$outputlangs->transnoentities("Name"));
+ $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";
+ }
+
+ $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
+
+ // Show sender
+ $posy=42+$top_shift;
+ $posx=$this->marge_gauche;
+ if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
+ $hautcadre=40;
+
+ // Show sender frame
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posx,$posy-5);
+ $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetFillColor(230,230,230);
+ $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
+ $pdf->SetTextColor(0,0,60);
+
+ // Show sender name
+ $pdf->SetXY($posx+2,$posy+3);
+ $pdf->SetFont('','B', $default_font_size);
+ $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
+ $posy=$pdf->getY();
+
+ // Show sender information
+ $pdf->SetXY($posx+2,$posy);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
+
+
+
+ // If CUSTOMER contact defined on order, we use it
+ $usecontact=false;
+ $arrayidcontact=$object->getIdContact('external','CUSTOMER');
+ if (count($arrayidcontact) > 0)
+ {
+ $usecontact=true;
+ $result=$object->fetch_contact($arrayidcontact[0]);
+ }
+
+ //Recipient name
+ // On peut utiliser le nom de la societe du contact
+ if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
+ $thirdparty = $object->contact;
+ } else {
+ $thirdparty = $object->thirdparty;
+ }
+
+ $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs);
+
+ $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target', $object);
+
+ // Show recipient
+ $widthrecbox=100;
+ if ($this->page_largeur < 210) $widthrecbox=84; // To work with US executive format
+ $posy=42+$top_shift;
+ $posx=$this->page_largeur-$this->marge_droite-$widthrecbox;
+ if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
+
+ // Show recipient frame
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posx+2,$posy-5);
+ $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":",0,'L');
+ $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
+
+ // Show recipient name
+ $pdf->SetXY($posx+2,$posy+3);
+ $pdf->SetFont('','B', $default_font_size);
+ $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L');
+
+ $posy = $pdf->getY();
+
+ // Show recipient information
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->SetXY($posx+2,$posy);
+ $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
+ }
+
+ $pdf->SetTextColor(0,0,0);
+ return $top_shift;
+ }
+
+ /**
+ * Show footer of page. Need this->emetteur object
+ *
+ * @param TCPDF $pdf PDF
+ * @param Object $object Object to show
+ * @param Translate $outputlangs Object lang for output
+ * @param int $hidefreetext 1=Hide free text
+ * @return int Return height of bottom margin including footer text
+ */
+ private function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
+ {
+ global $conf;
+ $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
+ return pdf_pagefoot($pdf,$outputlangs,'ORDER_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
+ }
+
+
+
+ /**
+ * Define Array Column Field
+ *
+ * @param object $object common object
+ * @param Translate $outputlangs langs
+ * @param int $hidedetails Do not show line details
+ * @param int $hidedesc Do not show desc
+ * @param int $hideref Do not show ref
+ * @return null
+ */
+ public function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
+ {
+ global $conf, $hookmanager;
+
+ // Default field style for content
+ $this->defaultContentsFieldsStyle = array(
+ 'align' => 'R', // R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ );
+
+ // Default field style for content
+ $this->defaultTitlesFieldsStyle = array(
+ 'align' => 'C', // R,C,L
+ 'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ );
+
+ /*
+ * For exemple
+ $this->cols['theColKey'] = array(
+ 'rank' => $rank, // int : use for ordering columns
+ 'width' => 20, // the column width in mm
+ 'title' => array(
+ 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
+ 'label' => ' ', // the final label : used fore final generated text
+ 'align' => 'L', // text alignement : R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'content' => array(
+ 'align' => 'L', // text alignement : R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ );
+ */
+
+ $rank=0; // do not use negative rank
+ $this->cols['desc'] = array(
+ 'rank' => $rank,
+ 'width' => false, // only for desc
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'Designation', // use lang key is usefull in somme case with module
+ 'align' => 'L',
+ // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
+ // 'label' => ' ', // the final label
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'content' => array(
+ 'align' => 'L',
+ ),
+ );
+
+ $rank = $rank + 10;
+ $this->cols['photo'] = array(
+ 'rank' => $rank,
+ 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Photo',
+ 'label' => ' '
+ ),
+ 'content' => array(
+ 'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'border-left' => false, // remove left line separator
+ );
+
+ if (! empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE))
+ {
+ $this->cols['photo']['status'] = true;
+ }
+
+
+ $rank = $rank + 10;
+ $this->cols['vat'] = array(
+ 'rank' => $rank,
+ 'status' => false,
+ 'width' => 16, // in mm
+ 'title' => array(
+ 'textkey' => 'VAT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
+ {
+ $this->cols['vat']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['subprice'] = array(
+ 'rank' => $rank,
+ 'width' => 19, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'PriceUHT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ $rank = $rank + 10;
+ $this->cols['qty'] = array(
+ 'rank' => $rank,
+ 'width' => 16, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'Qty'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ $rank = $rank + 10;
+ $this->cols['progress'] = array(
+ 'rank' => $rank,
+ 'width' => 19, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Progress'
+ ),
+ 'border-left' => false, // add left line separator
+ );
+
+ if($this->situationinvoice)
+ {
+ $this->cols['progress']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['unit'] = array(
+ 'rank' => $rank,
+ 'width' => 11, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Unit'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+ if($conf->global->PRODUCT_USE_UNITS){
+ $this->cols['unit']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['discount'] = array(
+ 'rank' => $rank,
+ 'width' => 13, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'ReductionShort'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+ if ($this->atleastonediscount){
+ $this->cols['discount']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['totalexcltax'] = array(
+ 'rank' => $rank,
+ 'width' => 26, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'TotalHT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+
+ $parameters=array(
+ 'object' => $object,
+ 'outputlangs' => $outputlangs,
+ 'hidedetails' => $hidedetails,
+ 'hidedesc' => $hidedesc,
+ 'hideref' => $hideref
+ );
+
+ $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this); // Note that $object may have been modified by hook
+ if ($reshook < 0)
+ {
+ setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+ }
+ elseif (empty($reshook))
+ {
+ $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
+ }
+ else
+ {
+ $this->cols = $hookmanager->resArray;
+ }
+ }
+}
diff --git a/htdocs/core/modules/commande/modules_commande.php b/htdocs/core/modules/commande/modules_commande.php
index 1a4b732246d..7a1ffea8792 100644
--- a/htdocs/core/modules/commande/modules_commande.php
+++ b/htdocs/core/modules/commande/modules_commande.php
@@ -39,10 +39,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
*/
abstract class ModelePDFCommandes extends CommonDocGenerator
{
- /**
- * @var string Error code (or message)
- */
- public $error='';
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
/**
diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
index af770999fda..c4d69424cb2 100644
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -1598,27 +1598,30 @@ class pdf_crabe extends ModelePDFFactures
$pdf->SetXY($this->marge_gauche,$posy);
// Logo
- $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
- if ($this->emetteur->logo)
+ if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
{
- if (is_readable($logo))
+ $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
+ if ($this->emetteur->logo)
{
- $height=pdf_getHeightForLogo($logo);
- $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ if (is_readable($logo))
+ {
+ $height=pdf_getHeightForLogo($logo);
+ $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ }
+ else
+ {
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B',$default_font_size - 2);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ }
}
else
{
- $pdf->SetTextColor(200,0,0);
- $pdf->SetFont('','B',$default_font_size - 2);
- $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
- $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ $text=$this->emetteur->name;
+ $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
}
}
- else
- {
- $text=$this->emetteur->name;
- $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
- }
$pdf->SetFont('','B', $default_font_size + 3);
$pdf->SetXY($posx,$posy);
diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
new file mode 100644
index 00000000000..d03d60f50fe
--- /dev/null
+++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
@@ -0,0 +1,2027 @@
+
+ * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2008 Raphael Bertrand
+ * Copyright (C) 2010-2014 Juanjo Menent
+ * Copyright (C) 2012 Christophe Battarel
+ * Copyright (C) 2012 Cédric Salvador
+ * Copyright (C) 2012-2014 Raphaël Doursenaud
+ * Copyright (C) 2015 Marcos García
+ * Copyright (C) 2017 Ferran Marcet
+ * Copyright (C) 2018 Frédéric France
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/facture/doc/pdf_sponge.modules.php
+ * \ingroup facture
+ * \brief File of class to generate customers invoices from sponge model
+ */
+
+require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
+require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
+
+
+/**
+ * Class to manage PDF invoice template sponge
+ */
+class pdf_sponge extends ModelePDFFactures
+{
+ /**
+ * @var DoliDb Database handler
+ */
+ public $db;
+
+ /**
+ * @var string model name
+ */
+ public $name;
+
+ /**
+ * @var string model description (short text)
+ */
+ public $description;
+
+ /**
+ * @var int Save the name of generated file as the main doc when generating a doc with this template
+ */
+ public $update_main_doc_field;
+
+ /**
+ * @var string document type
+ */
+ public $type;
+
+ /**
+ * @var array Minimum version of PHP required by module.
+ * e.g.: PHP ≥ 5.3 = array(5, 3)
+ */
+ public $phpmin = array(5, 2);
+
+ /**
+ * Dolibarr version of the loaded document
+ * @public string
+ */
+ public $version = 'development';
+
+ public $page_largeur;
+ public $page_hauteur;
+ public $format;
+ public $marge_gauche;
+ public $marge_droite;
+ public $marge_haute;
+ public $marge_basse;
+
+ public $emetteur; // Objet societe qui emet
+
+ /**
+ * @var bool Situation invoice type
+ */
+ public $situationinvoice;
+
+ /**
+ * @var float X position for the situation progress column
+ */
+ public $posxprogress;
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ function __construct($db)
+ {
+ global $conf,$langs,$mysoc;
+
+ // Translations
+ $langs->loadLangs(array("main", "bills"));
+
+ $this->db = $db;
+ $this->name = "sponge";
+ $this->description = $langs->trans('PDFSpongeDescription');
+ $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
+
+ // Dimensiont page
+ $this->type = 'pdf';
+ $formatarray=pdf_getFormat();
+ $this->page_largeur = $formatarray['width'];
+ $this->page_hauteur = $formatarray['height'];
+ $this->format = array($this->page_largeur,$this->page_hauteur);
+ $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10;
+ $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10;
+ $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
+ $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
+
+ $this->option_logo = 1; // Affiche logo
+ $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION
+ $this->option_modereg = 1; // Affiche mode reglement
+ $this->option_condreg = 1; // Affiche conditions reglement
+ $this->option_codeproduitservice = 1; // Affiche code produit-service
+ $this->option_multilang = 1; // Dispo en plusieurs langues
+ $this->option_escompte = 1; // Affiche si il y a eu escompte
+ $this->option_credit_note = 1; // Support credit notes
+ $this->option_freetext = 1; // Support add of a personalised text
+ $this->option_draft_watermark = 1; // Support add of a watermark on drafts
+
+ $this->franchise=!$mysoc->tva_assuj;
+
+ // Get source company
+ $this->emetteur=$mysoc;
+ if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined
+
+ // Define position of columns
+ $this->posxdesc=$this->marge_gauche+1; // used for notes ans other stuff
+
+ // Use new system for position of columns, view $this->defineColumnField()
+
+ $this->tva=array();
+ $this->localtax1=array();
+ $this->localtax2=array();
+ $this->atleastoneratenotnull=0;
+ $this->atleastonediscount=0;
+ $this->situationinvoice=false;
+ }
+
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * Function to build pdf onto disk
+ *
+ * @param Object $object Object to generate
+ * @param Translate $outputlangs Lang output object
+ * @param string $srctemplatepath Full path of source filename for generator using a template file
+ * @param int $hidedetails Do not show line details
+ * @param int $hidedesc Do not show desc
+ * @param int $hideref Do not show ref
+ * @return int 1=OK, 0=KO
+ */
+ public function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
+ {
+ // phpcs:enable
+ global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
+
+ if (! is_object($outputlangs)) $outputlangs=$langs;
+ // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
+ if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
+
+ // Translations
+ $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
+
+ $nblignes = count($object->lines);
+
+ // Loop on each lines to detect if there is at least one image to show
+ $realpatharray=array();
+ $this->atleastonephoto = false;
+ if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE))
+ {
+ $objphoto = new Product($this->db);
+
+ for ($i = 0 ; $i < $nblignes ; $i++)
+ {
+ if (empty($object->lines[$i]->fk_product)) continue;
+
+ $objphoto->fetch($object->lines[$i]->fk_product);
+ //var_dump($objphoto->ref);exit;
+ if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
+ {
+ $pdir[0] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";
+ $pdir[1] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';
+ }
+ else
+ {
+ $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/'; // default
+ $pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/"; // alternative
+ }
+
+ $arephoto = false;
+ foreach ($pdir as $midir)
+ {
+ if (! $arephoto)
+ {
+ $dir = $conf->product->dir_output.'/'.$midir;
+
+ foreach ($objphoto->liste_photos($dir,1) as $key => $obj)
+ {
+ if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
+ {
+ if ($obj['photo_vignette'])
+ {
+ $filename= $obj['photo_vignette'];
+ }
+ else
+ {
+ $filename=$obj['photo'];
+ }
+ }
+ else
+ {
+ $filename=$obj['photo'];
+ }
+
+ $realpath = $dir.$filename;
+ $arephoto = true;
+ $this->atleastonephoto = true;
+ }
+ }
+ }
+
+ if ($realpath && $arephoto) $realpatharray[$i]=$realpath;
+ }
+ }
+
+ //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
+
+ if ($conf->facture->dir_output)
+ {
+ $object->fetch_thirdparty();
+
+ $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
+ $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
+ $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
+
+ // Definition of $dir and $file
+ if ($object->specimen)
+ {
+ $dir = $conf->facture->dir_output;
+ $file = $dir . "/SPECIMEN.pdf";
+ }
+ else
+ {
+ $objectref = dol_sanitizeFileName($object->ref);
+ $dir = $conf->facture->dir_output . "/" . $objectref;
+ $file = $dir . "/" . $objectref . ".pdf";
+ }
+ if (! file_exists($dir))
+ {
+ if (dol_mkdir($dir) < 0)
+ {
+ $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
+ return 0;
+ }
+ }
+
+ if (file_exists($dir))
+ {
+ // Add pdfgeneration hook
+ if (! is_object($hookmanager))
+ {
+ include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
+ $hookmanager=new HookManager($this->db);
+ }
+ $hookmanager->initHooks(array('pdfgeneration'));
+ $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
+ global $action;
+ $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
+
+ // Set nblignes with the new facture lines content after hook
+ $nblignes = count($object->lines);
+ $nbpayments = count($object->getListOfPayments());
+
+ // Create pdf instance
+ $pdf=pdf_getInstance($this->format);
+ $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
+ $pdf->SetAutoPageBreak(1,0);
+
+ $heightforinfotot = 50+(4*$nbpayments); // Height reserved to output the info and total part and payment part
+ $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page
+ $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22); // Height reserved to output the footer (value include bottom margin)
+
+ if (class_exists('TCPDF'))
+ {
+ $pdf->setPrintHeader(false);
+ $pdf->setPrintFooter(false);
+ }
+ $pdf->SetFont(pdf_getPDFFont($outputlangs));
+
+ // Set path to the background PDF File
+ if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
+ {
+ $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
+ $tplidx = $pdf->importPage(1);
+ }
+
+ $pdf->Open();
+ $pagenb=0;
+ $pdf->SetDrawColor(128,128,128);
+
+ $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
+ $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle"));
+ $pdf->SetCreator("Dolibarr ".DOL_VERSION);
+ $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
+ $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
+ if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
+
+ $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
+
+ // Does we have at least one line with discount $this->atleastonediscount
+ foreach ($object->lines as $line) {
+ if ($line->remise_percent){
+ $this->atleastonediscount = true;
+ break;
+ }
+ }
+
+
+ // Situation invoice handling
+ if ($object->situation_cycle_ref)
+ {
+ $this->situationinvoice = true;
+ }
+
+ // New page
+ $pdf->AddPage();
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ $pagenb++;
+
+ $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->MultiCell(0, 3, ''); // Set interline to 3
+ $pdf->SetTextColor(0,0,0);
+
+ $tab_top = 90+$top_shift;
+ $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
+ $tab_height = 130-$top_shift;
+ $tab_height_newpage = 150;
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift;
+
+ // Incoterm
+ $height_incoterms = 0;
+ if ($conf->incoterm->enabled)
+ {
+ $desc_incoterms = $object->getIncotermsForPDF();
+ if ($desc_incoterms)
+ {
+ $tab_top -= 2;
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
+ $nexY = max($pdf->GetY(),$nexY);
+ $height_incoterms=$nexY-$tab_top;
+
+ // Rect prend une longueur en 3eme param
+ $pdf->SetDrawColor(192,192,192);
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
+
+ $tab_top = $nexY+6;
+ $height_incoterms += 4;
+ }
+ }
+
+ // Affiche notes
+ $notetoshow=empty($object->note_public)?'':$object->note_public;
+ if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
+ {
+ // Get first sale rep
+ if (is_object($object->thirdparty))
+ {
+ $salereparray=$object->thirdparty->getSalesRepresentatives($user);
+ $salerepobj=new User($this->db);
+ $salerepobj->fetch($salereparray[0]['id']);
+ if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
+ }
+ }
+
+ $pagenb = $pdf->getPage();
+ if ($notetoshow)
+ {
+ $tab_top -= 2;
+
+ $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
+ $pageposbeforenote = $pagenb;
+
+ $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
+ complete_substitutions_array($substitutionarray, $outputlangs, $object);
+ $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
+
+
+ $pdf->startTransaction();
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
+ // Description
+ $pageposafternote=$pdf->getPage();
+ $posyafter = $pdf->GetY();
+
+ if($pageposafternote>$pageposbeforenote )
+ {
+ $pdf->rollbackTransaction(true);
+
+ // prepar pages to receive notes
+ while ($pagenb < $pageposafternote) {
+ $pdf->AddPage();
+ $pagenb++;
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ // $this->_pagefoot($pdf,$object,$outputlangs,1);
+ $pdf->setTopMargin($tab_top_newpage);
+ // The only function to edit the bottom margin of current page to set it.
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ }
+
+ // back to start
+ $pdf->setPage($pageposbeforenote);
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
+ $pageposafternote=$pdf->getPage();
+
+ $posyafter = $pdf->GetY();
+
+ if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20))) // There is no space left for total+free text
+ {
+ $pdf->AddPage('','',true);
+ $pagenb++;
+ $pageposafternote++;
+ $pdf->setPage($pageposafternote);
+ $pdf->setTopMargin($tab_top_newpage);
+ // The only function to edit the bottom margin of current page to set it.
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ //$posyafter = $tab_top_newpage;
+ }
+
+
+ // apply note frame to previus pages
+ $i = $pageposbeforenote;
+ while ($i < $pageposafternote) {
+ $pdf->setPage($i);
+
+
+ $pdf->SetDrawColor(128,128,128);
+ // Draw note frame
+ if($i>$pageposbeforenote){
+ $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
+ $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1);
+ }
+ else{
+ $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
+ }
+
+ // Add footer
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+
+ $i++;
+ }
+
+ // apply note frame to last page
+ $pdf->setPage($pageposafternote);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ $height_note=$posyafter-$tab_top_newpage;
+ $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
+
+ }
+ else // No pagebreak
+ {
+ $pdf->commitTransaction();
+ $posyafter = $pdf->GetY();
+ $height_note=$posyafter-$tab_top;
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
+
+
+ if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
+ {
+ // not enough space, need to add page
+ $pdf->AddPage('','',true);
+ $pagenb++;
+ $pageposafternote++;
+ $pdf->setPage($pageposafternote);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+
+ $posyafter = $tab_top_newpage;
+ }
+
+ }
+
+ $tab_height = $tab_height - $height_note;
+ $tab_top = $posyafter +6;
+ }
+ else
+ {
+ $height_note=0;
+ }
+
+ $iniY = $tab_top + 7;
+ $curY = $tab_top + 7;
+ $nexY = $tab_top + 7;
+
+ // Use new auto collum system
+ $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
+
+ // Loop on each lines
+ $pageposbeforeprintlines=$pdf->getPage();
+ $pagenb = $pageposbeforeprintlines;
+ for ($i = 0; $i < $nblignes; $i++)
+ {
+
+ $curY = $nexY;
+ $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage
+ $pdf->SetTextColor(0,0,0);
+
+ // Define size of image if we need it
+ $imglinesize=array();
+ if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]);
+
+ $pdf->setTopMargin($tab_top_newpage);
+ $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot); // The only function to edit the bottom margin of current page to set it.
+ $pageposbefore=$pdf->getPage();
+
+ $showpricebeforepagebreak=1;
+ $posYAfterImage=0;
+ $posYAfterDescription=0;
+
+ if($this->getColumnStatus('photo'))
+ {
+ // We start with Photo of product line
+ if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur-($heightforfooter+$heightforfreetext+$heightforinfotot))) // If photo too high, we moved completely on new page
+ {
+ $pdf->AddPage('','',true);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ $pdf->setPage($pageposbefore+1);
+
+ $curY = $tab_top_newpage;
+ $showpricebeforepagebreak=0;
+ }
+
+ if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
+ {
+ $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
+ // $pdf->Image does not increase value return by getY, so we save it manually
+ $posYAfterImage=$curY+$imglinesize['height'];
+ }
+ }
+
+ // Description of product line
+ if ($this->getColumnStatus('desc'))
+ {
+ $pdf->startTransaction();
+ pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
+ $pageposafter=$pdf->getPage();
+ if ($pageposafter > $pageposbefore) // There is a pagebreak
+ {
+ $pdf->rollbackTransaction(true);
+ $pageposafter=$pageposbefore;
+ //print $pageposafter.'-'.$pageposbefore;exit;
+ $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
+ pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
+ $pageposafter=$pdf->getPage();
+ $posyafter=$pdf->GetY();
+ //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
+ if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text
+ {
+ if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new page
+ {
+ $pdf->AddPage('','',true);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ $pdf->setPage($pageposafter+1);
+ }
+ }
+ else
+ {
+ // We found a page break
+ $showpricebeforepagebreak=0;
+ }
+ }
+ else // No pagebreak
+ {
+ $pdf->commitTransaction();
+ }
+ $posYAfterDescription=$pdf->GetY();
+ }
+
+ $nexY = $pdf->GetY();
+ $pageposafter=$pdf->getPage();
+ $pdf->setPage($pageposbefore);
+ $pdf->setTopMargin($this->marge_haute);
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+
+ // We suppose that a too long description or photo were moved completely on next page
+ if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
+ $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
+ }
+
+ $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut
+
+ // VAT Rate
+ if ($this->getColumnStatus('vat'))
+ {
+ $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Unit price before discount
+ if ($this->getColumnStatus('subprice'))
+ {
+ $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Quantity
+ // Enough for 6 chars
+ if ($this->getColumnStatus('qty'))
+ {
+ $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Situation progress
+ if ($this->getColumnStatus('progress'))
+ {
+ $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'progress', $progress);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Unit
+ if ($this->getColumnStatus('unit'))
+ {
+ $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
+ $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Discount on line
+ if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
+ {
+ $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Total HT line
+ if ($this->getColumnStatus('totalexcltax'))
+ {
+ $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+
+ $parameters=array(
+ 'object' => $object,
+ 'i' => $i,
+ 'pdf' =>& $pdf,
+ 'curY' =>& $curY,
+ 'nexY' =>& $nexY,
+ 'outputlangs' => $outputlangs,
+ 'hidedetails' => $hidedetails
+ );
+ $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this); // Note that $object may have been modified by hook
+
+
+
+ $sign=1;
+ if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
+ // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
+ $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
+ if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) // Compute progress from previous situation
+ {
+ if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
+ else $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
+ } else {
+ if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne= $sign * $object->lines[$i]->multicurrency_total_tva;
+ else $tvaligne= $sign * $object->lines[$i]->total_tva;
+ }
+
+ $localtax1ligne=$object->lines[$i]->total_localtax1;
+ $localtax2ligne=$object->lines[$i]->total_localtax2;
+ $localtax1_rate=$object->lines[$i]->localtax1_tx;
+ $localtax2_rate=$object->lines[$i]->localtax2_tx;
+ $localtax1_type=$object->lines[$i]->localtax1_type;
+ $localtax2_type=$object->lines[$i]->localtax2_type;
+
+ if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
+ if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
+ if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
+
+ $vatrate=(string) $object->lines[$i]->tva_tx;
+
+ // Retrieve type from database for backward compatibility with old records
+ if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
+ && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
+ {
+ $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0, $object->thirdparty, $mysoc);
+ $localtax1_type = $localtaxtmp_array[0];
+ $localtax2_type = $localtaxtmp_array[2];
+ }
+
+ // retrieve global local tax
+ if ($localtax1_type && $localtax1ligne != 0)
+ $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
+ if ($localtax2_type && $localtax2ligne != 0)
+ $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
+
+ if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
+ if (! isset($this->tva[$vatrate])) $this->tva[$vatrate]=0;
+ $this->tva[$vatrate] += $tvaligne;
+
+ $nexY = max($nexY,$posYAfterImage);
+
+ // Add line
+ if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
+ {
+ $pdf->setPage($pageposafter);
+ $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
+ //$pdf->SetDrawColor(190,190,200);
+ $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
+ $pdf->SetLineStyle(array('dash'=>0));
+ }
+
+ $nexY+=2; // Passe espace entre les lignes
+
+ // Detect if some page were added automatically and output _tableau for past pages
+ while ($pagenb < $pageposafter)
+ {
+ $pdf->setPage($pagenb);
+ if ($pagenb == $pageposbeforeprintlines)
+ {
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
+ }
+ else
+ {
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
+ }
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+ $pagenb++;
+ $pdf->setPage($pagenb);
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ }
+
+ if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+ {
+ if ($pagenb == $pageposafter)
+ {
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
+ }
+ else
+ {
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
+ }
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+ // New page
+ $pdf->AddPage();
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ $pagenb++;
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ }
+
+ }
+
+ // Show square
+ if ($pagenb == $pageposbeforeprintlines)
+ {
+ $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;
+ }
+
+ // Affiche zone infos
+ $posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
+
+ // Affiche zone totaux
+ $posy=$this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
+
+ // Affiche zone versements
+ if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
+ {
+ $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
+ }
+
+ // Pied de page
+ $this->_pagefoot($pdf,$object,$outputlangs);
+ if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages();
+
+ $pdf->Close();
+
+ $pdf->Output($file,'F');
+
+ // Add pdfgeneration hook
+ $hookmanager->initHooks(array('pdfgeneration'));
+ $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
+
+ if (! empty($conf->global->MAIN_UMASK))
+ @chmod($file, octdec($conf->global->MAIN_UMASK));
+
+ $this->result = array('fullpath'=>$file);
+
+ return 1; // No error
+ }
+ else
+ {
+ $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
+ return 0;
+ }
+ }
+ else
+ {
+ $this->error=$langs->transnoentities("ErrorConstantNotDefined","FAC_OUTPUTDIR");
+ return 0;
+ }
+ }
+
+
+ /**
+ * Show payments table
+ *
+ * @param PDF $pdf Object PDF
+ * @param Object $object Object invoice
+ * @param int $posy Position y in PDF
+ * @param Translate $outputlangs Object langs for output
+ * @return int <0 if KO, >0 if OK
+ */
+ function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
+ {
+ global $conf;
+
+ $sign=1;
+ if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
+
+ $tab3_posx = 120;
+ $tab3_top = $posy + 8;
+ $tab3_width = 80;
+ $tab3_height = 4;
+ if ($this->page_largeur < 210) // To work with US executive format
+ {
+ $tab3_posx -= 20;
+ }
+
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ $title=$outputlangs->transnoentities("PaymentsAlreadyDone");
+ if ($object->type == 2) $title=$outputlangs->transnoentities("PaymentsBackAlreadyDone");
+
+ $pdf->SetFont('','', $default_font_size - 3);
+ $pdf->SetXY($tab3_posx, $tab3_top - 4);
+ $pdf->MultiCell(60, 3, $title, 0, 'L', 0);
+
+ $pdf->line($tab3_posx, $tab3_top, $tab3_posx+$tab3_width, $tab3_top);
+
+ $pdf->SetFont('','', $default_font_size - 4);
+ $pdf->SetXY($tab3_posx, $tab3_top);
+ $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+21, $tab3_top);
+ $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+40, $tab3_top);
+ $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+58, $tab3_top);
+ $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0);
+
+ $pdf->line($tab3_posx, $tab3_top-1+$tab3_height, $tab3_posx+$tab3_width, $tab3_top-1+$tab3_height);
+
+ $y=0;
+
+ $pdf->SetFont('','', $default_font_size - 4);
+
+
+ // Loop on each deposits and credit notes included
+ $sql = "SELECT re.rowid, re.amount_ht, re.multicurrency_amount_ht, re.amount_tva, re.multicurrency_amount_tva, re.amount_ttc, re.multicurrency_amount_ttc,";
+ $sql.= " re.description, re.fk_facture_source,";
+ $sql.= " f.type, f.datef";
+ $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re, ".MAIN_DB_PREFIX ."facture as f";
+ $sql.= " WHERE re.fk_facture_source = f.rowid AND re.fk_facture = ".$object->id;
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+ $num = $this->db->num_rows($resql);
+ $i=0;
+ $invoice=new Facture($this->db);
+ while ($i < $num)
+ {
+ $y+=3;
+ $obj = $this->db->fetch_object($resql);
+
+ if ($obj->type == 2) $text=$outputlangs->trans("CreditNote");
+ elseif ($obj->type == 3) $text=$outputlangs->trans("Deposit");
+ else $text=$outputlangs->trans("UnknownType");
+
+ $invoice->fetch($obj->fk_facture_source);
+
+ $pdf->SetXY($tab3_posx, $tab3_top+$y);
+ $pdf->MultiCell(20, 3, dol_print_date($obj->datef,'day',false,$outputlangs,true), 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+21, $tab3_top+$y);
+ $pdf->MultiCell(20, 3, price(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $obj->multicurrency_amount_ttc : $obj->amount_ttc, 0, $outputlangs), 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+40, $tab3_top+$y);
+ $pdf->MultiCell(20, 3, $text, 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+58, $tab3_top+$y);
+ $pdf->MultiCell(20, 3, $invoice->ref, 0, 'L', 0);
+
+ $pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3);
+
+ $i++;
+ }
+ }
+ else
+ {
+ $this->error=$this->db->lasterror();
+ return -1;
+ }
+
+ // Loop on each payment
+ // TODO Call getListOfPaymentsgetListOfPayments instead of hard coded sql
+ $sql = "SELECT p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,";
+ $sql.= " cp.code";
+ $sql.= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p";
+ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id";
+ $sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".$object->id;
+ //$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = 1";
+ $sql.= " ORDER BY p.datep";
+
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+ $num = $this->db->num_rows($resql);
+ $i=0;
+ while ($i < $num) {
+ $y+=3;
+ $row = $this->db->fetch_object($resql);
+
+ $pdf->SetXY($tab3_posx, $tab3_top+$y);
+ $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->date),'day',false,$outputlangs,true), 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+21, $tab3_top+$y);
+ $pdf->MultiCell(20, 3, price($sign * (($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $row->multicurrency_amount : $row->amount), 0, $outputlangs), 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+40, $tab3_top+$y);
+ $oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort" . $row->code);
+
+ $pdf->MultiCell(20, 3, $oper, 0, 'L', 0);
+ $pdf->SetXY($tab3_posx+58, $tab3_top+$y);
+ $pdf->MultiCell(30, 3, $row->num, 0, 'L', 0);
+
+ $pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3);
+
+ $i++;
+ }
+ }
+ else
+ {
+ $this->error=$this->db->lasterror();
+ return -1;
+ }
+ }
+
+
+ /**
+ * Show miscellaneous information (payment mode, payment term, ...)
+ *
+ * @param PDF $pdf Object PDF
+ * @param Object $object Object to show
+ * @param int $posy Y
+ * @param Translate $outputlangs Langs object
+ * @return void
+ */
+ private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
+ {
+ global $conf;
+
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // If France, show VAT mention if not applicable
+ if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
+
+ $posy=$pdf->GetY()+4;
+ }
+
+ $posxval=52;
+
+ // Show payments conditions
+ if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement))
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("PaymentConditions").':';
+ $pdf->MultiCell(43, 4, $titre, 0, 'L');
+
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc);
+ $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement);
+ $pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L');
+
+ $posy=$pdf->GetY()+3;
+ }
+
+ if ($object->type != 2)
+ {
+ // Check a payment mode is defined
+ if (empty($object->mode_reglement_code)
+ && empty($conf->global->FACTURE_CHQ_NUMBER)
+ && empty($conf->global->FACTURE_RIB_NUMBER))
+ {
+ $this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured");
+ }
+ // Avoid having any valid PDF with setup that is not complete
+ elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))
+ || ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank)))
+ {
+ $outputlangs->load("errors");
+
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup",$object->mode_reglement_code);
+ $pdf->MultiCell(80, 3, $this->error,0,'L',0);
+ $pdf->SetTextColor(0,0,0);
+
+ $posy=$pdf->GetY()+1;
+ }
+
+ // Show payment mode
+ if ($object->mode_reglement_code
+ && $object->mode_reglement_code != 'CHQ'
+ && $object->mode_reglement_code != 'VIR')
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("PaymentMode").':';
+ $pdf->MultiCell(80, 5, $titre, 0, 'L');
+
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement);
+ $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L');
+
+ $posy=$pdf->GetY()+2;
+ }
+
+ // Show payment mode CHQ
+ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
+ {
+ // Si mode reglement non force ou si force a CHQ
+ if (! empty($conf->global->FACTURE_CHQ_NUMBER))
+ {
+ $diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE);
+
+ if ($conf->global->FACTURE_CHQ_NUMBER > 0)
+ {
+ $account = new Account($this->db);
+ $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
+
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','B', $default_font_size - $diffsizetitle);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0);
+ $posy=$pdf->GetY()+1;
+
+ if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','', $default_font_size - $diffsizetitle);
+ $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
+ $posy=$pdf->GetY()+2;
+ }
+ }
+ if ($conf->global->FACTURE_CHQ_NUMBER == -1)
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','B', $default_font_size - $diffsizetitle);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0);
+ $posy=$pdf->GetY()+1;
+
+ if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','', $default_font_size - $diffsizetitle);
+ $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
+ $posy=$pdf->GetY()+2;
+ }
+ }
+ }
+ }
+
+ // If payment mode not forced or forced to VIR, show payment with BAN
+ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
+ {
+ if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER))
+ {
+ $bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account);
+ if (! empty($object->fk_bank)) $bankid=$object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
+ $account = new Account($this->db);
+ $account->fetch($bankid);
+
+ $curx=$this->marge_gauche;
+ $cury=$posy;
+
+ $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size);
+
+ $posy+=2;
+ }
+ }
+ }
+
+ return $posy;
+ }
+
+
+ /**
+ * Show total to pay
+ *
+ * @param PDF $pdf Object PDF
+ * @param Facture $object Object invoice
+ * @param int $deja_regle Montant deja regle
+ * @param int $posy Position depart
+ * @param Translate $outputlangs Objet langs
+ * @return int Position pour suite
+ */
+ private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
+ {
+ global $conf,$mysoc;
+
+ $sign=1;
+ if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
+
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ $tab2_top = $posy;
+ $tab2_hl = 4;
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // Tableau total
+ $col1x = 120; $col2x = 170;
+ if ($this->page_largeur < 210) // To work with US executive format
+ {
+ $col2x-=20;
+ }
+ $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
+
+ $useborder=0;
+ $index = 0;
+
+ // Total HT
+ $pdf->SetFillColor(255,255,255);
+ $pdf->SetXY($col1x, $tab2_top + 0);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
+
+ $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
+ $pdf->SetXY($col2x, $tab2_top + 0);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (! empty($object->remise)?$object->remise:0)), 0, $outputlangs), 0, 'R', 1);
+
+ // Show VAT by rates and total
+ $pdf->SetFillColor(248,248,248);
+
+ $total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
+
+ $this->atleastoneratenotnull=0;
+ if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
+ {
+ $tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
+ if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
+ {
+ // Nothing to do
+ }
+ else
+ {
+ // FIXME amount of vat not supported with multicurrency
+
+ //Local tax 1 before VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
+ //{
+ foreach( $this->localtax1 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('1','3','5'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey!=0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ }
+ //}
+ //Local tax 2 before VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
+ //{
+ foreach( $this->localtax2 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('1','3','5'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey!=0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+
+ }
+ }
+ }
+
+ //}
+
+ // VAT
+ // Situations totals migth be wrong on huge amounts
+ if ($object->situation_cycle_ref && $object->situation_counter > 1) {
+
+ $sum_pdf_tva = 0;
+ foreach($this->tva as $tvakey => $tvaval){
+ $sum_pdf_tva+=$tvaval; // sum VAT amounts to compare to object
+ }
+
+ if($sum_pdf_tva!=$object->total_tva) { // apply coef to recover the VAT object amount (the good one)
+ $coef_fix_tva = $object->total_tva / $sum_pdf_tva;
+
+ foreach($this->tva as $tvakey => $tvaval) {
+ $this->tva[$tvakey]=$tvaval * $coef_fix_tva;
+ }
+ }
+
+ }
+
+ foreach($this->tva as $tvakey => $tvaval)
+ {
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ $this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' ';
+ $totalvat.=vatrate($tvakey,1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+
+ //Local tax 1 after VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
+ //{
+ foreach( $this->localtax1 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('2','4','6'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ }
+ //}
+ //Local tax 2 after VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
+ //{
+ foreach( $this->localtax2 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('2','4','6'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ // retrieve global local tax
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
+
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ //}
+ }
+
+ // Revenue stamp
+ if (price2num($object->revenuestamp) != 0)
+ {
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RevenueStamp"), $useborder, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($sign * $object->revenuestamp), $useborder, 'R', 1);
+ }
+
+ // Total TTC
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFillColor(224,224,224);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($sign * $total_ttc, 0, $outputlangs), $useborder, 'R', 1);
+ }
+ }
+
+ $pdf->SetTextColor(0,0,0);
+
+ $creditnoteamount=$object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
+ $depositsamount=$object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
+ //print "x".$creditnoteamount."-".$depositsamount;exit;
+ $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
+ if ($object->paye) $resteapayer=0;
+
+ if (($deja_regle > 0 || $creditnoteamount > 0 || $depositsamount > 0) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
+ {
+ // Already paid + Deposits
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("Paid"), 0, 'L', 0);
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', 0);
+
+ // Credit note
+ if ($creditnoteamount)
+ {
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("CreditNotes"), 0, 'L', 0);
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($creditnoteamount, 0, $outputlangs), 0, 'R', 0);
+ }
+
+ // Escompte
+ if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT)
+ {
+ $index++;
+ $pdf->SetFillColor(255,255,255);
+
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1);
+
+ $resteapayer=0;
+ }
+
+ $index++;
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFillColor(224,224,224);
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->SetTextColor(0,0,0);
+ }
+
+ $index++;
+ return ($tab2_top + ($tab2_hl * $index));
+ }
+
+ /**
+ * Show table for lines
+ *
+ * @param PDF $pdf Object PDF
+ * @param string $tab_top Top position of table
+ * @param string $tab_height Height of table (rectangle)
+ * @param int $nexY Y (not used)
+ * @param Translate $outputlangs Langs object
+ * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
+ * @param int $hidebottom Hide bottom bar of array
+ * @param string $currency Currency code
+ * @return void
+ */
+ function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
+ {
+ global $conf;
+
+ // Force to disable hidetop and hidebottom
+ $hidebottom=0;
+ if ($hidetop) $hidetop=-1;
+
+ $currency = !empty($currency) ? $currency : $conf->currency;
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ // Amount in (at tab_top - 1)
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+
+ if (empty($hidetop))
+ {
+ $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency));
+ $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
+ $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
+
+ //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
+ if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
+ }
+
+ $pdf->SetDrawColor(128,128,128);
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // Output Rect
+ $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param
+
+
+ foreach ($this->cols as $colKey => $colDef)
+ {
+ if(!$this->getColumnStatus($colKey)) continue;
+
+ // get title label
+ $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
+
+ // Add column separator
+ if(!empty($colDef['border-left'])){
+ $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
+ }
+
+ if (empty($hidetop))
+ {
+ $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
+
+ $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
+ $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
+ }
+ }
+
+ if (empty($hidetop)){
+ $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line prend une position y en 2eme param et 4eme param
+ }
+ }
+
+ /**
+ * Show top header of page.
+ *
+ * @param PDF $pdf Object PDF
+ * @param Object $object Object to show
+ * @param int $showaddress 0=no, 1=yes
+ * @param Translate $outputlangs Object lang for output
+ * @return void
+ */
+ function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
+ {
+ global $conf, $langs;
+
+ // Translations
+ $outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
+
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
+
+ // Show Draft Watermark
+ if($object->statut==Facture::STATUS_DRAFT && (! empty($conf->global->FACTURE_DRAFT_WATERMARK)) )
+ {
+ pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->FACTURE_DRAFT_WATERMARK);
+ }
+
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFont('','B', $default_font_size + 3);
+
+ $w = 110;
+
+ $posy=$this->marge_haute;
+ $posx=$this->page_largeur-$this->marge_droite-$w;
+
+ $pdf->SetXY($this->marge_gauche,$posy);
+
+ // Logo
+ if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
+ {
+ $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
+ if ($this->emetteur->logo)
+ {
+ if (is_readable($logo))
+ {
+ $height=pdf_getHeightForLogo($logo);
+ $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ }
+ else
+ {
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B',$default_font_size - 2);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ }
+ }
+ else
+ {
+ $text=$this->emetteur->name;
+ $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
+ }
+ }
+
+ $pdf->SetFont('','B', $default_font_size + 3);
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $title=$outputlangs->transnoentities("PdfInvoiceTitle");
+ if ($object->type == 1) $title=$outputlangs->transnoentities("InvoiceReplacement");
+ if ($object->type == 2) $title=$outputlangs->transnoentities("InvoiceAvoir");
+ if ($object->type == 3) $title=$outputlangs->transnoentities("InvoiceDeposit");
+ if ($object->type == 4) $title=$outputlangs->transnoentities("InvoiceProForma");
+ if ($this->situationinvoice) $title=$outputlangs->transnoentities("InvoiceSituation");
+ $pdf->MultiCell($w, 3, $title, '', 'R');
+
+ $pdf->SetFont('','B',$default_font_size);
+
+ $posy+=5;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $textref=$outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref);
+ if ($object->statut == Facture::STATUS_DRAFT)
+ {
+ $pdf->SetTextColor(128,0,0);
+ $textref.=' - '.$outputlangs->transnoentities("NotValidated");
+ }
+ $pdf->MultiCell($w, 4, $textref, '', 'R');
+
+ $posy+=1;
+ $pdf->SetFont('','', $default_font_size - 2);
+
+ if ($object->ref_client)
+ {
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
+ }
+
+ $objectidnext=$object->getIdReplacingInvoice('validated');
+ if ($object->type == 0 && $objectidnext)
+ {
+ $objectreplacing=new Facture($this->db);
+ $objectreplacing->fetch($objectidnext);
+
+ $posy+=3;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R');
+ }
+ if ($object->type == 1)
+ {
+ $objectreplaced=new Facture($this->db);
+ $objectreplaced->fetch($object->fk_facture_source);
+
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
+ }
+ if ($object->type == 2 && !empty($object->fk_facture_source))
+ {
+ $objectreplaced=new Facture($this->db);
+ $objectreplaced->fetch($object->fk_facture_source);
+
+ $posy+=3;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
+ }
+
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateInvoice")." : " . dol_print_date($object->date,"day",false,$outputlangs), '', 'R');
+
+ if (! empty($conf->global->INVOICE_POINTOFTAX_DATE))
+ {
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : " . dol_print_date($object->date_pointoftax,"day",false,$outputlangs), '', 'R');
+ }
+
+ if ($object->type != 2)
+ {
+ $posy+=3;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateDue")." : " . dol_print_date($object->date_lim_reglement,"day",false,$outputlangs,true), '', 'R');
+ }
+
+ if ($object->thirdparty->code_client)
+ {
+ $posy+=3;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
+ }
+
+ // Get contact
+ if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
+ {
+ $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
+ if (count($arrayidcontact) > 0)
+ {
+ $usertmp=new User($this->db);
+ $usertmp->fetch($arrayidcontact[0]);
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
+ }
+ }
+
+ $posy+=1;
+
+ $top_shift = 0;
+ // Show list of linked objects
+ $current_y = $pdf->getY();
+ $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
+ if ($current_y < $pdf->getY())
+ {
+ $top_shift = $pdf->getY() - $current_y;
+ }
+
+ if ($showaddress)
+ {
+ // Sender properties
+ $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
+
+ // Show sender
+ $posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
+ $posy+=$top_shift;
+ $posx=$this->marge_gauche;
+ if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
+
+ $hautcadre=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
+ $widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
+
+
+ // Show sender frame
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posx,$posy-5);
+ $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetFillColor(230,230,230);
+ $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
+ $pdf->SetTextColor(0,0,60);
+
+ // Show sender name
+ $pdf->SetXY($posx+2,$posy+3);
+ $pdf->SetFont('','B', $default_font_size);
+ $pdf->MultiCell($widthrecbox-2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
+ $posy=$pdf->getY();
+
+ // Show sender information
+ $pdf->SetXY($posx+2,$posy);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->MultiCell($widthrecbox-2, 4, $carac_emetteur, 0, 'L');
+
+ // If BILLING contact defined on invoice, we use it
+ $usecontact=false;
+ $arrayidcontact=$object->getIdContact('external','BILLING');
+ if (count($arrayidcontact) > 0)
+ {
+ $usecontact=true;
+ $result=$object->fetch_contact($arrayidcontact[0]);
+ }
+
+ //Recipient name
+ // On peut utiliser le nom de la societe du contact
+ if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
+ $thirdparty = $object->contact;
+ } else {
+ $thirdparty = $object->thirdparty;
+ }
+
+ $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs);
+
+ $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target',$object);
+
+ // Show recipient
+ $widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
+ if ($this->page_largeur < 210) $widthrecbox=84; // To work with US executive format
+ $posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
+ $posy+=$top_shift;
+ $posx=$this->page_largeur-$this->marge_droite-$widthrecbox;
+ if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
+
+ // Show recipient frame
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posx+2,$posy-5);
+ $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":",0,'L');
+ $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
+
+ // Show recipient name
+ $pdf->SetXY($posx+2,$posy+3);
+ $pdf->SetFont('','B', $default_font_size);
+ $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L');
+
+ $posy = $pdf->getY();
+
+ // Show recipient information
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->SetXY($posx+2,$posy);
+ $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
+ }
+
+ $pdf->SetTextColor(0,0,0);
+ return $top_shift;
+ }
+
+ /**
+ * Show footer of page. Need this->emetteur object
+ *
+ * @param PDF $pdf PDF
+ * @param Object $object Object to show
+ * @param Translate $outputlangs Object lang for output
+ * @param int $hidefreetext 1=Hide free text
+ * @return int Return height of bottom margin including footer text
+ */
+ function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
+ {
+ global $conf;
+ $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
+ return pdf_pagefoot($pdf,$outputlangs,'INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
+ }
+
+ /**
+ * Define Array Column Field
+ *
+ * @param object $object common object
+ * @param outputlangs $outputlangs langs
+ * @param int $hidedetails Do not show line details
+ * @param int $hidedesc Do not show desc
+ * @param int $hideref Do not show ref
+ * @return null
+ */
+ function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
+ {
+ global $conf, $hookmanager;
+
+ // Default field style for content
+ $this->defaultContentsFieldsStyle = array(
+ 'align' => 'R', // R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ );
+
+ // Default field style for content
+ $this->defaultTitlesFieldsStyle = array(
+ 'align' => 'C', // R,C,L
+ 'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ );
+
+ /*
+ * For exemple
+ $this->cols['theColKey'] = array(
+ 'rank' => $rank, // int : use for ordering columns
+ 'width' => 20, // the column width in mm
+ 'title' => array(
+ 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
+ 'label' => ' ', // the final label : used fore final generated text
+ 'align' => 'L', // text alignement : R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'content' => array(
+ 'align' => 'L', // text alignement : R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ );
+ */
+
+ $rank=0; // do not use negative rank
+ $this->cols['desc'] = array(
+ 'rank' => $rank,
+ 'width' => false, // only for desc
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'Designation', // use lang key is usefull in somme case with module
+ 'align' => 'L',
+ // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
+ // 'label' => ' ', // the final label
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'content' => array(
+ 'align' => 'L',
+ ),
+ );
+
+ // PHOTO
+ $rank = $rank + 10;
+ $this->cols['photo'] = array(
+ 'rank' => $rank,
+ 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Photo',
+ 'label' => ' '
+ ),
+ 'content' => array(
+ 'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'border-left' => false, // remove left line separator
+ );
+
+ if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto))
+ {
+ $this->cols['photo']['status'] = true;
+ }
+
+
+ $rank = $rank + 10;
+ $this->cols['vat'] = array(
+ 'rank' => $rank,
+ 'status' => false,
+ 'width' => 16, // in mm
+ 'title' => array(
+ 'textkey' => 'VAT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
+ {
+ $this->cols['vat']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['subprice'] = array(
+ 'rank' => $rank,
+ 'width' => 19, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'PriceUHT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ $rank = $rank + 10;
+ $this->cols['qty'] = array(
+ 'rank' => $rank,
+ 'width' => 16, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'Qty'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ $rank = $rank + 10;
+ $this->cols['progress'] = array(
+ 'rank' => $rank,
+ 'width' => 19, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Progress'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ if($this->situationinvoice)
+ {
+ $this->cols['progress']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['unit'] = array(
+ 'rank' => $rank,
+ 'width' => 11, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Unit'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+ if($conf->global->PRODUCT_USE_UNITS){
+ $this->cols['unit']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['discount'] = array(
+ 'rank' => $rank,
+ 'width' => 13, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'ReductionShort'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+ if ($this->atleastonediscount){
+ $this->cols['discount']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['totalexcltax'] = array(
+ 'rank' => $rank,
+ 'width' => 26, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'TotalHT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+
+ $parameters=array(
+ 'object' => $object,
+ 'outputlangs' => $outputlangs,
+ 'hidedetails' => $hidedetails,
+ 'hidedesc' => $hidedesc,
+ 'hideref' => $hideref
+ );
+
+ $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this); // Note that $object may have been modified by hook
+ if ($reshook < 0)
+ {
+ setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+ }
+ elseif (empty($reshook))
+ {
+ $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
+ }
+ else
+ {
+ $this->cols = $hookmanager->resArray;
+ }
+ }
+}
diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php
index 60dc9bf6c15..34bff81e55c 100644
--- a/htdocs/core/modules/import/import_csv.modules.php
+++ b/htdocs/core/modules/import/import_csv.modules.php
@@ -633,6 +633,7 @@ class ImportCsv extends ModeleImports
//print 'listfields='.$listfields.'
listvalues='.$listvalues.'
';
// If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
+ // so we can try to make the insert or update now.
if (! $errorforthistable)
{
//print "$alias/$tablename/$listfields/$listvalues
";
@@ -644,7 +645,7 @@ class ImportCsv extends ModeleImports
if (!empty($updatekeys)) {
// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
- if (empty($lastinsertid)) {
+ if (empty($lastinsertid)) { // No insert done yet for a parent table
$sqlSelect = 'SELECT rowid FROM '.$tablename;
$data = array_combine($listfields, $listvalues);
@@ -680,10 +681,11 @@ class ImportCsv extends ModeleImports
$error++;
}
} else {
- // We have a last INSERT ID. Check if we have a row referencing this foreign key.
+ // We have a last INSERT ID (got by previous pass), so we check if we have a row referencing this foreign key.
// This is required when updating table with some extrafields. When inserting a record in parent table, we can make
// a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record
- // may already exists. So we rescan the extrafield table to be know if record exists or not for the rowid.
+ // may already exists. So we rescan the extrafield table to know if record exists or not for the rowid.
+ // Note: For extrafield tablename, we have in importfieldshidden_array an enty 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object'
$sqlSelect = 'SELECT rowid FROM '.$tablename;
if(empty($keyfield)) $keyfield = 'rowid';
diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php
index 36b57e2d69a..2c37caa5d40 100644
--- a/htdocs/core/modules/import/import_xlsx.modules.php
+++ b/htdocs/core/modules/import/import_xlsx.modules.php
@@ -656,6 +656,7 @@ class ImportXlsx extends ModeleImports
//print 'listfields='.$listfields.'
listvalues='.$listvalues.'
';
// If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
+ // so we can try to make the insert or update now.
if (! $errorforthistable)
{
//print "$alias/$tablename/$listfields/$listvalues
";
@@ -665,7 +666,8 @@ class ImportXlsx extends ModeleImports
$insertdone = false;
if (!empty($updatekeys)) {
// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
- if (empty($lastinsertid)) {
+
+ if (empty($lastinsertid)) { // No insert done yet for a parent table
$sqlSelect = 'SELECT rowid FROM '.$tablename;
$data = array_combine($listfields, $listvalues);
@@ -704,7 +706,8 @@ class ImportXlsx extends ModeleImports
// We have a last INSERT ID. Check if we have a row referencing this foreign key.
// This is required when updating table with some extrafields. When inserting a record in parent table, we can make
// a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record
- // may already exists. So we rescan the extrafield table to be know if record exists or not for the rowid.
+ // may already exists. So we rescan the extrafield table to know if record exists or not for the rowid.
+ // Note: For extrafield tablename, we have in importfieldshidden_array an enty 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object'
$sqlSelect = 'SELECT rowid FROM '.$tablename;
if(empty($keyfield)) $keyfield = 'rowid';
diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php
index e0316a75390..f7136d4aa63 100644
--- a/htdocs/core/modules/mailings/modules_mailings.php
+++ b/htdocs/core/modules/mailings/modules_mailings.php
@@ -41,7 +41,7 @@ class MailingTargets // This can't be abstract as it is used for some method
*/
public $error='';
- var $tooltip='';
+ public $tooltip='';
/**
diff --git a/htdocs/core/modules/modDataPolicies.class.php b/htdocs/core/modules/modDataPolicy.class.php
similarity index 59%
rename from htdocs/core/modules/modDataPolicies.class.php
rename to htdocs/core/modules/modDataPolicy.class.php
index 74bbe0ba7d2..ca53440a3b9 100644
--- a/htdocs/core/modules/modDataPolicies.class.php
+++ b/htdocs/core/modules/modDataPolicy.class.php
@@ -18,12 +18,12 @@
*/
/**
- * \defgroup datapolicies Module datapolicies
- * \brief datapolicies module descriptor.
+ * \defgroup datapolicy Module datapolicy
+ * \brief datapolicy module descriptor.
*
- * \file htdocs/datapolicies/core/modules/modGdpr.class.php
- * \ingroup datapolicies
- * \brief Description and activation file for module DATAPOLICIES
+ * \file htdocs/datapolicy/core/modules/modDataPolicy.class.php
+ * \ingroup datapolicy
+ * \brief Description and activation file for module DATAPOLICY
*/
include_once DOL_DOCUMENT_ROOT . '/core/modules/DolibarrModules.class.php';
@@ -33,9 +33,9 @@ include_once DOL_DOCUMENT_ROOT . '/core/modules/DolibarrModules.class.php';
// so we ignore the Squiz.Classes.ValidClassName.NotCamelCaps rule.
// @codingStandardsIgnoreStart
/**
- * Description and activation class for module datapolicies
+ * Description and activation class for module datapolicy
*/
-class modDataPolicies extends DolibarrModules {
+class modDataPolicy extends DolibarrModules {
// @codingStandardsIgnoreEnd
/**
@@ -53,7 +53,7 @@ class modDataPolicies extends DolibarrModules {
// Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
$this->numero = 4100;
// Key text used to identify module (for permissions, menus, etc...)
- $this->rights_class = 'datapolicies';
+ $this->rights_class = 'datapolicy';
// Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
// It is used to group modules by family in module setup page
@@ -62,16 +62,16 @@ class modDataPolicies extends DolibarrModules {
$this->module_position = '70';
// Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
- // Module label (no space allowed), used if translation string 'ModuledatapoliciesName' not found (MyModue is name of module).
+ // Module label (no space allowed), used if translation string 'ModuledatapolicyName' not found (MyModue is name of module).
$this->name = preg_replace('/^mod/i', '', get_class($this));
- // Module description, used if translation string 'ModuledatapoliciesDesc' not found (MyModue is name of module).
- $this->description = "Module to manage Data policies (for compliance with GDPR in Europe or other Data policies rules)";
+ // Module description, used if translation string 'ModuledatapolicyDesc' not found (MyModue is name of module).
+ $this->description = "Module to manage Data policy (for compliance with GDPR in Europe or other Data policy rules)";
// Used only if file README.md and README-LL.md not found.
$this->descriptionlong = "";
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
$this->version = 'development';
- // Key used in llx_const table to save module status enabled/disabled (where datapolicies is value of property name of module in uppercase)
+ // Key used in llx_const table to save module status enabled/disabled (where datapolicy is value of property name of module in uppercase)
$this->const_name = 'MAIN_MODULE_' . strtoupper($this->name);
// Name of image file used for this module.
// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
@@ -79,9 +79,9 @@ class modDataPolicies extends DolibarrModules {
$this->picto = 'generic';
// Defined all module parts (triggers, login, substitutions, menus, css, etc...)
- // for default path (eg: /datapolicies/core/xxxxx) (0=disable, 1=enable)
- // for specific path of parts (eg: /datapolicies/core/modules/barcode)
- // for specific css file (eg: /datapolicies/css/datapolicies.css.php)
+ // for default path (eg: /datapolicy/core/xxxxx) (0=disable, 1=enable)
+ // for specific path of parts (eg: /datapolicy/core/modules/barcode)
+ // for specific css file (eg: /datapolicy/css/datapolicy.css.php)
$this->module_parts = array(
'triggers' => 0, // Set this to 1 if module has its own trigger directory (core/triggers)
'login' => 0, // Set this to 1 if module has its own login method file (core/login)
@@ -95,41 +95,41 @@ class modDataPolicies extends DolibarrModules {
);
// Data directories to create when module is enabled.
- // Example: this->dirs = array("/datapolicies/temp","/datapolicies/subdir");
- $this->dirs = array("/datapolicies/temp");
+ // Example: this->dirs = array("/datapolicy/temp","/datapolicy/subdir");
+ $this->dirs = array("/datapolicy/temp");
- // Config pages. Put here list of php page, stored into datapolicies/admin directory, to use to setup module.
- $this->config_page_url = array("setup.php@datapolicies");
+ // Config pages. Put here list of php page, stored into datapolicy/admin directory, to use to setup module.
+ $this->config_page_url = array("setup.php@datapolicy");
// Dependencies
$this->hidden = false; // A condition to hide module
$this->depends = array(); // List of module class names as string that must be enabled if this module is enabled
$this->requiredby = array(); // List of module ids to disable if this one is disabled
$this->conflictwith = array(); // List of module class names as string this module is in conflict with
- $this->langfiles = array("datapolicies@datapolicies");
+ $this->langfiles = array("datapolicy@datapolicy");
$this->phpmin = array(5, 3); // Minimum version of PHP required by module
$this->need_dolibarr_version = array(4, 0); // Minimum version of Dolibarr required by module
$this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
$this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
- //$this->automatic_activation = array('FR'=>'datapoliciesWasAutomaticallyActivatedBecauseOfYourCountryChoice');
+ //$this->automatic_activation = array('FR'=>'datapolicyWasAutomaticallyActivatedBecauseOfYourCountryChoice');
//$this->always_enabled = true; // If true, can't be disabled
// Constants
// List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
- // Example: $this->const=array(0=>array('datapolicies_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
- // 1=>array('datapolicies_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
+ // Example: $this->const=array(0=>array('datapolicy_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
+ // 1=>array('datapolicy_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
// );
$this->const = array(
- array('DATAPOLICIES_TIERS_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_TIERS_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_TIERS_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_TIERS_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_CONTACT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_CONTACT_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_CONTACT_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_CONTACT_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
- array('DATAPOLICIES_ADHERENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_TIERS_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_TIERS_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_TIERS_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_TIERS_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_TIERS_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_CONTACT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_CONTACT_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_CONTACT_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_CONTACT_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
+ array('DATAPOLICY_ADHERENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
);
$country = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY);
@@ -140,17 +140,17 @@ class modDataPolicies extends DolibarrModules {
'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
) */
- if (!isset($conf->datapolicies) || !isset($conf->datapolicies->enabled)) {
- $conf->datapolicies = new stdClass();
- $conf->datapolicies->enabled = 0;
+ if (!isset($conf->datapolicy) || !isset($conf->datapolicy->enabled)) {
+ $conf->datapolicy = new stdClass();
+ $conf->datapolicy->enabled = 0;
}
// Array to add new pages in new tabs
$this->tabs = array();
// Example:
- // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@datapolicies:$user->rights->datapolicies->read:/datapolicies/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1
- // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@datapolicies:$user->rights->othermodule->read:/datapolicies/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
+ // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@datapolicy:$user->rights->datapolicy->read:/datapolicy/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1
+ // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@datapolicy:$user->rights->othermodule->read:/datapolicy/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
// $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname
//
// Where objecttype can be
@@ -177,7 +177,7 @@ class modDataPolicies extends DolibarrModules {
$this->dictionaries = array();
/* Example:
$this->dictionaries=array(
- 'langs'=>'mylangfile@datapolicies',
+ 'langs'=>'mylangfile@datapolicy',
'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"), // List of tables we want to see into dictonnary editor
'tablib'=>array("Table1","Table2","Table3"), // Label of tables
'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'), // Request to select fields
@@ -186,21 +186,21 @@ class modDataPolicies extends DolibarrModules {
'tabfieldvalue'=>array("code,label","code,label","code,label"), // List of fields (list of fields to edit a record)
'tabfieldinsert'=>array("code,label","code,label","code,label"), // List of fields (list of fields for insert)
'tabrowid'=>array("rowid","rowid","rowid"), // Name of columns with primary key (try to always name it 'rowid')
- 'tabcond'=>array($conf->datapolicies->enabled,$conf->datapolicies->enabled,$conf->datapolicies->enabled) // Condition to show each dictionary
+ 'tabcond'=>array($conf->datapolicy->enabled,$conf->datapolicy->enabled,$conf->datapolicy->enabled) // Condition to show each dictionary
);
*/
// Boxes/Widgets
- // Add here list of php file(s) stored in datapolicies/core/boxes that contains class to show a widget.
+ // Add here list of php file(s) stored in datapolicy/core/boxes that contains class to show a widget.
$this->boxes = array();
// Cronjobs (List of cron jobs entries to add when module is enabled)
// unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
$this->cronjobs = array(
- 0 => array('label' => 'DATAPOLICIES Cron', 'jobtype' => 'method', 'class' => '/datapolicies/class/datapoliciesCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'exec', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 1, 'test' => true),
- 1 => array('label' => 'DATAPOLICIES Mailing', 'jobtype' => 'method', 'class' => '/datapolicies/class/datapoliciesCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'sendMailing', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 0, 'test' => true)
+ 0 => array('label' => 'DATAPOLICY Cron', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'exec', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 1, 'test' => true),
+ //1 => array('label' => 'DATAPOLICY Mailing', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'sendMailing', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 0, 'test' => true)
);
// Example: $this->cronjobs=array(0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>true),
// 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>true)
@@ -224,36 +224,34 @@ class modDataPolicies extends DolibarrModules {
{
global $langs;
- $this->_load_tables('/datapolicies/sql/');
+ $this->_load_tables('/datapolicy/sql/');
// Create extrafields
include_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
$extrafields = new ExtraFields($this->db);
-
+ /*
// Extrafield contact
- //$result1=$extrafields->addExtraField('datapolicies_separate', "DATAPOLICIES_BLOCKCHECKBOX", 'separate', 100, 1, 'thirdparty', 0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_consentement', $langs->trans("DATAPOLICIES_consentement"), 'boolean', 101, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_opposition_traitement', $langs->trans("DATAPOLICIES_opposition_traitement"), 'boolean', 102, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_opposition_prospection', $langs->trans("DATAPOLICIES_opposition_prospection"), 'boolean', 103, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_date', $langs->trans("DATAPOLICIES_date"), 'date', 104, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0);
- $result1 = $extrafields->addExtraField('datapolicies_send', $langs->trans("DATAPOLICIES_send"), 'date', 105, 3, 'thirdparty', 0, 0, '', '', 0, '', '0', 0);
+ $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0);
+ $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'thirdparty', 0, 0, '', '', 0, '', '0', 0);
// Extrafield Tiers
- //$result1=$extrafields->addExtraField('datapolicies_separate', "DATAPOLICIES_BLOCKCHECKBOX", 'separate', 100, 1, 'contact', 0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_consentement', $langs->trans("DATAPOLICIES_consentement"), 'boolean', 101, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_opposition_traitement', $langs->trans("DATAPOLICIES_opposition_traitement"), 'boolean', 102, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_opposition_prospection', $langs->trans("DATAPOLICIES_opposition_prospection"), 'boolean', 103, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_date', $langs->trans("DATAPOLICIES_date"), 'date', 104, 3, 'contact', 0, 0, '', '', 1, '', '3', 0);
- $result1 = $extrafields->addExtraField('datapolicies_send', $langs->trans("DATAPOLICIES_send"), 'date', 105, 3, 'contact', 0, 0, '', '', 0, '', '0', 0);
+ $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'contact', 0, 0, '', '', 1, '', '3', 0);
+ $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'contact', 0, 0, '', '', 0, '', '0', 0);
// Extrafield Adherent
- //$result1=$extrafields->addExtraField('datapolicies_separate', "DATAPOLICIES_BLOCKCHECKBOX", 'separate', 100, 1, 'adherent', 0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_consentement', $langs->trans("DATAPOLICIES_consentement"), 'boolean', 101, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_opposition_traitement', $langs->trans("DATAPOLICIES_opposition_traitement"), 'boolean', 102, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_opposition_prospection', $langs->trans("DATAPOLICIES_opposition_prospection"), 'boolean', 103, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
- $result1 = $extrafields->addExtraField('datapolicies_date', $langs->trans("DATAPOLICIES_date"), 'date', 104, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0);
- $result1 = $extrafields->addExtraField('datapolicies_send', $langs->trans("DATAPOLICIES_send"), 'date', 105, 3, 'adherent', 0, 0, '', '', 0, '', '0', 0);
+ $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
+ $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0);
+ $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'adherent', 0, 0, '', '', 0, '', '0', 0);
+ */
$sql = array();
diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php
index e9e33c8bbf3..d4f79f1efcf 100644
--- a/htdocs/core/modules/modStock.class.php
+++ b/htdocs/core/modules/modStock.class.php
@@ -273,7 +273,7 @@ class modStock extends DolibarrModules
'e.rowid'=>'IdWarehouse','e.ref'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip',
'e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",
'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation',
- 'p.tms'=>'DateModification','sm.rowid'=>'MovementId','sm.value'=>'Qty','sm.datem'=>'DateMovement','sm.label'=>'LabelMovement',
+ 'p.tms'=>'DateModification','sm.rowid'=>'MovementId','sm.value'=>'Qty','sm.datem'=>'DateMovement','sm.label'=>'MovementLabel',
'sm.inventorycode'=>'InventoryCode'
);
$this->export_TypeFields_array[$r]=array(
diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
index 40b73e4bf7f..adb52867a36 100644
--- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php
+++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
@@ -1463,27 +1463,30 @@ class pdf_azur extends ModelePDFPropales
$pdf->SetXY($this->marge_gauche,$posy);
// Logo
- $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
- if ($this->emetteur->logo)
+ if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
{
- if (is_readable($logo))
+ $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
+ if ($this->emetteur->logo)
{
- $height=pdf_getHeightForLogo($logo);
- $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ if (is_readable($logo))
+ {
+ $height=pdf_getHeightForLogo($logo);
+ $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ }
+ else
+ {
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B',$default_font_size - 2);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ }
}
else
{
- $pdf->SetTextColor(200,0,0);
- $pdf->SetFont('','B',$default_font_size - 2);
- $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
- $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ $text=$this->emetteur->name;
+ $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
}
}
- else
- {
- $text=$this->emetteur->name;
- $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
- }
$pdf->SetFont('','B',$default_font_size + 3);
$pdf->SetXY($posx,$posy);
diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
new file mode 100644
index 00000000000..e43734039ca
--- /dev/null
+++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
@@ -0,0 +1,1891 @@
+
+ * Copyright (C) 2005-2012 Regis Houssin
+ * Copyright (C) 2008 Raphael Bertrand
+ * Copyright (C) 2010-2015 Juanjo Menent
+ * Copyright (C) 2012 Christophe Battarel
+ * Copyright (C) 2012 Cedric Salvador
+ * Copyright (C) 2015 Marcos García
+ * Copyright (C) 2017 Ferran Marcet
+ * Copyright (C) 2018 Frédéric France
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/modules/propale/doc/pdf_cyan.modules.php
+ * \ingroup propale
+ * \brief Fichier de la classe permettant de generer les propales au modele Cyan
+ */
+require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
+require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
+
+
+/**
+ * Class to generate PDF proposal Cyan
+ */
+class pdf_cyan extends ModelePDFPropales
+{
+ public $db;
+ public $name;
+ public $description;
+ public $update_main_doc_field; // Save the name of generated file as the main doc when generating a doc with this template
+ public $type;
+
+ public $phpmin = array(4,3,0); // Minimum version of PHP required by module
+ public $version = 'development';
+
+ public $page_largeur;
+ public $page_hauteur;
+ public $format;
+ public $marge_gauche;
+ public $marge_droite;
+ public $marge_haute;
+ public $marge_basse;
+
+ public $emetteur; // Objet societe qui emet
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db Database handler
+ */
+ public function __construct($db)
+ {
+ global $conf,$langs,$mysoc;
+
+ // Translations
+ $langs->loadLangs(array("main", "bills"));
+
+ $this->db = $db;
+ $this->name = "cyan";
+ $this->description = $langs->trans('DocModelCyanDescription');
+ $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template
+
+ // Dimension page
+ $this->type = 'pdf';
+ $formatarray=pdf_getFormat();
+ $this->page_largeur = $formatarray['width'];
+ $this->page_hauteur = $formatarray['height'];
+ $this->format = array($this->page_largeur,$this->page_hauteur);
+ $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10;
+ $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10;
+ $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
+ $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
+
+ $this->option_logo = 1; // Affiche logo
+ $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION
+ $this->option_modereg = 1; // Affiche mode reglement
+ $this->option_condreg = 1; // Affiche conditions reglement
+ $this->option_codeproduitservice = 1; // Affiche code produit-service
+ $this->option_multilang = 1; // Dispo en plusieurs langues
+ $this->option_escompte = 0; // Affiche si il y a eu escompte
+ $this->option_credit_note = 0; // Support credit notes
+ $this->option_freetext = 1; // Support add of a personalised text
+ $this->option_draft_watermark = 1; //Support add of a watermark on drafts
+
+ $this->franchise=!$mysoc->tva_assuj;
+
+ // Get source company
+ $this->emetteur=$mysoc;
+ if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined
+
+ // Define position of columns
+ $this->posxdesc=$this->marge_gauche+1;
+
+
+
+ $this->tva=array();
+ $this->localtax1=array();
+ $this->localtax2=array();
+ $this->atleastoneratenotnull=0;
+ $this->atleastonediscount=0;
+ }
+
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
+ /**
+ * Function to build pdf onto disk
+ *
+ * @param Object $object Object to generate
+ * @param Translate $outputlangs Lang output object
+ * @param string $srctemplatepath Full path of source filename for generator using a template file
+ * @param int $hidedetails Do not show line details
+ * @param int $hidedesc Do not show desc
+ * @param int $hideref Do not show ref
+ * @return int 1=OK, 0=KO
+ */
+ public function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
+ {
+ // phpcs:enable
+ global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
+
+ if (! is_object($outputlangs)) $outputlangs=$langs;
+ // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
+ if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
+
+ $outputlangs->load("main");
+ $outputlangs->load("dict");
+ $outputlangs->load("companies");
+ $outputlangs->load("bills");
+ $outputlangs->load("propal");
+ $outputlangs->load("products");
+
+ $nblignes = count($object->lines);
+
+ // Loop on each lines to detect if there is at least one image to show
+ $realpatharray=array();
+ $this->atleastonephoto = false;
+ if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE))
+ {
+ $objphoto = new Product($this->db);
+
+ for ($i = 0 ; $i < $nblignes ; $i++)
+ {
+ if (empty($object->lines[$i]->fk_product)) continue;
+
+ $objphoto->fetch($object->lines[$i]->fk_product);
+ //var_dump($objphoto->ref);exit;
+ if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
+ {
+ $pdir[0] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";
+ $pdir[1] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';
+ }
+ else
+ {
+ $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/'; // default
+ $pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/"; // alternative
+ }
+
+ $arephoto = false;
+ foreach ($pdir as $midir)
+ {
+ if (! $arephoto)
+ {
+ $dir = $conf->product->dir_output.'/'.$midir;
+
+ foreach ($objphoto->liste_photos($dir,1) as $key => $obj)
+ {
+ if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
+ {
+ if ($obj['photo_vignette'])
+ {
+ $filename= $obj['photo_vignette'];
+ }
+ else
+ {
+ $filename=$obj['photo'];
+ }
+ }
+ else
+ {
+ $filename=$obj['photo'];
+ }
+
+ $realpath = $dir.$filename;
+ $arephoto = true;
+ $this->atleastonephoto = true;
+ }
+ }
+ }
+
+ if ($realpath && $arephoto) $realpatharray[$i]=$realpath;
+ }
+ }
+
+ if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
+
+ if ($conf->propal->multidir_output[$conf->entity])
+ {
+ $object->fetch_thirdparty();
+
+ $deja_regle = 0;
+
+ // Definition of $dir and $file
+ if ($object->specimen)
+ {
+ $dir = $conf->propal->multidir_output[$conf->entity];
+ $file = $dir . "/SPECIMEN.pdf";
+ }
+ else
+ {
+ $objectref = dol_sanitizeFileName($object->ref);
+ $dir = $conf->propal->multidir_output[$object->entity] . "/" . $objectref;
+ $file = $dir . "/" . $objectref . ".pdf";
+ }
+
+ if (! file_exists($dir))
+ {
+ if (dol_mkdir($dir) < 0)
+ {
+ $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
+ return 0;
+ }
+ }
+
+ if (file_exists($dir))
+ {
+ // Add pdfgeneration hook
+ if (! is_object($hookmanager))
+ {
+ include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
+ $hookmanager=new HookManager($this->db);
+ }
+ $hookmanager->initHooks(array('pdfgeneration'));
+ $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
+ global $action;
+ $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
+
+ // Create pdf instance
+ $pdf=pdf_getInstance($this->format);
+ $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance
+ $pdf->SetAutoPageBreak(1,0);
+
+ if (class_exists('TCPDF'))
+ {
+ $pdf->setPrintHeader(false);
+ $pdf->setPrintFooter(false);
+ }
+ $pdf->SetFont(pdf_getPDFFont($outputlangs));
+ // Set path to the background PDF File
+ if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
+ {
+ $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
+ $tplidx = $pdf->importPage(1);
+ }
+
+ $pdf->Open();
+ $pagenb=0;
+ $pdf->SetDrawColor(128,128,128);
+
+ $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
+ $pdf->SetSubject($outputlangs->transnoentities("PdfCommercialProposalTitle"));
+ $pdf->SetCreator("Dolibarr ".DOL_VERSION);
+ $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
+ $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
+ if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
+
+ $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right
+
+ // Does we have at least one line with discount $this->atleastonediscount
+ foreach ($object->lines as $line) {
+ if ($line->remise_percent){
+ $this->atleastonediscount = true;
+ break;
+ }
+ }
+
+
+
+ // New page
+ $pdf->AddPage();
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ $pagenb++;
+
+ $heightforinfotot = 40; // Height reserved to output the info and total part
+ $heightforsignature = empty($conf->global->PROPAL_DISABLE_SIGNATURE)?(pdfGetHeightForHtmlContent($pdf, $outputlangs->transnoentities("ProposalCustomerSignature"))+10):0;
+ $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page
+ $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22); // Height reserved to output the footer (value include bottom margin)
+ //print $heightforinfotot + $heightforsignature + $heightforfreetext + $heightforfooter;exit;
+
+ $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->MultiCell(0, 3, ''); // Set interline to 3
+ $pdf->SetTextColor(0,0,0);
+
+
+ $tab_top = 90+$top_shift;
+ $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
+
+
+ // Incoterm
+ $height_incoterms = 0;
+ if ($conf->incoterm->enabled)
+ {
+ $desc_incoterms = $object->getIncotermsForPDF();
+ if ($desc_incoterms)
+ {
+ $tab_top -= 2;
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
+ $nexY = $pdf->GetY();
+ $height_incoterms=$nexY-$tab_top;
+
+ // Rect prend une longueur en 3eme param
+ $pdf->SetDrawColor(192,192,192);
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
+
+ $tab_top = $nexY+6;
+ }
+ }
+
+ // Affiche notes
+ $notetoshow=empty($object->note_public)?'':$object->note_public;
+ if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
+ {
+ // Get first sale rep
+ if (is_object($object->thirdparty))
+ {
+ $salereparray=$object->thirdparty->getSalesRepresentatives($user);
+ $salerepobj=new User($this->db);
+ $salerepobj->fetch($salereparray[0]['id']);
+ if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
+ }
+ }
+ if (! empty($conf->global->MAIN_ADD_CREATOR_IN_NOTE) && $object->user_author_id > 0)
+ {
+ $tmpuser=new User($this->db);
+ $tmpuser->fetch($object->user_author_id);
+ $notetoshow.='Affaire suivi par '.$tmpuser->getFullName($langs);
+ if ($tmpuser->email) $notetoshow.=', Mail: '.$tmpuser->email;
+ if ($tmpuser->office_phone) $notetoshow.=', Tel: '.$tmpuser->office_phone;
+ }
+
+ $pagenb = $pdf->getPage();
+ if ($notetoshow)
+ {
+ $tab_top -= 2;
+
+ $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
+ $pageposbeforenote = $pagenb;
+
+ $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
+ complete_substitutions_array($substitutionarray, $outputlangs, $object);
+ $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
+
+
+ $pdf->startTransaction();
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
+ // Description
+ $pageposafternote=$pdf->getPage();
+ $posyafter = $pdf->GetY();
+
+ if($pageposafternote>$pageposbeforenote )
+ {
+ $pdf->rollbackTransaction(true);
+
+ // prepar pages to receive notes
+ while ($pagenb < $pageposafternote) {
+ $pdf->AddPage();
+ $pagenb++;
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ // $this->_pagefoot($pdf,$object,$outputlangs,1);
+ $pdf->setTopMargin($tab_top_newpage);
+ // The only function to edit the bottom margin of current page to set it.
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ }
+
+ // back to start
+ $pdf->setPage($pageposbeforenote);
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
+ $pageposafternote=$pdf->getPage();
+
+ $posyafter = $pdf->GetY();
+
+ if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20))) // There is no space left for total+free text
+ {
+ $pdf->AddPage('','',true);
+ $pagenb++;
+ $pageposafternote++;
+ $pdf->setPage($pageposafternote);
+ $pdf->setTopMargin($tab_top_newpage);
+ // The only function to edit the bottom margin of current page to set it.
+ $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
+ //$posyafter = $tab_top_newpage;
+ }
+
+
+ // apply note frame to previus pages
+ $i = $pageposbeforenote;
+ while ($i < $pageposafternote) {
+ $pdf->setPage($i);
+
+
+ $pdf->SetDrawColor(128,128,128);
+ // Draw note frame
+ if($i>$pageposbeforenote){
+ $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
+ $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1);
+ }
+ else{
+ $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
+ }
+
+ // Add footer
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+
+ $i++;
+ }
+
+ // apply note frame to last page
+ $pdf->setPage($pageposafternote);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ $height_note=$posyafter-$tab_top_newpage;
+ $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
+
+ }
+ else // No pagebreak
+ {
+ $pdf->commitTransaction();
+ $posyafter = $pdf->GetY();
+ $height_note=$posyafter-$tab_top;
+ $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
+
+
+ if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
+ {
+ // not enough space, need to add page
+ $pdf->AddPage('','',true);
+ $pagenb++;
+ $pageposafternote++;
+ $pdf->setPage($pageposafternote);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+
+ $posyafter = $tab_top_newpage;
+ }
+
+ }
+
+ $tab_height = $tab_height - $height_note;
+ $tab_top = $posyafter +6;
+ }
+ else
+ {
+ $height_note=0;
+ }
+
+ $iniY = $tab_top + 7;
+ $curY = $tab_top + 7;
+ $nexY = $tab_top + 7;
+
+ // Use new auto collum system
+ $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
+
+ // Loop on each lines
+ $pageposbeforeprintlines=$pdf->getPage();
+ $pagenb = $pageposbeforeprintlines;
+ for ($i = 0; $i < $nblignes; $i++)
+ {
+ $curY = $nexY;
+ $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage
+ $pdf->SetTextColor(0,0,0);
+
+ // Define size of image if we need it
+ $imglinesize=array();
+ if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]);
+
+ $pdf->setTopMargin($tab_top_newpage);
+ $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot); // The only function to edit the bottom margin of current page to set it.
+ $pageposbefore=$pdf->getPage();
+
+ $showpricebeforepagebreak=1;
+ $posYAfterImage=0;
+ $posYAfterDescription=0;
+
+ if($this->getColumnStatus('photo'))
+ {
+ // We start with Photo of product line
+ if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur-($heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot))) // If photo too high, we moved completely on new page
+ {
+ $pdf->AddPage('','',true);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ //if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ $pdf->setPage($pageposbefore+1);
+
+ $curY = $tab_top_newpage;
+ $showpricebeforepagebreak=0;
+ }
+
+
+ if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
+ {
+ $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi
+ // $pdf->Image does not increase value return by getY, so we save it manually
+ $posYAfterImage=$curY+$imglinesize['height'];
+ }
+ }
+
+ // Description of product line
+ if($this->getColumnStatus('desc'))
+ {
+ $pdf->startTransaction();
+ pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
+ $pageposafter=$pdf->getPage();
+ if ($pageposafter > $pageposbefore) // There is a pagebreak
+ {
+ $pdf->rollbackTransaction(true);
+ $pageposafter=$pageposbefore;
+ //print $pageposafter.'-'.$pageposbefore;exit;
+ $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it.
+ pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
+
+ $pageposafter=$pdf->getPage();
+ $posyafter=$pdf->GetY();
+ //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
+ if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot))) // There is no space left for total+free text
+ {
+ if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new page
+ {
+ $pdf->AddPage('','',true);
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ //if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ $pdf->setPage($pageposafter+1);
+ }
+ }
+ else
+ {
+ // We found a page break
+ $showpricebeforepagebreak=0;
+ }
+ }
+ else // No pagebreak
+ {
+ $pdf->commitTransaction();
+ }
+ $posYAfterDescription=$pdf->GetY();
+ }
+
+ $nexY = $pdf->GetY();
+ $pageposafter=$pdf->getPage();
+
+ $pdf->setPage($pageposbefore);
+ $pdf->setTopMargin($this->marge_haute);
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+
+ // We suppose that a too long description or photo were moved completely on next page
+ if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
+ $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
+ }
+
+ $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut
+
+ // VAT Rate
+ if ($this->getColumnStatus('vat'))
+ {
+ $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Unit price before discount
+ if ($this->getColumnStatus('subprice'))
+ {
+ $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Quantity
+ // Enough for 6 chars
+ if ($this->getColumnStatus('qty'))
+ {
+ $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+
+ // Unit
+ if ($this->getColumnStatus('unit'))
+ {
+ $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
+ $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Discount on line
+ if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
+ {
+ $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+ // Total HT line
+ if ($this->getColumnStatus('totalexcltax'))
+ {
+ $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
+ $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
+ $nexY = max($pdf->GetY(),$nexY);
+ }
+
+
+ $parameters=array(
+ 'object' => $object,
+ 'i' => $i,
+ 'pdf' =>& $pdf,
+ 'curY' =>& $curY,
+ 'nexY' =>& $nexY,
+ 'outputlangs' => $outputlangs,
+ 'hidedetails' => $hidedetails
+ );
+ $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this); // Note that $object may have been modified by hook
+
+
+
+ // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
+ if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
+ else $tvaligne=$object->lines[$i]->total_tva;
+
+ $localtax1ligne=$object->lines[$i]->total_localtax1;
+ $localtax2ligne=$object->lines[$i]->total_localtax2;
+ $localtax1_rate=$object->lines[$i]->localtax1_tx;
+ $localtax2_rate=$object->lines[$i]->localtax2_tx;
+ $localtax1_type=$object->lines[$i]->localtax1_type;
+ $localtax2_type=$object->lines[$i]->localtax2_type;
+
+ if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
+ if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
+ if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
+
+ $vatrate=(string) $object->lines[$i]->tva_tx;
+
+ // Retrieve type from database for backward compatibility with old records
+ if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
+ && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
+ {
+ $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0,$object->thirdparty,$mysoc);
+ $localtax1_type = $localtaxtmp_array[0];
+ $localtax2_type = $localtaxtmp_array[2];
+ }
+
+ // retrieve global local tax
+ if ($localtax1_type && $localtax1ligne != 0)
+ $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
+ if ($localtax2_type && $localtax2ligne != 0)
+ $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
+
+ if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
+ if (! isset($this->tva[$vatrate])) $this->tva[$vatrate]=0;
+ $this->tva[$vatrate] += $tvaligne;
+
+ if ($posYAfterImage > $posYAfterDescription) $nexY=$posYAfterImage;
+
+ // Add line
+ if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
+ {
+ $pdf->setPage($pageposafter);
+ $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
+ //$pdf->SetDrawColor(190,190,200);
+ $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
+ $pdf->SetLineStyle(array('dash'=>0));
+ }
+
+ $nexY+=2; // Passe espace entre les lignes
+
+ // Detect if some page were added automatically and output _tableau for past pages
+ while ($pagenb < $pageposafter)
+ {
+ $pdf->setPage($pagenb);
+ if ($pagenb == $pageposbeforeprintlines)
+ {
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
+ }
+ else
+ {
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
+ }
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+ $pagenb++;
+ $pdf->setPage($pagenb);
+ $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it.
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ }
+ if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
+ {
+ if ($pagenb == $pageposafter)
+ {
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
+ }
+ else
+ {
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
+ }
+ $this->_pagefoot($pdf,$object,$outputlangs,1);
+ // New page
+ $pdf->AddPage();
+ if (! empty($tplidx)) $pdf->useTemplate($tplidx);
+ $pagenb++;
+ if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
+ }
+ }
+
+ // Show square
+ if ($pagenb == $pageposbeforeprintlines)
+ {
+ $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
+ $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
+ }
+ else
+ {
+ $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
+ $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
+ }
+
+ // Affiche zone infos
+ $posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
+
+ // Affiche zone totaux
+ $posy=$this->drawTotalTable($pdf, $object, 0, $bottomlasttab, $outputlangs);
+
+ // Affiche zone versements
+ /*
+ if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included)
+ {
+ $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
+ }
+ */
+
+ // Customer signature area
+ if (empty($conf->global->PROPAL_DISABLE_SIGNATURE))
+ {
+ $posy=$this->drawSignatureArea($pdf, $object, $posy, $outputlangs);
+ }
+
+ // Pied de page
+ $this->_pagefoot($pdf,$object,$outputlangs);
+ if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages();
+
+ //If propal merge product PDF is active
+ if (!empty($conf->global->PRODUIT_PDF_MERGE_PROPAL))
+ {
+ require_once DOL_DOCUMENT_ROOT.'/product/class/propalmergepdfproduct.class.php';
+
+ $already_merged = array ();
+ foreach ( $object->lines as $line ) {
+ if (! empty($line->fk_product) && ! (in_array($line->fk_product, $already_merged))) {
+ // Find the desire PDF
+ $filetomerge = new Propalmergepdfproduct($this->db);
+
+ if ($conf->global->MAIN_MULTILANGS) {
+ $filetomerge->fetch_by_product($line->fk_product, $outputlangs->defaultlang);
+ } else {
+ $filetomerge->fetch_by_product($line->fk_product);
+ }
+
+ $already_merged[] = $line->fk_product;
+
+ $product = new Product($this->db);
+ $product->fetch($line->fk_product);
+
+ if ($product->entity!=$conf->entity) {
+ $entity_product_file=$product->entity;
+ } else {
+ $entity_product_file=$conf->entity;
+ }
+
+ // If PDF is selected and file is not empty
+ if (count($filetomerge->lines) > 0) {
+ foreach ( $filetomerge->lines as $linefile ) {
+ if (! empty($linefile->id) && ! empty($linefile->file_name)) {
+
+
+ if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
+ {
+ if (! empty($conf->product->enabled)) {
+ $filetomerge_dir = $conf->product->multidir_output[$entity_product_file] . '/' . get_exdir($product->id,2,0,0,$product,'product') . $product->id ."/photos";
+ } elseif (! empty($conf->service->enabled)) {
+ $filetomerge_dir = $conf->service->multidir_output[$entity_product_file] . '/' . get_exdir($product->id,2,0,0,$product,'product') . $product->id ."/photos";
+ }
+ }
+ else
+ {
+ if (! empty($conf->product->enabled)) {
+ $filetomerge_dir = $conf->product->multidir_output[$entity_product_file] . '/' . get_exdir(0,0,0,0,$product,'product') . dol_sanitizeFileName($product->ref);
+ } elseif (! empty($conf->service->enabled)) {
+ $filetomerge_dir = $conf->service->multidir_output[$entity_product_file] . '/' . get_exdir(0,0,0,0,$product,'product') . dol_sanitizeFileName($product->ref);
+ }
+ }
+
+ dol_syslog(get_class($this) . ':: upload_dir=' . $filetomerge_dir, LOG_DEBUG);
+
+ $infile = $filetomerge_dir . '/' . $linefile->file_name;
+ if (file_exists($infile) && is_readable($infile)) {
+ $pagecount = $pdf->setSourceFile($infile);
+ for($i = 1; $i <= $pagecount; $i ++) {
+ $tplIdx = $pdf->importPage($i);
+ if ($tplIdx!==false) {
+ $s = $pdf->getTemplatesize($tplIdx);
+ $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
+ $pdf->useTemplate($tplIdx);
+ } else {
+ setEventMessages(null, array($infile.' cannot be added, probably protected PDF'),'warnings');
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ $pdf->Close();
+
+ $pdf->Output($file,'F');
+
+ //Add pdfgeneration hook
+ $hookmanager->initHooks(array('pdfgeneration'));
+ $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
+
+ if (! empty($conf->global->MAIN_UMASK))
+ @chmod($file, octdec($conf->global->MAIN_UMASK));
+
+ $this->result = array('fullpath'=>$file);
+
+ return 1; // Pas d'erreur
+ }
+ else
+ {
+ $this->error=$langs->trans("ErrorCanNotCreateDir",$dir);
+ return 0;
+ }
+ }
+ else
+ {
+ $this->error=$langs->trans("ErrorConstantNotDefined","PROP_OUTPUTDIR");
+ return 0;
+ }
+ }
+
+ /**
+ * Show payments table
+ *
+ * @param TCPDF $pdf Object PDF
+ * @param Object $object Object proposal
+ * @param int $posy Position y in PDF
+ * @param Translate $outputlangs Object langs for output
+ * @return int <0 if KO, >0 if OK
+ */
+ private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
+ {
+ }
+
+ /**
+ * Show miscellaneous information (payment mode, payment term, ...)
+ *
+ * @param TCPDF $pdf Object PDF
+ * @param Object $object Object to show
+ * @param int $posy Y
+ * @param Translate $outputlangs Langs object
+ * @return void
+ */
+ function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
+ {
+ global $conf;
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // If France, show VAT mention if not applicable
+ if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
+
+ $posy=$pdf->GetY()+4;
+ }
+
+ $posxval=52;
+
+ // Show shipping date
+ if (! empty($object->date_livraison))
+ {
+ $outputlangs->load("sendings");
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
+ $pdf->MultiCell(80, 4, $titre, 0, 'L');
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $dlp=dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true);
+ $pdf->MultiCell(80, 4, $dlp, 0, 'L');
+
+ $posy=$pdf->GetY()+1;
+ }
+ elseif ($object->availability_code || $object->availability) // Show availability conditions
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
+ $pdf->MultiCell(80, 4, $titre, 0, 'L');
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $lib_availability=$outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset($object->availability);
+ $lib_availability=str_replace('\n',"\n",$lib_availability);
+ $pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
+
+ $posy=$pdf->GetY()+1;
+ }
+
+ // Show payments conditions
+ if (empty($conf->global->PROPALE_PDF_HIDE_PAYMENTTERMCOND) && ($object->cond_reglement_code || $object->cond_reglement))
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("PaymentConditions").':';
+ $pdf->MultiCell(43, 4, $titre, 0, 'L');
+
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc);
+ $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement);
+ $pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L');
+
+ $posy=$pdf->GetY()+3;
+ }
+
+ if (empty($conf->global->PROPALE_PDF_HIDE_PAYMENTTERMMODE))
+ {
+ // Check a payment mode is defined
+ /* Not required on a proposal
+ if (empty($object->mode_reglement_code)
+ && ! $conf->global->FACTURE_CHQ_NUMBER
+ && ! $conf->global->FACTURE_RIB_NUMBER)
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->MultiCell(90, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
+ $pdf->SetTextColor(0,0,0);
+
+ $posy=$pdf->GetY()+1;
+ }
+ */
+
+ // Show payment mode
+ if ($object->mode_reglement_code
+ && $object->mode_reglement_code != 'CHQ'
+ && $object->mode_reglement_code != 'VIR')
+ {
+ $pdf->SetFont('','B', $default_font_size - 2);
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $titre = $outputlangs->transnoentities("PaymentMode").':';
+ $pdf->MultiCell(80, 5, $titre, 0, 'L');
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posxval, $posy);
+ $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement);
+ $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L');
+
+ $posy=$pdf->GetY()+2;
+ }
+
+ // Show payment mode CHQ
+ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
+ {
+ // Si mode reglement non force ou si force a CHQ
+ if (! empty($conf->global->FACTURE_CHQ_NUMBER))
+ {
+ $diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE);
+
+ if ($conf->global->FACTURE_CHQ_NUMBER > 0)
+ {
+ $account = new Account($this->db);
+ $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
+
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','B', $default_font_size - $diffsizetitle);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0);
+ $posy=$pdf->GetY()+1;
+
+ if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','', $default_font_size - $diffsizetitle);
+ $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
+ $posy=$pdf->GetY()+2;
+ }
+ }
+ if ($conf->global->FACTURE_CHQ_NUMBER == -1)
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','B', $default_font_size - $diffsizetitle);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0);
+ $posy=$pdf->GetY()+1;
+
+ if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
+ {
+ $pdf->SetXY($this->marge_gauche, $posy);
+ $pdf->SetFont('','', $default_font_size - $diffsizetitle);
+ $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
+ $posy=$pdf->GetY()+2;
+ }
+ }
+ }
+ }
+
+ // If payment mode not forced or forced to VIR, show payment with BAN
+ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
+ {
+ if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER))
+ {
+ $bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account);
+ if (! empty($object->fk_bank)) $bankid=$object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank
+ $account = new Account($this->db);
+ $account->fetch($bankid);
+
+ $curx=$this->marge_gauche;
+ $cury=$posy;
+
+ $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size);
+
+ $posy+=2;
+ }
+ }
+ }
+
+ return $posy;
+ }
+
+
+ /**
+ * Show total to pay
+ *
+ * @param PDF $pdf Object PDF
+ * @param Facture $object Object invoice
+ * @param int $deja_regle Montant deja regle
+ * @param int $posy Position depart
+ * @param Translate $outputlangs Objet langs
+ * @return int Position pour suite
+ */
+ private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
+ {
+ global $conf,$mysoc;
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ $tab2_top = $posy;
+ $tab2_hl = 4;
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // Tableau total
+ $col1x = 120; $col2x = 170;
+ if ($this->page_largeur < 210) // To work with US executive format
+ {
+ $col2x-=20;
+ }
+ $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
+
+ $useborder=0;
+ $index = 0;
+
+ // Total HT
+ $pdf->SetFillColor(255,255,255);
+ $pdf->SetXY($col1x, $tab2_top + 0);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
+
+ $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
+ $pdf->SetXY($col2x, $tab2_top + 0);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1);
+
+ // Show VAT by rates and total
+ $pdf->SetFillColor(248,248,248);
+
+ $total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
+
+ $this->atleastoneratenotnull=0;
+ if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
+ {
+ $tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
+ if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
+ {
+ // Nothing to do
+ }
+ else
+ {
+ //Local tax 1 before VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
+ //{
+ foreach( $this->localtax1 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('1','3','5'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey!=0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ }
+ //}
+ //Local tax 2 before VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
+ //{
+ foreach( $this->localtax2 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('1','3','5'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey!=0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+
+ }
+ }
+ }
+ //}
+ // VAT
+ foreach($this->tva as $tvakey => $tvaval)
+ {
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ $this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' ';
+ $totalvat.=vatrate($tvakey,1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+
+ //Local tax 1 after VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
+ //{
+ foreach( $this->localtax1 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('2','4','6'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
+
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ }
+ //}
+ //Local tax 2 after VAT
+ //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
+ //{
+ foreach( $this->localtax2 as $localtax_type => $localtax_rate )
+ {
+ if (in_array((string) $localtax_type, array('2','4','6'))) continue;
+
+ foreach( $localtax_rate as $tvakey => $tvaval )
+ {
+ // retrieve global local tax
+ if ($tvakey != 0) // On affiche pas taux 0
+ {
+ //$this->atleastoneratenotnull++;
+
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+
+ $tvacompl='';
+ if (preg_match('/\*/',$tvakey))
+ {
+ $tvakey=str_replace('*','',$tvakey);
+ $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
+ }
+ $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
+
+ $totalvat.=vatrate(abs($tvakey),1).$tvacompl;
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
+ }
+ }
+ }
+ //}
+
+ // Total TTC
+ $index++;
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFillColor(224,224,224);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
+ }
+ }
+
+ $pdf->SetTextColor(0,0,0);
+
+ /*
+ $resteapayer = $object->total_ttc - $deja_regle;
+ if (! empty($object->paye)) $resteapayer=0;
+ */
+
+ if ($deja_regle > 0)
+ {
+ $index++;
+
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
+
+ /*
+ if ($object->close_code == 'discount_vat')
+ {
+ $index++;
+ $pdf->SetFillColor(255,255,255);
+
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle, 0, $outputlangs), $useborder, 'R', 1);
+
+ $resteapayer=0;
+ }
+ */
+
+ $index++;
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFillColor(224,224,224);
+ $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
+
+ $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
+ $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
+
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->SetTextColor(0,0,0);
+ }
+
+ $index++;
+ return ($tab2_top + ($tab2_hl * $index));
+ }
+
+ /**
+ * Show table for lines
+ *
+ * @param PDF $pdf Object PDF
+ * @param string $tab_top Top position of table
+ * @param string $tab_height Height of table (rectangle)
+ * @param int $nexY Y (not used)
+ * @param Translate $outputlangs Langs object
+ * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
+ * @param int $hidebottom Hide bottom bar of array
+ * @param string $currency Currency code
+ * @return void
+ */
+ function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
+ {
+ global $conf;
+
+ // Force to disable hidetop and hidebottom
+ $hidebottom=0;
+ if ($hidetop) $hidetop=-1;
+
+ $currency = !empty($currency) ? $currency : $conf->currency;
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ // Amount in (at tab_top - 1)
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+
+ if (empty($hidetop))
+ {
+ $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency));
+ $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
+ $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
+
+ //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
+ if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
+ }
+
+ $pdf->SetDrawColor(128,128,128);
+ $pdf->SetFont('','', $default_font_size - 1);
+
+ // Output Rect
+ $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param
+
+
+ foreach ($this->cols as $colKey => $colDef)
+ {
+ if(!$this->getColumnStatus($colKey)) continue;
+
+ // get title label
+ $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
+
+ // Add column separator
+ if(!empty($colDef['border-left'])){
+ $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
+ }
+
+ if (empty($hidetop))
+ {
+ $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
+
+ $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
+ $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
+ }
+ }
+
+ if (empty($hidetop)){
+ $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line prend une position y en 2eme param et 4eme param
+ }
+ }
+
+ /**
+ * Show top header of page.
+ *
+ * @param PDF $pdf Object PDF
+ * @param Object $object Object to show
+ * @param int $showaddress 0=no, 1=yes
+ * @param Translate $outputlangs Object lang for output
+ * @return void
+ */
+ function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
+ {
+ global $conf,$langs;
+
+ $outputlangs->load("main");
+ $outputlangs->load("bills");
+ $outputlangs->load("propal");
+ $outputlangs->load("companies");
+
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+
+ pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
+
+ // Show Draft Watermark
+ if($object->statut==0 && (! empty($conf->global->PROPALE_DRAFT_WATERMARK)) )
+ {
+ pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->PROPALE_DRAFT_WATERMARK);
+ }
+
+ $pdf->SetTextColor(0,0,60);
+ $pdf->SetFont('','B', $default_font_size + 3);
+
+ $posy=$this->marge_haute;
+ $posx=$this->page_largeur-$this->marge_droite-100;
+
+ $pdf->SetXY($this->marge_gauche,$posy);
+
+ // Logo
+ if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
+ {
+ $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
+ if ($this->emetteur->logo)
+ {
+ if (is_readable($logo))
+ {
+ $height=pdf_getHeightForLogo($logo);
+ $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto)
+ }
+ else
+ {
+ $pdf->SetTextColor(200,0,0);
+ $pdf->SetFont('','B',$default_font_size - 2);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
+ }
+ }
+ else
+ {
+ $text=$this->emetteur->name;
+ $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
+ }
+ }
+
+ $pdf->SetFont('','B',$default_font_size + 3);
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $title=$outputlangs->transnoentities("PdfCommercialProposalTitle");
+ $pdf->MultiCell(100, 4, $title, '', 'R');
+
+ $pdf->SetFont('','B',$default_font_size);
+
+ $posy+=5;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref), '', 'R');
+
+ $posy+=1;
+ $pdf->SetFont('','', $default_font_size - 2);
+
+ if ($object->ref_client)
+ {
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
+ }
+
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Date")." : " . dol_print_date($object->date,"day",false,$outputlangs,true), '', 'R');
+
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DateEndPropal")." : " . dol_print_date($object->fin_validite,"day",false,$outputlangs,true), '', 'R');
+
+ if ($object->thirdparty->code_client)
+ {
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
+ }
+
+ // Get contact
+ if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
+ {
+ $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
+ if (count($arrayidcontact) > 0)
+ {
+ $usertmp=new User($this->db);
+ $usertmp->fetch($arrayidcontact[0]);
+ $posy+=4;
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetTextColor(0,0,60);
+ $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
+ }
+ }
+
+ $posy+=2;
+
+ $top_shift = 0;
+ // Show list of linked objects
+ $current_y = $pdf->getY();
+ $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
+ if ($current_y < $pdf->getY())
+ {
+ $top_shift = $pdf->getY() - $current_y;
+ }
+
+ if ($showaddress)
+ {
+ // Sender properties
+ $carac_emetteur='';
+ // Add internal contact of proposal if defined
+ $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
+ if (count($arrayidcontact) > 0)
+ {
+ $object->fetch_user($arrayidcontact[0]);
+ $labelbeforecontactname=($outputlangs->transnoentities("FromContactName")!='FromContactName'?$outputlangs->transnoentities("FromContactName"):$outputlangs->transnoentities("Name"));
+ $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";
+ }
+
+ $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
+
+ // Show sender
+ $posy=42+$top_shift;
+ $posx=$this->marge_gauche;
+ if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
+ $hautcadre=40;
+
+ // Show sender frame
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posx,$posy-5);
+ $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
+ $pdf->SetXY($posx,$posy);
+ $pdf->SetFillColor(230,230,230);
+ $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
+ $pdf->SetTextColor(0,0,60);
+
+ // Show sender name
+ $pdf->SetXY($posx+2,$posy+3);
+ $pdf->SetFont('','B', $default_font_size);
+ $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
+ $posy=$pdf->getY();
+
+ // Show sender information
+ $pdf->SetXY($posx+2,$posy);
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
+
+
+ // If CUSTOMER contact defined, we use it
+ $usecontact=false;
+ $arrayidcontact=$object->getIdContact('external','CUSTOMER');
+ if (count($arrayidcontact) > 0)
+ {
+ $usecontact=true;
+ $result=$object->fetch_contact($arrayidcontact[0]);
+ }
+
+ //Recipient name
+ // On peut utiliser le nom de la societe du contact
+ if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
+ $thirdparty = $object->contact;
+ } else {
+ $thirdparty = $object->thirdparty;
+ }
+
+ $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs);
+
+ $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target',$object);
+
+ // Show recipient
+ $widthrecbox=100;
+ if ($this->page_largeur < 210) $widthrecbox=84; // To work with US executive format
+ $posy=42+$top_shift;
+ $posx=$this->page_largeur-$this->marge_droite-$widthrecbox;
+ if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
+
+ // Show recipient frame
+ $pdf->SetTextColor(0,0,0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->SetXY($posx+2,$posy-5);
+ $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L');
+ $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
+
+ // Show recipient name
+ $pdf->SetXY($posx+2,$posy+3);
+ $pdf->SetFont('','B', $default_font_size);
+ $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L');
+
+ $posy = $pdf->getY();
+
+ // Show recipient information
+ $pdf->SetFont('','', $default_font_size - 1);
+ $pdf->SetXY($posx+2,$posy);
+ $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
+ }
+
+ $pdf->SetTextColor(0,0,0);
+ return $top_shift;
+ }
+
+ /**
+ * Show footer of page. Need this->emetteur object
+ *
+ * @param PDF $pdf PDF
+ * @param Object $object Object to show
+ * @param Translate $outputlangs Object lang for output
+ * @param int $hidefreetext 1=Hide free text
+ * @return int Return height of bottom margin including footer text
+ */
+ function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
+ {
+ global $conf;
+ $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
+ return pdf_pagefoot($pdf,$outputlangs,'PROPOSAL_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
+ }
+
+ /**
+ * Show area for the customer to sign
+ *
+ * @param PDF $pdf Object PDF
+ * @param Facture $object Object invoice
+ * @param int $posy Position depart
+ * @param Translate $outputlangs Objet langs
+ * @return int Position pour suite
+ */
+ private function drawSignatureArea(&$pdf, $object, $posy, $outputlangs)
+ {
+ global $conf;
+ $default_font_size = pdf_getPDFFontSize($outputlangs);
+ $tab_top = $posy + 4;
+ $tab_hl = 4;
+
+ $posx = 120;
+ $largcol = ($this->page_largeur - $this->marge_droite - $posx);
+ $useborder=0;
+ $index = 0;
+ // Total HT
+ $pdf->SetFillColor(255,255,255);
+ $pdf->SetXY($posx, $tab_top + 0);
+ $pdf->SetFont('','', $default_font_size - 2);
+ $pdf->MultiCell($largcol, $tab_hl, $outputlangs->transnoentities("ProposalCustomerSignature"), 0, 'L', 1);
+
+ $pdf->SetXY($posx, $tab_top + $tab_hl);
+ $pdf->MultiCell($largcol, $tab_hl*3, '', 1, 'R');
+ if (! empty($conf->global->MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING)) {
+ $pdf->addEmptySignatureAppearance($posx, $tab_top + $tab_hl, $largcol, $tab_hl*3);
+ }
+
+ return ($tab_hl*7);
+ }
+
+
+ /**
+ * Define Array Column Field
+ *
+ * @param object $object common object
+ * @param outputlangs $outputlangs langs
+ * @param int $hidedetails Do not show line details
+ * @param int $hidedesc Do not show desc
+ * @param int $hideref Do not show ref
+ * @return null
+ */
+ function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
+ {
+ global $conf, $hookmanager;
+
+ // Default field style for content
+ $this->defaultContentsFieldsStyle = array(
+ 'align' => 'R', // R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ );
+
+ // Default field style for content
+ $this->defaultTitlesFieldsStyle = array(
+ 'align' => 'C', // R,C,L
+ 'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ );
+
+ /*
+ * For exemple
+ $this->cols['theColKey'] = array(
+ 'rank' => $rank, // int : use for ordering columns
+ 'width' => 20, // the column width in mm
+ 'title' => array(
+ 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
+ 'label' => ' ', // the final label : used fore final generated text
+ 'align' => 'L', // text alignement : R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'content' => array(
+ 'align' => 'L', // text alignement : R,C,L
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ );
+ */
+
+ $rank=0; // do not use negative rank
+ $this->cols['desc'] = array(
+ 'rank' => $rank,
+ 'width' => false, // only for desc
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'Designation', // use lang key is usefull in somme case with module
+ 'align' => 'L',
+ // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
+ // 'label' => ' ', // the final label
+ 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'content' => array(
+ 'align' => 'L',
+ ),
+ );
+
+ $rank = $rank + 10;
+ $this->cols['photo'] = array(
+ 'rank' => $rank,
+ 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Photo',
+ 'label' => ' '
+ ),
+ 'content' => array(
+ 'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
+ ),
+ 'border-left' => false, // remove left line separator
+ );
+
+ if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE) && !empty($this->atleastonephoto))
+ {
+ $this->cols['photo']['status'] = true;
+ }
+
+
+ $rank = $rank + 10;
+ $this->cols['vat'] = array(
+ 'rank' => $rank,
+ 'status' => false,
+ 'width' => 16, // in mm
+ 'title' => array(
+ 'textkey' => 'VAT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
+ {
+ $this->cols['vat']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['subprice'] = array(
+ 'rank' => $rank,
+ 'width' => 19, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'PriceUHT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ $rank = $rank + 10;
+ $this->cols['qty'] = array(
+ 'rank' => $rank,
+ 'width' => 16, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'Qty'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+ $rank = $rank + 10;
+ $this->cols['progress'] = array(
+ 'rank' => $rank,
+ 'width' => 19, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Progress'
+ ),
+ 'border-left' => false, // add left line separator
+ );
+
+ if($this->situationinvoice)
+ {
+ $this->cols['progress']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['unit'] = array(
+ 'rank' => $rank,
+ 'width' => 11, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'Unit'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+ if($conf->global->PRODUCT_USE_UNITS){
+ $this->cols['unit']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['discount'] = array(
+ 'rank' => $rank,
+ 'width' => 13, // in mm
+ 'status' => false,
+ 'title' => array(
+ 'textkey' => 'ReductionShort'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+ if ($this->atleastonediscount){
+ $this->cols['discount']['status'] = true;
+ }
+
+ $rank = $rank + 10;
+ $this->cols['totalexcltax'] = array(
+ 'rank' => $rank,
+ 'width' => 26, // in mm
+ 'status' => true,
+ 'title' => array(
+ 'textkey' => 'TotalHT'
+ ),
+ 'border-left' => true, // add left line separator
+ );
+
+
+ $parameters=array(
+ 'object' => $object,
+ 'outputlangs' => $outputlangs,
+ 'hidedetails' => $hidedetails,
+ 'hidedesc' => $hidedesc,
+ 'hideref' => $hideref
+ );
+
+ $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this); // Note that $object may have been modified by hook
+ if ($reshook < 0)
+ {
+ setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
+ }
+ elseif (empty($reshook))
+ {
+ $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
+ }
+ else
+ {
+ $this->cols = $hookmanager->resArray;
+ }
+ }
+}
diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
index 6079006d315..8e6dddeebd5 100644
--- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
+++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
@@ -91,14 +91,18 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
$tooltip.=$langs->trans("GenericMaskCodes5");
// Parametrage du prefix
- $texte.= ''.$langs->trans("Mask");
- //$texte.= ' ('.$langs->trans("InvoiceStandard").')';
+ $texte.= ' '.$langs->trans("Mask").' ('.$langs->trans("InvoiceStandard").')';
$texte.= ': ';
$texte.= ''.$form->textwithpicto('',$tooltip,1,1).' ';
$texte.= ' ';
$texte.= ' ';
+
+ // Parametrage du prefix des avoirs
+ $texte.= ''.$langs->trans("Mask").' ('.$langs->trans("InvoiceAvoir").'): ';
+ $texte.= ''.$form->textwithpicto('',$tooltip,1,1).' ';
+ $texte.= ' ';
if ($conf->global->MAIN_FEATURE_LEVEL >= 2)
{
@@ -107,10 +111,6 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
$texte.= ''.$form->textwithpicto('',$tooltip,1,1).' ';
$texte.= ' ';
- // Parametrage du prefix des avoirs
- $texte.= ''.$langs->trans("Mask").' ('.$langs->trans("InvoiceAvoir").'): ';
- $texte.= ''.$form->textwithpicto('',$tooltip,1,1).' ';
- $texte.= ' ';
// Parametrage du prefix des acomptes
$texte.= ''.$langs->trans("Mask").' ('.$langs->trans("InvoiceDeposit").'): ';
diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php
index 99ae9a699a1..cc361be5e60 100644
--- a/htdocs/core/tpl/contacts.tpl.php
+++ b/htdocs/core/tpl/contacts.tpl.php
@@ -199,12 +199,12 @@ if ($permission) {
if ($tab[$i]['source']=='internal')
{
$userstatic->fetch($tab[$i]['id']);
- echo $userstatic->getNomUrl(-1);
+ echo $userstatic->getNomUrl(-1, '', 0, 0, 0, 0, '', 'valignmiddle');
}
if ($tab[$i]['source']=='external')
{
$contactstatic->fetch($tab[$i]['id']);
- echo $contactstatic->getNomUrl(1);
+ echo $contactstatic->getNomUrl(1, '', 0, 0, 0, 0, '', 'valignmiddle');
}
?>
diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php
index aa7caaa1e87..429fe8ac682 100644
--- a/htdocs/core/tpl/document_actions_post_headers.tpl.php
+++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php
@@ -52,7 +52,7 @@ if (in_array($modulepart, array('product', 'produit', 'societe', 'user', 'ticket
if ($action == 'delete')
{
$langs->load("companies"); // Need for string DeleteFile+ConfirmDeleteFiles
- $ret = $form->form_confirm(
+ print $form->formconfirm(
$_SERVER["PHP_SELF"] . '?id=' . $object->id . '&urlfile=' . urlencode(GETPOST("urlfile")) . '&linkid=' . GETPOST('linkid', 'int') . (empty($param)?'':$param),
$langs->trans('DeleteFile'),
$langs->trans('ConfirmDeleteFile'),
@@ -61,7 +61,6 @@ if ($action == 'delete')
0,
1
);
- if ($ret == 'html') print '
';
}
$formfile=new FormFile($db);
diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
index b506bda0793..6b6d22cf822 100644
--- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
+++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
@@ -23,7 +23,7 @@ if (! empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_
if ($align) print ' align="'.$align.'"';
print '>';
$tmpkey='options_'.$key;
- if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$key], array('date', 'datetime', 'timestamp')))
+ if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$key], array('date', 'datetime', 'timestamp')) && !is_numeric($obj->$tmpkey))
{
$datenotinstring = $obj->$tmpkey;
if (! is_numeric($obj->$tmpkey)) // For backward compatibility
diff --git a/htdocs/core/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php
index 8ca6b6f215a..5ee19aa25a8 100644
--- a/htdocs/core/tpl/filemanager.tpl.php
+++ b/htdocs/core/tpl/filemanager.tpl.php
@@ -28,7 +28,7 @@ if (empty($conf) || ! is_object($conf))
?>
-
+
use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABL
'."\n";
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
$formfile=new FormFile($db);
@@ -168,14 +168,14 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
print '';
- // Show filemanager tree (will be filled by call of ajax /ecm/tpl/enablefiletreeajax.tpl.php that execute ajaxdirtree.php)
+ // Show filemanager tree (will be filled by a call of ajax /ecm/tpl/enablefiletreeajax.tpl.php, later, that executes ajaxdirtree.php)
print '';
if ($action == 'deletefile') print $form->formconfirm('eeeee', $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 'deletefile');
print ' ';
}
- else
+ else // Show filtree when ajax is disabled (rare)
{
print '';
@@ -186,6 +186,9 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
// Show filemanager tree (will be filled by direct include of ajaxdirtree.php in mode noajax, this will return all dir - all levels - to show)
print '';
+ // Variables that may be defined:
+ // $_GET['modulepart'], $_GET['openeddir'], $_GET['sortfield'], $_GET['sortorder']
+ // $_POST['dir']
$mode='noajax';
if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirtree.php';
@@ -211,7 +214,7 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
$mode='noajax';
if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
-include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';
+include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php'; // Show content of a directory on right side
// End right panel
@@ -224,7 +227,15 @@ include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';
use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) {
+if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) // Show filtree when ajax is enabled
+{
+ //var_dump($modulepart);
+ // Variables that may be defined:
+ // $_GET['modulepart'], $_GET['openeddir'], $_GET['sortfield'], $_GET['sortorder']
+ // $_POST['dir']
+ // $_POST['section_dir'], $_POST['section_id'], $_POST['token'], $_POST['max_file_size'], $_POST['sendit']
+ if (GETPOST('section_dir','alpha')) { $preopened=GETPOST('section_dir','alpha'); }
+
include DOL_DOCUMENT_ROOT.'/ecm/tpl/enablefiletreeajax.tpl.php';
}
diff --git a/htdocs/core/tpl/onlinepaymentlinks.tpl.php b/htdocs/core/tpl/onlinepaymentlinks.tpl.php
index a5c5ce7cf11..37639a5f8e6 100644
--- a/htdocs/core/tpl/onlinepaymentlinks.tpl.php
+++ b/htdocs/core/tpl/onlinepaymentlinks.tpl.php
@@ -1,4 +1,4 @@
-<
*
* This program is free software; you can redistribute it and/or modify
diff --git a/htdocs/core/tpl/passwordforgotten.tpl.php b/htdocs/core/tpl/passwordforgotten.tpl.php
index 0e1942c1c64..101c9ec7e67 100644
--- a/htdocs/core/tpl/passwordforgotten.tpl.php
+++ b/htdocs/core/tpl/passwordforgotten.tpl.php
@@ -184,7 +184,7 @@ if (! empty($morelogincontent)) {
-
+';
$out .= '';
$events=array();
-$out .= $formresources->select_resource_list('','fk_resource','',1,1,0,$events,'',2);
+$out .= $formresources->select_resource_list('','fk_resource','',1,1,0,$events,'',2,null);
$out .= '';
$out .= ' '.$form->selectyesno('busy',(isset($_POST['busy'])?$_POST['busy']:1),1).'';
diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
index 26b36964676..f5995c47c84 100644
--- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
+++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
@@ -44,6 +44,7 @@ class InterfaceNotification extends DolibarrTriggers
*/
public $picto = 'email';
+ // @TODO Defined also into notify.class.php)
public $listofmanagedevents=array(
'BILL_VALIDATE',
'BILL_PAYED',
@@ -55,8 +56,12 @@ class InterfaceNotification extends DolibarrTriggers
'ORDER_SUPPLIER_VALIDATE',
'ORDER_SUPPLIER_APPROVE',
'ORDER_SUPPLIER_REFUSE',
- 'SHIPPING_VALIDATE'
- );
+ 'SHIPPING_VALIDATE',
+ 'EXPENSE_REPORT_VALIDATE',
+ 'EXPENSE_REPORT_APPROVE',
+ 'HOLIDAY_VALIDATE',
+ 'HOLIDAY_APPROVE'
+ );
/**
* Function called when a Dolibarrr business event is done.
@@ -112,7 +117,7 @@ class InterfaceNotification extends DolibarrTriggers
$qualified=0;
// Check is this event is supported by notification module
- if (in_array($obj->code,$this->listofmanagedevents)) $qualified=1;
+ if (in_array($obj->code, $this->listofmanagedevents)) $qualified=1;
// Check if module for this event is active
if ($qualified)
{
@@ -125,7 +130,7 @@ class InterfaceNotification extends DolibarrTriggers
elseif ($element == 'withdraw' && empty($conf->prelevement->enabled)) $qualified=0;
elseif ($element == 'shipping' && empty($conf->expedition->enabled)) $qualified=0;
elseif ($element == 'member' && empty($conf->adherent->enabled)) $qualified=0;
- elseif (! in_array($element,array('order_supplier','invoice_supplier','withdraw','shipping','member')) && empty($conf->$element->enabled)) $qualified=0;
+ elseif (! in_array($element,array('order_supplier','invoice_supplier','withdraw','shipping','member','expensereport')) && empty($conf->$element->enabled)) $qualified=0;
}
if ($qualified)
diff --git a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
index 3c86dc805ff..cb03315496a 100644
--- a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
+++ b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
@@ -17,7 +17,7 @@
*/
/**
- * \file htdocs/core/triggers/interface_50_modStripe_Stripe.class.php
+ * \file htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
* \ingroup core
* \brief Fichier
* \remarks Son propre fichier d'actions peut etre cree par recopie de celui-ci:
@@ -147,19 +147,33 @@ class InterfaceStripe
if ($customer)
{
$namecleaned = $object->name ? $object->name : null;
- $vatcleaned = $object->tva_intra ? $object->tva_intra : null; // We force data to "null" if empty as expected by Stripe
+ $vatcleaned = $object->tva_intra ? $object->tva_intra : null;
+
+ $taxinfo = array('type'=>'vat');
+ if ($vatcleaned)
+ {
+ $taxinfo["tax_id"] = $vatcleaned;
+ }
+ // We force data to "null" if not defined as expected by Stripe
+ if (empty($vatcleaned)) $taxinfo=null;
// Detect if we change a Stripe info (email, description, vat id)
$changerequested = 0;
if (! empty($object->email) && $object->email != $customer->email) $changerequested++;
if ($namecleaned != $customer->description) $changerequested++;
- if ($vatcleaned != $customer->business_vat_id) $changerequested++;
+ if (! isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned)) $changerequested++;
+ elseif (isset($customer->tax_info['tax_id']) && is_null($vatcleaned)) $changerequested++;
+ elseif (isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned))
+ {
+ if ($vatcleaned != $customer->tax_info['tax_id']) $changerequested++;
+ }
if ($changerequested)
{
if (! empty($object->email)) $customer->email = $object->email;
$customer->description = $namecleaned;
- $customer->business_vat_id = $vatcleaned;
+ if (empty($taxinfo)) $customer->tax_info = array('type'=>'vat', 'tax_id'=>null);
+ else $customer->tax_info = $taxinfo;
$customer->save();
}
diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php
index ac4d6b35988..1338104de0b 100644
--- a/htdocs/core/website.inc.php
+++ b/htdocs/core/website.inc.php
@@ -19,21 +19,75 @@
/**
* \file htdocs/core/website.inc.php
* \brief Common file loaded by all website pages (after master.inc.php). It set the new object $weblangs, using parameter 'l'.
+ * This file is included in top of all container pages.
* The global variable $websitekey must be defined.
*/
// Load website class
include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
-// Define $website and $weblangs
+// Define $website
if (! is_object($website))
{
$website=new Website($db);
$website->fetch(0,$websitekey);
}
+// Define $weblangs
if (! is_object($weblangs))
{
- $weblangs = dol_clone($langs);
+ $weblangs = dol_clone($langs); // TODO Use an object lang from a language set into $website object instead of backoffice
}
+// Define $websitepage if we have $websitepagefile defined
+if (! $pageid && ! empty($websitepagefile))
+{
+ $pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
+}
+if ($pageid > 0)
+{
+ include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
+ $websitepage=new WebsitePage($db);
+ $websitepage->fetch($pageid);
+}
+
+// A lang was forced, so we change weblangs init
if (GETPOST('l','aZ09')) $weblangs->setDefaultLang(GETPOST('l','aZ09'));
+// A lang was forced, so we check to find if we must make a redirect on translation page
+if ($_SERVER['PHP_SELF'] != DOL_URL_ROOT.'/website/index.php') // If we browsing page using Dolibarr server or a Native web server
+{
+ //print_r(get_defined_constants(true));exit;
+ if (GETPOST('l','aZ09'))
+ {
+ $sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
+ $sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp";
+ $sql.=" WHERE wp.fk_website = ".$website->id;
+ $sql.=" AND (wp.fk_page = ".$pageid." OR wp.rowid = ".$pageid;
+ if (is_object($websitepage) && $websitepage->fk_page > 0) $sql.=" OR wp.fk_page = ".$websitepage->fk_page." OR wp.rowid = ".$websitepage->fk_page;
+ $sql.=")";
+ $sql.= " AND wp.lang = '".$db->escape(GETPOST('l','aZ09'))."'";
+
+ $resql = $db->query($sql);
+ if ($resql)
+ {
+ $obj = $db->fetch_object($resql);
+ if ($obj)
+ {
+ $newpageid = $obj->rowid;
+ if ($newpageid != $pageid) // To avoid to make a redirect on same page (infinite loop)
+ {
+ if (defined('USEDOLIBARRSERVER')) {
+ header("Location: ".DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$newpageid.'&l='.GETPOST('l','aZ09'));
+ exit;
+ }
+ else
+ {
+ $newpageref = $obj->pageurl;
+ header("Location: ".$newpageref.'.php?l='.GETPOST('l','aZ09'));
+ exit;
+ }
+ }
+ }
+ }
+ }
+}
+
// Load websitepage class
include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php
index a0db4a1f572..a71088f3286 100644
--- a/htdocs/cron/class/cronjob.class.php
+++ b/htdocs/cron/class/cronjob.class.php
@@ -76,10 +76,24 @@ class Cronjob extends CommonObject
public $lastoutput;
public $unitfrequency;
public $frequency;
+
+ /**
+ * @var int Status
+ */
public $status;
+
public $processing;
+
+ /**
+ * @var int ID
+ */
public $fk_user_author;
+
+ /**
+ * @var int ID
+ */
public $fk_user_mod;
+
public $nbrun;
public $libname;
public $test; // A test condition to know if job is visible/qualified
@@ -1379,9 +1393,22 @@ class Cronjobline
public $lastoutput;
public $unitfrequency;
public $frequency;
+
+ /**
+ * @var int Status
+ */
public $status;
+
+ /**
+ * @var int ID
+ */
public $fk_user_author;
+
+ /**
+ * @var int ID
+ */
public $fk_user_mod;
+
public $note;
public $nbrun;
public $libname;
diff --git a/htdocs/datapolicies/langs/en_US/datapolicies.lang b/htdocs/datapolicies/langs/en_US/datapolicies.lang
deleted file mode 100644
index 164581bcca5..00000000000
--- a/htdocs/datapolicies/langs/en_US/datapolicies.lang
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (C) 2018 Nicolas ZABOURI
-#
-# 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 .
-
-# Module label 'ModulergpdName'
-ModulergpdName = GDPR
-# Module description 'ModulergpdDesc'
-ModulergpdDesc = Conformity with the GDPR
-
-#
-# Page d'administration
-#
-rgpdSetup = Module Setup
-Settings_DATAPOLICIES = Settings of DATAPOLICIES module
-rgpdSetupPage = According to Article 5 of the GDPR, personal data must be kept for a period not exceeding that necessary for the purposes for which they were processed, except for archival purposes.
-The deletion will be done automatically after a certain duration without event (the duration which you will have indicated below).
-NB_MONTHS = %s months
-ONE_YEAR = 1 year
-NB_YEARS = %s years
-DATAPOLICIES_TIERS_CLIENT = Customer
-DATAPOLICIES_TIERS_PROSPECT = Prospect
-DATAPOLICIES_TIERS_PROSPECT_CLIENT = Prospect/Customer
-DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
-DATAPOLICIES_TIERS_FOURNISSEUR = Supplier
-DATAPOLICIES_CONTACT_CLIENT = Customer
-DATAPOLICIES_CONTACT_PROSPECT = Prospect
-DATAPOLICIES_CONTACT_PROSPECT_CLIENT = Prospect/Customer
-DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
-DATAPOLICIES_CONTACT_FOURNISSEUR = Supplier
-DATAPOLICIES_ADHERENT = Member
-DATAPOLICIES_Tooltip_SETUP = Type of contact - Indicate your choices for each type.
-DATAPOLICIESMail=Emails Setup
-DATAPOLICIESSUBJECTMAIL=Subject of email
-DATAPOLICIESCONTENTMAIL=Content of the email
-DATAPOLICIESSUBSITUTION=You can use the following variables in your email (LINKACCEPT allows to create a link recording the agreement of the person, LINKREFUSED makes it possible to record the refusal of the person):
-DATAPOLICIESACCEPT=Message after agreement
-DATAPOLICIESREFUSE=Message after desagreement
-SendAgreementText=You can send a GDPR email to all your relevant contacts (who have not yet received an email and for which you have not registered anything about their GDPR agreement). To do this, use the following button.
-SendAgreement=Send emails
-AllAgreementSend = All emails have been sent
-TXTLINKDATAPOLICIESACCEPT= Text for the link "agreement"
-TXTLINKDATAPOLICIESREFUSE= Text for the link "desagreement"
-
-
-#
-# Extrafield
-#
-DATAPOLICIES_BLOCKCHECKBOX = GDPR : Processing of personal data
-DATAPOLICIES_consentement = Consent obtained for the processing of personal data
-DATAPOLICIES_opposition_traitement = Opposes the processing of his personal data
-DATAPOLICIES_opposition_prospection = Opposes the processing of his personal data for the purposes of prospecting
-
-#
-# Popup
-#
-DATAPOLICIES_POPUP_ANONYME_TITLE = Anonymize a thirdparty
-DATAPOLICIES_POPUP_ANONYME_TEXTE = You can not delete this contact from Dolibarr because there are related items. In accordance with the GDPR, you will make all this data anonymous to respect your obligations. Would you like to continue ?
-
-#
-# Bouton portabilité
-#
-DATAPOLICIES_PORTABILITE = Portability GDPR
-DATAPOLICIES_PORTABILITE_TITLE = Export of personal data
-DATAPOLICIES_PORTABILITE_CONFIRMATION = You want to export the personal data of this contact. Are you sure ?
-
-#
-# Note ajoutés lors d'une anonymisation
-#
-ANONYMISER_AT = Anonymised the %s
-
-#V2
-DATAPOLICIESReturn=GDPR Validation
-DATAPOLICIES_date = Date of agreement/desagreement GDPR
-DATAPOLICIES_send = Date sending agreement email
-DATAPOLICIESReturn = GDPR Return
-DATAPOLICIES_SEND = Send GDPR email
-MailSent = Email has been sent
-
-#ERROR
-ErrorSubjectIsRequired= Error : The subject of email is required. Indicate it in the module setup
-=Due to a technical problem, we were unable to register your choice. We apologize for that. Contact us to send us your choice.
-NUMBER_MONTH_BEFORE_DELETION = Number of month before deletion
diff --git a/htdocs/datapolicies/langs/fr_FR/datapolicies.lang b/htdocs/datapolicies/langs/fr_FR/datapolicies.lang
deleted file mode 100644
index 916cdffb776..00000000000
--- a/htdocs/datapolicies/langs/fr_FR/datapolicies.lang
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2018 INOVEA CONSEil info@inovea-conseil.com
-#
-# 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 .
-
-#
-# Générique
-#
-
-# Module label 'ModulergpdName'
-ModulergpdName = DATAPOLICIES
-# Module description 'ModulergpdDesc'
-Module432452Desc = Module de mise en conformité avec le DATAPOLICIES
-
-#
-# Page d'administration
-#
-rgpdSetup = Configuration du module DATAPOLICIES
-Settings_DATAPOLICIES = Paramétrage du module DATAPOLICIES
-rgpdSetupPage = Selon l’article 5 du DATAPOLICIES, les données à caractère personnel doivent être conservées pendant une durée n’excédant pas celle nécessaire au regard des finalités pour lesquelles elles ont été traitées, à l’exception de fins archivistiques. La suppression se fera automatiquement après une certaine durée sans évènement (la durée que vous aurez indiquée ci-dessous).
-NB_MONTHS = %s mois
-ONE_YEAR = 1 an
-NB_YEARS = %s ans
-DATAPOLICIES_TIERS_CLIENT = Client
-DATAPOLICIES_TIERS_PROSPECT = Prospect
-DATAPOLICIES_TIERS_PROSPECT_CLIENT = Prospect/Client
-DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT = Ni prospect / Ni client
-DATAPOLICIES_TIERS_FOURNISSEUR = Fournisseur
-DATAPOLICIES_CONTACT_CLIENT = Client
-DATAPOLICIES_CONTACT_PROSPECT = Prospect
-DATAPOLICIES_CONTACT_PROSPECT_CLIENT = Prospect/Client
-DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT = Ni prospect / Ni client
-DATAPOLICIES_CONTACT_FOURNISSEUR = Fournisseur
-DATAPOLICIES_ADHERENT = Adhérent
-DATAPOLICIES_Tooltip_SETUP = Type du contact - Indiquez vos choix pour chaque type.
-DATAPOLICIESMail=Paramétrage des emails
-DATAPOLICIESSUBJECTMAIL=Objet du mail
-DATAPOLICIESCONTENTMAIL=Contenu du mail
-DATAPOLICIESSUBSITUTION=Vous pouvez utiliser les variables suivantes dans votre email (LINKACCEPT permet de créer un lien enregistrant l'acceptation de la personne, LINKREFUSED permet d'enregistrer le refus de la personne) :
-DATAPOLICIESACCEPT=Message suite acceptation
-DATAPOLICIESREFUSE=Message suite opposition
-SendAgreementText=Vous pouvez envoyer un email DATAPOLICIES à tous vos contacts concernés (qui n'ont pas encore reçus de mail et pour lesquels vous n'avez rien enregistré concernant leur accord/désaccord DATAPOLICIES). Pour cela, utilisez le bouton suivant.
-SendAgreement=Envoyer les emails
-AllAgreementSend = Tous les e-mails de consentement ont été envoyés
-TXTLINKDATAPOLICIESACCEPT= Texte du lien d'acceptation
-TXTLINKDATAPOLICIESREFUSE= Texte du lien d'opposition
-
-
-
-#
-# Extrafield
-#
-DATAPOLICIES_BLOCKCHECKBOX = DATAPOLICIES : Traitement des données à caractère personnel
-DATAPOLICIES_consentement = Consentement recueilli pour le traitement des données à caractère personnel le concernant
-DATAPOLICIES_opposition_traitement = S’oppose au traitement de ses données à caractère personnel
-DATAPOLICIES_opposition_prospection = S’oppose au traitement de ses données à caractère personnel à des fins de prospection
-
-#
-# Popup
-#
-DATAPOLICIES_POPUP_ANONYME_TITLE = Anonymiser un tiers
-DATAPOLICIES_POPUP_ANONYME_TEXTE = Vous ne pouvez pas supprimer ce contact de Dolibarr car des éléments y sont liés. Conformément au DATAPOLICIES, vous allez rendre toutes ces données anonymes afin de respecter vos obligations. Souhaitez-vous continuer ?
-
-#
-# Bouton portabilité
-#
-DATAPOLICIES_PORTABILITE = Portabilité DATAPOLICIES
-DATAPOLICIES_PORTABILITE_TITLE = Export des données à caractère personnel
-DATAPOLICIES_PORTABILITE_CONFIRMATION = Vous souhaitez exporter les données à caractère personnel de ce contact. Etes-vous sûr ?
-
-#
-# Note ajoutés lors d'une anonymisation
-#
-ANONYMISER_AT = Anonymisé le %s
-
-#V2
-DATAPOLICIESReturn=Validation DATAPOLICIES
-DATAPOLICIES_date=Date d'accord/opposition au traitement
-DATAPOLICIES_send=Date envoi consentement
-DATAPOLICIESReturn=Retour DATAPOLICIES
-DATAPOLICIES_SEND=Envoyer l'email de consentement
-MailSent=L'email a bien été envoyé
-
-#ERROR
-ErrorSubjectIsRequired=Erreur : vous n'avez pas indiqué l'objet de l'email dans la configuration
-=Suite à un problème technique, nous n'avons pas pu enregistrer votre choix. Nous nous en excusons. Contactez-nous pour nous transmettre votre choix.
-NUMBER_MONTH_BEFORE_DELETION = Nombre de mois avant suppression des données
diff --git a/htdocs/datapolicies/langs/it_IT/datapolicies.lang b/htdocs/datapolicies/langs/it_IT/datapolicies.lang
deleted file mode 100644
index a979c931c41..00000000000
--- a/htdocs/datapolicies/langs/it_IT/datapolicies.lang
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2018 INOVEA CONSEIl info@inovea-conseil.com - Thanks to Claudio Aschieri
-#
-# # Module label 'ModulergpdName'
-ModulergpdName = GDPR
-# Module description 'ModulergpdDesc'
-ModulergpdDesc = Conformità con GDPR
-Module432452Name=GDPR
-Module432452Desc=Conformità con GDPR (Regolamento Generale sulla protezione di dati)
-
-#
-# Page d'administration
-#
-rgpdSetup = Module Setup
-Settings_DATAPOLICIES = Configurazione modulo GDPR
-rgpdSetupPage = In accordo con l'art 5 del GDPR i dati personali devono essere conservati per un periodo di tempo che .... ed eliminati se non sono più utili agli scopi per cui sono stati processati.
-NB_MONTHS = %s mesi
-ONE_YEAR = 1 anno
-NB_YEARS = %s anni
-DATAPOLICIES_TIERS_CLIENT = Cliente
-DATAPOLICIES_TIERS_PROSPECT = Fornitore
-DATAPOLICIES_TIERS_PROSPECT_CLIENT = Potenziale Cliente / Cliente
-DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT = Nè potenziale cliente / Nè cliente
-DATAPOLICIES_TIERS_FOURNISSEUR = Fornitore
-DATAPOLICIES_CONTACT_CLIENT = Cliente
-DATAPOLICIES_CONTACT_PROSPECT = Potenziale cliente
-DATAPOLICIES_CONTACT_PROSPECT_CLIENT = Potenziale Cliente / Cliente
-DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT = Nè potenziale cliente / Nè cliente
-DATAPOLICIES_CONTACT_FOURNISSEUR = Fornitore
-DATAPOLICIES_ADHERENT = Membri
-DATAPOLICIES_Tooltip_SETUP = Tipo di contatto - Indica la scelta per ogni tipologia
-DATAPOLICIESMail=Configurazione Email
-DATAPOLICIESSUBJECTMAIL=Subject dell'e-mail
-DATAPOLICIESCONTENTMAIL=Contenuto dell'e-mail
-DATAPOLICIESSUBSITUTION=Puoi utilizzare le seguenti variabili nella tua email (LINKACCEPT consente di creare un link per registrare l'accettazione della persona, LINKREFUSED consente di registrare il rifiuto della persona):
-DATAPOLICIESACCEPT= Messaggio dopo il consenso
-DATAPOLICIESREFUSE=Messaggio dopo il rifiuto
-SendAgreementText=Puoi inviare un'email GDPR a tutti i tuoi contatti rilevanti (che non hanno ancora ricevuto un'e-mail e per i quali non hai registrato nulla sul loro accordo GDPR). Per fare ciò, utilizzare il seguente pulsante.
-SendAgreement=Invia emails
-AllAgreementSend = Tutte le email sono state inviate
-TXTLINKDATAPOLICIESACCEPT= Testo per il link "Consenso"
-TXTLINKDATAPOLICIESREFUSE= Testo per il link "Consenso negato"
-
-#
-# Extrafield
-#
-DATAPOLICIES_BLOCKCHECKBOX = GDPR : Trattamento dei dati personali
-DATAPOLICIES_consentement = Consenso ottenuto al Trattamento dei dati personali
-DATAPOLICIES_opposition_traitement = Consenso negato al trattamento dei dati personali
-DATAPOLICIES_opposition_prospection = Consenso negato al trattamento dei dati personali a fini commerciali
-
-#
-# Popup
-#
-DATAPOLICIES_POPUP_ANONYME_TITLE = Anonimizza un soggetto terzo
-DATAPOLICIES_POPUP_ANONYME_TEXTE = Impossibile eliminare questo contatto da Dolibarr perchè vi sono elementi collegati. In conformità con il GDPR, renderai tutti questi dati anonimi per rispettare i tuoi obblighi. Vuoi continuare?
-
-
-#
-# Bouton portabilité
-#
-DATAPOLICIES_PORTABILITE = Portabilità GDPR
-DATAPOLICIES_PORTABILITE_TITLE = Esporta i dati personali
-DATAPOLICIES_PORTABILITE_CONFIRMATION = Vuoi davvero esportare i dati personali di questo contatto?
-
-#
-# Note ajoutée lors d'une anonymisation
-#
-ANONYMISER_AT = Anonimizzato il %s
-
-#V2
-DATAPOLICIESReturn=GDPR Validazione
-DATAPOLICIES_date = Data di accordo / disaccordo GDPR
-DATAPOLICIES_send = Data di invio del consenso (e-mail)
-DATAPOLICIESReturn = GDPR ritorno
-DATAPOLICIES_SEND = Inviare GDPR e-mail
-MailSent=L'email è stata inviata
-
-#ERROR
-ErrorSubjectIsRequired= Errore: L'oggetto della mail è obbligatorio. Inserisci l'oggetto nella configurazione del modulo.
-=A causa di un problema tecnico, non siamo stati in grado di registrare la tua scelta. Ci scusiamo per questo. Contattaci per inviarci la tua scelta.
diff --git a/htdocs/datapolicies/ChangeLog.md b/htdocs/datapolicy/ChangeLog.md
similarity index 100%
rename from htdocs/datapolicies/ChangeLog.md
rename to htdocs/datapolicy/ChangeLog.md
diff --git a/htdocs/datapolicies/admin/setup.php b/htdocs/datapolicy/admin/setup.php
similarity index 71%
rename from htdocs/datapolicies/admin/setup.php
rename to htdocs/datapolicy/admin/setup.php
index f6edd5b3e90..777fa6cb893 100644
--- a/htdocs/datapolicies/admin/setup.php
+++ b/htdocs/datapolicy/admin/setup.php
@@ -17,21 +17,21 @@
*/
/**
- * \file datapolicies/admin/setup.php
- * \ingroup datapolicies
- * \brief datapolicies setup page.
+ * \file datapolicy/admin/setup.php
+ * \ingroup datapolicy
+ * \brief datapolicy setup page.
*/
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
-require_once '../lib/datapolicies.lib.php';
+require_once '../lib/datapolicy.lib.php';
//require_once "../class/myclass.class.php";
// Translations
$langs->load('admin');
$langs->load('companies');
$langs->load('members');
-$langs->load('datapolicies@datapolicies');
+$langs->load('datapolicy@datapolicy');
// Access control
if (! $user->admin) accessforbidden();
@@ -41,17 +41,17 @@ $action = GETPOST('action', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
$arrayofparameters=array(
- 'DATAPOLICIES_TIERS_CLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_ADHERENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_CLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_ADHERENT'=>array('css'=>'minwidth200'),
);
@@ -81,26 +81,26 @@ if (DOL_VERSION < '7' && $action == 'update') {
$arrayofparameters=array(
'ThirdParty' => array(
- 'DATAPOLICIES_TIERS_CLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_CLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
),
'Contact' => array(
- 'DATAPOLICIES_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
- 'DATAPOLICIES_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
),
'Member' => array(
- 'DATAPOLICIES_ADHERENT'=>array('css'=>'minwidth200'),
+ 'DATAPOLICY_ADHERENT'=>array('css'=>'minwidth200'),
)
);
$valTab = array(
- '' => $langs->trans('None'),
+ '' => $langs->trans('Never'),
'6' => $langs->trans('NB_MONTHS', 6),
'12' => $langs->trans('ONE_YEAR'),
'24' => $langs->trans('NB_YEARS', 2),
@@ -108,6 +108,8 @@ $valTab = array(
'48' => $langs->trans('NB_YEARS', 4),
'60' => $langs->trans('NB_YEARS', 5),
'120' => $langs->trans('NB_YEARS', 10),
+ '180' => $langs->trans('NB_YEARS', 15),
+ '240' => $langs->trans('NB_YEARS', 20),
);
@@ -115,20 +117,20 @@ $valTab = array(
* View
*/
-$page_name = "datapoliciesSetup";
+$page_name = "datapolicySetup";
llxHeader('', $langs->trans($page_name));
// Subheader
$linkback = ''.$langs->trans("BackToModuleList").'';
-print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicies@datapolicies');
+print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicy@datapolicy');
// Configuration header
-$head = datapoliciesAdminPrepareHead();
-dol_fiche_head($head, 'settings', '', -1, "datapolicies@datapolicies");
+$head = datapolicyAdminPrepareHead();
+dol_fiche_head($head, 'settings', '', -1, "datapolicy@datapolicy");
// Setup page goes here
-echo $langs->trans("datapoliciesSetupPage");
+echo ''.$langs->trans("datapolicySetupPage").'
';
if ($action == 'edit')
@@ -180,7 +182,7 @@ else
foreach($tab as $key => $val)
{
print '';
- print $form->textwithpicto($langs->trans($key),$langs->trans('DATAPOLICIES_Tooltip_SETUP'));
+ print $form->textwithpicto($langs->trans($key),$langs->trans('DATAPOLICY_Tooltip_SETUP'));
print ' ' . ($conf->global->$key == '' ? $langs->trans('None') : $valTab[$conf->global->$key]) . ' ';
}
diff --git a/htdocs/datapolicies/admin/setupmail.php b/htdocs/datapolicy/admin/setupmail.php
similarity index 94%
rename from htdocs/datapolicies/admin/setupmail.php
rename to htdocs/datapolicy/admin/setupmail.php
index a6560c1f7d5..214f673a15f 100644
--- a/htdocs/datapolicies/admin/setupmail.php
+++ b/htdocs/datapolicy/admin/setupmail.php
@@ -22,10 +22,10 @@ require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formadmin.class.php';
-require_once '../lib/datapolicies.lib.php';
+require_once '../lib/datapolicy.lib.php';
// Translations
-$langs->loadLangs(array('admin', 'companies', 'members', 'datapolicies'));
+$langs->loadLangs(array('admin', 'companies', 'members', 'datapolicy'));
// Parameters
@@ -78,17 +78,17 @@ if ($action == 'setvalue' && $user->admin) {
* View
*/
-$page_name = "datapoliciesSetup";
+$page_name = "datapolicySetup";
llxHeader('', $langs->trans($page_name));
// Subheader
$linkback = '' . $langs->trans("BackToModuleList") . '';
-print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicies@datapolicies');
+print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicy@datapolicy');
// Configuration header
-$head = datapoliciesAdminPrepareHead();
-dol_fiche_head($head, 'settings', '', -1, "datapolicies@datapolicies");
+$head = datapolicyAdminPrepareHead();
+dol_fiche_head($head, 'settings', '', -1, "datapolicy@datapolicy");
@@ -161,7 +161,7 @@ dol_fiche_end();
print '
';
print $langs->trans('SendAgreementText');
-print ''.$langs->trans('SendAgreement').'';
+print ''.$langs->trans('SendAgreement').'';
llxFooter();
$db->close();
diff --git a/htdocs/datapolicies/class/actions_datapolicies.class.php b/htdocs/datapolicy/class/actions_datapolicy.class.php
similarity index 72%
rename from htdocs/datapolicies/class/actions_datapolicies.class.php
rename to htdocs/datapolicy/class/actions_datapolicy.class.php
index d65de390b8c..21fcb4a5a44 100644
--- a/htdocs/datapolicies/class/actions_datapolicies.class.php
+++ b/htdocs/datapolicy/class/actions_datapolicy.class.php
@@ -17,15 +17,15 @@
*/
/**
- * \file datapolicies/class/actions_datapolicies.class.php
- * \ingroup datapolicies
+ * \file datapolicy/class/actions_datapolicy.class.php
+ * \ingroup datapolicy
* \brief Example hook overload.
*/
/**
- * Class ActionsDatapolicies
+ * Class ActionsDatapolicy
*/
-class ActionsDatapolicies
+class ActionsDatapolicy
{
/**
* @var DoliDB Database handler.
@@ -91,7 +91,7 @@ class ActionsDatapolicies
public function doActions($parameters, &$object, &$action, $hookmanager)
{
global $conf, $user, $langs;
- $langs->load('datapolicies@datapolicies');
+ $langs->load('datapolicy@datapolicy');
$error = 0; // Error counter
if (GETPOST('socid') && $parameters['currentcontext'] == 'thirdpartycard') {
@@ -129,9 +129,9 @@ class ActionsDatapolicies
header('Location:' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id);
}
}
- } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'datapolicies_portabilite') {
+ } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'datapolicy_portabilite') {
header('Content-Type: application/csv');
- header('Content-Disposition: attachment; filename=datapolicies_portabilite.csv');
+ header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
header('Pragma: no-cache');
$object->fetch(GETPOST('socid'));
echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;' . PHP_EOL;
@@ -152,9 +152,9 @@ class ActionsDatapolicies
echo $object->skype . ';';
echo ';';
exit;
- } elseif ($parameters['currentcontext'] == 'membercard' && $action == 'datapolicies_portabilite') {
+ } elseif ($parameters['currentcontext'] == 'membercard' && $action == 'datapolicy_portabilite') {
header('Content-Type: application/csv');
- header('Content-Disposition: attachment; filename=datapolicies_portabilite.csv');
+ header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
header('Pragma: no-cache');
$soc = $object->fetch_thirdparty();
@@ -176,10 +176,10 @@ class ActionsDatapolicies
echo $object->skype . ';';
echo dol_print_date($object->birth) . ';';
exit;
- } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'datapolicies_portabilite') {
+ } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'datapolicy_portabilite') {
$object->fetch(GETPOST('id'));
header('Content-Type: application/csv');
- header('Content-Disposition: attachment; filename=datapolicies_portabilite.csv');
+ header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
header('Pragma: no-cache');
$soc = $object->fetch_thirdparty();
echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;' . PHP_EOL;
@@ -200,23 +200,23 @@ class ActionsDatapolicies
echo $object->jabberid . ';';
echo dol_print_date($object->birth) . ';';
exit;
- } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'send_datapolicies') {
+ } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'send_datapolicy') {
$object->fetch(GETPOST('id'));
require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
- require_once DOL_DOCUMENT_ROOT . '/datapolicies/class/datapolicies.class.php';
- DataPolicies::sendMailDataPoliciesContact($object);
+ require_once DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
+ DataPolicy::sendMailDataPolicyContact($object);
}
- elseif ($parameters['currentcontext'] == 'membercard' && $action == 'send_datapolicies') {
+ elseif ($parameters['currentcontext'] == 'membercard' && $action == 'send_datapolicy') {
$object->fetch(GETPOST('id'));
require_once DOL_DOCUMENT_ROOT . '/adherents/class/adherent.class.php';
- require_once DOL_DOCUMENT_ROOT . '/datapolicies/class/datapolicies.class.php';
- DataPolicies::sendMailDataPoliciesAdherent($object);
- } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'send_datapolicies') {
+ require_once DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
+ DataPolicy::sendMailDataPolicyAdherent($object);
+ } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'send_datapolicy') {
$object->fetch(GETPOST('socid'));
require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
- require_once DOL_DOCUMENT_ROOT . '/datapolicies/class/datapolicies.class.php';
- DataPolicies::sendMailDataPoliciesCompany($object);
+ require_once DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
+ DataPolicy::sendMailDataPolicyCompany($object);
}
@@ -280,7 +280,7 @@ class ActionsDatapolicies
/* 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 = '';
+ $this->resprints = '';
}
if (!$error) {
@@ -361,47 +361,50 @@ class ActionsDatapolicies
function addMoreActionsButtons($parameters, &$object, &$action, $hookmanager)
{
global $conf, $user, $langs;
- $langs->load('datapolicies@datapolicies');
+ $langs->load('datapolicy@datapolicy');
- $dialog = '";
- $dialog .= '';
- echo $dialog;
- if ($parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
- echo '';
- } elseif ($parameters['currentcontext'] == 'membercard') {
- echo '';
- } elseif ($parameters['currentcontext'] == 'contactcard') {
- echo '';
- }
- if (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
- echo '';
- } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'membercard') {
- echo '';
- } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'contactcard') {
- echo '';
+ return false;
+ });
+ } );
+ ';
+ echo $dialog;
+ if ($parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
+ echo '';
+ } elseif ($parameters['currentcontext'] == 'membercard') {
+ echo '';
+ } elseif ($parameters['currentcontext'] == 'contactcard') {
+ echo '';
+ }
+ if (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
+ echo '';
+ } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'membercard') {
+ echo '';
+ } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'contactcard') {
+ echo '';
+ }
}
}
@@ -422,11 +425,14 @@ class ActionsDatapolicies
if ($parameters['currentcontext'] == 'thirdpartycard') {
if (GETPOST('action') == 'create' || GETPOST('action') == 'edit' || GETPOST('action') == '') {
$jsscript .= '';
@@ -454,7 +460,7 @@ class ActionsDatapolicies
require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
$jsscript .= '';
}
@@ -462,8 +468,8 @@ class ActionsDatapolicies
} elseif ($parameters['currentcontext'] == 'contactcard') {
if (GETPOST('action') == 'create' || GETPOST('action') == 'edit') {
$jsscript .= ''."\n";
+ init_customer_categ();
+ $("#customerprospect").change(function() {
+ init_customer_categ();
+ });
+ function init_customer_categ() {
+ console.log("is customer or prospect = "+jQuery("#customerprospect").val());
+ if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() == 0 || '.(empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER)?'1':'0').'))
+ {
+ jQuery(".visibleifcustomer").hide();
+ }
+ else
+ {
+ jQuery(".visibleifcustomer").show();
+ }
+ }
+ init_supplier_categ();
+ $("#fournisseur").change(function() {
+ init_supplier_categ();
+ });
+ function init_supplier_categ() {
+ console.log("is supplier = "+jQuery("#fournisseur").val());
+ if (jQuery("#fournisseur").val() == 0)
+ {
+ jQuery(".visibleifsupplier").hide();
+ }
+ else
+ {
+ jQuery(".visibleifsupplier").show();
+ }
+ };
- if ($conf->use_javascript_ajax)
- {
- print "\n".''."\n";
}
@@ -2022,34 +2075,30 @@ else
if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire))
{
// Customer
- if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) {
- print '' . fieldLabel('CustomersCategoriesShort', 'custcats') . ' ';
- print '';
- $cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, null, null, null, 1);
- $c = new Categorie($db);
- $cats = $c->containing($object->id, Categorie::TYPE_CUSTOMER);
- $arrayselected=array();
- foreach ($cats as $cat) {
- $arrayselected[] = $cat->id;
- }
- print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
- print " ";
+ print '' . fieldLabel('CustomersCategoriesShort', 'custcats') . ' ';
+ print '';
+ $cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, null, null, null, 1);
+ $c = new Categorie($db);
+ $cats = $c->containing($object->id, Categorie::TYPE_CUSTOMER);
+ $arrayselected=array();
+ foreach ($cats as $cat) {
+ $arrayselected[] = $cat->id;
}
+ print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
+ print " ";
// Supplier
- if ($object->fournisseur) {
- print '' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . ' ';
- print '';
- $cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, null, null, null, 1);
- $c = new Categorie($db);
- $cats = $c->containing($object->id, Categorie::TYPE_SUPPLIER);
- $arrayselected=array();
- foreach ($cats as $cat) {
- $arrayselected[] = $cat->id;
- }
- print $form->multiselectarray('suppcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
- print " ";
+ print '' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . ' ';
+ print '';
+ $cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, null, null, null, 1);
+ $c = new Categorie($db);
+ $cats = $c->containing($object->id, Categorie::TYPE_SUPPLIER);
+ $arrayselected=array();
+ foreach ($cats as $cat) {
+ $arrayselected[] = $cat->id;
}
+ print $form->multiselectarray('suppcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
+ print " ";
}
// Multicurrency
diff --git a/htdocs/societe/class/address.class.php b/htdocs/societe/class/address.class.php
index 37a350b81ff..63b23d42f9e 100644
--- a/htdocs/societe/class/address.class.php
+++ b/htdocs/societe/class/address.class.php
@@ -47,7 +47,12 @@ class Address
public $socid;
public $name;
+
+ /**
+ * @var string Address
+ */
public $address;
+
public $zip;
public $town;
public $country_id;
@@ -522,7 +527,12 @@ class AddressLine
public $label;
public $name;
+
+ /**
+ * @var string Address
+ */
public $address;
+
public $zip;
public $town;
public $country_id;
diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php
index 0b640fe1085..365073726bc 100644
--- a/htdocs/societe/class/api_thirdparties.class.php
+++ b/htdocs/societe/class/api_thirdparties.class.php
@@ -52,6 +52,7 @@ class Thirdparties extends DolibarrApi
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+ require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
$this->company = new Societe($this->db);
diff --git a/htdocs/societe/class/companypaymentmode.class.php b/htdocs/societe/class/companypaymentmode.class.php
index f5ef70c2407..83303a3a41d 100644
--- a/htdocs/societe/class/companypaymentmode.class.php
+++ b/htdocs/societe/class/companypaymentmode.class.php
@@ -127,7 +127,7 @@ class CompanyPaymentMode extends CommonObject
/**
* @var int Thirdparty ID
*/
- public $fk_soc;
+ public $fk_soc;
/**
* @var string company payment mode label
@@ -161,7 +161,12 @@ class CompanyPaymentMode extends CommonObject
public $preapproval_key;
public $total_amount_of_all_payments;
public $stripe_card_ref;
+
+ /**
+ * @var int Status
+ */
public $status;
+
public $starting_date;
public $ending_date;
public $datec;
diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
index a6dec311d0d..c91593b079f 100644
--- a/htdocs/societe/class/societe.class.php
+++ b/htdocs/societe/class/societe.class.php
@@ -66,6 +66,7 @@ class Societe extends CommonObject
* @var int
*/
public $ismultientitymanaged = 1;
+
/**
* 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
* @var integer
@@ -103,7 +104,7 @@ class Societe extends CommonObject
* Thirdparty name
* @var string
* @deprecated Use $name instead
- * @see name
+ * @see $name
*/
public $nom;
@@ -119,7 +120,12 @@ class Societe extends CommonObject
public $name_alias;
public $particulier;
+
+ /**
+ * @var string Address
+ */
public $address;
+
public $zip;
public $town;
@@ -148,21 +154,21 @@ class Societe extends CommonObject
* State code
* @var string
* @deprecated Use state_code instead
- * @see state_code
+ * @see $state_code
*/
public $departement_code;
/**
* @var string
* @deprecated Use state instead
- * @see state
+ * @see $state
*/
public $departement;
/**
* @var string
* @deprecated Use country instead
- * @see country
+ * @see $country
*/
public $pays;
@@ -275,7 +281,12 @@ class Societe extends CommonObject
public $remise_supplier_percent;
public $mode_reglement_supplier_id;
public $cond_reglement_supplier_id;
+
+ /**
+ * @var int ID
+ */
public $fk_prospectlevel;
+
public $name_bis;
//Log data
@@ -353,7 +364,7 @@ class Societe extends CommonObject
/**
* @var string
* @deprecated Note is split in public and private notes
- * @see note_public, note_private
+ * @see $note_public, $note_private
*/
public $note;
@@ -443,12 +454,20 @@ class Societe extends CommonObject
public $array_options;
// Incoterms
+ /**
+ * @var int ID
+ */
public $fk_incoterms;
+
public $location_incoterms;
public $libelle_incoterms; //Used into tooltip
// Multicurrency
+ /**
+ * @var int ID
+ */
public $fk_multicurrency;
+
public $multicurrency_code;
@@ -1052,10 +1071,26 @@ class Societe extends CommonObject
$resql=$this->db->query($sql);
if ($resql)
{
- unset($this->country_code); // We clean this because it may have been changed after an update of country_id
- unset($this->country);
- unset($this->state_code);
- unset($this->state);
+ if (is_object($this->oldcopy)) // If we have information on old values
+ {
+ if ($this->oldcopy->country_id != $this->country_id)
+ {
+ unset($this->country_code);
+ unset($this->country);
+ }
+ if ($this->oldcopy->state_id != $this->state_id)
+ {
+ unset($this->state_code);
+ unset($this->state);
+ }
+ }
+ else
+ {
+ unset($this->country_code); // We clean this, in the doubt, because it may have been changed after an update of country_id
+ unset($this->country);
+ unset($this->state_code);
+ unset($this->state);
+ }
$nbrowsaffected = $this->db->affected_rows($resql);
@@ -1708,10 +1743,13 @@ class Societe extends CommonObject
$discount = new DiscountAbsolute($this->db);
$discount->fk_soc=$this->id;
+
$discount->discount_type=$discount_type;
- $discount->amount_ht=price2num($remise,'MT');
- $discount->amount_tva=price2num($remise*$tva_tx/100,'MT');
- $discount->amount_ttc=price2num($discount->amount_ht+$discount->amount_tva,'MT');
+
+ $discount->amount_ht=$discount->multicurrency_amount_ht=price2num($remise,'MT');
+ $discount->amount_tva=$discount->multicurrency_amount_tva=price2num($remise*$tva_tx/100,'MT');
+ $discount->amount_ttc=$discount->multicurrency_amount_ttc=price2num($discount->amount_ht+$discount->amount_tva,'MT');
+
$discount->tva_tx=price2num($tva_tx,'MT');
$discount->description=$desc;
@@ -1950,24 +1988,33 @@ class Societe extends CommonObject
if (! empty($conf->global->SOCIETE_ADD_REF_IN_LIST) && (!empty($withpicto)))
{
+ $code = '';
if (($this->client) && (! empty ( $this->code_client ))
&& ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1
|| $conf->global->SOCIETE_ADD_REF_IN_LIST == 2
)
)
- $code = $this->code_client . ' - ';
+ {
+ $code = $this->code_client . ' - ';
+ }
if (($this->fournisseur) && (! empty ( $this->code_fournisseur ))
&& ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1
|| $conf->global->SOCIETE_ADD_REF_IN_LIST == 3
)
)
- $code .= $this->code_fournisseur . ' - ';
+ {
+ $code .= $this->code_fournisseur . ' - ';
+ }
if ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1)
+ {
$name =$code.' '.$name;
+ }
else
+ {
$name =$code;
+ }
}
if (!empty($this->name_alias)) $name .= ' ('.$this->name_alias.')';
@@ -3150,8 +3197,12 @@ class Societe extends CommonObject
// Define if third party is treated as company (or not) when nature is unknown
$isacompany=empty($conf->global->MAIN_UNKNOWN_CUSTOMERS_ARE_COMPANIES)?0:1; // 0 by default
if (! empty($this->tva_intra)) $isacompany=1;
- else if (! empty($this->typent_code) && in_array($this->typent_code,array('TE_PRIVATE'))) $isacompany=0;
- else if (! empty($this->typent_code) && in_array($this->typent_code,array('TE_SMALL','TE_MEDIUM','TE_LARGE','TE_GROUP'))) $isacompany=1;
+ else if (! empty($this->typent_code) && $this->typent_code != 'TE_UNKNOWN')
+ {
+ // TODO Add a field is_a_company into dictionary
+ if (preg_match('/^TE_PRIVATE/', $this->typent_code)) $isacompany=0;
+ else $isacompany=1;
+ }
return $isacompany;
}
@@ -3312,6 +3363,7 @@ class Societe extends CommonObject
$this->town=empty($conf->global->MAIN_INFO_SOCIETE_TOWN)?'':$conf->global->MAIN_INFO_SOCIETE_TOWN;
$this->state_id=empty($conf->global->MAIN_INFO_SOCIETE_STATE)?'':$conf->global->MAIN_INFO_SOCIETE_STATE;
$this->region_code=empty($conf->global->MAIN_INFO_SOCIETE_REGION)?'':$conf->global->MAIN_INFO_SOCIETE_REGION;
+ $this->object=empty($conf->global->MAIN_INFO_SOCIETE_OBJECT)?'':$conf->global->MAIN_INFO_SOCIETE_OBJECT;
$this->note_private=empty($conf->global->MAIN_INFO_SOCIETE_NOTE)?'':$conf->global->MAIN_INFO_SOCIETE_NOTE;
diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php
index 422dd4ddb8e..de228c576b5 100644
--- a/htdocs/societe/class/societeaccount.class.php
+++ b/htdocs/societe/class/societeaccount.class.php
@@ -99,6 +99,10 @@ class SocieteAccount extends CommonObject
'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'visible'=>-2, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1, 'index'=>1,),
'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'index'=>1, 'default'=>1, 'arrayofkeyval'=>array('1'=>'Active','0'=>'Disabled')),
);
+
+ /**
+ * @var int ID
+ */
public $rowid;
/**
@@ -123,10 +127,24 @@ class SocieteAccount extends CommonObject
public $note_private;
public $date_creation;
public $tms;
+
+ /**
+ * @var int ID
+ */
public $fk_user_creat;
+
+ /**
+ * @var int ID
+ */
public $fk_user_modif;
+
public $import_key;
+
+ /**
+ * @var int Status
+ */
public $status;
+
// END MODULEBUILDER PROPERTIES
@@ -270,8 +288,6 @@ class SocieteAccount extends CommonObject
*/
public function getCustomerAccount($id, $site, $status=0)
{
- global $conf;
-
$sql = "SELECT sa.key_account as key_account, sa.entity";
$sql.= " FROM " . MAIN_DB_PREFIX . "societe_account as sa";
$sql.= " WHERE sa.fk_soc = " . $id;
@@ -280,7 +296,7 @@ class SocieteAccount extends CommonObject
$sql.= " AND key_account IS NOT NULL AND key_account <> ''";
//$sql.= " ORDER BY sa.key_account DESC";
- dol_syslog(get_class($this) . "::getCustomerAccount Try to find the system customer id of thirdparty id=".$id." (exemple: cus_.... for stripe)", LOG_DEBUG);
+ dol_syslog(get_class($this) . "::getCustomerAccount Try to find the first system customer id for ".$site." of thirdparty id=".$id." (exemple: cus_.... for stripe)", LOG_DEBUG);
$result = $this->db->query($sql);
if ($result) {
if ($this->db->num_rows($result)) {
diff --git a/htdocs/societe/index.php b/htdocs/societe/index.php
index f53a9042fca..0759008c435 100644
--- a/htdocs/societe/index.php
+++ b/htdocs/societe/index.php
@@ -1,6 +1,6 @@
- * Copyright (C) 2004-2015 Laurent Destailleur
+ * Copyright (C) 2004-2018 Laurent Destailleur
* Copyright (C) 2005-2012 Regis Houssin
* Copyright (C) 2014 Charles-Fr Benke
* Copyright (C) 2015 Jean-François Ferry
diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php
index 604012a24c3..13fdf048382 100644
--- a/htdocs/societe/paymentmodes.php
+++ b/htdocs/societe/paymentmodes.php
@@ -557,7 +557,7 @@ if (empty($reshook))
$sql.= " SET key_account = '".$db->escape(GETPOST('key_account', 'alpha'))."'";
$sql.= " WHERE site = 'stripe' AND fk_soc = ".$object->id." AND status = ".$servicestatus." AND entity = ".$conf->entity; // Keep = here for entity. Only 1 record must be modified !
}
-
+
$resql = $db->query($sql);
$num = $db->num_rows($resql);
if (empty($num) && !empty($newcu))
@@ -959,9 +959,17 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
print '';
print ' ';
}
+ // Src ID
print '';
- print $src->id;
+ if (!empty($stripeacc)) $connect=$stripeacc.'/';
+ $url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
+ if ($servicestatus)
+ {
+ $url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
+ }
+ print $src->id." ".img_picto($langs->trans('ShowInStripe'), 'object_globe')."";
print ' ';
+ // Img of credit card
print '';
if ($src->object=='card')
{
@@ -975,8 +983,8 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
{
print '';
}
-
- print' ';
+ print' ';
+ print '';
if ($src->object=='card')
{
print '....'.$src->last4.' - '.$src->exp_month.'/'.$src->exp_year.'';
diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
index 901997cef3b..0e9c3cbb4a8 100644
--- a/htdocs/stripe/class/stripe.class.php
+++ b/htdocs/stripe/class/stripe.class.php
@@ -36,8 +36,11 @@ class Stripe extends CommonObject
/**
* @var int Thirdparty ID
*/
- public $fk_soc;
+ public $fk_soc;
+ /**
+ * @var int ID
+ */
public $fk_key;
/**
@@ -119,8 +122,6 @@ class Stripe extends CommonObject
*/
public function getStripeCustomerAccount($id, $status=0)
{
- global $conf;
-
include_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
$societeaccount = new SocieteAccount($this->db);
return $societeaccount->getCustomerAccount($id, 'stripe', $status); // Get thirdparty cus_...
@@ -186,11 +187,22 @@ class Stripe extends CommonObject
{
$dataforcustomer = array(
"email" => $object->email,
- "business_vat_id" => $object->tva_intra,
"description" => $object->name,
"metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR']))
);
+ $vatcleaned = $object->tva_intra ? $object->tva_intra : null;
+
+ $taxinfo = array('type'=>'vat');
+ if ($vatcleaned)
+ {
+ $taxinfo["tax_id"] = $vatcleaned;
+ }
+ // We force data to "null" if not defined as expected by Stripe
+ if (empty($vatcleaned)) $taxinfo=null;
+
+ $dataforcustomer["tax_info"] = $taxinfo;
+
//$a = \Stripe\Stripe::getApiKey();
//var_dump($a);var_dump($key);exit;
try {
diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php
index 7aa22678d7a..6141c2a32f8 100644
--- a/htdocs/stripe/config.php
+++ b/htdocs/stripe/config.php
@@ -55,4 +55,4 @@ else
\Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
\Stripe\Stripe::setAppInfo("Dolibarr Stripe", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version
-\Stripe\Stripe::setApiVersion("2018-07-27"); // force version API
+\Stripe\Stripe::setApiVersion("2018-09-24"); // force version API
diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php
index ecd940fea96..adc2c8643ac 100644
--- a/htdocs/supplier_proposal/class/supplier_proposal.class.php
+++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php
@@ -60,6 +60,9 @@ class SupplierProposal extends CommonObject
*/
public $table_element_line='supplier_proposaldet';
+ /**
+ * @var int Field with ID of parent key if this field has a parent
+ */
public $fk_element='fk_supplier_proposal';
public $picto='propal';
@@ -163,7 +166,11 @@ class SupplierProposal extends CommonObject
public $specimen;
// Multicurrency
+ /**
+ * @var int ID
+ */
public $fk_multicurrency;
+
public $multicurrency_code;
public $multicurrency_tx;
public $multicurrency_total_ht;
@@ -2709,9 +2716,21 @@ class SupplierProposalLine extends CommonObjectLine
*/
public $id;
+ /**
+ * @var int ID
+ */
public $fk_supplier_proposal;
+
+ /**
+ * @var int ID
+ */
public $fk_parent_line;
+
public $desc; // Description ligne
+
+ /**
+ * @var int ID
+ */
public $fk_product; // Id produit predefini
/**
@@ -2730,11 +2749,19 @@ class SupplierProposalLine extends CommonObjectLine
public $tva_tx;
public $subprice;
public $remise_percent;
+
+ /**
+ * @var int ID
+ */
public $fk_remise_except;
public $rang = 0;
+ /**
+ * @var int ID
+ */
public $fk_fournprice;
+
public $pa_ht;
public $marge_tx;
public $marque_tx;
@@ -2808,7 +2835,11 @@ class SupplierProposalLine extends CommonObjectLine
public $ref_supplier;
// Multicurrency
+ /**
+ * @var int ID
+ */
public $fk_multicurrency;
+
public $multicurrency_code;
public $multicurrency_subprice;
public $multicurrency_total_ht;
diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php
index 939d1ea2189..c71f7f861a3 100644
--- a/htdocs/takepos/invoice.php
+++ b/htdocs/takepos/invoice.php
@@ -77,12 +77,14 @@ if ($action == 'valid' && $user->rights->facture->creer){
if (($action=="addline" || $action=="freezone") and $placeid==0)
{
+ // $place is id of POS, $placeid is id of invoice
if ($placeid==0) {
$invoice = new Facture($db);
$invoice->socid=$conf->global->CASHDESK_ID_THIRDPARTY;
$invoice->date=dol_now();
$invoice->ref="(PROV-POS)";
$invoice->module_source = 'takepos';
+ $invoice->pos_source = (string) (empty($place)?'0':$place);
$placeid=$invoice->create($user);
$sql="UPDATE ".MAIN_DB_PREFIX."facture set facnumber='(PROV-POS-".$place.")' where rowid=".$placeid;
@@ -113,7 +115,7 @@ if ($action=="deleteline"){
$row = $db->fetch_array ($resql);
$deletelineid=$row[0];
$invoice->deleteline($deletelineid);
- $invoice->fetch($deletelineid);
+ $invoice->fetch($placeid);
}
}
diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
index 82f50a5771c..d9ad2a590ac 100644
--- a/htdocs/theme/eldy/style.css.php
+++ b/htdocs/theme/eldy/style.css.php
@@ -696,6 +696,9 @@ textarea.centpercent {
height: 28px;
vertical-align: middle;
}
+.divsocialnetwork:not(:first-child) {
+ padding-left: 20px;
+}
div.divsearchfield {
float: ;
margin-: 12px;
@@ -3268,7 +3271,7 @@ ul.noborder li:nth-child(even):not(.liste_titre) {
.boxstats130 {
width: 158px;
height: 48px;
- padding: 3px
+ padding: 3px;
}
.boxstats {
padding: 3px;
diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
index 23575680acf..2b760fcd894 100644
--- a/htdocs/theme/md/style.css.php
+++ b/htdocs/theme/md/style.css.php
@@ -689,6 +689,9 @@ textarea.centpercent {
height: 28px;
vertical-align: middle;
}
+.divsocialnetwork:not(:first-child) {
+ padding-left: 20px;
+}
div.divsearchfield {
float: ;
margin-: 12px;
@@ -1202,6 +1205,13 @@ td.showDragHandle {
.side-nav-vert {
margin-left: 228px;
}
+global->THEME_DISABLE_STICKY_TOPMENU)) { ?>
+.side-nav-vert {
+ position: sticky;
+ top: 0px;
+ z-index: 210;
+}
+
/* For smartphone (testmenuhider is on) */
browser->layout, array('phone','tablet')) && ((GETPOST('testmenuhider') || ! empty($conf->global->MAIN_TESTMENUHIDER)) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))) { ?>
@@ -1233,6 +1243,11 @@ div.backgroundsemitransparent {
padding-left: 10px;
padding-right: 10px;
}
+
+
+
+/* Login */
+
div.login_block {
/* position: initial !important;*/
display: none;
@@ -1247,6 +1262,10 @@ div.login_block {
color: #333 !important;
font-weight: normal !important;
}
+
+
+
+
#id-right {
padding-left: 0 ! important;
}
@@ -1510,7 +1529,7 @@ div#tmenu_tooltip {
background: rgb();
/*
- background-image: linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
+ background-image: linear-gradient(to top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
background-image: -o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
background-image: -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
background-image: -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
@@ -1591,7 +1610,7 @@ ul.tmenu { /* t r b l */
ul.tmenu li {
background: rgb();
/*
- background-image: linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
+ background-image: linear-gradient(to top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
background-image: -o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
background-image: -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
background-image: -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
@@ -2887,7 +2906,7 @@ div.pagination li.paginationafterarrows {
/* Prepare to remove class pair - impair
.noborder > tbody > tr:nth-child(even) td {
- background: linear-gradient(bottom, rgb() 85%, rgb() 100%);
+ background: linear-gradient(to bottom, rgb() 85%, rgb() 100%);
background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%);
background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%);
background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%);
@@ -2900,7 +2919,7 @@ div.pagination li.paginationafterarrows {
}
.noborder > tbody > tr:nth-child(odd) td {
- background: linear-gradient(bottom, rgb() 85%, rgb() 100%);
+ background: linear-gradient(to bottom, rgb() 85%, rgb() 100%);
background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%);
background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%);
background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%);
@@ -3165,7 +3184,7 @@ div .tdtop {
/* Prepare to remove class pair - impair */
.noborder > tbody > tr:nth-child(even):not(.liste_titre), .liste > tbody > tr:nth-child(even):not(.liste_titre) {
- background: linear-gradient(bottom, rgb() 85%, rgb() 100%);
+ background: linear-gradient(to bottom, rgb() 85%, rgb() 100%);
background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%);
background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%);
background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%);
@@ -3176,7 +3195,7 @@ div .tdtop {
}
.noborder > tbody > tr:nth-child(odd):not(.liste_titre), .liste > tbody > tr:nth-child(odd):not(.liste_titre) {
- background: linear-gradient(bottom, rgb() 85%, rgb() 100%);
+ background: linear-gradient(to bottom, rgb() 85%, rgb() 100%);
background: -o-linear-gradient(bottom, rgb() 85%, rgb() 100%);
background: -moz-linear-gradient(bottom, rgb() 85%, rgb() 100%);
background: -webkit-linear-gradient(bottom, rgb() 85%, rgb() 100%);
@@ -3222,7 +3241,7 @@ div .tdtop {
.boxstats130 {
width: 135px;
height: 48px;
- padding: 3px
+ padding: 3px;
}
@media only screen and (max-width: 767px)
{
diff --git a/htdocs/ticket/class/actions_ticket.class.php b/htdocs/ticket/class/actions_ticket.class.php
index 2fd26b5797b..7e8ae39564a 100644
--- a/htdocs/ticket/class/actions_ticket.class.php
+++ b/htdocs/ticket/class/actions_ticket.class.php
@@ -70,6 +70,9 @@ class ActionsTicket
*/
public $description;
+ /**
+ * @var int ID
+ */
public $fk_statut;
/**
diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php
index c75ab7e2450..110c27a5cce 100644
--- a/htdocs/ticket/class/api_tickets.class.php
+++ b/htdocs/ticket/class/api_tickets.class.php
@@ -473,190 +473,6 @@ class Tickets extends DolibarrApi
);
}
-
- /**
- * Get the list of tickets categories.
- *
- * @param string $sortfield Sort field
- * @param string $sortorder Sort order
- * @param int $limit Number of items per page
- * @param int $page Page number (starting from zero)
- * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
- * @return List of events types
- *
- * @url GET setup/dictionary/categories
- *
- * @throws RestException
- */
- function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
- {
- $list = array();
-
- $sql = "SELECT rowid, code, pos, label, use_default, description";
- $sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
- $sql.= " WHERE t.active = 1";
- // Add sql filters
- if ($sqlfilters)
- {
- if (! DolibarrApi::_checkFilters($sqlfilters))
- {
- throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
- }
- $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
- $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
- }
-
-
- $sql.= $this->db->order($sortfield, $sortorder);
-
- if ($limit) {
- if ($page < 0) {
- $page = 0;
- }
- $offset = $limit * $page;
-
- $sql .= $this->db->plimit($limit, $offset);
- }
-
- $result = $this->db->query($sql);
-
- if ($result) {
- $num = $this->db->num_rows($result);
- $min = min($num, ($limit <= 0 ? $num : $limit));
- for ($i = 0; $i < $min; $i++) {
- $list[] = $this->db->fetch_object($result);
- }
- } else {
- throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
- }
-
- return $list;
- }
-
- /**
- * Get the list of tickets severity.
- *
- * @param string $sortfield Sort field
- * @param string $sortorder Sort order
- * @param int $limit Number of items per page
- * @param int $page Page number (starting from zero)
- * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
- * @return List of events types
- *
- * @url GET setup/dictionary/severities
- *
- * @throws RestException
- */
- function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
- {
- $list = array();
-
- $sql = "SELECT rowid, code, pos, label, use_default, color, description";
- $sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
- $sql.= " WHERE t.active = 1";
- // Add sql filters
- if ($sqlfilters)
- {
- if (! DolibarrApi::_checkFilters($sqlfilters))
- {
- throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
- }
- $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
- $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
- }
-
-
- $sql.= $this->db->order($sortfield, $sortorder);
-
- if ($limit) {
- if ($page < 0) {
- $page = 0;
- }
- $offset = $limit * $page;
-
- $sql .= $this->db->plimit($limit, $offset);
- }
-
- $result = $this->db->query($sql);
-
- if ($result) {
- $num = $this->db->num_rows($result);
- $min = min($num, ($limit <= 0 ? $num : $limit));
- for ($i = 0; $i < $min; $i++) {
- $list[] = $this->db->fetch_object($result);
- }
- } else {
- throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
- }
-
- return $list;
- }
-
- /**
- * Get the list of tickets types.
- *
- * @param string $sortfield Sort field
- * @param string $sortorder Sort order
- * @param int $limit Number of items per page
- * @param int $page Page number (starting from zero)
- * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
- * @return List of events types
- *
- * @url GET setup/dictionary/types
- *
- * @throws RestException
- */
- function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
- {
- $list = array();
-
- $sql = "SELECT rowid, code, pos, label, use_default, description";
- $sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
- $sql.= " WHERE t.active = 1";
- if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'";
- if ($module) $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'";
- // Add sql filters
- if ($sqlfilters)
- {
- if (! DolibarrApi::_checkFilters($sqlfilters))
- {
- throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
- }
- $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
- $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
- }
-
-
- $sql.= $this->db->order($sortfield, $sortorder);
-
- if ($limit) {
- if ($page < 0) {
- $page = 0;
- }
- $offset = $limit * $page;
-
- $sql .= $this->db->plimit($limit, $offset);
- }
-
- $result = $this->db->query($sql);
-
- if ($result) {
- $num = $this->db->num_rows($result);
- $min = min($num, ($limit <= 0 ? $num : $limit));
- for ($i = 0; $i < $min; $i++) {
- $list[] = $this->db->fetch_object($result);
- }
- } else {
- throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
- }
-
- return $list;
- }
-
-
-
-
-
/**
* Validate fields before create or update object
*
diff --git a/htdocs/ticket/class/ticketlogs.class.php b/htdocs/ticket/class/ticketlogs.class.php
index 01ba7972ced..66cecd6eb5e 100644
--- a/htdocs/ticket/class/ticketlogs.class.php
+++ b/htdocs/ticket/class/ticketlogs.class.php
@@ -1,5 +1,6 @@
+/* Copyright (C) 2013-2016 Jean-François FERRY
+ * Copyright (C) 2018 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -62,8 +63,16 @@ class Ticketlogs// extends CommonObject
*/
public $id;
+ /**
+ * @var string trackid
+ */
public $fk_track_id;
+
+ /**
+ * @var int user create ID
+ */
public $fk_user_create;
+
public $datec = '';
public $message;
@@ -96,7 +105,7 @@ class Ticketlogs// extends CommonObject
}
if (isset($this->fk_user_create)) {
- $this->fk_user_create = trim($this->fk_user_create);
+ $this->fk_user_create = (int) $this->fk_user_create;
}
if (isset($this->message)) {
@@ -135,7 +144,7 @@ class Ticketlogs// extends CommonObject
if (!$error) {
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "ticket_logs");
- if (!$notrigger) {
+ //if (!$notrigger) {
// Uncomment this and change MYOBJECT to your own tag if you
// want this action calls a trigger.
@@ -145,7 +154,7 @@ class Ticketlogs// extends CommonObject
//$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
//if ($result < 0) { $error++; $this->errors=$interface->errors; }
//// End call triggers
- }
+ //}
}
// Commit or rollback
@@ -224,7 +233,7 @@ class Ticketlogs// extends CommonObject
}
if (isset($this->fk_user_create)) {
- $this->fk_user_create = trim($this->fk_user_create);
+ $this->fk_user_create = (int) $this->fk_user_create;
}
if (isset($this->message)) {
@@ -253,8 +262,8 @@ class Ticketlogs// extends CommonObject
$this->errors[] = "Error " . $this->db->lasterror();
}
- if (!$error) {
- if (!$notrigger) {
+ //if (!$error) {
+ //if (!$notrigger) {
// Uncomment this and change MYOBJECT to your own tag if you
// want this action calls a trigger.
@@ -264,8 +273,8 @@ class Ticketlogs// extends CommonObject
//$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
//if ($result < 0) { $error++; $this->errors=$interface->errors; }
//// End call triggers
- }
- }
+ //}
+ //}
// Commit or rollback
if ($error) {
@@ -295,8 +304,8 @@ class Ticketlogs// extends CommonObject
$this->db->begin();
- if (!$error) {
- if (!$notrigger) {
+ //if (!$error) {
+ //if (!$notrigger) {
// Uncomment this and change MYOBJECT to your own tag if you
// want this action calls a trigger.
@@ -306,8 +315,8 @@ class Ticketlogs// extends CommonObject
//$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
//if ($result < 0) { $error++; $this->errors=$interface->errors; }
//// End call triggers
- }
- }
+ //}
+ //}
if (!$error) {
$sql = "DELETE FROM " . MAIN_DB_PREFIX . "ticket_logs";
@@ -343,10 +352,12 @@ class Ticketlogs// extends CommonObject
*/
public function initAsSpecimen()
{
+ global $user;
+
$this->id = 0;
$this->fk_track_id = '';
- $this->fk_user_create = '';
+ $this->fk_user_create = $user->id;
$this->datec = '';
$this->message = '';
}
diff --git a/htdocs/user/agenda_extsites.php b/htdocs/user/agenda_extsites.php
index 3146f1095b0..2eb2ede000b 100644
--- a/htdocs/user/agenda_extsites.php
+++ b/htdocs/user/agenda_extsites.php
@@ -157,17 +157,22 @@ dol_fiche_head($head, 'extsites', $langs->trans("User"), -1, 'user');
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
-print $langs->trans("AgendaExtSitesDesc")."
\n";
+
+print '';
+
+print '
';
+print ''.$langs->trans("AgendaExtSitesDesc")."
\n";
print "
\n";
$selectedvalue=$conf->global->AGENDA_DISABLE_EXT;
if ($selectedvalue==1) $selectedvalue=0; else $selectedvalue=1;
+
print '';
print "";
@@ -210,12 +215,13 @@ while ($i <= $MAXAGENDA)
print '
';
print '';
-dol_fiche_end();
print '';
print "trans("Save")."\">";
print "";
+dol_fiche_end();
+
print "\n";
// End of page
diff --git a/htdocs/user/bank.php b/htdocs/user/bank.php
index 2820e9e4690..13b555b6d5c 100644
--- a/htdocs/user/bank.php
+++ b/htdocs/user/bank.php
@@ -194,7 +194,7 @@ if ($action != 'edit' && $action != 'create') // If not bank account yet, $acco
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
diff --git a/htdocs/user/card.php b/htdocs/user/card.php
index dc2437af825..6a8e0d4f14a 100644
--- a/htdocs/user/card.php
+++ b/htdocs/user/card.php
@@ -201,6 +201,8 @@ if (empty($reshook)) {
$object->office_fax = GETPOST("office_fax", 'alpha');
$object->user_mobile = GETPOST("user_mobile");
$object->skype = GETPOST("skype", 'alpha');
+ $object->twitter = GETPOST("twitter", 'alpha');
+ $object->facebook = GETPOST("facebook", 'alpha');
$object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha'));
$object->job = GETPOST("job", 'alpha');
$object->signature = GETPOST("signature");
@@ -348,6 +350,8 @@ if (empty($reshook)) {
$object->office_fax = GETPOST("office_fax", 'alpha');
$object->user_mobile = GETPOST("user_mobile");
$object->skype = GETPOST("skype", 'alpha');
+ $object->twitter = GETPOST("twitter", 'alpha');
+ $object->facebook = GETPOST("facebook", 'alpha');
$object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha'));
$object->job = GETPOST("job", 'alpha');
$object->signature = GETPOST("signature",'none');
@@ -588,6 +592,8 @@ if (empty($reshook)) {
$ldap_fax = $attribute[$conf->global->LDAP_FIELD_FAX];
$ldap_mobile = $attribute[$conf->global->LDAP_FIELD_MOBILE];
$ldap_skype = $attribute[$conf->global->LDAP_FIELD_SKYPE];
+ $ldap_twitter = $attribute[$conf->global->LDAP_FIELD_TWITTER];
+ $ldap_facebook = $attribute[$conf->global->LDAP_FIELD_FACEBOOK];
$ldap_mail = $attribute[$conf->global->LDAP_FIELD_MAIL];
$ldap_sid = $attribute[$conf->global->LDAP_FIELD_SID];
}
@@ -1000,7 +1006,7 @@ if ($action == 'create' || $action == 'adduserldap')
print ' ';
// Skype
- if (! empty($conf->skype->enabled))
+ if (! empty($conf->socialnetworks->enabled))
{
print ''.$langs->trans("Skype").' ';
print '';
@@ -1011,7 +1017,41 @@ if ($action == 'create' || $action == 'adduserldap')
}
else
{
- print '';
+ print '';
+ }
+ print ' ';
+ }
+
+ // Twitter
+ if (! empty($conf->socialnetworks->enabled))
+ {
+ print ''.$langs->trans("Twitter").' ';
+ print '';
+ if (! empty($ldap_twitter))
+ {
+ print '';
+ print $ldap_twitter;
+ }
+ else
+ {
+ print '';
+ }
+ print ' ';
+ }
+
+ // Facebook
+ if (! empty($conf->socialnetworks->enabled))
+ {
+ print ''.$langs->trans("Facebook").' ';
+ print '';
+ if (! empty($ldap_facebook))
+ {
+ print '';
+ print $ldap_facebook;
+ }
+ else
+ {
+ print '';
}
print ' ';
}
@@ -1343,7 +1383,7 @@ else
// Password
print ''.$langs->trans("Password").' ';
- print '';
+ print ' ';
$valuetoshow='';
if (preg_match('/ldap/',$dolibarr_main_authentication))
{
@@ -2195,7 +2235,7 @@ else
print ' ';
// Skype
- if (! empty($conf->skype->enabled))
+ if (! empty($conf->socialnetworks->enabled))
{
print ''.$langs->trans("Skype").' ';
print '';
@@ -2211,6 +2251,40 @@ else
print ' ';
}
+ // Twitter
+ if (! empty($conf->socialnetworks->enabled))
+ {
+ print ''.$langs->trans("Twitter").' ';
+ print '';
+ if ($caneditfield && empty($object->ldap_sid))
+ {
+ print '';
+ }
+ else
+ {
+ print '';
+ print $object->twitter;
+ }
+ print ' ';
+ }
+
+ // Skype
+ if (! empty($conf->socialnetworks->enabled))
+ {
+ print ''.$langs->trans("Facebook").' ';
+ print '';
+ if ($caneditfield && empty($object->ldap_sid))
+ {
+ print '';
+ }
+ else
+ {
+ print '';
+ print $object->facebook;
+ }
+ print ' ';
+ }
+
// EMail
print "".'global->USER_MAIL_REQUIRED)?' class="fieldrequired"':'').'>'.$langs->trans("EMail").' ';
print '';
@@ -2285,7 +2359,7 @@ else
{
print ' ' . fieldLabel( 'Categories', 'usercats' ) . ' ';
print '';
- $cate_arbo = $form->select_all_categories( Categorie::TYPE_CONTACT, null, null, null, null, 1 );
+ $cate_arbo = $form->select_all_categories( Categorie::TYPE_USER, null, null, null, null, 1 );
$c = new Categorie( $db );
$cats = $c->containing($object->id, Categorie::TYPE_USER);
foreach ($cats as $cat) {
diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php
index 9020cd3a4bc..d2afacce54a 100644
--- a/htdocs/user/class/user.class.php
+++ b/htdocs/user/class/user.class.php
@@ -50,8 +50,16 @@ class User extends CommonObject
*/
public $table_element='user';
+ /**
+ * @var int Field with ID of parent key if this field has a parent
+ */
public $fk_element='fk_user';
- public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
+
+ /**
+ * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
+ * @var int
+ */
+ public $ismultientitymanaged = 1;
public $id=0;
public $statut;
@@ -61,10 +69,19 @@ class User extends CommonObject
public $gender;
public $birth;
public $email;
+
public $skype;
+ public $twitter;
+ public $facebook;
+
public $job; // job position
public $signature;
+
+ /**
+ * @var string Address
+ */
public $address;
+
public $zip;
public $town;
public $state_id; // The state/department
@@ -106,6 +123,9 @@ class User extends CommonObject
public $socid;
public $contactid;
+ /**
+ * @var int ID
+ */
public $fk_member;
/**
@@ -207,7 +227,8 @@ class User extends CommonObject
$login=trim($login);
// Get user
- $sql = "SELECT u.rowid, u.lastname, u.firstname, u.employee, u.gender, u.birth, u.email, u.job, u.skype, u.signature, u.office_phone, u.office_fax, u.user_mobile,";
+ $sql = "SELECT u.rowid, u.lastname, u.firstname, u.employee, u.gender, u.birth, u.email, u.job, u.skype, u.twitter, u.facebook,";
+ $sql.= " u.signature, u.office_phone, u.office_fax, u.user_mobile,";
$sql.= " u.address, u.zip, u.town, u.fk_state as state_id, u.fk_country as country_id,";
$sql.= " u.admin, u.login, u.note,";
$sql.= " u.pass, u.pass_crypted, u.pass_temp, u.api_key,";
@@ -312,6 +333,8 @@ class User extends CommonObject
$this->user_mobile = $obj->user_mobile;
$this->email = $obj->email;
$this->skype = $obj->skype;
+ $this->twitter = $obj->twitter;
+ $this->facebook = $obj->facebook;
$this->job = $obj->job;
$this->signature = $obj->signature;
$this->admin = $obj->admin;
@@ -1207,6 +1230,8 @@ class User extends CommonObject
$this->gender = $contact->gender;
$this->email = $contact->email;
$this->skype = $contact->skype;
+ $this->twitter = $contact->twitter;
+ $this->facebook = $contact->facebook;
$this->office_phone = $contact->phone_pro;
$this->office_fax = $contact->fax;
$this->user_mobile = $contact->phone_mobile;
@@ -1420,7 +1445,11 @@ class User extends CommonObject
$this->office_fax = trim($this->office_fax);
$this->user_mobile = trim($this->user_mobile);
$this->email = trim($this->email);
+
$this->skype = trim($this->skype);
+ $this->twitter = trim($this->twitter);
+ $this->facebook = trim($this->facebook);
+
$this->job = trim($this->job);
$this->signature = trim($this->signature);
$this->note = trim($this->note);
@@ -1470,6 +1499,8 @@ class User extends CommonObject
$sql.= ", user_mobile = '".$this->db->escape($this->user_mobile)."'";
$sql.= ", email = '".$this->db->escape($this->email)."'";
$sql.= ", skype = '".$this->db->escape($this->skype)."'";
+ $sql.= ", twitter = '".$this->db->escape($this->twitter)."'";
+ $sql.= ", facebook = '".$this->db->escape($this->facebook)."'";
$sql.= ", job = '".$this->db->escape($this->job)."'";
$sql.= ", signature = '".$this->db->escape($this->signature)."'";
$sql.= ", accountancy_code = '".$this->db->escape($this->accountancy_code)."'";
@@ -1554,7 +1585,11 @@ class User extends CommonObject
$adh->country_id=$this->country_id;
$adh->email=$this->email;
+
$adh->skype=$this->skype;
+ $adh->twitter=$this->twitter;
+ $adh->facebook=$this->facebook;
+
$adh->phone=$this->office_phone;
$adh->phone_mobile=$this->user_mobile;
@@ -1602,7 +1637,11 @@ class User extends CommonObject
//$tmpobj->societe=(empty($tmpobj->societe) && $this->societe_id ? $this->societe_id : $tmpobj->societe);
$tmpobj->email=$this->email;
+
$tmpobj->skype=$this->skype;
+ $tmpobj->twitter=$this->twitter;
+ $tmpobj->facebook=$this->facebook;
+
$tmpobj->phone_pro=$this->office_phone;
$tmpobj->phone_mobile=$this->user_mobile;
$tmpobj->fax=$this->office_fax;
@@ -2461,13 +2500,15 @@ class User extends CommonObject
'LDAP_FIELD_NAME' => 'lastname',
'LDAP_FIELD_FIRSTNAME' => 'firstname',
'LDAP_FIELD_LOGIN' => 'login',
- 'LDAP_FIELD_LOGIN_SAMBA' => 'login',
+ 'LDAP_FIELD_LOGIN_SAMBA'=> 'login',
'LDAP_FIELD_PHONE' => 'office_phone',
'LDAP_FIELD_MOBILE' => 'user_mobile',
- 'LDAP_FIELD_FAX' => 'office_fax',
+ 'LDAP_FIELD_FAX' => 'office_fax',
'LDAP_FIELD_MAIL' => 'email',
- 'LDAP_FIELD_SID' => 'ldap_sid',
- 'LDAP_FIELD_SKYPE' => 'skype'
+ 'LDAP_FIELD_SID' => 'ldap_sid',
+ 'LDAP_FIELD_SKYPE' => 'skype',
+ 'LDAP_FIELD_TWITTER' => 'twitter',
+ 'LDAP_FIELD_FACEBOOK' => 'facebook'
);
// Champs
@@ -2578,7 +2619,9 @@ class User extends CommonObject
$this->gender='man';
$this->note='This is a note';
$this->email='email@specimen.com';
- $this->skype='tom.hanson';
+ $this->skype='skypepseudo';
+ $this->twitter='twitterpseudo';
+ $this->facebook='facebookpseudo';
$this->office_phone='0999999999';
$this->office_fax='0999999998';
$this->user_mobile='0999999997';
@@ -2732,6 +2775,8 @@ class User extends CommonObject
$this->office_fax=$ldapuser->{$conf->global->LDAP_FIELD_FAX};
$this->email=$ldapuser->{$conf->global->LDAP_FIELD_MAIL};
$this->skype=$ldapuser->{$conf->global->LDAP_FIELD_SKYPE};
+ $this->twitter=$ldapuser->{$conf->global->LDAP_FIELD_TWITTER};
+ $this->facebook=$ldapuser->{$conf->global->LDAP_FIELD_FACEBOOK};
$this->ldap_sid=$ldapuser->{$conf->global->LDAP_FIELD_SID};
$this->job=$ldapuser->{$conf->global->LDAP_FIELD_TITLE};
diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php
index e3ada6efcac..6f3e333f6f5 100644
--- a/htdocs/user/class/usergroup.class.php
+++ b/htdocs/user/class/usergroup.class.php
@@ -45,7 +45,11 @@ class UserGroup extends CommonObject
*/
public $table_element='usergroup';
- public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
+ /**
+ * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
+ * @var int
+ */
+ public $ismultientitymanaged = 1;
public $picto='group';
diff --git a/htdocs/user/clicktodial.php b/htdocs/user/clicktodial.php
index bfab243bbaf..6719d6ca120 100644
--- a/htdocs/user/clicktodial.php
+++ b/htdocs/user/clicktodial.php
@@ -102,7 +102,7 @@ if ($id > 0)
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
diff --git a/htdocs/user/document.php b/htdocs/user/document.php
index 3088320e50c..decc53a379c 100644
--- a/htdocs/user/document.php
+++ b/htdocs/user/document.php
@@ -133,7 +133,7 @@ if ($object->id)
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
diff --git a/htdocs/user/info.php b/htdocs/user/info.php
index 8fba36a3e8a..bb262804d33 100644
--- a/htdocs/user/info.php
+++ b/htdocs/user/info.php
@@ -72,7 +72,7 @@ dol_fiche_head($head, 'info', $title, -1, 'user');
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin);
diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php
index 4a4ffeb875d..fa5e5e023eb 100644
--- a/htdocs/user/ldap.php
+++ b/htdocs/user/ldap.php
@@ -98,7 +98,7 @@ dol_fiche_head($head, 'ldap', $title, 0, 'user');
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
diff --git a/htdocs/user/list.php b/htdocs/user/list.php
index 088148ba4af..64c63c05426 100644
--- a/htdocs/user/list.php
+++ b/htdocs/user/list.php
@@ -26,6 +26,9 @@
*/
require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
+if (! empty($conf->categorie->enabled))
+ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
if (! $user->rights->user->user->lire && ! $user->admin)
accessforbidden();
@@ -123,10 +126,12 @@ $search_thirdparty=GETPOST('search_thirdparty','alpha');
$search_supervisor=GETPOST('search_supervisor','intcomma');
$search_previousconn=GETPOST('search_previousconn','alpha');
$optioncss = GETPOST('optioncss','alpha');
+$search_categ = GETPOST("search_categ",'int');
+$catid = GETPOST('catid','int');
// Default search
if ($search_statut == '') $search_statut='1';
-if ($mode == 'employee') $search_employee=1;
+if ($mode == 'employee' && ! GETPOSTISSET('search_employee')) $search_employee=1;
@@ -165,6 +170,7 @@ if (empty($reshook))
$search_date_creation="";
$search_date_update="";
$search_array_options=array();
+ $search_categ=0;
}
}
@@ -173,6 +179,8 @@ if (empty($reshook))
* View
*/
+$htmlother=new FormOther($db);
+
$user2=new User($db);
$buttonviewhierarchy='';
@@ -193,6 +201,7 @@ $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user_extrafields as ef on (u.rowid = ef.fk_object)";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON u.fk_soc = s.rowid";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u2 ON u.fk_user = u2.rowid";
+if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_user as cu ON u.rowid = cu.fk_user"; // We'll need this table joined to the select in order to filter by categ
// Add fields from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printUserListWhere',$parameters); // Note that $action and $object may have been modified by hook
@@ -216,6 +225,10 @@ if ($search_accountancy_code != '') $sql.= natural_search("u.accountancy_code",
if ($search_email != '') $sql.= natural_search("u.email", $search_email);
if ($search_statut != '' && $search_statut >= 0) $sql.= " AND u.statut IN (".$db->escape($search_statut).")";
if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall);
+if ($catid > 0) $sql.= " AND cu.fk_categorie = ".$catid;
+if ($catid == -2) $sql.= " AND cu.fk_categorie IS NULL";
+if ($search_categ > 0) $sql.= " AND cu.fk_categorie = ".$db->escape($search_categ);
+if ($search_categ == -2) $sql.= " AND cu.fk_categorie IS NULL";
// Add where from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
// Add where from hooks
@@ -268,6 +281,7 @@ if ($search_supervisor > 0) $param.="&search_supervisor=".$search_supervisor;
if ($search_statut != '') $param.="&search_statut=".$search_statut;
if ($optioncss != '') $param.='&optioncss='.$optioncss;
if ($mode != '') $param.='&mode='.$mode;
+if ($search_categ > 0) $param.="&search_categ=".urlencode($search_categ);
// Add $param from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
@@ -296,6 +310,15 @@ $morehtmlright = '";
+ $c = new Categorie($db);
+ $ways = $c->print_all_ways(' > ','user/list.php');
+ print " > ".$ways[0]."
\n";
+ print "
";
+}
+
if ($sall)
{
foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
@@ -304,7 +327,29 @@ if ($sall)
$moreforfilter='';
+// Filter on categories
+if (! empty($conf->categorie->enabled))
+{
+ $moreforfilter.='';
+ $moreforfilter.=$langs->trans('Categories'). ': ';
+ $moreforfilter.=$htmlother->select_categories(Categorie::TYPE_USER,$search_categ,'search_categ',1);
+ $moreforfilter.='';
+}
+
+$parameters=array();
+$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook
+if (empty($reshook)) $moreforfilter.=$hookmanager->resPrint;
+else $moreforfilter=$hookmanager->resPrint;
+
+if ($moreforfilter)
+{
+ print '';
+ print $moreforfilter;
+ print '';
+}
+
$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
+
$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
diff --git a/htdocs/user/note.php b/htdocs/user/note.php
index 5e1c33cb57d..1cf994db9e9 100644
--- a/htdocs/user/note.php
+++ b/htdocs/user/note.php
@@ -93,7 +93,7 @@ if ($id)
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
diff --git a/htdocs/user/notify/card.php b/htdocs/user/notify/card.php
index 575af204618..f4e06075e79 100644
--- a/htdocs/user/notify/card.php
+++ b/htdocs/user/notify/card.php
@@ -137,7 +137,7 @@ if ($result > 0)
dol_fiche_head($head, 'notify', $langs->trans("User"), -1, 'user');
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', '', '', 0, '', '', 0, '');
diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php
index 563ff54c490..521b0e4022e 100644
--- a/htdocs/user/param_ihm.php
+++ b/htdocs/user/param_ihm.php
@@ -195,7 +195,7 @@ if ($action == 'edit')
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php
index e6487cba47c..8b7599f3707 100644
--- a/htdocs/user/perms.php
+++ b/htdocs/user/perms.php
@@ -239,13 +239,13 @@ else
$linkback = '';
if ($user->rights->user->user->lire || $user->admin) {
- $linkback = ''.$langs->trans("BackToList").'';
+ $linkback = ''.$langs->trans("BackToList").'';
}
dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
-//print '';
+print '';
if ($user->admin) print info_admin($langs->trans("WarningOnlyPermissionOfActivatedModules"));
// Show warning about external users
@@ -257,6 +257,7 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e
print "\n";
+print '';
print '';
print '';
print ''.$langs->trans("Module").' ';
@@ -392,6 +393,7 @@ if ($result)
}
else dol_print_error($db);
print '
';
+print '';
$parameters=array();
$reshook=$hookmanager->executeHooks('insertExtraFooter',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
diff --git a/htdocs/variants/card.php b/htdocs/variants/card.php
index be73db1fff0..8cb4e13b33e 100644
--- a/htdocs/variants/card.php
+++ b/htdocs/variants/card.php
@@ -133,7 +133,6 @@ if ($confirm == 'yes') {
$langs->load('products');
$title = $langs->trans('ProductAttributeName', dol_htmlentities($object->label));
-$var = false;
llxHeader('', $title);
diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
index 58eb2178da4..a0aed832eac 100644
--- a/htdocs/variants/class/ProductCombination.class.php
+++ b/htdocs/variants/class/ProductCombination.class.php
@@ -1,6 +1,7 @@
+ * Copyright (C) 2018 Juanjo Menent
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -329,6 +330,8 @@ class ProductCombination
$child->price_autogen = $parent->price_autogen;
$child->weight = $parent->weight + $this->variation_weight;
$child->weight_units = $parent->weight_units;
+ $varlabel = $this->getCombinationLabel($this->fk_product_child);
+ $child->label = $parent->label.$varlabel;
if ($child->update($child->id, $user) > 0) {
@@ -337,14 +340,33 @@ class ProductCombination
// MultiPrix
if (! empty($conf->global->PRODUIT_MULTIPRICES)) {
- $new_type = $parent->multiprices_base_type[1];
- $new_min_price = $parent->multiprices_min[1];
- $new_psq = $parent->multiprices_recuperableonly[1];
+ for ($i=1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++)
+ {
+ if ($parent->multiprices[$i] != '') {
+ $new_type = $parent->multiprices_base_type[$i];
+ $new_min_price = $parent->multiprices_min[$i];
+ if ($parent->prices_by_qty_list[$i]) {
+ $new_psq = 1;
+ } else {
+ $new_psq = 0;
+ }
- if ($new_type == 'TTC') {
- $new_price = $parent->multiprices_ttc[1];
- } else {
- $new_price = $parent->multiprices[1];
+ if ($new_type == 'TTC') {
+ $new_price = $parent->multiprices_ttc[$i];
+ } else {
+ $new_price = $parent->multiprices[$i];
+ }
+
+ if ($this->variation_price_percentage) {
+ if ($new_price != 0) {
+ $new_price *= 1 + ($this->variation_price / 100);
+ }
+ } else {
+ $new_price += $this->variation_price;
+ }
+
+ $child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, $i, $new_npr, $new_psq);
+ }
}
} else {
$new_type = $parent->price_base_type;
@@ -356,15 +378,17 @@ class ProductCombination
} else {
$new_price = $parent->price;
}
- }
- if ($this->variation_price_percentage) {
- $new_price *= 1 + ($this->variation_price/100);
- } else {
- $new_price += $this->variation_price;
- }
+ if ($this->variation_price_percentage) {
+ if ($new_price != 0) {
+ $new_price *= 1 + ($this->variation_price / 100);
+ }
+ } else {
+ $new_price += $this->variation_price;
+ }
- $child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, 1, $new_npr, $new_psq);
+ $child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, 1, $new_npr, $new_psq);
+ }
$this->db->commit();
@@ -634,7 +658,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
}
$db->commit();
- return 1;
+ return $newproduct->id;
}
/**
@@ -681,4 +705,39 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
return 1;
}
+
+ /**
+ * Return label for combinations
+ * @param int $prod_child id of child
+ * @return string combination label
+ */
+ public function getCombinationLabel($prod_child)
+ {
+ $label = '';
+ $sql = 'SELECT pav.value AS label';
+ $sql.= ' FROM '.MAIN_DB_PREFIX.'product_attribute_combination pac';
+ $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product_attribute_combination2val pac2v ON pac2v.fk_prod_combination=pac.rowid';
+ $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product_attribute_value pav ON pav.rowid=pac2v.fk_prod_attr_val';
+ $sql.= ' WHERE pac.fk_product_child='.$prod_child;
+
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $num = $this->db->num_rows($resql);
+
+ $i = 0;
+
+ while ($i < $num)
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ if ($obj->label)
+ {
+ $label.=' '.$obj->label;
+ }
+ $i++;
+ }
+
+ }
+ return $label;
+ }
}
diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php
index 0d1ea7af03b..fb23921be25 100644
--- a/htdocs/variants/combinations.php
+++ b/htdocs/variants/combinations.php
@@ -27,7 +27,6 @@ require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination2ValuePair.cla
$langs->loadLangs(array("products", "other"));
-$var = false;
$id = GETPOST('id', 'int');
$valueid = GETPOST('valueid', 'int');
$ref = GETPOST('ref');
@@ -319,6 +318,66 @@ if (! empty($id) || ! empty($ref))
dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', '', '', '', 0, '', '', 1);
+ print '';
+
+ print '';
+ print '';
+
+ // TVA
+ print '' . $langs->trans("DefaultTaxRate") . ' ';
+
+ $positiverates='';
+ if (price2num($object->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($object->tva_tx);
+ if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx);
+ if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx);
+ if (empty($positiverates)) $positiverates='0';
+ echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr);
+ /*
+ if ($object->default_vat_code)
+ {
+ print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')';
+ }
+ else print vatrate($object->tva_tx, true, $object->tva_npr, true);*/
+ print ' ';
+
+ // Price
+ print '' . $langs->trans("SellingPrice") . ' ';
+ if ($object->price_base_type == 'TTC') {
+ print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type);
+ } else {
+ print price($object->price) . ' ' . $langs->trans($object->price_base_type);
+ }
+ print ' ';
+
+ // Price minimum
+ print '' . $langs->trans("MinPrice") . ' ';
+ if ($object->price_base_type == 'TTC') {
+ print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type);
+ } else {
+ print price($object->price_min) . ' ' . $langs->trans($object->price_base_type);
+ }
+ print ' ';
+
+ // Weight
+ print ''.$langs->trans("Weight").' ';
+ if ($object->weight != '')
+ {
+ print $object->weight." ".measuring_units_string($object->weight_units,"weight");
+ }
+ else
+ {
+ print ' ';
+ }
+ print " \n";
+
+
+
+
+ print "
\n";
+
+ print '';
+ print '';
+
dol_fiche_end();
@@ -327,7 +386,7 @@ if (! empty($id) || ! empty($ref))
if ($action == 'add') {
$title = $langs->trans('NewProductCombination');
- print dol_fiche_head();
+ //print dol_fiche_head();
$features = $_SESSION['addvariant_'.$object->id];
//First, sanitize
print '';
@@ -348,7 +407,8 @@ if (! empty($id) || ! empty($ref))
}
}
print '';
- print dol_fiche_end();
+ print '
';
+ //print dol_fiche_end();
} else {
$title = $langs->trans('EditProductCombination');
}
@@ -634,12 +694,14 @@ if (! empty($id) || ! empty($ref))
print '';
print ' ';
- if ($productCombinations) {
- print ''.$langs->trans('PropagateVariant').'';
- }
print ''.$langs->trans('NewProductCombination').''; // NewVariant
+ if ($productCombinations)
+ {
+ print ''.$langs->trans('PropagateVariant').'';
+ }
+
// Too much bugged page.
/*
print ''.$langs->trans('ProductCombinationGenerator').'';
diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php
index 843304fbe45..3f51f669829 100644
--- a/htdocs/website/class/website.class.php
+++ b/htdocs/website/class/website.class.php
@@ -1079,20 +1079,72 @@ class Website extends CommonObject
}
/**
- * Component to select language (Full CSS Only)
+ * Component to select language inside a container (Full CSS Only)
*
- * @param array $languagecodes Language codes array. Example: array('en_US','fr_FR','de_DE','es_ES')
- * @param Translate $weblangs Language Object
- * @param string $morecss More CSS class on component
- * @param string $htmlname Suffix for HTML name
- * @return string HTML select component
+ * @param array|string $languagecodes 'auto' to show all languages available for page, or language codes array like array('en_US','fr_FR','de_DE','es_ES')
+ * @param Translate $weblangs Language Object
+ * @param string $morecss More CSS class on component
+ * @param string $htmlname Suffix for HTML name
+ * @return string HTML select component
*/
public function componentSelectLang($languagecodes, $weblangs, $morecss='', $htmlname='')
{
+ global $websitepagefile, $website;
+
if (! is_object($weblangs)) return 'ERROR componentSelectLang called with parameter $weblangs not defined';
- $languagecodeselected = $weblangs->defaultlang;
+ // Load tmppage if we have $websitepagefile defined
+ $tmppage=new WebsitePage($this->db);
+
+ $pageid = 0;
+ if (! empty($websitepagefile))
+ {
+ $pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
+ if ($pageid > 0)
+ {
+ $tmppage->fetch($pageid);
+ }
+ }
+
+ // Fill with existing translation, nothing if none
+ if (! is_array($languagecodes) && $pageid > 0)
+ {
+ $languagecodes = array();
+
+ $sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
+ $sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp";
+ $sql.=" WHERE wp.fk_website = ".$website->id;
+ $sql.=" AND (wp.fk_page = ".$pageid." OR wp.rowid = ".$pageid;
+ if ($tmppage->fk_page > 0) $sql.=" OR wp.fk_page = ".$tmppage->fk_page." OR wp.rowid = ".$tmppage->fk_page;
+ $sql.=")";
+
+ $resql = $this->db->query($sql);
+ if ($resql)
+ {
+ while ($obj = $this->db->fetch_object($resql))
+ {
+ $newlang = $obj->lang;
+ if ($obj->rowid == $pageid) $newlang = $obj->lang;
+ if (! in_array($newlang, $languagecodes)) $languagecodes[]=$newlang;
+ }
+ }
+ }
+ // Now $languagecodes is always an array
+
+ $languagecodeselected= $weblangs->defaultlang; // Because we must init with a value, but real value is the lang of main parent container
+ if (! empty($websitepagefile))
+ {
+ $pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
+ if ($pageid > 0)
+ {
+
+ $languagecodeselected=$tmppage->lang;
+ if (! in_array($tmppage->lang, $languagecodes)) $languagecodes[]=$tmppage->lang; // We add language code of page into combo list
+ }
+ }
+
$weblangs->load('languages');
+ //var_dump($weblangs->defaultlang);
$url = $_SERVER["REQUEST_URI"];
$url = preg_replace('/(\?|&)l=([a-zA-Z_]*)/', '', $url); // We remove param l from url
@@ -1103,7 +1155,8 @@ class Website extends CommonObject
$MAXHEIGHT = 4 * $HEIGHTOPTION;
$nboflanguage = count($languagecodes);
- $out.=''."\n";
+ $out =''."\n";
+
$out.= '