diff --git a/COPYRIGHT b/COPYRIGHT index 1631f85d321..cf31432caf0 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -21,6 +21,7 @@ GeoIP 1.4 LGPL-2.1+ Yes NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package) odtPHP 1.0.1 GPL-2+ b Yes Library to build/edit ODT files PHPExcel 1.7.8 LGPL-2.1+ Yes Read/Write XLS files, read ODS files +php-iban 1.4.6 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests TCPDF 6.0.093 LGPL-3+ Yes PDF generation @@ -54,7 +55,10 @@ Copyright --------- Copyright (C) 2015 +- Laurent Destailleur - Marcos GarcĂ­a +- Alexandre Spangaro +- Frederic France Copyright (C) 2014 - Laurent Destailleur @@ -67,6 +71,7 @@ Copyright (C) 2014 - Maxime Kohlhaas - Juanjo Menent - Alexandre Spangaro +- Frederic France Copyright (C) 2013 - Christophe Battarel diff --git a/htdocs/compta/bank/bankid_fr.php b/htdocs/compta/bank/bankid_fr.php index 03f0babe75d..f20d70ef14f 100644 --- a/htdocs/compta/bank/bankid_fr.php +++ b/htdocs/compta/bank/bankid_fr.php @@ -245,10 +245,26 @@ if (($_GET["id"] || $_GET["ref"]) && $action != 'edit') if ($account->getCountryCode() == 'IN') $bickey="SWIFT"; print ''.$langs->trans($ibankey).''; - print ''.$account->iban.''; + print ''.$account->iban.' '; + if (! empty($account->iban)) { + if (! checkIbanForAccount($account)) { + print img_picto($langs->trans("IbanNotValid"),'warning'); + } else { + print img_picto($langs->trans("IbanValid"),'info'); + } + } + print ''; print ''.$langs->trans($bickey).''; - print ''.$account->bic.''; + print ''.$account->bic.' '; + if (! empty($account->bic)) { + if (! checkSwiftForAccount($account)) { + print img_picto($langs->trans("SwiftNotValid"),'warning'); + } else { + print img_picto($langs->trans("SwiftValid"),'info'); + } + } + print ''; print ''.$langs->trans("BankAccountDomiciliation").''; print nl2br($account->domiciliation); diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php index e3fb787657b..db6b9d5b8aa 100644 --- a/htdocs/core/lib/bank.lib.php +++ b/htdocs/core/lib/bank.lib.php @@ -121,7 +121,43 @@ function bank_admin_prepare_head($object) complete_head_from_modules($conf, $langs, $object, $head, $h, 'bank_admin', 'remove'); return $head; - } +} + +/** + * Check SWIFT informations for a bank account + * + * @param Account $account A bank account + * @return int True if informations are valid, false otherwise + */ +function checkSwiftForAccount($account) +{ + $swift = $account->bic; + if (eregi("^([a-zA-Z]){4}([a-zA-Z]){2}([0-9a-zA-Z]){2}([0-9a-zA-Z]{3})?$", $swift)) { + return true; + } else { + return false; + } + +} + +/** + * Check IBAN number informations for a bank account + * + * @param Account $account A bank account + * @return int True if informations are valid, false otherwise + */ +function checkIbanForAccount($account) +{ + require_once DOL_DOCUMENT_ROOT.'/includes/php-iban/oophp-iban.php'; + $iban = new Iban($account->iban); + $check = $iban->Verify(); + if ($check) { + return true; + } else { + return false; + } + +} /** * Check account number informations for a bank account diff --git a/htdocs/includes/php-iban/LICENSE b/htdocs/includes/php-iban/LICENSE new file mode 100644 index 00000000000..65c5ca88a67 --- /dev/null +++ b/htdocs/includes/php-iban/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/htdocs/includes/php-iban/docs/COMEDY-OF-ERRORS b/htdocs/includes/php-iban/docs/COMEDY-OF-ERRORS new file mode 100644 index 00000000000..0eb3b8860ad --- /dev/null +++ b/htdocs/includes/php-iban/docs/COMEDY-OF-ERRORS @@ -0,0 +1,55 @@ +This file lists specific errors observed in the official IBAN specification. + +In addition to the specific errors, there persist basic outstanding +matters that cause issue for implementers: + - Non 1:1 mapping of records to countries (eg: French territories, etc.) + - Mixing of free text and hard data in specification fields + - Lack of validation of information in fields prior to publishing + - Lack of synchronisation between TXT and PDF versions of the registry + +2011-07-16 +---------- + - No information for Kuwait past sixth column + - Total absence of information regarding Kazakhstan + - '1.00001E+15' instead of a valid BBAN example for Lithuania + - Repeated IBAN example in human format instead of IBAN format- + specification for UAE + - Incorrect domestic example for Bulgaria, Kazakhstan, Latvia, + Lithuania, Luxembourg, Macedonia, Mauritius, Romania, San Marino + (complete, human-format IBAN instead of domestic example) + +Early 2012 +---------- + - Inconsistent record ordering (KW, KZ) + - Inconsistent capitalization (DK) + - Continued presence of incorrect domestic examples + +February 2013 +------------- + - Deployment of unparseable special values such as "Not in use" (FI). + - Still(!) missing a registry entry for 2010's 'new' entry of Khazakstan + +September 2013 +-------------- + - Azerbaijan, Brazil, Costa Rica, Palestine, Virgin Islands 'SEPA + Country' field in PDF (yes/no) is completely blank + +March 2014 +---------- + - In multiple cases, territories of a major country have a SEPA status + that differs from the parent jurisdiction. The IBAN specification as + previously released does not include individual records for these + territories, and thus cannot convey this important information. + - The IBAN registry's old URL is no longer publicly available! Its now + ends in a 404, and the apparent new home, located over at + http://www.swift.com/products_services/by_type/reference_data/iban_registry_iso13616 + does not have any content. The parent portion of this part of the + SWIFT website suggests the information may have been moved to a new + 'SWIFTRef' site, however that site appears to only peddle paid for + directories of BICs and similar. The new location after much + searching was found to be http://www.swift.com/products_services/bic_and_iban_format_registration_iban_format_r + +June 2014 +--------- + - The TXT registry records of QA and JO do not match those within the + PDF and are essentially spurious while looking roughly correct. Dang. diff --git a/htdocs/includes/php-iban/docs/ECBS standard implementation guidelines SIG203V3.2.pdf b/htdocs/includes/php-iban/docs/ECBS standard implementation guidelines SIG203V3.2.pdf new file mode 100644 index 00000000000..c7c860aee67 Binary files /dev/null and b/htdocs/includes/php-iban/docs/ECBS standard implementation guidelines SIG203V3.2.pdf differ diff --git a/htdocs/includes/php-iban/docs/HACKING b/htdocs/includes/php-iban/docs/HACKING new file mode 100644 index 00000000000..dfc48f1ae5b --- /dev/null +++ b/htdocs/includes/php-iban/docs/HACKING @@ -0,0 +1,63 @@ +By unix tradition, this file outlines information that may be useful to +people who wish to modify the php-iban project. It outlines some basic +information around design decisions and other considerations. + + Procedural style + ---------------- + The code is written in PHP's original procedural style, and does + not require or assume any OO model. This is unix tradition and + should ease any integration pains due to objectspace mismatches. + In addition, it should make it easy for users both within an OO + or a procedural codebase to make use of the library. An OO wrapper + has been supplied to make things more familiar for those who are + only exposed to OO PHP: please try to keep it in synch with the + procedural (main) library where possible. + + Registry maintenance + -------------------- + The 'convert-registry.php' tool found in the 'utils/' subdirectory + is intended to assist with the automatic conversion of the SWIFT- + provided 'IBAN Registry' text files to the format required to + support php-iban execution. Why is there a new format, and why is it + distributed with php-iban instead of being generated on the fly + from SWIFT-provided data files? There are a few reasons: + + - Error correction + If errors are discovered in the official specification then they + can be resolved by us. There are (or have been) known errors + with the official IBAN Registry. (See COMEDY-OF-ERRORS) + + - Exclusion correction + If exclusions are discovered in the official specification then + they can be resolved by us. There are (or have been) known + exclusions from the official IBAN Registry. (See COMEDY-OF-ERRORS) + + - Efficiency + Because pattern matching is a core part of the functionality of + php-iban, and the pattern algorithms distributed by SWIFT are + (rather strangely) not in regular expression format, using their + files directly would result in a fairly significant startup + penalty as pattern conversion would be required (at each + invocation!) unless a caching strategy were deployed, which would + create additional complexity and sources of bugs (in addition, + due to the previous two points automatic conversion is not + presently possible ... and may never be!) + + - Maintainability + Distribution of a modified registry along with php-iban places + the burden of registry maintenance on with the package + maintainer(s) rather than with the user. This is better for + users who, if they really want, can still hack their local copy. + + Note that due to points one and two, the 'convert-registry.php' tool + is insufficient to produce a correct 'registry.txt' file. (You may + wish to review the differences between your newly generated file + and the original with the 'diff' tool in order to ascertain what + has changed.) + + A closing point on the registry: obviously, if any new fields are + added, then it is best to append them to the end of the registry + (rightmost, new field) in order to preserve backwards compatibility + instead of re-ordering the fields which would break older installs. + (The internal '_iban_load_registry()' function re-orders these fields + at load time in order to simplify runtime debugging, anyway.) diff --git a/htdocs/includes/php-iban/docs/ISO13616.pdf b/htdocs/includes/php-iban/docs/ISO13616.pdf new file mode 100644 index 00000000000..fa23285c4f7 Binary files /dev/null and b/htdocs/includes/php-iban/docs/ISO13616.pdf differ diff --git a/htdocs/includes/php-iban/docs/LICENSE b/htdocs/includes/php-iban/docs/LICENSE new file mode 100644 index 00000000000..fc8a5de7edf --- /dev/null +++ b/htdocs/includes/php-iban/docs/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/htdocs/includes/php-iban/docs/README b/htdocs/includes/php-iban/docs/README new file mode 100644 index 00000000000..e0deacd88f3 --- /dev/null +++ b/htdocs/includes/php-iban/docs/README @@ -0,0 +1,207 @@ +php-iban README +--------------- + +php-iban is a library for parsing and validating International Bank +Account Number (IBAN) information in PHP. + +It also validates Internet International Bank Account Number +(IIBAN) as specified at http://tools.ietf.org/html/draft-iiban-01 +(see also http://www.ifex-project.org/our-proposals/iiban) + +php-iban lives at http://code.google.com/p/php-iban + + What is an IBAN? + ---------------- + An IBAN is basically a standardised way of explaining a bank + account number that works across borders. Its structure is: + + + + + BBAN is the term used to describe the national-level format + for a bank account number, which varies between countries + (and was sometimes created just to get IBAN connectivity!). + Note that a BBAN may have its own checksum algorithm. + + IBAN provides basic protection, using the checksum, against + transcription (ie: human copying) errors. It also provides + a registry of valid destination countries and their BBAN + formats. Thus, when you ask php-iban to 'validate' an IBAN + it ensures that these checks are passed. However, it cannot + ensure that a bank account actually exists - the only party + who can do that is the receiving bank or country. + + IBAN was invented in Europe, however its usage is growing + rapidly to other parts of the world. Thus, the future of + this library looks pretty good. + + For further information, please see 'docs/ISO13616.pdf' or + visit Wikipedia at http://en.wikipedia.org/wiki/IBAN + + What is an IIBAN? + ----------------- + An Internet IBAN (IIBAN) identifies an internet-based financial + endpoint in a manner that is superset-compatible with the existing + European Committee for Banking Standards (ECBS) International Bank + Account Number (IBAN) standard [ISO13616]. + + For more information see http://tools.ietf.org/html/draft-iiban-00 + and http://www.ifex-project.org/our-proposals/iiban + + To disable IIBAN support from your installation, simply remove + the second ('AA|...') line from the top of the registry.txt file. + + Execution environment + --------------------- + At present the library merely requires a PHP engine to be present + and has no external dependencies. It is recommended that your + PHP engine is configured to disable verbose warnings for events + such as access of unknown array indexes, though this should be + standard on almost any PHP deployment today. Any PHP engine + in use today should be compatible, though PHP3 or PHP4 execution + environments may require minor modifications (specifically, + some string functions may have changed). + + Installation + ------------ + Simply copy 'php-iban.php' and 'registry.txt' to an appropriate + location for your project. The location of the files will affect + the 'require_once()' line used to load the library from your + codebase, and may have relevance security (see 'Security' below). + Note that 'php-iban.php' expects to find 'registry.txt' in the + same directory as itself. + + Security + -------- + Following best practice for library files, the location chosen + for the php-iban.php and registry.txt files should ideally be + outside of any web-accessible directories. Thus, if your + web project lives in /var/www/myproject/htdocs/ then it would + be preferably to place php-iban in /var/www/myproject or some + other directory that is not visible to regular web users. + + Secondly, neither file should be writable by the web server + itself in order to prevent compromise of the execution path + (ie: getting hacked). So, for example if your web server runs + as user 'www', group 'www', you can ensure that the web server + has minimal required privileges against the files as follows + (note that you will need to be root to execute these commands): + + # chown php-iban registry.txt # where is a + # non-root user that + # is not 'www'. + # chgrp www php-iban registry.txt # set group to 'www' + # chmod ugo-rwx php-iban registry.txt # remove privileges + # chmod g+r php-iban registry.txt # allow 'www' group + # to read the files + + Obviously the above do not apply if you are using PHP in a + non web-oriented project (eg: a cronjob or daemon), a usage + of the language that is apparently growing - but limited. + + Using the library + ----------------- + Basic invocation is as follows: + + # include the library + require_once('/path/to/php-iban.php'); # /path/to/ is optional + + # use some library function or other... + if(!verify_iban($iban_to_verify)) { + # blame the user... + } + + Note that because the library is designed in a procedural manner + rather than an object-oriented manner it should be easy to + integrate with a wide variety of established codebases and + PHP interpreter versions. + + Using the library's OO wrapper + ------------------------------ + Because many new PHP programmers seems to learn the language via + books that only teach OO based programming and are thus unfamiliar + with procedural PHP (and often relatively inexperienced as + programmers, too) an OO wrapper-library has been provided. + + ======================= READ THIS ================================= + However *you should avoid excessive use of OO*. For some thought + provoking discussions of the negative aspects of overusing OO, + please refer to 'Coders at Work' and 'The Art of UNIX Programming'. + (OO is great for some problems, but simply pointless for most.) + =================================================================== + + Anyway, to use the OO wrapper supplied, invocation is as follows: + + # include the OO wrapper to the library + require_once('/path/to/oophp-iban.php'); # /path/to is optional + + # instantiate an IBAN object + $myIban = new IBAN('AZ12345678901234'); + if(!$myIban->Verify()) { + # blame the user... + } + + Documentation + ------------- + There are three types of functions provided by the library: + + - IBAN-level functions + + These are functions that operate on an IBAN. All of these + functions accept either machine format or human format + IBANs as input. Typically they return facts about an IBAN + as their output (for example whether it is valid or not, + or the BBAN (national-level) portion of the IBAN), though + some of them may perform other functions (eg: fixing a + broken IBAN checksum). These functions are named 'iban_*' + with the exception of the most commonly used function, + 'verify_iban()', and excepting the country-level functions. + + (Regarding the object oriented wrapper - all of these + functions are implemented as methods on IBAN objects) + + - IBAN country-level functions + These functions return information about countries that are + part of the IBAN standard. They each take the two letter + ISO country code at the beginning of an IBAN as their + argument. They are named 'iban_country_*', with the + exception of 'iban_countries()' which returns a list of + the known IBAN countries. (For example, functions that + return an example IBAN or BBAN for the country, or the + name of the country.) + + (Regarding the object oriented wrapper - all of these + functions are implemented as methods on IBANCountry + objects, except for 'iban_countries()' which is + implemented as the Countries() method on the IBAN class) + + - Internal functions + These functions begin with '_iban_*' and can be ignored. + + (Regarding the object oriented wrapper - these functions + are not present) + + Please refer to either http://code.google.com/p/php-iban or the + commented source code of php-iban itself for the complete list of + which functions are available. Of course, in unix style one could + achieve the same in a pinch as follows (instant documentation!): + $ grep function php-iban.php + $ egrep '(Class|function)' oophp-iban.php + + Community + --------- + You are encouraged to contribute bugs, feedback and suggestions + through the project's website. + + Particularly if you deploy php-iban in a commercial setting, you are + STRONGLY encouraged to join the project's mailing list, which can + be found via the website. Joining the mailing list ensures that you + can be made aware of important updates. Important updates include: + - Updates to new registry editions (support new countries that have + been added to the IBAN system) + - Bug fixes + - Security updates + + The email list receives almost no traffic and as a 'Google Group' is + well protected from spam, so don't worry about junk in your inbox. + +Thanks for choosing php-iban! You have excellent taste in software ;) diff --git a/htdocs/includes/php-iban/docs/REGISTRY-URL b/htdocs/includes/php-iban/docs/REGISTRY-URL new file mode 100644 index 00000000000..58fb8c6dadb --- /dev/null +++ b/htdocs/includes/php-iban/docs/REGISTRY-URL @@ -0,0 +1,17 @@ +To get the latest ISO13616 IBAN registry, go to: + http://www.swift.com/products_services/bic_and_iban_format_registration_iban_format_r + +TXT format: + http://www.swift.com/dsp/resources/documents/IBAN_Registry.txt + +PDF format: + http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf + +Unfortunately, it has been noticed in 2011 that the official .txt file is +not an accurate representation of the PDF format specification, and lacks +some information. It is hoped that in future SWIFT will be more careful to +publish only correct standards information. + +It has been noted in 2014 that this is still the case. + +(For more information on this subject, see the HACKING file) diff --git a/htdocs/includes/php-iban/docs/SEPA b/htdocs/includes/php-iban/docs/SEPA new file mode 100644 index 00000000000..8310ff1cfb0 --- /dev/null +++ b/htdocs/includes/php-iban/docs/SEPA @@ -0,0 +1,9 @@ +Interpreting the SEPA Field +=========================== + +Note that some IIBAN providers may in fact provide SEPA connectivity. + +Thus, implementers are reminded to consider the reported SEPA status +of a country within the registry as confirming rather than negating +the potential SEPA status of a potential financial institution who +may be party to a proposed transaction. diff --git a/htdocs/includes/php-iban/docs/TODO b/htdocs/includes/php-iban/docs/TODO new file mode 100644 index 00000000000..906ab7e3fb6 --- /dev/null +++ b/htdocs/includes/php-iban/docs/TODO @@ -0,0 +1,21 @@ +TODO +---- + + - Finnish record suggests position at which to pad domestic account + numbers in order to reach a BBAN / IBAN, this data could be of + some use for certain applications and would be nice to include + - Addition of information regarding preferred human-level formatting + for each country's BBAN - worthwhile? + - Addition of 'date effective' information for records such as BH + and the UAE that published data in advance of deployment + - Support for calculating or validating any known national (sub- + BBAN-level) checksum algorithms? + - URLs to national-level BBAN format specifications + - Consider adding a library of localised forms and abbreviations + for account number portions, for example Austria and Germany seem + to have 'Kontonummer' (KTO) for account number, and 'Bankleitzah' + (BLZ) for bank identifier. This could assist greatly with + deployments requiring international and/or constrained input. + - Consider building a library of national-level bank or payment + institution identifier codes. This would be rather large and an + optional extension and would be in competition with SWIFTRef. diff --git a/htdocs/includes/php-iban/mistranscriptions.txt b/htdocs/includes/php-iban/mistranscriptions.txt new file mode 100644 index 00000000000..7593475ff6f --- /dev/null +++ b/htdocs/includes/php-iban/mistranscriptions.txt @@ -0,0 +1,49 @@ + ; formalities + input-roman = number / letter + number = c-0 / c-1 / c-2 / c-3 / c-4 / c-5 / c-6 / c-7 / c-8 / c-9 + letter = c-a / c-b / c-c / c-d / c-e / c-f / c-g / c-h / c-i / c-j + / c-k / c-l / c-m / c-n / c-o / c-p / c-q / c-r / c-s + / c-t / c-u / c-v / c-w / c-x / c-y / c-z + + ; possible sources of mistranscribed numbers + c-0 = "O" / "6" / "D" / "G" + c-1 = "I" / "L" / "7" / "2" / "Z" + c-2 = "Z" / "7" / "P" / "E" / "1" + c-3 = "8" / "B" + c-4 = "G" / "U" + c-5 = "S" / "7" + c-6 = "0" / "O" / "8" / "G" / "C" / "B" / "D" + c-7 = "J" / "I" / "1" / "L" + c-8 = "B" / "3" / "6" + c-9 = "G" / "Y" / "O" / "0" / "D" + + ; possible sources of mistranscribed letters + c-a = "G" / "Q" / "O" / "0" + c-b = "6" / "3" / "8" / "P" / "0" / "O" + c-c = "R" / "6" / "I" / "L" / "O" / "0" + c-d = "0" / "O" / "9" / "Q" / "G" / "6" / "A" + c-e = "F" / "G" / "0" / "2" / "K" / "Z" / "S" / "O" + c-f = "E" / "K" / "T" / "P" / "Y" / "4" / "B" / "7" / "1" + c-g = "9" / "Q" / "8" / "6" / "0" / "C" / "4" / "O" + c-h = "B" / "N" / "A" / "4" / "6" / "M" / "W" / "F" / "R" / "T" / "X" + c-i = "1" / "L" / "7" / "J" / "2" / "T" / "Z" + c-j = "I" / "7" / "2" / "9" / "1" / "U" / "T" / "Q" / "P" / "Y" / "Z" + / "L" / "S" + c-k = "F" / "X" / "H" / "R" + c-l = "1" / "2" / "7" / "C" / "I" / "J" / "R" / "T" / "Y" / "Z" + c-m = "H" / "8" / "E" / "3" / "N" / "V" / "W" + c-n = "H" / "R" / "C" / "2" / "4" / "M" / "O" / "P" / "K" / "T" / "Z" + c-o = "0" / "6" / "9" / "A" / "D" / "G" / "C" / "E" / "B" / "N" / "P" + / "Q" / "R" + c-p = "F" / "4" / "8" / "2" / "B" / "J" / "R" / "N" / "O" / "T" / "Y" + c-q = "O" / "G" / "9" / "Y" / "1" / "7" / "L" + c-r = "K" / "B" / "V" / "C" / "1" / "L" / "2" + c-s = "5" / "6" / "9" / "B" / "G" / "Q" / "A" / "Y" + c-t = "1" / "4" / "7" / "F" / "I" / "J" / "L" / "P" / "X" / "Y" + c-u = "V" / "N" / "A" / "4" / "9" / "W" / "Y" + c-v = "U" / "R" / "N" + c-w = "M" / "N" / "U" / "V" + c-x = "K" / "F" / "4" / "T" / "V" / "Y" + c-y = "G" / "V" / "J" / "I" / "4" / "9" / "T" / "F" / "Q" / "1" + c-z = "2" / "1" / "L" / "R" / "I" / "7" / "V" / "3" / "4" + diff --git a/htdocs/includes/php-iban/oophp-iban.php b/htdocs/includes/php-iban/oophp-iban.php new file mode 100644 index 00000000000..76e3cd0d06b --- /dev/null +++ b/htdocs/includes/php-iban/oophp-iban.php @@ -0,0 +1,157 @@ +iban = $iban; + } + + public function Verify($iban='') { + if($iban!='') { return verify_iban($iban); } + return verify_iban($this->iban); + # we could throw exceptions of various types, but why - does it really + # add anything? possibly some slightly better user feedback potential. + # however, this can be written by hand by performing individual checks + # ala the code in verify_iban() itself where required, which is likely + # almost never. for the increased complexity and + # maintenance/documentation cost, i say, therefore: no. no exceptions. + } + + public function MistranscriptionSuggestions() { + return iban_mistranscription_suggestions($this->iban); + } + + public function MachineFormat() { + return iban_to_machine_format($this->iban); + } + + public function HumanFormat() { + return iban_to_human_format($this->iban); + } + + public function Country($iban='') { + return iban_get_country_part($this->iban); + } + + public function Checksum($iban='') { + return iban_get_checksum_part($this->iban); + } + + public function BBAN() { + return iban_get_bban_part($this->iban); + } + + public function VerifyChecksum() { + return iban_verify_checksum($this->iban); + } + + public function FindChecksum() { + return iban_find_checksum($this->iban); + } + + public function SetChecksum() { + $this->iban = iban_set_checksum($this->iban); + } + + public function ChecksumStringReplace() { + return iban_checksum_string_replace($this->iban); + } + + public function Parts() { + return iban_get_parts($this->iban); + } + + public function Bank() { + return iban_get_bank_part($this->iban); + } + + public function Branch() { + return iban_get_branch_part($this->iban); + } + + public function Account() { + return iban_get_account_part($this->iban); + } + + public function Countries() { + return iban_countries(); + } +} + +# IBANCountry +Class IBANCountry { + + # constructor with code + function __construct($code = '') { + $this->code = $code; + } + + public function Name() { + return iban_country_get_country_name($this->code); + } + + public function DomesticExample() { + return iban_country_get_domestic_example($this->code); + } + + public function BBANExample() { + return iban_country_get_bban_example($this->code); + } + + public function BBANFormatSWIFT() { + return iban_country_get_bban_format_swift($this->code); + } + + public function BBANFormatRegex() { + return iban_country_get_bban_format_regex($this->code); + } + + public function BBANLength() { + return iban_country_get_bban_length($this->code); + } + + public function IBANExample() { + return iban_country_get_iban_example($this->code); + } + + public function IBANFormatSWIFT() { + return iban_country_get_iban_format_swift($this->code); + } + + public function IBANFormatRegex() { + return iban_country_get_iban_format_regex($this->code); + } + + public function IBANLength() { + return iban_country_get_iban_length($this->code); + } + + public function BankIDStartOffset() { + return iban_country_get_bankid_start_offset($this->code); + } + + public function BankIDStopOffset() { + return iban_country_get_bankid_stop_offset($this->code); + } + + public function BranchIDStartOffset() { + return iban_country_get_branchid_start_offset($this->code); + } + + public function BranchIDStopOffset() { + return iban_country_get_branchid_stop_offset($this->code); + } + + public function RegistryEdition() { + return iban_country_get_registry_edition($this->code); + } + + public function IsSEPA() { + return iban_country_is_sepa($this->code); + } + +} + +?> diff --git a/htdocs/includes/php-iban/php-iban.php b/htdocs/includes/php-iban/php-iban.php new file mode 100644 index 00000000000..e4ef4d8dd1d --- /dev/null +++ b/htdocs/includes/php-iban/php-iban.php @@ -0,0 +1,486 @@ +0) && (($i+1)%4==0)) { $human_iban .= ' '; } + } + return $human_iban; +} + +# Get the country part from an IBAN +function iban_get_country_part($iban) { + $iban = iban_to_machine_format($iban); + return substr($iban,0,2); +} + +# Get the checksum part from an IBAN +function iban_get_checksum_part($iban) { + $iban = iban_to_machine_format($iban); + return substr($iban,2,2); +} + +# Get the BBAN part from an IBAN +function iban_get_bban_part($iban) { + $iban = iban_to_machine_format($iban); + return substr($iban,4); +} + +# Check the checksum of an IBAN - code modified from Validate_Finance PEAR class +function iban_verify_checksum($iban) { + # convert to machine format + $iban = iban_to_machine_format($iban); + # move first 4 chars (countrycode and checksum) to the end of the string + $tempiban = substr($iban, 4).substr($iban, 0, 4); + # subsitutute chars + $tempiban = iban_checksum_string_replace($tempiban); + # mod97-10 + $result = iban_mod97_10($tempiban); + # checkvalue of 1 indicates correct IBAN checksum + if ($result != 1) { + return false; + } + return true; +} + +# Find the correct checksum for an IBAN +# $iban The IBAN whose checksum should be calculated +function iban_find_checksum($iban) { + $iban = iban_to_machine_format($iban); + # move first 4 chars to right + $left = substr($iban,0,2) . '00'; # but set right-most 2 (checksum) to '00' + $right = substr($iban,4); + # glue back together + $tmp = $right . $left; + # convert letters using conversion table + $tmp = iban_checksum_string_replace($tmp); + # get mod97-10 output + $checksum = iban_mod97_10_checksum($tmp); + # return 98 minus the mod97-10 output, left zero padded to two digits + return str_pad((98-$checksum),2,'0',STR_PAD_LEFT); +} + +# Set the correct checksum for an IBAN +# $iban IBAN whose checksum should be set +function iban_set_checksum($iban) { + $iban = iban_to_machine_format($iban); + return substr($iban,0,2) . iban_find_checksum($iban) . substr($iban,4); +} + +# Character substitution required for IBAN MOD97-10 checksum validation/generation +# $s Input string (IBAN) +function iban_checksum_string_replace($s) { + $iban_replace_chars = range('A','Z'); + foreach (range(10,35) as $tempvalue) { $iban_replace_values[]=strval($tempvalue); } + return str_replace($iban_replace_chars,$iban_replace_values,$s); +} + +# Same as below but actually returns resulting checksum +function iban_mod97_10_checksum($numeric_representation) { + $checksum = intval(substr($numeric_representation, 0, 1)); + for ($position = 1; $position < strlen($numeric_representation); $position++) { + $checksum *= 10; + $checksum += intval(substr($numeric_representation,$position,1)); + $checksum %= 97; + } + return $checksum; +} + +# Perform MOD97-10 checksum calculation ('Germanic-level effiency' version - thanks Chris!) +function iban_mod97_10($numeric_representation) { + global $__disable_iiban_gmp_extension; + # prefer php5 gmp extension if available + if(!($__disable_iiban_gmp_extension) && function_exists('gmp_intval')) { return gmp_intval(gmp_mod(gmp_init($numeric_representation, 10),'97')) === 1; } + +/* + # old manual processing (~16x slower) + $checksum = intval(substr($numeric_representation, 0, 1)); + for ($position = 1; $position < strlen($numeric_representation); $position++) { + $checksum *= 10; + $checksum += intval(substr($numeric_representation,$position,1)); + $checksum %= 97; + } + return $checksum; + */ + + # new manual processing (~3x slower) + $length = strlen($numeric_representation); + $rest = ""; + $position = 0; + while ($position < $length) { + $value = 9-strlen($rest); + $n = $rest . substr($numeric_representation,$position,$value); + $rest = $n % 97; + $position = $position + $value; + } + return ($rest === 1); +} + +# Get an array of all the parts from an IBAN +function iban_get_parts($iban) { + return array( + 'country' => iban_get_country_part($iban), + 'checksum' => iban_get_checksum_part($iban), + 'bban' => iban_get_bban_part($iban), + 'bank' => iban_get_bank_part($iban), + 'country' => iban_get_country_part($iban), + 'branch' => iban_get_branch_part($iban), + 'account' => iban_get_account_part($iban) + ); +} + +# Get the Bank ID (institution code) from an IBAN +function iban_get_bank_part($iban) { + $iban = iban_to_machine_format($iban); + $country = iban_get_country_part($iban); + $start = iban_country_get_bankid_start_offset($country); + $stop = iban_country_get_bankid_stop_offset($country); + if($start!=''&&$stop!='') { + $bban = iban_get_bban_part($iban); + return substr($bban,$start,($stop-$start+1)); + } + return ''; +} + +# Get the Branch ID (sort code) from an IBAN +function iban_get_branch_part($iban) { + $iban = iban_to_machine_format($iban); + $country = iban_get_country_part($iban); + $start = iban_country_get_branchid_start_offset($country); + $stop = iban_country_get_branchid_stop_offset($country); + if($start!=''&&$stop!='') { + $bban = iban_get_bban_part($iban); + return substr($bban,$start,($stop-$start+1)); + } + return ''; +} + +# Get the (branch-local) account ID from an IBAN +function iban_get_account_part($iban) { + $iban = iban_to_machine_format($iban); + $country = iban_get_country_part($iban); + $start = iban_country_get_branchid_stop_offset($country); + if($start=='') { + $start = iban_country_get_bankid_stop_offset($country); + } + if($start!='') { + $bban = iban_get_bban_part($iban); + return substr($bban,$start+1); + } + return ''; +} + +# Get the name of an IBAN country +function iban_country_get_country_name($iban_country) { + return _iban_country_get_info($iban_country,'country_name'); +} + +# Get the domestic example for an IBAN country +function iban_country_get_domestic_example($iban_country) { + return _iban_country_get_info($iban_country,'domestic_example'); +} + +# Get the BBAN example for an IBAN country +function iban_country_get_bban_example($iban_country) { + return _iban_country_get_info($iban_country,'bban_example'); +} + +# Get the BBAN format (in SWIFT format) for an IBAN country +function iban_country_get_bban_format_swift($iban_country) { + return _iban_country_get_info($iban_country,'bban_format_swift'); +} + +# Get the BBAN format (as a regular expression) for an IBAN country +function iban_country_get_bban_format_regex($iban_country) { + return _iban_country_get_info($iban_country,'bban_format_regex'); +} + +# Get the BBAN length for an IBAN country +function iban_country_get_bban_length($iban_country) { + return _iban_country_get_info($iban_country,'bban_length'); +} + +# Get the IBAN example for an IBAN country +function iban_country_get_iban_example($iban_country) { + return _iban_country_get_info($iban_country,'iban_example'); +} + +# Get the IBAN format (in SWIFT format) for an IBAN country +function iban_country_get_iban_format_swift($iban_country) { + return _iban_country_get_info($iban_country,'iban_format_swift'); +} + +# Get the IBAN format (as a regular expression) for an IBAN country +function iban_country_get_iban_format_regex($iban_country) { + return _iban_country_get_info($iban_country,'iban_format_regex'); +} + +# Get the IBAN length for an IBAN country +function iban_country_get_iban_length($iban_country) { + return _iban_country_get_info($iban_country,'iban_length'); +} + +# Get the BBAN Bank ID start offset for an IBAN country +function iban_country_get_bankid_start_offset($iban_country) { + return _iban_country_get_info($iban_country,'bban_bankid_start_offset'); +} + +# Get the BBAN Bank ID stop offset for an IBAN country +function iban_country_get_bankid_stop_offset($iban_country) { + return _iban_country_get_info($iban_country,'bban_bankid_stop_offset'); +} + +# Get the BBAN Branch ID start offset for an IBAN country +function iban_country_get_branchid_start_offset($iban_country) { + return _iban_country_get_info($iban_country,'bban_branchid_start_offset'); +} + +# Get the BBAN Branch ID stop offset for an IBAN country +function iban_country_get_branchid_stop_offset($iban_country) { + return _iban_country_get_info($iban_country,'bban_branchid_stop_offset'); +} + +# Get the registry edition for an IBAN country +function iban_country_get_registry_edition($iban_country) { + return _iban_country_get_info($iban_country,'registry_edition'); +} + +# Is the IBAN country a SEPA member? +function iban_country_is_sepa($iban_country) { + return _iban_country_get_info($iban_country,'country_sepa'); +} + +# Get the list of all IBAN countries +function iban_countries() { + global $_iban_registry; + return array_keys($_iban_registry); +} + +# Given an incorrect IBAN, return an array of zero or more checksum-valid +# suggestions for what the user might have meant, based upon common +# mistranscriptions. +function iban_mistranscription_suggestions($incorrect_iban) { + + # abort on ridiculous length input (but be liberal) + $length = strlen($incorrect_iban); + if($length<5 || $length>34) { return array('(length bad)'); } + + # abort if mistranscriptions data is unable to load + if(!_iban_load_mistranscriptions()) { return array('(failed to load)'); } + + # init + global $_iban_mistranscriptions; + $suggestions = array(); + + # we have a string of approximately IBAN-like length. + # ... now let's make suggestions. + $numbers = array('0','1','2','3','4','5','6','7','8','9'); + for($i=0;$i<$length;$i++) { + # get the character at this position + $character = substr($incorrect_iban,$i,1); + # for each known transcription error resulting in this character + foreach($_iban_mistranscriptions[$character] as $possible_origin) { + # if we're: + # - in the first 2 characters (country) and the possible replacement + # is a letter + # - in the 3rd or 4th characters (checksum) and the possible + # replacement is a number + # - later in the string + if(($i<2 && !in_array($possible_origin,$numbers)) || + ($i>=2 && $i<=3 && in_array($possible_origin,$numbers)) || + $i>3) { + # construct a possible IBAN using this possible origin for the + # mistranscribed character, replaced at this position only + $possible_iban = substr($incorrect_iban,0,$i) . $possible_origin . substr($incorrect_iban,$i+1); + # if the checksum passes, return it as a possibility + if(verify_iban($possible_iban)) { + array_push($suggestions,$possible_iban); + } + } + } + } + + # now we check for the type of mistransposition case where all of + # the characters of a certain type within a string were mistransposed. + # - first generate a character frequency table + $char_freqs = array(); + for($i=0;$i$freq) { + # if the character occurs more than once + if($freq>1) { + # check the 'all occurrences of were mistranscribed' case + foreach($_iban_mistranscriptions[$char] as $possible_origin) { + $possible_iban = str_replace($char,$possible_origin,$incorrect_iban); + if(verify_iban($possible_iban)) { + array_push($suggestions,$possible_iban); + } + } + } + } + + return $suggestions; +} + + +##### internal use functions - safe to ignore ###### + +# Load the IBAN registry from disk. +global $_iban_registry; +$_iban_registry = array(); +_iban_load_registry(); +function _iban_load_registry() { + global $_iban_registry; + # if the registry is not yet loaded, or has been corrupted, reload + if(!is_array($_iban_registry) || count($_iban_registry)<1) { + $data = file_get_contents(dirname(__FILE__) . '/registry.txt'); + $lines = explode("\n",$data); + array_shift($lines); # drop leading description line + # loop through lines + foreach($lines as $line) { + if($line!='') { + # split to fields + $old_display_errors_value = ini_get('display_errors'); + ini_set('display_errors',false); + $old_error_reporting_value = ini_get('error_reporting'); + ini_set('error_reporting',false); + list($country,$country_name,$domestic_example,$bban_example,$bban_format_swift,$bban_format_regex,$bban_length,$iban_example,$iban_format_swift,$iban_format_regex,$iban_length,$bban_bankid_start_offset,$bban_bankid_stop_offset,$bban_branchid_start_offset,$bban_branchid_stop_offset,$registry_edition,$country_sepa) = explode('|',$line); + ini_set('display_errors',$old_display_errors_value); + ini_set('error_reporting',$old_error_reporting_value); + # assign to registry + $_iban_registry[$country] = array( + 'country' => $country, + 'country_name' => $country_name, + 'country_sepa' => $country_sepa, + 'domestic_example' => $domestic_example, + 'bban_example' => $bban_example, + 'bban_format_swift' => $bban_format_swift, + 'bban_format_regex' => $bban_format_regex, + 'bban_length' => $bban_length, + 'iban_example' => $iban_example, + 'iban_format_swift' => $iban_format_swift, + 'iban_format_regex' => $iban_format_regex, + 'iban_length' => $iban_length, + 'bban_bankid_start_offset' => $bban_bankid_start_offset, + 'bban_bankid_stop_offset' => $bban_bankid_stop_offset, + 'bban_branchid_start_offset' => $bban_branchid_start_offset, + 'bban_branchid_stop_offset' => $bban_branchid_stop_offset, + 'registry_edition' => $registry_edition + ); + } + } + } +} + +# Get information from the IBAN registry by example IBAN / code combination +function _iban_get_info($iban,$code) { + $country = iban_get_country_part($iban); + return _iban_country_get_info($country,$code); +} + +# Get information from the IBAN registry by country / code combination +function _iban_country_get_info($country,$code) { + global $_iban_registry; + $country = strtoupper($country); + $code = strtolower($code); + if(array_key_exists($country,$_iban_registry)) { + if(array_key_exists($code,$_iban_registry[$country])) { + return $_iban_registry[$country][$code]; + } + } + return false; +} + +# Load common mistranscriptions from disk. +function _iban_load_mistranscriptions() { + global $_iban_mistranscriptions; + # do not reload if already present + if(is_array($_iban_mistranscriptions) && count($_iban_mistranscriptions) == 36) { return true; } + $_iban_mistranscriptions = array(); + $file = dirname(__FILE__) . '/mistranscriptions.txt'; + if(!file_exists($file) || !is_readable($file)) { return false; } + $data = file_get_contents($file); + $lines = explode("\n",$data); + foreach($lines as $line) { + # match lines with ' c- = ' where x is a word-like character + if(preg_match('/^ *c-(\w) = (.*?)$/',$line,$matches)) { + # normalize the character to upper case + $character = strtoupper($matches[1]); + # break the possible origins list at '/', strip quotes & spaces + $chars = explode(' ',str_replace('"','',preg_replace('/ *?\/ *?/','',$matches[2]))); + # assign as possible mistranscriptions for that character + $_iban_mistranscriptions[$character] = $chars; + } + } + return true; +} + +?> diff --git a/htdocs/includes/php-iban/registry.txt b/htdocs/includes/php-iban/registry.txt new file mode 100644 index 00000000000..ffe714139dd --- /dev/null +++ b/htdocs/includes/php-iban/registry.txt @@ -0,0 +1,81 @@ +country_code|country_name|domestic_example|bban_example|bban_format_swift|bban_format_regex|bban_length|iban_example|iban_format_swift|iban_format_regex|iban_length|bban_bankid_start_offset|bban_bankid_stop_offset|bban_branchid_start_offset|bban_branchid_stop_offset|registry_edition|country_sepa +AA|IIBAN (Internet)|0011123Z5678|0011123Z5678|12!a|^[A-Z0-9]{12}$|12|AA120011123Z5678|AA2!n12!a|^AA(\d{2})([A-Z0-9]{12})$|16|0|3|||N/A|0 +AL|Albania|0000000235698741|212110090000000235698741|8!n16!c|^(\d{8})([A-Za-z0-9]{16})$|24|AL47212110090000000235698741|AL2!n8!n16!c|^AL(\d{2})(\d{8})([A-Za-z0-9]{16})$|28|0|2|3|6|2011-06-20|0 +AD|Andorra|2030200359100100|00012030200359100100|4!n4!n12!c|^(\d{4})(\d{4})([A-Za-z0-9]{12})$|20|AD1200012030200359100100|AD2!n4!n4!n12!c|^AD(\d{2})(\d{4})(\d{4})([A-Za-z0-9]{12})$|24|0|3|4|7|2011-06-20|0 +AT|Austria|19043-234573201|1904300234573201|5!n11!n|^(\d{5})(\d{11})$|16|AT611904300234573201|AT2!n5!n11!n|^AT(\d{2})(\d{5})(\d{11})$|20|0|4|||2011-06-20|1 +AX|Aland Islands|123456-785|12345600000785|6!n7!n1!n|^(\d{6})(\d{7})(\d{1})$|14|AX2112345600000785|AX2!n6!n7!n1!n|^AX(\d{2})(\d{6})(\d{7})(\d{1})$|18|0|2|||2013-09-05|1 +AZ|Azerbaijan|NABZ00000000137010001944|NABZ00000000137010001944|4!a20!c|^([A-Z]{4})([A-Za-z0-9]{20})$|24|AZ21NABZ00000000137010001944|AZ2!n4!a20!c|^AZ(\d{2})([A-Z]{4})([A-Za-z0-9]{20})$|28|0|3|||2012-05-29|0 +BH|Bahrain|00001299123456|BMAG00001299123456|4!a14!c|^([A-Z]{4})([A-Za-z0-9]{14})$|22|BH67BMAG00001299123456|BH2!n4!a14!c|^BH(\d{2})([A-Z]{4})([A-Za-z0-9]{14})$|22|0|3|||2012-05-29|0 +BE|Belgium|539-0075470-34|539007547034|3!n7!n2!n|^(\d{3})(\d{7})(\d{2})$|12|BE68539007547034|BE2!n3!n7!n2!n|^BE(\d{2})(\d{3})(\d{7})(\d{2})$|16|0|2|||2011-06-20|1 +BA|Bosnia and Herzegovina|199-044-00012002-79|1990440001200279|3!n3!n8!n2!n|^(\d{3})(\d{3})(\d{8})(\d{2})$|16|BA391290079401028494|BA2!n3!n3!n8!n2!n|^BA(\d{2})(\d{3})(\d{3})(\d{8})(\d{2})$|20|0|2|3|5|2011-06-20|0 +BR|Brazil|0009795493C1|00360305000010009795493P1|8!n5!n10!n1!a1!c|^(\d{8})(\d{5})(\d{10})([A-Z]{1})([A-Za-z0-9]{1})$|25|BR2300360305000010009795493P1BR1800000000141455123924100C2|BR2!n8!n5!n10!n1!a1!c|^BR(\d{2})(\d{8})(\d{5})(\d{10})([A-Z]{1})([A-Za-z0-9]{1})$|29|0|7|8|12|2013-06-20|0 +BG|Bulgaria|BNBG 9661 1020 3456 78|BNBG96611020345678|4!a4!n2!n8!c|^([A-Z]{4})(\d{4})(\d{2})([A-Za-z0-9]{8})$|18|BG80BNBG96611020345678|BG2!n4!a4!n2!n8!c|^BG(\d{2})([A-Z]{4})(\d{4})(\d{2})([A-Za-z0-9]{8})$|22|0|3|4|7|2011-06-20|1 +CR|Costa Rica|1026284066|15202001026284066|3!n14!n|^(\d{3})(\d{14})$|7|CR91202001026284066|CR2!n3!n14!n|^CR(\d{2})(\d{3})(\d{14})$|21|0|2|||2012-05-29|0 +HR|Croatia|1001005-1863000160|10010051863000160|7!n10!n|^(\d{7})(\d{10})$|17|HR1210010051863000160|HR2!n7!n10!n|^HR(\d{2})(\d{7})(\d{10})$|21|0|6|||2011-06-20|1 +CY|Cyprus|1200527600|002001280000001200527600|3!n5!n16!c|^(\d{3})(\d{5})([A-Za-z0-9]{16})$|24|CY17002001280000001200527600|CY2!n3!n5!n16!c|^CY(\d{2})(\d{3})(\d{5})([A-Za-z0-9]{16})$|28|0|2|3|7|2011-06-20|1 +CZ|Czech Republic|19-2000145399/0800|08000000192000145399|4!n6!n10!n|^(\d{4})(\d{6})(\d{10})$|20|CZ6508000000192000145399|CZ2!n4!n6!n10!n|^CZ(\d{2})(\d{4})(\d{6})(\d{10})$|24|0|3|4|9|2011-06-20|1 +DK|Denmark|0040 0440116243, 6460 0001631634, 6471 0001000206|00400440116243, 64600001631634, 64710001000206|4!n9!n1!n|^(\d{4})(\d{9})(\d{1})$|14|DK5000400440116243|DK2!n4!n9!n1!n|^DK(\d{2})(\d{4})(\d{9})(\d{1})$|18|0|3|||2011-06-20|1 +FO|Faroe Islands|0040 0440116243, 6460 0001631634, 6471 0001000206|00400440116243, 64600001631634, 64710001000206|4!n9!n1!n|^(\d{4})(\d{9})(\d{1})$|14|FO2000400440116243|FO2!n4!n9!n1!n|^FO(\d{2})(\d{4})(\d{9})(\d{1})$|18|0|3|||2011-06-20|0 +GL|Greenland|0040 0440116243, 6460 0001631634, 6471 0001000206|00400440116243, 64600001631634, 64710001000206|4!n9!n1!n|^(\d{4})(\d{9})(\d{1})$|14|GL2000400440116243|GL2!n4!n9!n1!n|^GL(\d{2})(\d{4})(\d{9})(\d{1})$|18|0|3|||2011-06-20|0 +DO|Dominican Republic|1212453611324|AGR00000001212453611324|4!c20!n|^([A-Za-z0-9]{4})(\d{20})$|24|DO28BAGR00000001212453611324|DO2!n4!c20!n|^DO(\d{2})([A-Za-z0-9]{4})(\d{20})$|28|0|3|||2011-06-20|0 +EE|Estonia|221020145685|2200221020145685|2!n2!n11!n1!n|^(\d{2})(\d{2})(\d{11})(\d{1})$|16|EE382200221020145685|EE2!n2!n2!n11!n1!n|^EE(\d{2})(\d{2})(\d{2})(\d{11})(\d{1})$|20|0|1|||2011-06-20|1 +FI|Finland|123456-785|12345600000785|6!n7!n1!n|^(\d{6})(\d{7})(\d{1})$|14|FI2112345600000785|FI2!n6!n7!n1!n|^FI(\d{2})(\d{6})(\d{7})(\d{1})$|18|0|2|||2013-08-05|1 +FR|France|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|FR1420041010050500013M02606|FR2!n5!n5!n11!c2!n|^FR(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1 +BL|Saint Barthelemy|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|BL9820041010050500013M02606|BL2!n5!n5!n11!c2!n|^BL(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-02-08|0 +GF|French Guyana|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|GF4120041010050500013M02606|GF2!n5!n5!n11!c2!n|^GF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1 +GP|Guadelope|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|GP1120041010050500013M02606|GP2!n5!n5!n11!c2!n|^GP(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1 +MF|Saint Martin (French Part)|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|MF9820041010050500013M02606|MF2!n5!n5!n11!c2!n|^MF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-02-08|0 +MQ|Martinique|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|MQ5120041010050500013M02606|MQ2!n5!n5!n11!c2!n|^MQ(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1 +RE|Reunion|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|RE4220041010050500013M02606|RE2!n5!n5!n11!c2!n|^RE(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1 +PF|French Polynesia|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|PF5720041010050500013M02606|PF2!n5!n5!n11!c2!n|^PF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|0 +TF|French Southern Territories|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|TF2120041010050500013M02606|TF2!n5!n5!n11!c2!n|^TF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|0 +YT|Mayotte|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|YT3120041010050500013M02606|YT2!n5!n5!n11!c2!n|^YT(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1 +NC|New Caledonia|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|NC8420041010050500013M02606|NC2!n5!n5!n11!c2!n|^NC(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|0 +PM|Saint Pierre et Miquelon|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|PM3620041010050500013M02606|PM2!n5!n5!n11!c2!n|^PM(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2013-08-28|1 +WF|Wallis and Futuna Islands|20041 01005 0500013M026 06|20041010050500013M02606|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|WF9120041010050500013M02606|WF2!n5!n5!n11!c2!n|^WF(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|0 +GE|Georgia|0000000101904917|NB0000000101904917|2!a16!n|^([A-Z]{2})(\d{16})$|18|GE29NB0000000101904917|GE2!n2!a16!n|^GE(\d{2})([A-Z]{2})(\d{16})$|22|0|1|||2011-06-20|0 +DE|Germany|37040044-532013000|370400440532013000|8!n10!n|^(\d{8})(\d{10})$|18|DE89370400440532013000|DE2!n8!n10!n|^DE(\d{2})(\d{8})(\d{10})$|22|0|7|||2011-06-20|1 +GI|Gibraltar|0000 00007099 453|NWBK000000007099453|4!a15!c|^([A-Z]{4})([A-Za-z0-9]{15})$|19|GI75NWBK000000007099453|GI2!n4!a15!c|^GI(\d{2})([A-Z]{4})([A-Za-z0-9]{15})$|23|0|3|||2011-06-20|1 +GR|Greece|01250000000012300695|01101250000000012300695|3!n4!n16!c|^(\d{3})(\d{4})([A-Za-z0-9]{16})$|23|GR1601101250000000012300695|GR2!n3!n4!n16!c|^GR(\d{2})(\d{3})(\d{4})([A-Za-z0-9]{16})$|27|0|2|3|6|2011-06-20|1 +GT|Guatemala|01020000001210029690|TRAJ01020000001210029690|4!c20!c|^([A-Za-z0-9]{4})([A-Za-z0-9]{20})$|24|GT82TRAJ01020000001210029690|GT2!n4!c20!c|^GT(\d{2})([A-Za-z0-9]{4})([A-Za-z0-9]{20})$|28|0|3|||2012-05-29|0 +HU|Hungary|11773016-11111018-00000000|117730161111101800000000|3!n4!n1!n15!n1!n|^(\d{3})(\d{4})(\d{1})(\d{15})(\d{1})$|24|HU42117730161111101800000000|HU2!n3!n4!n1!n15!n1!n|^HU(\d{2})(\d{3})(\d{4})(\d{1})(\d{15})(\d{1})$|28|0|2|3|6|2011-06-20|1 +IS|Iceland|0159-26-007654-551073-0339|0159260076545510730339|4!n2!n6!n10!n|^(\d{4})(\d{2})(\d{6})(\d{10})$|22|IS140159260076545510730339|IS2!n4!n2!n6!n10!n|^IS(\d{2})(\d{4})(\d{2})(\d{6})(\d{10})$|26|0|3|6|11|2011-06-20|1 +IE|Ireland|93-11-52 12345678|AIBK93115212345678|4!a6!n8!n|^([A-Z]{4})(\d{6})(\d{8})$|18|IE29AIBK93115212345678|IE2!n4!a6!n8!n|^IE(\d{2})([A-Z]{4})(\d{6})(\d{8})$|22|0|3|4|9|2011-06-20|1 +IL|Israel|10-800-99999999|100800000099999000|3!n3!n13!n|^(\d{3})(\d{3})(\d{13})$|19|IL620108000000099999999|IL2!n3!n3!n13!n|^IL(\d{2})(\d{3})(\d{3})(\d{13})$|23|0|2|3|5|2011-06-20|0 +IT|Italy|X 05428 11101 000000123456|X0542811101000000123456|1!a5!n5!n12!c|^([A-Z]{1})(\d{5})(\d{5})([A-Za-z0-9]{12})$|23|IT60X0542811101000000123456|IT2!n1!a5!n5!n12!c|^IT(\d{2})([A-Z]{1})(\d{5})(\d{5})([A-Za-z0-9]{12})$|27|0|5|6|10|2011-06-20|1 +JO|Jordan|1310000302|CBJO0010000000000131000302|4!a4!n18!c|^([A-Z]{4})(\d{4})([A-Za-z0-9]{18})$|26|JO94CBJO0010000000000131000302|JO2!n4!a4!n18!c|^JO(\d{2})([A-Z]{4})(\d{4})([A-Za-z0-9]{18})$|30|0|3|4|7|2014-06-05|0 +KZ|Kazakhstan|KZ86 125K ZT50 0410 0100|125KZT5004100100|3!n13!c|^(\d{3})([A-Za-z0-9]{13})$|16|KZ07|KZ2!n3!n13!c|^KZ(\d{2})(\d{3})([A-Za-z0-9]{13})$||0|2|||2014-06-05|0 +KW|Kuwait|CBKU0000000000001234560101|CBKU0000000000001234560101|4!a22!c|^([A-Z]{4})([A-Za-z0-9]{22})$|26|KW81CBKU0000000000001234560101|KW2!n4!a22!n|^KW(\d{2})([A-Z]{4})(\d{22})$|30|0|3|||2011-06-20|0 +LV|Latvia|BANK 0000 4351 9500 1|BANK0000435195001|4!a13!c|^([A-Z]{4})([A-Za-z0-9]{13})$|17|LV80BANK0000435195001|LV2!n4!a13!c|^LV(\d{2})([A-Z]{4})([A-Za-z0-9]{13})$|21|0|3|||2011-06-20|1 +LB|Lebanon|01 001 901229114|0999 0000 0001 0019 0122 9114|4!n20!c|^(\d{4})([A-Za-z0-9]{20})$|24|LB62099900000001001901229114|LB2!n4!n20!c|^LB(\d{2})(\d{4})([A-Za-z0-9]{20})$|28|0|3|||2011-06-20|0 +LI|Liechtenstein|8810 2324013AA|088100002324013AA|5!n12!c|^(\d{5})([A-Za-z0-9]{12})$|19|LI21088100002324013AA|LI2!n5!n12!c|^LI(\d{2})(\d{5})([A-Za-z0-9]{12})$|21|0|4|||2012-05-29|1 +LT|Lithuania|1000 0111 0100 1000|10000011101001000|5!n11!n|^(\d{5})(\d{11})$|16|LT121000011101001000|LT2!n5!n11!n|^LT(\d{2})(\d{5})(\d{11})$|20|0|4|||2011-06-20|1 +LU|Luxembourg|0019 4006 4475 0000|0019400644750000|3!n13!c|^(\d{3})([A-Za-z0-9]{13})$|16|LU280019400644750000|LU2!n3!n13!c|^LU(\d{2})(\d{3})([A-Za-z0-9]{13})$|20|0|2|||2011-06-20|1 +MK|Macedonia|300 0000000424 25|250120000058984|3!n10!c2!n|^(\d{3})([A-Za-z0-9]{10})(\d{2})$|15|MK07250120000058984|MK2!n3!n10!c2!n|^MK(\d{2})(\d{3})([A-Za-z0-9]{10})(\d{2})$|19|0|2|||2012-05-29|0 +MT|Malta|12345MTLCAST001S|MALT011000012345MTLCAST001S|4!a5!n18!c|^([A-Z]{4})(\d{5})([A-Za-z0-9]{18})$|27|MT84MALT011000012345MTLCAST001S|MT2!n4!a5!n18!c|^MT(\d{2})([A-Z]{4})(\d{5})([A-Za-z0-9]{18})$|31|0|3|4|8|2011-06-20|1 +MR|Mauritania|00020 00101 00001234567 53|00020001010000123456753|5!n5!n11!n2!n|^(\d{5})(\d{5})(\d{11})(\d{2})$|23|MR1300020001010000123456753|MR135!n5!n11!n2!n|^MR13(\d{5})(\d{5})(\d{11})(\d{2})$|27|0|4|5|9|2011-06-20|0 +MU|Mauritius|BOMM 0101 1010 3030 0200 000M UR|BOMM0101101030300200000MUR|4!a2!n2!n12!n3!n3!a|^([A-Z]{4})(\d{2})(\d{2})(\d{12})(\d{3})([A-Z]{3})$|26|MU17BOMM0101101030300200000MUR|MU2!n4!a2!n2!n12!n3!n3!a|^MU(\d{2})([A-Z]{4})(\d{2})(\d{2})(\d{12})(\d{3})([A-Z]{3})$|30|0|5|6|7|2011-06-20|0 +MD|Moldova|00225100013104168|AG000225100013104168|2!c18!c|^([A-Za-z0-9]{2})([A-Za-z0-9]{18})$|20|MD24AG000225100013104168|MD2!n20!c|^MD(\d{2})([A-Za-z0-9]{20})$|24|0|1|||2012-09-09|0 +MC|Monaco|0011111000h|11222 00001 01234567890 30|5!n5!n11!c2!n|^(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|23|MC5811222000010123456789030|MC2!n5!n5!n11!c2!n|^MC(\d{2})(\d{5})(\d{5})([A-Za-z0-9]{11})(\d{2})$|27|0|4|5|9|2011-06-20|1 +ME|Montenegro|505 0000123456789 51|505000012345678951|3!n13!n2!n|^(\d{3})(\d{13})(\d{2})$|18|ME25505000012345678951|ME2!n3!n13!n2!n|^ME(\d{2})(\d{3})(\d{13})(\d{2})$|22|0|2|||2011-06-20|0 +NL|The Netherlands|041 71 64 300|ABNA0417164300|4!a10!n|^([A-Z]{4})(\d{10})$|14|NL91ABNA0417164300|NL2!n4!a10!n|^NL(\d{2})([A-Z]{4})(\d{10})$|18|0|3|4|3|2013-06-20|1 +NO|Norway|8601 11 17947|86011117947|4!n6!n1!n|^(\d{4})(\d{6})(\d{1})$|11|NO9386011117947|NO2!n4!n6!n1!n|^NO(\d{2})(\d{4})(\d{6})(\d{1})$|15|0|3|||2011-06-20|1 +PK|Pakistan|00260101036360|SCBL0000001123456702|4!a16!c|^([A-Z]{4})([A-Za-z0-9]{16})$|20|PK36SCBL0000001123456702|PK2!n4!a16!c|^PK(\d{2})([A-Z]{4})([A-Za-z0-9]{16})$|24|0|3|||2012-05-29|0 +PL|Poland|61 1090 1014 0000 0712 1981 2874|109010140000071219812874|8!n16!n|^(\d{8})(\d{16})$|24|PL61109010140000071219812874|PL2!n8!n16n|^PL(\d{2})(\d{8})(\d{1,16})$|28|0|7|||2011-06-20|1 +PS|Palestine|400123456702|PALS000000000400123456702|4!a21!c|^([A-Z]{4})([A-Za-z0-9]{21})$|25|PS92PALS000000000400123456702|PS2!n4!a21!c|^PS(\d{2})([A-Z]{4})([A-Za-z0-9]{21})$|29|0|3|||2013-09-05|0 +PT|Portugal|0002.0123.12345678901.54|000201231234567890154|4!n4!n11!n2!n|^(\d{4})(\d{4})(\d{11})(\d{2})$|21|PT50000201231234567890154|PT2!n4!n4!n11!n2!n|^PT(\d{2})(\d{4})(\d{4})(\d{11})(\d{2})$|25|0|3|4|7|2013-09-05|1 +QA|Qatar|QA58DOHB00001234567890ABCDEFG|DOHB00001234567890ABCDEFG|4!a4!n17!c|^([A-Z]{4})(\d{4})([A-Za-z0-9]{17})$|29|QA58DOHB00001234567890ABCDEFG|QA2!n4!a4!n17!c|^QA(\d{2})([A-Z]{4})(\d{4})([A-Za-z0-9]{17})$|29|0|3|4|7|2014-06-05|0 +RO|Romania|AAAA 1B31 0075 9384 0000|AAAA1B31007593840000|4!a16!c|^([A-Z]{4})([A-Za-z0-9]{16})$|20|RO49AAAA1B31007593840000|RO2!n4!a16!c|^RO(\d{2})([A-Z]{4})([A-Za-z0-9]{16})$|24|0|3|||2011-06-20|1 +SM|San Marino|U032 2509 8000 0000 0270 100|U0322509800000000270100|1!a5!n5!n12!c|^([A-Z]{1})(\d{5})(\d{5})([A-Za-z0-9]{12})$|23|SM86U0322509800000000270100|SM2!n1!a5!n5!n12!c|^SM(\d{2})([A-Z]{1})(\d{5})(\d{5})([A-Za-z0-9]{12})$|27|0|5|6|10|2011-06-20|1 +SA|Saudi Arabia|608010167519|80000000608010167519|2!n18!c|^(\d{2})([A-Za-z0-9]{18})$|20|SA0380000000608010167519|SA2!n2!n18!c|^SA(\d{2})(\d{2})([A-Za-z0-9]{18})$|24|0|1|||2012-05-29|0 +RS|Serbia|260-0056010016113-79|260005601001611379|3!n13!n2!n|^(\d{3})(\d{13})(\d{2})$|18|RS35260005601001611379|RS2!n3!n13!n2!n|^RS(\d{2})(\d{3})(\d{13})(\d{2})$|22|0|2|||2011-06-20|0 +SK|Slovak Republic|19-8742637541/1200|12000000198742637541|4!n6!n10!n|^(\d{4})(\d{6})(\d{10})$|20|SK3112000000198742637541|SK2!n4!n6!n10!n|^SK(\d{2})(\d{4})(\d{6})(\d{10})$|24|0|3|4|9|2011-06-20|1 +SI|Slovenia|2633 0001 2039 086|263300012039086|5!n8!n2!n|^(\d{5})(\d{8})(\d{2})$|15|SI56191000000123438|SI2!n5!n8!n2!n|^SI(\d{2})(\d{5})(\d{8})(\d{2})$|19|0|1|2|4|2012-09-09|1 +ES|Spain|2100 0418 45 0200051332|21000418450200051332|4!n4!n1!n1!n10!n|^(\d{4})(\d{4})(\d{1})(\d{1})(\d{10})$|20|ES9121000418450200051332|ES2!n4!n4!n1!n1!n10!n|^ES(\d{2})(\d{4})(\d{4})(\d{1})(\d{1})(\d{10})$|24|0|3|4|7|2013-09-05|1 +SE|Sweden|1234 12 3456 1|5000 0000 0583 9825 7466|3!n16!n1!n|^(\d{3})(\d{16})(\d{1})$|20|SE4550000000058398257466|SE2!n3!n16!n1!n|^SE(\d{2})(\d{3})(\d{16})(\d{1})$|24|0|2|||2011-06-20|1 +CH|Switzerland|762 1162-3852.957|00762011623852957|5!n12!c|^(\d{5})([A-Za-z0-9]{12})$|17|CH9300762011623852957|CH2!n5!n12!c|^CH(\d{2})(\d{5})([A-Za-z0-9]{12})$|21|0|4|||2011-06-20|1 +TN|Tunisia|10 006 0351835984788 31|10006035183598478831|2!n3!n13!n2!n|^(\d{2})(\d{3})(\d{13})(\d{2})$|20|TN5910006035183598478831|TN592!n3!n13!n2!n|^TN59(\d{2})(\d{3})(\d{13})(\d{2})$|24|0|1|2|4|2011-06-20|0 +TR|Turkey|0061 01299 1234567890123456789|0006100519786457841326|5!n1!c16!c|^(\d{5})([A-Za-z0-9]{1})([A-Za-z0-9]{16})$|22|TR330006100519786457841326|TR2!n5!n1!c16!c|^TR(\d{2})(\d{5})([A-Za-z0-9]{1})([A-Za-z0-9]{16})$|26|0|4|||2011-06-20|0 +AE|United Arab Emirates|1234567890123456|0331234567890123456|3!n16!n|^(\d{3})(\d{16})$|19|AE070331234567890123456|AE2!n3!n16!n|^AE(\d{2})(\d{3})(\d{16})$|23|0|2|||2011-06-20|0 +GB|United Kingdom|60-16-13 31926819|NWBK60161331926819|4!a6!n8!n|^([A-Z]{4})(\d{6})(\d{8})$|18|GB29NWBK60161331926819|GB2!n4!a6!n8!n|^GB(\d{2})([A-Z]{4})(\d{6})(\d{8})$|22|0|3|4|9|2011-06-20|1 +VG|British Virgin Islands|00000 12 345 678 901|VPVG0000012345678901|4!a16!n|^([A-Z]{4})(\d{16})$|20|VG96VPVG0000012345678901|VG2!n4!a16!n|^VG(\d{2})([A-Z]{4})(\d{16})$|24|0|3|||2012-05-29|0 diff --git a/htdocs/langs/en_US/banks.lang b/htdocs/langs/en_US/banks.lang index 10a5f5b3c14..dfa0934ce70 100644 --- a/htdocs/langs/en_US/banks.lang +++ b/htdocs/langs/en_US/banks.lang @@ -33,7 +33,11 @@ AllTime=From start Reconciliation=Reconciliation RIB=Bank Account Number IBAN=IBAN number +IbanValid=IBAN is Valid +IbanNotValid=IBAN is Not Valid BIC=BIC/SWIFT number +SwiftValid=BIC/SWIFT is Valid +SwiftNotValid=BIC/SWIFT is Not Valid StandingOrders=Standing orders StandingOrder=Standing order Withdrawals=Withdrawals diff --git a/htdocs/product/stats/commande.php b/htdocs/product/stats/commande.php index 472b9ce4a45..2ae1dcd1582 100644 --- a/htdocs/product/stats/commande.php +++ b/htdocs/product/stats/commande.php @@ -2,6 +2,7 @@ /* Copyright (C) 2003-2007 Rodolphe Quiedeville * Copyright (C) 2004-2009 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2014 Florian Henry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +28,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $langs->load("orders"); $langs->load("products"); @@ -38,7 +40,8 @@ $ref = GETPOST('ref', 'alpha'); // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); -if ($user->societe_id) $socid=$user->societe_id; +$socid=''; +if (! empty($user->societe_id)) $socid=$user->societe_id; $result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype); // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array @@ -55,13 +58,23 @@ $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="c.date_commande"; +$search_month = GETPOST('search_month', 'aplha'); +$search_year = GETPOST('search_year', 'int'); +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) { + $search_month=''; + $search_year=''; +} /* * View */ +$orderstatic=new Commande($db); +$societestatic=new Societe($db); + $form = new Form($db); +$formother= new FormOther($db); if ($id > 0 || ! empty($ref)) { @@ -76,9 +89,6 @@ if ($id > 0 || ! empty($ref)) if ($result > 0) { - /* - * En mode visu - */ $head=product_prepare_head($product, $user); $titre=$langs->trans("CardProduct".$product->type); $picto=($product->type==1?'service':'product'); @@ -87,7 +97,6 @@ if ($id > 0 || ! empty($ref)) $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$product,$action); // Note that $action and $object may have been modified by hook if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - print ''; // Reference @@ -117,83 +126,138 @@ if ($id > 0 || ! empty($ref)) print ''; - - $sql = "SELECT distinct s.nom as name, s.rowid as socid, s.code_client, c.rowid, c.total_ht as total_ht, c.ref,"; - $sql.= " c.date_commande, c.fk_statut as statut, c.facture, c.rowid as commandeid, d.qty"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", sc.fk_soc, sc.fk_user "; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - $sql.= ", ".MAIN_DB_PREFIX."commande as c"; - $sql.= ", ".MAIN_DB_PREFIX."commandedet as d"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE c.fk_soc = s.rowid"; - $sql.= " AND c.entity = ".$conf->entity; - $sql.= " AND d.fk_commande = c.rowid"; - $sql.= " AND d.fk_product =".$product->id; - if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND c.fk_soc = ".$socid; - $sql.= " ORDER BY $sortfield $sortorder "; - $sql.= $db->plimit($conf->liste_limit +1, $offset); - - $result = $db->query($sql); - if ($result) + if ($user->rights->commande->lire) { - $num = $db->num_rows($result); - - print_barre_liste($langs->trans("CustomersOrders"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,0,''); - - $i = 0; - print "
"; - - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"c.rowid","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"s.nom","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("CustomerCode"),$_SERVER["PHP_SELF"],"s.code_client","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("OrderDate"),$_SERVER["PHP_SELF"],"c.date_commande","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"],"d.qty","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountHT"),$_SERVER["PHP_SELF"],"c.total_ht","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"c.fk_statut","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print "\n"; - - $commandestatic=new Commande($db); - - if ($num > 0) + $sql = "SELECT distinct s.nom as name, s.rowid as socid, s.code_client, c.rowid, d.total_ht as total_ht, c.ref,"; + $sql .= " c.ref_client,"; + $sql.= " c.date_commande, c.fk_statut as statut, c.facture, c.rowid as commandeid, d.qty"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= ", sc.fk_soc, sc.fk_user "; + $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql.= ", ".MAIN_DB_PREFIX."commande as c"; + $sql.= ", ".MAIN_DB_PREFIX."commandedet as d"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE c.fk_soc = s.rowid"; + $sql.= " AND c.entity = ".$conf->entity; + $sql.= " AND d.fk_commande = c.rowid"; + $sql.= " AND d.fk_product =".$product->id; + if (! empty($search_month)) + $sql.= ' AND MONTH(f.datef) IN (' . $search_month . ')'; + if (! empty($search_year)) + $sql.= ' AND YEAR(f.datef) IN (' . $search_year . ')'; + if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + if ($socid) $sql.= " AND c.fk_soc = ".$socid; + $sql.= " ORDER BY $sortfield $sortorder "; + + //Calcul total qty and amount for global if full scan list + $total_ht=0; + $total_qty=0; + $totalrecords=0; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $result = $db->query($sql); + if ($result) { + $totalrecords = $db->num_rows($result); + while ($objp = $db->fetch_object($result)) { + $total_ht+=$objp->total_ht; + $total_qty+=$objp->qty; + } + } + } + + $sql.= $db->plimit($conf->liste_limit +1, $offset); + + $result = $db->query($sql); + if ($result) { - $var=True; - while ($i < $num && $i < $conf->liste_limit) + $num = $db->num_rows($result); + + if (! empty($id)) + $option .= '&id='.$product->id; + if (! empty($search_month)) + $option .= '&search_month='.$search_month; + if (! empty($search_year)) + $option .= '&search_year='.$search_year; + + print '' . "\n"; + if (! empty($sortfield)) + print ''; + if (! empty($sortorder)) + print ''; + if (! empty($page)) { + print ''; + $option .= '&page=' . $page; + } + + print_barre_liste($langs->trans("CustomersOrders"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,$totalrecords,''); + print '
'; + print $langs->trans('Period').'('.$langs->trans("DateInvoice") .') '; + print $langs->trans('Month') . ': '; + print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print ''; + print ''; + print '
'; + + $i = 0; + print '
'; + print ''; + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"c.rowid","",$option,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"s.nom","",$option,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("CustomerCode"),$_SERVER["PHP_SELF"],"s.code_client","",$option,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("OrderDate"),$_SERVER["PHP_SELF"],"c.date_commande","",$option,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"],"d.qty","",$option,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountHT"),$_SERVER["PHP_SELF"],"c.total_ht","",$option,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"c.fk_statut","",$option,'align="right"',$sortfield,$sortorder); + print "\n"; + + if ($num > 0) { - $objp = $db->fetch_object($result); - $var=!$var; - - print ""; - print '\n"; - print ''; - print "\n"; - print ""; - print "\n"; - print "\n"; - print ''; - print "\n"; - $i++; + $var=True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + $var=!$var; + + print ''; + print '\n"; + $societestatic->fetch($objp->socid); + print ''; + print "\n"; + print '"; + print '\n"; + print '\n"; + print ''; + print "\n"; + $i++; + + if (!empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $total_ht+=$objp->total_ht; + $total_qty+=$objp->qty; + } + } } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "
'.img_object($langs->trans("ShowOrder"),"order").' '; - print $objp->ref; - print "'.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($objp->name,44).'".$objp->code_client.""; - print dol_print_date($db->jdate($objp->date_commande))."".$objp->qty."".price($objp->total_ht)."'.$commandestatic->LibStatut($objp->statut,$objp->facture,5).'
'; + $orderstatic->id=$objp->commandeid; + $orderstatic->ref=$objp->ref; + $orderstatic->ref_client=$objp->ref_client; + print $orderstatic->getNomUrl(1); + print "'.$societestatic->getNomUrl(1).'".$objp->code_client."'; + print dol_print_date($db->jdate($objp->date_commande))."'.$objp->qty."'.price($objp->total_ht)."'.$commandestatic->LibStatut($objp->statut,$objp->facture,5).'
' . $langs->trans('Total') . ''.$total_qty.''.price($total_ht).'
"; + print ''; + print '
'; + } else { + dol_print_error($db); } + $db->free($result); } - else - { - dol_print_error($db); - } - print ""; - print '
'; - $db->free($result); } -} -else -{ +} else { dol_print_error(); } - llxFooter(); $db->close(); diff --git a/htdocs/product/stats/commande_fournisseur.php b/htdocs/product/stats/commande_fournisseur.php index 73de0374ebe..3141b3266e9 100644 --- a/htdocs/product/stats/commande_fournisseur.php +++ b/htdocs/product/stats/commande_fournisseur.php @@ -2,6 +2,7 @@ /* Copyright (C) 2003-2007 Rodolphe Quiedeville * Copyright (C) 2004-2009 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2014 Florian Henry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,15 +19,15 @@ */ /** - * \file htdocs/product/stats/commande_fournisseur.php - * \ingroup product service commande - * \brief Page des stats des commandes fournisseurs pour un produit + * \file htdocs/product/stats/commande_fournisseur.php + * \ingroup product service commande + * \brief Page des stats des commandes fournisseurs pour un produit */ - require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.commande.class.php'; +require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; $langs->load("orders"); $langs->load("products"); @@ -38,157 +39,233 @@ $ref = GETPOST('ref', 'alpha'); // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); -if ($user->societe_id) $socid=$user->societe_id; -$result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype); +$socid = ''; +if (! empty($user->societe_id)) + $socid = $user->societe_id; +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array -$hookmanager->initHooks(array('productstatssupplyorder')); +$hookmanager->initHooks(array ( + 'productstatssupplyorder' +)); $mesg = ''; -$sortfield = GETPOST("sortfield",'alpha'); -$sortorder = GETPOST("sortorder",'alpha'); -$page = GETPOST("page",'int'); -if ($page == -1) { $page = 0; } +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOST("page", 'int'); +if ($page == - 1) { + $page = 0; +} $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -if (! $sortorder) $sortorder="DESC"; -if (! $sortfield) $sortfield="c.date_commande"; +if (! $sortorder) + $sortorder = "DESC"; +if (! $sortfield) + $sortfield = "c.date_commande"; +$search_month = GETPOST('search_month', 'aplha'); +$search_year = GETPOST('search_year', 'int'); +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) { + $search_month = ''; + $search_year = ''; +} /* * View */ -$form = new Form($db); +$commandefournstatic = new CommandeFournisseur($db); +$societestatic = new Societe($db); -if ($id > 0 || ! empty($ref)) -{ +$form = new Form($db); +$formother = new FormOther($db); + +if ($id > 0 || ! empty($ref)) { $product = new Product($db); $result = $product->fetch($id, $ref); - - $parameters=array('id'=>$id); - $reshook=$hookmanager->executeHooks('doActions',$parameters,$product,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - - llxHeader("","",$langs->trans("CardProduct".$product->type)); - - if ($result > 0) - { - $head=product_prepare_head($product, $user); - $titre=$langs->trans("CardProduct".$product->type); - $picto=($product->type==1?'service':'product'); + + $parameters = array ( + 'id' => $id + ); + $reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + + llxHeader("", "", $langs->trans("CardProduct" . $product->type)); + + if ($result > 0) { + $head = product_prepare_head($product, $user); + $titre = $langs->trans("CardProduct" . $product->type); + $picto = ($product->type == 1 ? 'service' : 'product'); dol_fiche_head($head, 'referers', $titre, 0, $picto); - - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$product,$action); // Note that $action and $object may have been modified by hook - if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - + + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $product, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + print ''; - + // Reference print ''; - print ''; - + print ''; + print ''; + // Libelle - print ''; - + print ''; + print ''; + // Status (to sell) - print ''; - + // Status (to buy) - print ''; - - show_stats_for_company($product,$socid); - + + show_stats_for_company($product, $socid); + print "
'.$langs->trans("Ref").''; - print $form->showrefnav($product,'ref','',1,'ref'); - print '
' . $langs->trans("Ref") . ''; + print $form->showrefnav($product, 'ref', '', 1, 'ref'); + print '
'.$langs->trans("Label").''.$product->libelle.'
' . $langs->trans("Label") . '' . $product->libelle . '
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; - print $product->getLibStatut(2,0); + print '
' . $langs->trans("Status") . ' (' . $langs->trans("Sell") . ')'; + print $product->getLibStatut(2, 0); print '
'.$langs->trans("Status").' ('.$langs->trans("Buy").')'; - print $product->getLibStatut(2,1); + print '
' . $langs->trans("Status") . ' (' . $langs->trans("Buy") . ')'; + print $product->getLibStatut(2, 1); print '
"; + print ''; - - $sql = "SELECT distinct s.nom as name, s.rowid as socid, s.code_client,"; - $sql.= " c.rowid, c.total_ht as total_ht, c.ref,"; - $sql.= " c.date_commande, c.fk_statut as statut, c.rowid as commandeid, d.qty"; - if (!$user->rights->societe->client->voir && !$socid) $sql .= ", sc.fk_soc, sc.fk_user "; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseur as c"; - $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseurdet as d"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE c.fk_soc = s.rowid"; - $sql.= " AND c.entity = ".$conf->entity; - $sql.= " AND d.fk_commande = c.rowid"; - $sql.= " AND d.fk_product =".$product->id; - if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND c.fk_soc = ".$socid; - $sql.= " ORDER BY $sortfield $sortorder "; - $sql.= $db->plimit($conf->liste_limit +1, $offset); - - $result = $db->query($sql); - if ($result) - { - $num = $db->num_rows($result); - - print_barre_liste($langs->trans("SuppliersOrders"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,0,''); - - $i = 0; - print ""; - - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"c.rowid","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"s.nom","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("SupplierCode"),$_SERVER["PHP_SELF"],"s.code_client","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("OrderDate"),$_SERVER["PHP_SELF"],"c.date_commande","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"],"d.qty","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountHT"),$_SERVER["PHP_SELF"],"c.total_ht","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"c.fk_statut","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print "\n"; - - $commandestatic=new CommandeFournisseur($db); - - if ($num > 0) - { - $var=True; - while ($i < $num && $i < $conf->liste_limit) - { - $objp = $db->fetch_object($result); - $var=!$var; - - $commandestatic->id=$objp->commandeid; - $commandestatic->ref=$objp->ref; - $commandestatic->statut=$objp->statut; - - print ""; - print '\n"; - print "\n"; - print ''; - print "\n"; - print '"; - print "\n"; - print '\n"; - print ''; - print "\n"; - $i++; + + if ($user->rights->fournisseur->commande->lire) { + $sql = "SELECT distinct s.nom as name, s.rowid as socid, s.code_client,"; + $sql .= " c.rowid, d.total_ht as total_ht, c.ref,"; + $sql .= " c.date_commande, c.fk_statut as statut, c.rowid as commandeid, d.qty"; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= ", sc.fk_soc, sc.fk_user "; + $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s"; + $sql .= ", " . MAIN_DB_PREFIX . "commande_fournisseur as c"; + $sql .= ", " . MAIN_DB_PREFIX . "commande_fournisseurdet as d"; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc"; + $sql .= " WHERE c.fk_soc = s.rowid"; + $sql .= " AND c.entity = " . $conf->entity; + $sql .= " AND d.fk_commande = c.rowid"; + $sql .= " AND d.fk_product =" . $product->id; + if (! empty($search_month)) + $sql .= ' AND MONTH(f.datef) IN (' . $search_month . ')'; + if (! empty($search_year)) + $sql .= ' AND YEAR(f.datef) IN (' . $search_year . ')'; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . $user->id; + if ($socid) + $sql .= " AND c.fk_soc = " . $socid; + $sql .= " ORDER BY $sortfield $sortorder "; + + // Calcul total qty and amount for global if full scan list + $total_ht = 0; + $total_qty = 0; + $totalrecords = 0; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $result = $db->query($sql); + if ($result) { + $totalrecords = $db->num_rows($result); + while ( $objp = $db->fetch_object($result) ) { + $total_ht += $objp->total_ht; + $total_qty += $objp->qty; + } } } + + $sql .= $db->plimit($conf->liste_limit + 1, $offset); + + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + + if (! empty($id)) + $option .= '&id=' . $product->id; + if (! empty($search_month)) + $option .= '&search_month=' . $search_month; + if (! empty($search_year)) + $option .= '&search_year=' . $search_year; + + print '' . "\n"; + if (! empty($sortfield)) + print ''; + if (! empty($sortorder)) + print ''; + if (! empty($page)) { + print ''; + $option .= '&page=' . $page; + } + + print_barre_liste($langs->trans("SuppliersOrders"), $page, $_SERVER["PHP_SELF"], "&id=$product->id", $sortfield, $sortorder, '', $num, $totalrecords, ''); + print '
'; + print $langs->trans('Period') . '(' . $langs->trans("DateInvoice") . ') '; + print $langs->trans('Month') . ': '; + print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print ''; + print ''; + print '
'; + + $i = 0; + print '
'.$commandestatic->getNomUrl(1)."'.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($objp->name,44).'".$objp->code_client."'.dol_print_date($db->jdate($objp->date_commande))."".$objp->qty."'.price($objp->total_ht)."'.$commandestatic->getLibStatut(4).'
'; + print ''; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "c.rowid", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Company"), $_SERVER["PHP_SELF"], "s.nom", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("SupplierCode"), $_SERVER["PHP_SELF"], "s.code_client", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("OrderDate"), $_SERVER["PHP_SELF"], "c.date_commande", "", $option, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Qty"), $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AmountHT"), $_SERVER["PHP_SELF"], "c.total_ht", "", $option, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Status"), $_SERVER["PHP_SELF"], "c.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder); + print "\n"; + + if ($num > 0) { + $var = True; + while ( $i < $num && $i < $conf->liste_limit ) { + $objp = $db->fetch_object($result); + $var = ! $var; + + print ''; + print '\n"; + $societestatic->fetch($objp->socid); + print ''; + print "\n"; + print '"; + print '\n"; + print '\n"; + print ''; + print "\n"; + $i ++; + + if (! empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $total_ht += $objp->total_ht; + $total_qty += $objp->qty; + } + } + } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "
'; + $commandestatic->id = $objp->commandeid; + $commandestatic->ref = $objp->ref; + $commandestatic->statut = $objp->statut; + print $commandestatic->getNomUrl(1); + print "' . $societestatic->getNomUrl(1) . '" . $objp->code_client . "'; + print dol_print_date($db->jdate($objp->date_commande)) . "' . $objp->qty . "' . price($objp->total_ht) . "' . $commandestatic->getLibStatut(4) . '
' . $langs->trans('Total') . '' . $total_qty . '' . price($total_ht) . '
"; + print ''; + print '
'; + } else { + dol_print_error($db); + } + $db->free($result); } - else - { - dol_print_error($db); - } - print ""; - print '
'; - $db->free($result); } -} -else -{ +} else { dol_print_error(); } - llxFooter(); $db->close(); diff --git a/htdocs/product/stats/facture.php b/htdocs/product/stats/facture.php index 49e5651b065..b59bc008f17 100644 --- a/htdocs/product/stats/facture.php +++ b/htdocs/product/stats/facture.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2010 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2014 Florian Henry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +29,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $langs->load("companies"); $langs->load("bills"); @@ -36,12 +38,11 @@ $langs->load("products"); $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); -$socid=''; -if (! empty($user->societe_id)) $socid=$user->societe_id; - // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); +$socid=''; +if (! empty($user->societe_id)) $socid=$user->societe_id; $result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype); // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array @@ -58,16 +59,23 @@ $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="f.datef"; +$search_month = GETPOST('search_month', 'aplha'); +$search_year = GETPOST('search_year', 'int'); +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) { + $search_month=''; + $search_year=''; +} /* * View */ $invoicestatic=new Facture($db); +$societestatic=new Societe($db); $form = new Form($db); - +$formother= new FormOther($db); if ($id > 0 || ! empty($ref)) { @@ -80,9 +88,6 @@ if ($id > 0 || ! empty($ref)) llxHeader("","",$langs->trans("CardProduct".$product->type)); - /* - * En mode visu - */ if ($result > 0) { $head=product_prepare_head($product, $user); @@ -125,7 +130,7 @@ if ($id > 0 || ! empty($ref)) if ($user->rights->facture->lire) { $sql = "SELECT distinct s.nom as name, s.rowid as socid, s.code_client,"; - $sql.= " f.facnumber, f.total as total_ht,"; + $sql.= " f.facnumber, d.total_ht as total_ht,"; $sql.= " f.datef, f.paye, f.fk_statut as statut, f.rowid as facid, d.qty"; if (!$user->rights->societe->client->voir && !$socid) $sql.= ", sc.fk_soc, sc.fk_user "; $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; @@ -136,33 +141,79 @@ if ($id > 0 || ! empty($ref)) $sql.= " AND f.entity = ".$conf->entity; $sql.= " AND d.fk_facture = f.rowid"; $sql.= " AND d.fk_product =".$product->id; + if (! empty($search_month)) + $sql.= ' AND MONTH(f.datef) IN (' . $search_month . ')'; + if (! empty($search_year)) + $sql.= ' AND YEAR(f.datef) IN (' . $search_year . ')'; if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND f.fk_soc = $socid"; + if ($socid) $sql.= " AND f.fk_soc = ".$socid; $sql.= " ORDER BY $sortfield $sortorder "; + + //Calcul total qty and amount for global if full scan list + $total_ht=0; + $total_qty=0; + $totalrecords=0; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $result = $db->query($sql); + if ($result) { + $totalrecords = $db->num_rows($result); + while ($objp = $db->fetch_object($result)) { + $total_ht+=$objp->total_ht; + $total_qty+=$objp->qty; + } + } + } + $sql.= $db->plimit($conf->liste_limit +1, $offset); $result = $db->query($sql); - if ($result) { + if ($result) + { $num = $db->num_rows($result); - - print_barre_liste($langs->trans("CustomersInvoices"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,0,''); + + if (! empty($id)) + $option .= '&id='.$product->id; + if (! empty($search_month)) + $option .= '&search_month='.$search_month; + if (! empty($search_year)) + $option .= '&search_year='.$search_year; + + print '
' . "\n"; + if (! empty($sortfield)) + print ''; + if (! empty($sortorder)) + print ''; + if (! empty($page)) { + print ''; + $option .= '&page=' . $page; + } + + print_barre_liste($langs->trans("CustomersInvoices"),$page,$_SERVER["PHP_SELF"],"&id=".$product->id,$sortfield,$sortorder,'',$num,$totalrecords,''); + print '
'; + print $langs->trans('Period').'('.$langs->trans("DateInvoice") .') '; + print $langs->trans('Month') . ': '; + print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print ''; + print ''; + print '
'; $i = 0; print ''; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"s.rowid","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"s.nom","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("CustomerCode"),$_SERVER["PHP_SELF"],"s.code_client","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateInvoice"),$_SERVER["PHP_SELF"],"f.datef","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"],"d.qty","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountHT"),$_SERVER["PHP_SELF"],"f.total","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.paye,f.fk_statut","","&id=".$product->id,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"s.rowid","",$option,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"s.nom","",$option,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("CustomerCode"),$_SERVER["PHP_SELF"],"s.code_client","",$option,'',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateInvoice"),$_SERVER["PHP_SELF"],"f.datef","",$option,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"],"d.qty","",$option,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("AmountHT"),$_SERVER["PHP_SELF"],"f.total","",$option,'align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.paye,f.fk_statut","",$option,'align="right"',$sortfield,$sortorder); print "\n"; - if ($num > 0) { + if ($num > 0) + { $var=True; - while ($i < $num && $i < $conf->liste_limit) { + while ($i < $num && $i < $conf->liste_limit) + { $objp = $db->fetch_object($result); $var=!$var; @@ -172,7 +223,8 @@ if ($id > 0 || ! empty($ref)) $invoicestatic->ref=$objp->facnumber; print $invoicestatic->getNomUrl(1); print "\n"; - print ''; + $societestatic->fetch($objp->socid); + print ''; print "\n"; print '"; @@ -181,9 +233,21 @@ if ($id > 0 || ! empty($ref)) print ''; print "\n"; $i++; + + if (!empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $total_ht+=$objp->total_ht; + $total_qty+=$objp->qty; + } } } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; print "
'.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($objp->name,44).''.$societestatic->getNomUrl(1).'".$objp->code_client."'; print dol_print_date($db->jdate($objp->datef),'day')."'.$invoicestatic->LibStatut($objp->paye,$objp->statut,5).'
' . $langs->trans('Total') . ''.$total_qty.''.price($total_ht).'
"; + print '
'; print '
'; } else { dol_print_error($db); @@ -195,6 +259,5 @@ if ($id > 0 || ! empty($ref)) dol_print_error(); } - llxFooter(); $db->close(); diff --git a/htdocs/product/stats/facture_fournisseur.php b/htdocs/product/stats/facture_fournisseur.php index d8e30bdae6a..0feb415cc43 100644 --- a/htdocs/product/stats/facture_fournisseur.php +++ b/htdocs/product/stats/facture_fournisseur.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2009 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2014 Florian Henry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,15 +20,16 @@ */ /** - * \file htdocs/product/stats/facture_fournisseur.php - * \ingroup product service facture - * \brief Page des stats des factures fournisseurs pour un produit + * \file htdocs/product/stats/facture_fournisseur.php + * \ingroup product service facture + * \brief Page des stats des factures fournisseurs pour un produit */ require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php'; +require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; $langs->load("companies"); $langs->load("bills"); @@ -40,164 +42,223 @@ $ref = GETPOST('ref', 'alpha'); // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); -if ($user->societe_id) $socid=$user->societe_id; -$result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype); +$socid = ''; +if (! empty($user->societe_id)) $socid=$user->societe_id; +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array $hookmanager->initHooks(array('productstatssupplyinvoice')); $mesg = ''; -$sortfield = GETPOST("sortfield",'alpha'); -$sortorder = GETPOST("sortorder",'alpha'); -$page = GETPOST("page",'int'); +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOST("page", 'int'); if ($page == -1) { $page = 0; } $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -if (! $sortorder) $sortorder="DESC"; -if (! $sortfield) $sortfield="f.datef"; - +if (! $sortorder) $sortorder = "DESC"; +if (! $sortfield) $sortfield = "f.datef"; +$search_month = GETPOST('search_month', 'aplha'); +$search_year = GETPOST('search_year', 'int'); +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) { + $search_month = ''; + $search_year = ''; +} /* * View */ -$supplierinvoicestatic=new FactureFournisseur($db); +$supplierinvoicestatic = new FactureFournisseur($db); +$societestatic = new Societe($db); $form = new Form($db); +$formother = new FormOther($db); if ($id > 0 || ! empty($ref)) { $product = new Product($db); $result = $product->fetch($id, $ref); - - $parameters=array('id'=>$id); - $reshook=$hookmanager->executeHooks('doActions',$parameters,$product,$action); // Note that $action and $object may have been modified by some hooks + + $parameters = array('id' => $id); + $reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - - llxHeader("","",$langs->trans("CardProduct".$product->type)); - - if ($result > 0) - { - /* - * En mode visu - */ - $head=product_prepare_head($product, $user); - $titre=$langs->trans("CardProduct".$product->type); - $picto=($product->type==1?'service':'product'); + + llxHeader("", "", $langs->trans("CardProduct" . $product->type)); + + if ($result > 0) + { + $head = product_prepare_head($product, $user); + $titre = $langs->trans("CardProduct" . $product->type); + $picto = ($product->type == 1 ? 'service' : 'product'); dol_fiche_head($head, 'referers', $titre, 0, $picto); - - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$product,$action); // Note that $action and $object may have been modified by hook + + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $product, $action); // Note that $action and $object may have been modified by hook if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - - print ''; - - // Reference - print ''; - print ''; - print ''; - - // Libelle - print ''; - print ''; - + + print '
'.$langs->trans("Ref").''; - print $form->showrefnav($product,'ref','',1,'ref'); - print '
'.$langs->trans("Label").''.$product->libelle.'
'; + + // Reference + print ''; + print ''; + print ''; + + // Libelle + print ''; + print ''; + // Status (to sell) - print ''; - + // Status (to buy) - print ''; + + show_stats_for_company($product, $socid); + + print "
' . $langs->trans("Ref") . ''; + print $form->showrefnav($product, 'ref', '', 1, 'ref'); + print '
' . $langs->trans("Label") . '' . $product->libelle . '
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; - print $product->getLibStatut(2,0); + print '
' . $langs->trans("Status") . ' (' . $langs->trans("Sell") . ')'; + print $product->getLibStatut(2, 0); print '
'.$langs->trans("Status").' ('.$langs->trans("Buy").')'; - print $product->getLibStatut(2,1); + print '
' . $langs->trans("Status") . ' (' . $langs->trans("Buy") . ')'; + print $product->getLibStatut(2, 1); print '
"; + + print ''; + + if ($user->rights->fournisseur->facture->lire) + { + $sql = "SELECT distinct s.nom as name, s.rowid as socid, s.code_client, f.ref, d.total_ht as total_ht,"; + $sql .= " f.datef, f.paye, f.fk_statut as statut, f.rowid as facid, d.qty"; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= ", sc.fk_soc, sc.fk_user "; + $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s"; + $sql .= ", " . MAIN_DB_PREFIX . "facture_fourn as f"; + $sql .= ", " . MAIN_DB_PREFIX . "facture_fourn_det as d"; + if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc"; + $sql .= " WHERE f.fk_soc = s.rowid"; + $sql .= " AND f.entity = " . $conf->entity; + $sql .= " AND d.fk_facture_fourn = f.rowid"; + $sql .= " AND d.fk_product =" . $product->id; + if (! empty($search_month)) + $sql .= ' AND MONTH(f.datef) IN (' . $search_month . ')'; + if (! empty($search_year)) + $sql .= ' AND YEAR(f.datef) IN (' . $search_year . ')'; + if (! $user->rights->societe->client->voir && ! $socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . $user->id; + if ($socid) $sql .= " AND f.fk_soc = " . $socid; + $sql .= " ORDER BY $sortfield $sortorder "; + + // Calcul total qty and amount for global if full scan list + $total_ht = 0; + $total_qty = 0; + $totalrecords = 0; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $result = $db->query($sql); + if ($result) { + $totalrecords = $db->num_rows($result); + while ( $objp = $db->fetch_object($result) ) { + $total_ht += $objp->total_ht; + $total_qty += $objp->qty; + } + } + } + + $sql .= $db->plimit($conf->liste_limit + 1, $offset); + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + + if (! empty($id)) + $option .= '&id=' . $product->id; + if (! empty($search_month)) + $option .= '&search_month=' . $search_month; + if (! empty($search_year)) + $option .= '&search_year=' . $search_year; + + print '
' . "\n"; + if (! empty($sortfield)) + print ''; + if (! empty($sortorder)) + print ''; + if (! empty($page)) { + print ''; + $option .= '&page=' . $page; + } - show_stats_for_company($product,$socid); - - print ""; - - print ''; - - - $sql = "SELECT distinct s.nom as name, s.rowid as socid, s.code_client, f.ref, f.total_ht as total_ht,"; - $sql.= " f.datef, f.paye, f.fk_statut as statut, f.rowid as facid, d.qty"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", sc.fk_soc, sc.fk_user "; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - $sql.= ", ".MAIN_DB_PREFIX."facture_fourn as f"; - $sql.= ", ".MAIN_DB_PREFIX."facture_fourn_det as d"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE f.fk_soc = s.rowid"; - $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND d.fk_facture_fourn = f.rowid"; - $sql.= " AND d.fk_product =".$product->id; - if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND f.fk_soc = ".$socid; - $sql.= " ORDER BY $sortfield $sortorder "; - $sql.= $db->plimit($conf->liste_limit +1, $offset); - - $result = $db->query($sql); - if ($result) - { - $num = $db->num_rows($result); - - print_barre_liste($langs->trans("SuppliersInvoices"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,0,''); - - $i = 0; - print ""; - - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"s.rowid","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"s.nom","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("SupplierCode"),$_SERVER["PHP_SELF"],"s.code_client","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DateInvoice"),$_SERVER["PHP_SELF"],"f.datef","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"],"d.qty","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountHT"),$_SERVER["PHP_SELF"],"f.total_ht","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"f.paye,f.fk_statut","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print "\n"; - - if ($num > 0) - { - $var=True; - while ($i < $num && $conf->liste_limit) - { - $objp = $db->fetch_object($result); - $var=!$var; - - print ""; - print '\n"; - print ''; - print "\n"; - print ""; - print "\n"; - print "\n"; - print ''; - print "\n"; - $i++; - } - } - } - else - { - dol_print_error($db); - } - print "
'; - $supplierinvoicestatic->id=$objp->facid; - $supplierinvoicestatic->ref=$objp->facnumber; - print $supplierinvoicestatic->getNomUrl(1); - print "'.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($objp->name,44).'".$objp->code_client.""; - print dol_print_date($db->jdate($objp->datef))."".$objp->qty."".price($objp->total_ht)."'.$supplierinvoicestatic->LibStatut($objp->paye,$objp->statut,5).'
"; - print '
'; - $db->free($result); - } + print_barre_liste($langs->trans("SuppliersInvoices"), $page, $_SERVER["PHP_SELF"], "&id=$product->id", $sortfield, $sortorder, '', $num, $totalrecords, ''); + print '
'; + print $langs->trans('Period') . '(' . $langs->trans("DateInvoice") . ') '; + print $langs->trans('Month') . ': '; + print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print ''; + print ''; + print '
'; + + $i = 0; + print ''; + print ''; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "s.rowid", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Company"), $_SERVER["PHP_SELF"], "s.nom", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("SupplierCode"), $_SERVER["PHP_SELF"], "s.code_client", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("DateInvoice"), $_SERVER["PHP_SELF"], "f.datef", "", $option, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Qty"), $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AmountHT"), $_SERVER["PHP_SELF"], "f.total_ht", "", $option, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Status"), $_SERVER["PHP_SELF"], "f.paye,f.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder); + print "\n"; + + if ($num > 0) + { + $var = True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + $var = ! $var; + + print ''; + print '\n"; + $societestatic->fetch($objp->socid); + print ''; + print "\n"; + print '"; + print '\n"; + print '\n"; + print ''; + print "\n"; + $i ++; + + if (! empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $total_ht += $objp->total_ht; + $total_qty += $objp->qty; + } + } + } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "
'; + $supplierinvoicestatic->id = $objp->facid; + $supplierinvoicestatic->ref = $objp->facnumber; + print $supplierinvoicestatic->getNomUrl(1); + print "' . $societestatic->getNomUrl(1) . '" . $objp->code_client . "'; + print dol_print_date($db->jdate($objp->datef)) . "' . $objp->qty . "' . price($objp->total_ht) . "' . $supplierinvoicestatic->LibStatut($objp->paye, $objp->statut, 5) . '
' . $langs->trans('Total') . '' . $total_qty . '' . price($total_ht) . '
"; + print '
'; + print '
'; + } else { + dol_print_error($db); + } + $db->free($result); + } + } +} else { + dol_print_error(); } -else -{ - dol_print_error(); -} - llxFooter(); $db->close(); diff --git a/htdocs/product/stats/propal.php b/htdocs/product/stats/propal.php index 566961d9c5f..50d7c952b6d 100644 --- a/htdocs/product/stats/propal.php +++ b/htdocs/product/stats/propal.php @@ -2,6 +2,7 @@ /* Copyright (C) 2004-2007 Rodolphe Quiedeville * Copyright (C) 2004-2009 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2014 Florian Henry * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,16 +19,16 @@ */ /** - * \file htdocs/product/stats/propal.php - * \ingroup product service propal - * \brief Page des stats des propals pour un produit + * \file htdocs/product/stats/propal.php + * \ingroup product service propal + * \brief Page des stats des propals pour un produit */ - require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; -require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php'; +require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php'; $langs->load("products"); $langs->load("companies"); @@ -38,154 +39,226 @@ $ref = GETPOST('ref', 'alpha'); // Security check $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : '')); $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); -if ($user->societe_id) $socid=$user->societe_id; -$result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype); +$socid=''; +if (! empty($user->societe_id)) $socid=$user->societe_id; +$result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); // Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array -$hookmanager->initHooks(array('productstatspropal')); +$hookmanager->initHooks(array ('productstatspropal')); $mesg = ''; -$sortfield = GETPOST("sortfield",'alpha'); -$sortorder = GETPOST("sortorder",'alpha'); -$page = GETPOST("page",'int'); -if ($page == -1) { $page = 0; } +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOST("page", 'int'); +if ($page == - 1) { $page = 0;} $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -if (! $sortorder) $sortorder="DESC"; -if (! $sortfield) $sortfield="p.datep"; +if (! $sortorder) $sortorder = "DESC"; +if (! $sortfield) $sortfield = "p.datep"; +$search_month = GETPOST('search_month', 'aplha'); +$search_year = GETPOST('search_year', 'int'); + +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter")) { + $search_month = ''; + $search_year = ''; +} /* * View */ + +$propalstatic = new Propal($db); +$societestatic=new Societe($db); + $form = new Form($db); +$formother = new FormOther($db); if ($id > 0 || ! empty($ref)) { $product = new Product($db); $result = $product->fetch($id, $ref); - - $parameters=array('id'=>$id); - $reshook=$hookmanager->executeHooks('doActions',$parameters,$product,$action); // Note that $action and $object may have been modified by some hooks + + $parameters = array ('id' => $id); + $reshook = $hookmanager->executeHooks('doActions', $parameters, $product, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - - llxHeader("","",$langs->trans("CardProduct".$product->type)); - + + llxHeader("", "", $langs->trans("CardProduct" . $product->type)); + if ($result > 0) { - $head=product_prepare_head($product, $user); - $titre=$langs->trans("CardProduct".$product->type); - $picto=($product->type==1?'service':'product'); - dol_fiche_head($head, 'referers', $titre,0,$picto); - - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$product,$action); // Note that $action and $object may have been modified by hook + $head = product_prepare_head($product, $user); + $titre = $langs->trans("CardProduct" . $product->type); + $picto = ($product->type == 1 ? 'service' : 'product'); + dol_fiche_head($head, 'referers', $titre, 0, $picto); + + $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $product, $action); // Note that $action and $object may have been modified by hook if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - + print ''; - + // Reference print ''; - print ''; print ''; - + // Libelle - print ''; + print ''; print ''; - + // Status (to sell) - print ''; - + // Status (to buy) - print ''; - - show_stats_for_company($product,$socid); - + + show_stats_for_company($product, $socid); + print "
'.$langs->trans("Ref").''; - print $form->showrefnav($product,'ref','',1,'ref'); + print '' . $langs->trans("Ref") . ''; + print $form->showrefnav($product, 'ref', '', 1, 'ref'); print '
'.$langs->trans("Label").''.$product->libelle.'
' . $langs->trans("Label") . '' . $product->libelle . '
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; - print $product->getLibStatut(2,0); + print '
' . $langs->trans("Status") . ' (' . $langs->trans("Sell") . ')'; + print $product->getLibStatut(2, 0); print '
'.$langs->trans("Status").' ('.$langs->trans("Buy").')'; - print $product->getLibStatut(2,1); + print '
' . $langs->trans("Status") . ' (' . $langs->trans("Buy") . ')'; + print $product->getLibStatut(2, 1); print '
"; - + print ''; - - - $sql = "SELECT DISTINCT s.nom as name, s.rowid as socid, p.rowid as propalid, p.ref, p.total_ht as amount,"; - $sql.= "p.datep, p.fk_statut as statut, d.qty"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", sc.fk_soc, sc.fk_user "; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - $sql.= ",".MAIN_DB_PREFIX."propal as p"; - $sql.= ", ".MAIN_DB_PREFIX."propaldet as d"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE p.fk_soc = s.rowid"; - $sql.= " AND p.entity = ".$conf->entity; - $sql.= " AND d.fk_propal = p.rowid"; - $sql.= " AND d.fk_product =".$product->id; - if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND p.fk_soc = ".$socid; - $sql.= " ORDER BY $sortfield $sortorder "; - $sql.= $db->plimit($conf->liste_limit +1, $offset); - - $result = $db->query($sql); - if ($result) - { - $num = $db->num_rows($result); - - print_barre_liste($langs->trans("Proposals"),$page,$_SERVER["PHP_SELF"],"&id=$product->id",$sortfield,$sortorder,'',$num,0,''); - - $i = 0; - print ''; - print ''; - print_liste_field_titre($langs->trans("Ref"),$_SERVER["PHP_SELF"],"p.rowid","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Company"),$_SERVER["PHP_SELF"],"s.nom","","&id=".$product->id,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("DatePropal"),$_SERVER["PHP_SELF"],"p.datep","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Qty"),$_SERVER["PHP_SELF"],"d.qty","","&id=".$product->id,'align="center"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("AmountHT"),$_SERVER["PHP_SELF"],"p.total","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"p.fk_statut","","&id=".$product->id,'align="right"',$sortfield,$sortorder); - print "\n"; - - $propalstatic=new Propal($db); - - if ($num > 0) - { - $var=True; - while ($i < $num && $i < $conf->liste_limit) - { - $objp = $db->fetch_object($result); - $var=!$var; - - print ''; - print ''."\n"; - print ''; - print '"; - print "\n"; - print ''."\n"; - print ''; - print ''."\n"; - $i++; + + if ($user->rights->propale->lire) { + $sql = "SELECT DISTINCT s.nom as name, s.rowid as socid, p.rowid as propalid, p.ref, d.total_ht as amount,"; + $sql .= " p.ref_client,"; + $sql .= "p.datep, p.fk_statut as statut, d.qty"; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= ", sc.fk_soc, sc.fk_user "; + $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s"; + $sql .= "," . MAIN_DB_PREFIX . "propal as p"; + $sql .= ", " . MAIN_DB_PREFIX . "propaldet as d"; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc"; + $sql .= " WHERE p.fk_soc = s.rowid"; + $sql .= " AND p.entity = " . $conf->entity; + $sql .= " AND d.fk_propal = p.rowid"; + $sql .= " AND d.fk_product =" . $product->id; + if (! empty($search_month)) + $sql .= ' AND MONTH(p.datep) IN (' . $search_month . ')'; + if (! empty($search_year)) + $sql .= ' AND YEAR(p.datep) IN (' . $search_year . ')'; + if (! $user->rights->societe->client->voir && ! $socid) + $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . $user->id; + if ($socid) + $sql .= " AND p.fk_soc = " . $socid; + $sql .= " ORDER BY $sortfield $sortorder "; + + // Calcul total qty and amount for global if full scan list + $total_ht = 0; + $total_qty = 0; + $totalrecords = 0; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $result = $db->query($sql); + if ($result) { + $totalrecords = $db->num_rows($result); + while ( $objp = $db->fetch_object($result) ) { + $total_ht += $objp->amount; + $total_qty += $objp->qty; + } } } - } - else - { + + $sql .= $db->plimit($conf->liste_limit + 1, $offset); + + $result = $db->query($sql); + if ($result) + { + $num = $db->num_rows($result); + + if (! empty($id)) + $option .= '&id=' . $product->id; + if (! empty($search_month)) + $option .= '&search_month=' . $search_month; + if (! empty($search_year)) + $option .= '&search_year=' . $search_year; + + print '' . "\n"; + if (! empty($sortfield)) + print ''; + if (! empty($sortorder)) + print ''; + if (! empty($page)) { + print ''; + $option .= '&page=' . $page; + } + + print_barre_liste($langs->trans("Proposals"), $page, $_SERVER["PHP_SELF"], "&id=$product->id", $sortfield, $sortorder, '', $num, $totalrecords, ''); + print '
'; + print $langs->trans('Period') . '(' . $langs->trans("DateInvoice") . ') '; + print $langs->trans('Month') . ': '; + print $langs->trans('Year') . ':' . $formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print ''; + print ''; + print '
'; + + $i = 0; + print '
'.img_object($langs->trans("ShowPropal"),"propal").' '; - print $objp->ref; - print ''.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($objp->name,44).''; - print dol_print_date($db->jdate($objp->datep))."".$objp->qty."'.price($objp->amount).''.$propalstatic->LibStatut($objp->statut,5).'
'; + print ''; + print_liste_field_titre($langs->trans("Ref"), $_SERVER["PHP_SELF"], "p.rowid", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Company"), $_SERVER["PHP_SELF"], "s.nom", "", $option, '', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("DatePropal"), $_SERVER["PHP_SELF"], "p.datep", "", $option, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Qty"), $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("AmountHT"), $_SERVER["PHP_SELF"], "p.total", "", $option, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre($langs->trans("Status"), $_SERVER["PHP_SELF"], "p.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder); + print "\n"; + + if ($num > 0) + { + $var = True; + while ($i < $num && $i < $conf->liste_limit) + { + $objp = $db->fetch_object($result); + $var = ! $var; + + print ''; + print '\n"; + $societestatic->fetch($objp->socid); + print ''; + print '"; + print "\n"; + print '' . "\n"; + print ''; + print "\n"; + $i ++; + + if (! empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + $total_ht += $objp->total_ht; + $total_qty += $objp->qty; + } + } + } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "
'; + $propalstatic->id=$objp->propalid; + $propalstatic->ref=$objp->ref; + $propalstatic->ref_client=$objp->ref_client; + print $propalstatic->getNomUrl(1); + print "'.$societestatic->getNomUrl(1).''; + print dol_print_date($db->jdate($objp->datep)) . "" . $objp->qty . "' . price($objp->amount) . '' . $propalstatic->LibStatut($objp->statut, 5) . '
' . $langs->trans('Total') . '' . $total_qty . '' . price($total_ht) . '
"; + print ''; + print '
'; + } else { dol_print_error($db); } - print ""; - print '
'; $db->free($result); + } } -} -else -{ +} else { dol_print_error(); } - llxFooter(); $db->close(); diff --git a/htdocs/societe/rib.php b/htdocs/societe/rib.php index f57eb6a5b70..2a21f6cdc87 100644 --- a/htdocs/societe/rib.php +++ b/htdocs/societe/rib.php @@ -293,10 +293,26 @@ if ($socid && $action != 'edit' && $action != "create") } print ''.$langs->trans("IBAN").''; - print ''.$account->iban.''; + print ''.$account->iban . ' '; + if (! empty($account->iban)) { + if (! checkIbanForAccount($account)) { + print img_picto($langs->trans("IbanNotValid"),'warning'); + } else { + print img_picto($langs->trans("IbanValid"),'info'); + } + } + print ''; print ''.$langs->trans("BIC").''; - print ''.$account->bic.''; + print ''.$account->bic.' '; + if (! empty($account->bic)) { + if (! checkSwiftForAccount($account)) { + print img_picto($langs->trans("SwiftNotValid"),'warning'); + } else { + print img_picto($langs->trans("SwiftValid"),'info'); + } + } + print ''; print ''.$langs->trans("BankAccountDomiciliation").''; print $account->domiciliation;