diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index fed73d7b002..f112ea0523b 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -56,7 +56,7 @@ You can add it to your git configuration using:
git config --local commit.template .gitmessage
```
-where
+where
#### Keyword
In uppercase if you want to have the log comment appears into the generated ChangeLog file.
@@ -101,7 +101,7 @@ Long description (Can span accross multiple lines).
### Pull Requests
-Pull Request (PR) process is the process to submit a change (enhancement, bug fix, ...) into the code of the project. There is some rules to know and
+Pull Request (PR) process is the process to submit a change (enhancement, bug fix, ...) into the code of the project. There is some rules to know and
a process to follow to optimize the chance to have PRs merged efficiently...
* A PR must be atomic. It means it must contains the lower possible changes for 1 need (1 bug fix or 1 new feature) without breaking usability of code. If a PR can be split into several PRs, it often means your PR is not atomic.
@@ -120,7 +120,7 @@ Once a PR has been submitted, you may need to wait for its integration. It is co
If the label of PR start with "Draft" or "WIP" (Work In Progress), it will not be analyzed for merging until you change the label of PR (but it can be analyzed for discussion).
-If your PR has errors reported by the Continuous Integration Platform, it means your PR is not valid and nothing will be done with it. It will be kept open to allow developers to fix this, or it may be closed several month later. Don't expect anything on your PR if you have such errors, you MUST first fix the Continuous Integration error to have it taken into consideration.
+If your PR has errors reported by the Continuous Integration Platform, it means your PR is not valid and nothing will be done with it. It will be kept open to allow developers to fix this, or it may be closed several month later. Don't expect anything on your PR if you have such errors, you MUST first fix the Continuous Integration error to have it taken into consideration.
If the PR is valid, and is kept open for a long time, a tag will also be added on the PR to describe the status of your PR and why the PR is kept open. By putting your mouse on the tag, you will get a full explanation of the tag/status that explain why your PR has not been integrated yet.
In most cases, it gives you information of things you have to do to have the PR taken into consideration (for example a change is requested, a conflict is expected to be solved, some questions were asked). If you have a yellow, red flag of purple flag, don't expect to have your PR validated. You must first provide the answer the tag ask you. The majority of open PR are waiting an action of the author of the PR.
@@ -141,7 +141,7 @@ Translations done on transifex are available in the next major release.
Note: Sometimes, the source text (english) is modified. In such a case, the translation is reset. Transifex assume that if the original source
has changed, the translation is surely no more correct so must be done again. But old translation is not lost and you can use the tab "History"
-to retreive all old translation of a source text, and restore the translation in one click with no need to retranslate it if there is no need to.
+to retrieve all old translation of a source text, and restore the translation in one click with no need to retranslate it if there is no need to.
### Resources
diff --git a/.github/workflows/exakat.yml b/.github/workflows/exakat.yml
index 861f6ccd4b0..3cfc4f8ba23 100644
--- a/.github/workflows/exakat.yml
+++ b/.github/workflows/exakat.yml
@@ -13,5 +13,5 @@ jobs:
- name: Exakat
uses: docker://exakat/exakat-ga
with:
- ignore_rules: 'Classes/UseInstanceof,Performances/PrePostIncrement,Functions/WrongNumberOfArguments,Variables/UndefinedVariable,Classes/DontUnsetProperties,Classes/NonPpp,Classes/StaticMethodsCalledFromObject,Classes/UseClassOperator,Functions/UsesDefaultArguments,Php/NoClassInGlobal,Php/ShouldUseCoalesce,Structures/MergeIfThen,Structures/ElseIfElseif,Structures/RepeatedPrint,Structures/UselessParenthesis,Structures/SwitchWithoutDefault,Structures/ShouldMakeTernary,Structures/UseConstant'
- ignore_dirs: '/htdocs/includes,/htdocs/build,/htdocs/dev,/htdocs/doc,/htdocs/scripts,/htdocs/test'
\ No newline at end of file
+ ignore_rules: 'Classes/UseInstanceof,Performances/PrePostIncrement,Functions/UndefinedFunctions,Functions/WrongNumberOfArguments,Functions/WrongTypeWithCall,Variables/UndefinedVariable,Classes/DontUnsetProperties,Classes/NonPpp,Classes/StaticMethodsCalledFromObject,Classes/UseClassOperator,Functions/UsesDefaultArguments,Php/NoClassInGlobal,Php/ShouldUseCoalesce,Php/WrongTypeForNativeFunction,Structures/MergeIfThen,Structures/ElseIfElseif,Structures/RepeatedPrint,Structures/SameConditions,Structures/SwitchWithoutDefault,Structures/ShouldMakeTernary,Structures/UselessParenthesis,Structures/UseConstant'
+ ignore_dirs: '/htdocs/includes,/build,/dev,/doc,/scripts,/test'
\ No newline at end of file
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index 6dbf39bde26..3cffed355fa 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -17,8 +17,10 @@ filter:
- build/*
- dev/*
- doc/*
- - test/*
+ - documents/*
- htdocs/includes/*
+ - node_modules/*
+ - test/*
paths:
- htdocs/*
- scripts/*
diff --git a/.travis.yml b/.travis.yml
index 16d3403f554..639183de6ff 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -35,10 +35,6 @@ addons:
php:
- '5.6'
-- '7.0'
-- '7.1'
-- '7.2'
-- '7.3'
- '7.4'
- nightly
@@ -112,33 +108,48 @@ install:
echo "Updating Composer"
rm $TRAVIS_BUILD_DIR/composer.json
rm $TRAVIS_BUILD_DIR/composer.lock
+ composer -V
composer self-update
- # To have composer making parallel downloads
- composer global require hirak/prestissimo
composer -n init
composer -n config vendor-dir htdocs/includes
+ composer -n config -g vendor-dir htdocs/includes
echo
- |
echo "Installing Composer dependencies - PHP Unit, Parallel Lint, PHP CodeSniffer - for $TRAVIS_PHP_VERSION"
- if [ "$TRAVIS_PHP_VERSION" = '5.6' ] || [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] \
- [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ]; then
+ if [ "$TRAVIS_PHP_VERSION" = '5.6' ]; then
composer -n require phpunit/phpunit ^5 \
- php-parallel-lint/php-parallel-lint ^0 \
+ php-parallel-lint/php-parallel-lint ^1 \
php-parallel-lint/php-console-highlighter ^0 \
squizlabs/php_codesniffer ^3
fi
+ if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ]; then
+ composer -n require phpunit/phpunit ^6 \
+ php-parallel-lint/php-parallel-lint ^1 \
+ php-parallel-lint/php-console-highlighter ^0 \
+ squizlabs/php_codesniffer ^3
+ fi
+ if [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ]; then
+ composer -n require phpunit/phpunit ^7 \
+ php-parallel-lint/php-parallel-lint ^1.2 \
+ php-parallel-lint/php-console-highlighter ^0 \
+ squizlabs/php_codesniffer ^3
+ fi
+ # phpunit 9 is required for php 8
if [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then
- composer -n require --ignore-platform-reqs phpunit/phpunit ^5 \
- php-parallel-lint/php-parallel-lint ^1 \
+ composer -n require --ignore-platform-reqs phpunit/phpunit ^7 \
+ php-parallel-lint/php-parallel-lint ^1.2 \
php-parallel-lint/php-console-highlighter ^0 \
squizlabs/php_codesniffer ^3
- fi
+ fi
echo
- |
echo "Adding path of binaries tools installed by composer to the PATH"
- export PATH="$TRAVIS_BUILD_DIR/htdocs/includes/bin:$PATH"
+ export PATH="$TRAVIS_BUILD_DIR/htdocs/includes/bin:$TRAVIS_BUILD_DIR/vendor/bin:$TRAVIS_BUILD_DIR/htdocs/includes:$PATH"
+ echo $PATH
+ ls $TRAVIS_BUILD_DIR/vendor
+ ls $TRAVIS_BUILD_DIR/htdocs/includes/bin
echo
@@ -165,15 +176,20 @@ before_script:
- |
echo "Versions information"
+ echo
# Check PHP
echo "PHP version"
php -i | head -
- # Check PHP CodeSniffer installation
+ # Check Parallel-lint version
+ echo "Parallel-lint version"
+ which parallel-lint
+ parallel-lint -V
+ # Check PHP CodeSniffer version
echo "PHPCS version"
which phpcs
phpcs --version | head -
phpcs -i | head -
- # Check PHPUnit installation
+ # Check PHPUnit version
echo "PHPUnit version"
which phpunit
phpunit --version | head -
@@ -287,12 +303,13 @@ script:
echo
- |
- echo "Checking coding style (excluding Pull Requests builds)"
+ echo "Checking coding style (excluding Pull Requests builds to not overload travis, excluding also some jobs to avoid duplicate tests)"
# Ensure we catch errors
set -e
# Exclusions are defined in the ruleset.xml file
- #phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; fi
+ if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4" ] && [ "$DB" = "mysql" ]; then
+ phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .;
+ fi
set +e
echo
@@ -409,7 +426,7 @@ script:
php step5.php 12.0.0 13.0.0 > $TRAVIS_BUILD_DIR/upgrade12001300-3.log
# Enable modules not enabled into original dump
- php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_API,MAIN_MODULE_SUPPLIERPROPOSAL,MAIN_MODULE_WEBSITE,MAIN_MODULE_TICKETSUP,MAIN_MODULE_ACCOUNTING > $TRAVIS_BUILD_DIR/enablemodule.log
+ php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_API,MAIN_MODULE_SUPPLIERPROPOSAL,MAIN_MODULE_WEBSITE,MAIN_MODULE_TICKET,MAIN_MODULE_ACCOUNTING,MAIN_MODULE_MRP > $TRAVIS_BUILD_DIR/enablemodule.log
echo $?
cd -
set +e
@@ -428,7 +445,7 @@ script:
after_script:
- |
- echo "After script - Output lines of dolibarr.log"
+ echo "After script - Output last lines of dolibarr.log"
ls $TRAVIS_BUILD_DIR/documents
#cat $TRAVIS_BUILD_DIR/documents/dolibarr.log
sudo tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log
diff --git a/COPYRIGHT b/COPYRIGHT
index d8cefedcd65..d43f4d506f1 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -21,6 +21,7 @@ Mobiledetect 2.8.34 MIT License Yes
NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package)
PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency
ParseDown 1.6 MIT License Yes Markdown parser
+PCLZip 2.8.4 LGPL-3+ Yes Library to zip/unzip files
PHPDebugBar 1.15.1 MIT License Yes Used only by the module "debugbar" for developers
PHPExcel 1.8.1 LGPL-2.1+ Yes Read/Write XLS files, read ODS files
PHPSpreadSheet ? LGPL-2.1+ Yes Read/Write XLS files, read ODS files
diff --git a/ChangeLog b/ChangeLog
index 60aa376f96d..516bc270321 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,25 +7,242 @@ English Dolibarr ChangeLog
For users:
NEW: Add module "Credit transfer SEPA" to manage payment of vendors using bank credit transfer SEPA files.
NEW: Module Reception (for a more accurate management of your receptions) moved from experimental to stable.
+NEW: Several security issues after a private bug bounty campaign.
+NEW: #15065 Put the product label in bold in the PDF templates if configured
+NEW: Accountancy - Add chart of sub accounts
+NEW: Accountancy - Add options to disable binding on sales, purchases & expense reports independently of the modules
+NEW: Accountancy balance - Add a menu entry to show subtotal by group
+NEW: Accountancy - Move to real ledger, real journals, menu disposition
+NEW: Accountancy - On transfers, select the periodicity by default
+NEW: New currency rate editor.
+NEW: Add 2 rules for emailcollector: Message send/not sent from Dolibarr
+NEW: Add a counter of number of words for pages in website module
+NEW: add alert before changing thirdparty in takepos
+NEW: Add a page to list Stock at a given date in the past.
+NEW: Add a start date to begin binding in accountancy
+NEW: Add a statistics page to list popularity of products on invoices
+NEW: Add calendar selection for agenda view
+NEW: Support documents generation for ticket edition (pdf or odt)
+NEW: Add column payment term into list of supplier invoices.
+NEW: Add column quantity in product margin page
+NEW: Add column vat rate in page to define accounting account on product/service
+NEW: Add common list function for available app/module page
+NEW: add costprice in fields of products list
+NEW: Added an import profile for CUSTOMER ORDER, PO, PROPOSAL MODULE, SUPPLIER INVOICE
+NEW: Added incoterms dara into the substitution array
+NEW: Add employee link in expense report binding page
+NEW: Add export for various payment
+NEW: add extra fields labels and values in mail on create ticket
+NEW: Add extrafields support on ECM module
+NEW: Add filter rules "is answer" and "is not answer" in email collector
+NEW: Add focus when editing on product/stock/product.php Close #14548
+NEW: add formConfirm hook on product page
+NEW: add free text on each terminal of cash desk
+NEW: Add function dolButtonToOpenUrlInDialogPopup() to be able to open
+NEW: Add global search for customer payments and vendor payments
+NEW: Add global search for miscellaneous payments
+NEW: Add helper function for table headers with numbers
+NEW: add hooks on stats pages
+NEW: Add link to edit property from search result of website pages
+NEW: Add link to reset qty on supplier dispatch page
+NEW: add MAIN_EMAILCOLLECTOR_MAIL_WITHOUT_HEADER const to remove header stored by email collector
+NEW: Add Manufacturing Orders attached files into the automatic ECM view
+NEW: add margin info in invoice list
+NEW: Add mass action to set category on a list of website pages.
+NEW: Add mass deletion for events
+NEW: Add mass deletion for draft invoices
+NEW: Add __MEMBER_TYPE__ substitution key
+NEW: Add a message in error_log after detection of SQL or script injection
+NEW: Add module Credit transfer SEPA to manage payment of supplier using
+NEW: Add more filters on monthly statement list
+NEW: Add option TAKEPOS_CAN_FORCE_BANK_ACCOUNT_DURING_PAYMENT
+NEW: Add option to define a default warehouse at user level
+NEW: Add option to include products without alert in replenish
+NEW: add order by lastname and firstname by default in get sales representatives
+NEW: Add param to not show links when output tags
+NEW: Add PDF document templates for warehouses (list of stock)
+NEW: Add property cssview when declaring fields of an object
+NEW: Add prospect status managment for the contact with managment of custom icon
+NEW: Add public note on products. This also partially fix the #14342
+NEW: Add quick dropdown menu in top right menu (MAIN_USE_TOP_MENU_QUICKADD_DROPDOWN)
+NEW: add region in export companies and contacts
+NEW: add rights on margin info on invoice list
+NEW: Add search param for close date on order list
+NEW: add send context for ticket
+NEW: Add show preview for mail attachement on form mail
+NEW: add state origin for product
+NEW: add State/Province origin for products
+NEW: Add the workflow interaction close intervention on closing ticket
+NEW: Add third order printer to TakePOS
+NEW: add tracking number in list and search_all items
+NEW: add two hooks printFieldListFrom and printFieldSearchParam
+NEW: Add __TYPE__ substitution key
+NEW: Add validation of MX domain for emails
+NEW: add vcard for aderent and user
+NEW: add week number for month view in agenda
+NEW: Algeria data (tva and forme_juridique)
+NEW: Allow click on all header numbers on commerce area
+NEW: Allow to reopen interventions (green button)
+NEW: Allow zero quality on supplier/vendor order line
+NEW: Appearance tab in TakePOS with more visual parameters
+NEW: Better currency rate editor
+NEW: Calculate the virtual stock in transverse mode ( not on getEntity('commande'), ... but on getEntity('stock') )
+NEW: Can add event to log into blockedlog module with a constant.
+NEW: Can build vendor invoice from vendor orders
+NEW: Can change a product in line of recurring invoice or contract
+NEW: Can change size of logo on PDF documents
+NEW: Can change VAT rate of all lines of a draft object in one step.
+NEW: Can define date range of validity of a login during creation
+NEW: Can disable, from edit page, the whole web site
+NEW: can edit and set sales representatives directly on thirdparty card
+NEW: Can edit the list of sending email profiles.
+NEW: Can enable/disable users in bulk actions
+NEW: Can filter on accounting system ref in export of chart of account
+NEW: Can filter on container type, language and tags in the list of pages
+NEW: Can force the antivirus from conf file or autoprepend ini setup.
+NEW: Can hide eatby, sellby dates with option PRODUCT_DISABLE_SELLBY and PRODUCT_DISABLE_EATBY
+NEW: Can import proposals, sales orders, supplier invoices
+NEW: can set a dedicated SMTP config for sending email from public ticket interface
+NEW: Can set tags/categories to website pages.
+NEW: Can set type of price without tax per default for new sale price creation
+NEW: Can use desired stock of a given warehouse for replenishment
+NEW: Can use THEME_DARKMODEENABLED=2 for a preview of theme in dark mode
+NEW: change thirdparty with barcode scan in takepos
+NEW: Common behavior for monthly leave list view
+NEW: conf to allow show full arbo in warehouse getnomurl
+NEW: convert all subscription in datetime
+NEW: create thirdparty customer from TAKEPOS
+NEW: Date shipment from order accepts hours
+NEW: Declinaison price level compatibility
+NEW: Delayed payment in TakePOS
+NEW: Development of module Recruitment
+NEW: display date range if exist in takepos
+NEW: display resiliate status in takepos for member
+NEW: display stat for BOM on "object referent"/linked Object product tab
+NEW: edit and update a ticket
+NEW: edit or delete dispatched lines
+NEW: Email configuration - Allow auto signed certificat when smtp ssl activated
+NEW: enable free emails input with select2
+NEW: endpoint getContacts and Clean results
+NEW: Events in agenda for contact
+NEW: Field to link website page to an other object
+NEW: Fill ECM src object fields in dol_add_file_process
+NEW: filter on progress column in task list
+NEW: filter product list by country and/or state/province
+NEW: format tickets sent by mail in public interface
+NEW: add juridical status for Algeria
+NEW: form to add customer/supplier into categories
+NEW: Framework is ready for CSRF token protection on explicit GET URLs.
+NEW: get all child recursively
+NEW: Get contacts list of a given order
+NEW: helper functions for export with phpspreadsheet
+NEW: hide closed contract lines
+NEW: hide label in pdf for variants
+NEW: Hook on propal card
+NEW: If specific help page is available, we change color of icon
+NEW: Include the tag editor of page as a popup into website editor
+NEW: Introduce constant FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM
+NEW: Introducing new modal boxes in TakePOS
+NEW: Keep takepos terminal when login/logout
+NEW: Link on balance to the ledger
+NEW: MAIN_EMAILCOLLECTOR_MAIL_WITHOUT_HEADER const in email collector
+NEW: manage errors on update extra fields in ticket card
+NEW: mass-actions for the event list view
+NEW: Module Intracomm report
+NEW: More filter for "View change logs"
+NEW: multicurrency total in takepos
+NEW: multiselect type and date to date filter
+NEW: Nature of product is now a dictionay
+NEW: new line template: hidden conf to fill service dates from the last service line
+NEW: PDF model storm for delivery
+NEW: possibilty to group payments by mode and show their subtotal
+NEW: Print payment method and change in TakePOS
+NEW: Priority and transparency from external calendar events
+NEW: Products Import/Export 'default warehouse' and 'use batch number' fields
+NEW: Purchase price table: Added filterable table columns
+NEW: rate editor for multicurrency
+NEW: ref_ext field for Commande lines, order lines, Attributes and Combinations, Invoice lines, payments, order lines
+NEW: remove new lines in mail on add ticket message
+NEW: restrict thirdparty to customer in takepos
+NEW: Allow to edit "demand reason" field though API
+NEW: Rule "email to" accept wildcard *
+NEW: Save filter of the project homepage
+NEW: Select-able columns on customer invoice paymnet list
+NEW: Select-able columns on miscellaneous payments + more data columns
+NEW: Select-able columns on social taxes list
+NEW: Select-able columns on supplier invoice payment list
+NEW: send context and remove new lines on create ticket
+NEW: set entity when creating invoice on takepos
+NEW: Show available stock in TakePOS
+NEW: Show category filter on lists only when user have rights to read categories
+NEW: Show header number and make it clickable in warehouse arean, payment area, shipment area
+NEW: Show image of user in the combo select of users
+NEW: Show label on batch card
+NEW: Show line number on intervention card (via MAIN_VIEW_LINE_NUMBER)
+NEW: show links for select and multi-select in category extra field
+NEW: Show module and permission ids on user/group rights (only admin)
+NEW: Show place from events on import calender
+NEW: Show references in contract form on interventions
+NEW: Show tags and status in search list of website pages
+NEW: Show user on external calender events (when found)
+NEW: subject title with company name instead of application title in ticket message
+NEW: Support for Samba4 AD
+NEW: TakePOS connector compatibility with RECEIPT PRINTERS module
+NEW: TakePOS Gift Receipt
+NEW: TakePOS Multicurrency compatibility
+NEW: The global header of a website can also have dynamic content
+NEW: Third-Party Import new fields: mother company,outstanding debt limit,bank account,incoterms
+NEW: Thirdparty module : box on customer/supplier tab for invoice outsantding amount late
+NEW: ticket classification on create from email collector
+NEW: Ticket message notifications when edited from public interface
+NEW: translate classification labels in ticket
+NEW: triggers create, modify, delete
+NEW: VAT for Algeria
+NEW: Use preselect third-party from list on new card
+NEW: Vat report - Invert constant to show by default zero vat in reports
+NEW: website page fields selection
+NEW: Weighing Scale compatibility with TakePOS connector
+NEW: When creating a user from a member linked to a thirdparty, you can choose to create if as external or internal user
+NEW: Add clone functionality on miscellaneous payment
+For developers:
+NEW: Can use dynamic code into the 'enabled' property of DAO fields
+NEW: API Can update a payment
+NEW: api get member by thirdparty
+NEW: API get thirdparty by barcode
+NEW: API get users by email / login
+NEW: fetch contact by email with REST API
+NEW: field ref_ext in llx_commandedet
+NEW: fields ref_ext for Attributes and Combinations
+NEW: get state by REST API
+NEW: get state dictionnary by REST API
+NEW: Improve Product API for variant products
+NEW: Oauth SCOPE for Admin SDK
+NEW: Retrieve discount from invoice from API
+NEW: standardizes API thirdparties by email like other object
+NEW: thirdparty REST API: endpoint to set price level
+NEW: Use new category API for project list view
+NEW: Triggers Attributes and Attributes values
+NEW: Add hooks on newpayment page to allow external payment modules
WARNING:
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
-* Properties ->contactid have been renamed into ->contact_id
-* Properties ->titre have been renamed into ->title
-* Property $paiementid in API 'api_supplier_invoices.php' has been renamed into into $payment_mode_id (english)
-* The deprecated subsitution key __SIGNATURE__ has been removed. Replace with __USER_SIGNATURE__ if you used the old syntax in
- your email templates.
-* The hidden option HOLIDAY_MORE_PUBLIC_HOLIDAYS has been removed. Use instead the dictionary table if you need to define custom
- days of holiday.
+* The object "livraison" has been renamed into "delivery" (directory, class, keys, methods with livraison in name ...).
+* All properties ->contactid have been renamed into ->contact_id
+* All properties ->titre have been renamed into ->title
+* Property $paiementid in API 'api_supplier_invoices.php' has been renamed into into $payment_mode_id
* Property 'num_paiement' has been renamed 'num_payment' everywhere for better code consistency.
+* The deprecated subsitution key __SIGNATURE__ has been removed. Use __USER_SIGNATURE__ if you used the old syntax in your email templates.
+* The hidden option HOLIDAY_MORE_PUBLIC_HOLIDAYS has been removed. Use instead the dictionary table if you need to define custom days of holiday.
* If you build a class that implement CommonObject to use the incoterm properties or methods (->fk_incoterm, ->label_incoterm, ->location_incoterm),
- you must now also include declaration of the Trait 'CommonIncoterm' in your class. All incoterm functions were moved into this Trait.
+ you must now also include declaration of the Trait 'CommonIncoterm' in your class. All incoterm functions were moved into this Trait.
* The GETPOST(..., 'alpha') has now the same behaviour than GETPOST(..., 'alphanohtml') so no html will be allowed. Use GETPOST(..., 'restricthtml') to accept HTML.
-* If you have links in your code with '&action=delete' as a parameter, you must also add '&token='.newToken() as another parameter to avoid CSRF protection errors.
-* The API addPayment for api_invoice has evolved to accept amount into a foreign currency. You must provide array(amount=>X,mutlicurrency_ammount=>Y) instead of amount.
+* If you have links in your code with '&action=add', '&action=update', '&action=delete' as a parameter, you must also add '&token='.newToken() as another parameter to avoid CSRF protection errors.
+* The API addPayment for api_invoice has evolved to accept amount into a foreign currency. You must provide array(amount=>X,mutlicurrency_ammount=>Y) instead of simple amount.
* The method select_thirdparty(), deprecated since 3.8, into html.form.class.php has been removed.
+* Depreciate all methods with name ->valide(). Use instead methods ->validate().
+
***** ChangeLog for 12.0.3 compared to 12.0.2 *****
FIX: 10.0 - when the mime file name is different from the filesystem name, the attachment name should be the mime filename
@@ -383,28 +600,28 @@ Following changes may create regressions for some external modules, but were nec
* Default mode for GETPOST function is now 'alphanohtml' instead of 'none'. So check when you make POST or GET requests with
HTML content that you make a GETPOST('myparam', 'restricthtml') or GETPOST('myparam', 'none') if you really need posted content without sanitizing
the HTML code of content (in such a case, sanitize data later)
-* Removed hidden constant MAIN_EXTRAFIELDS_IN_ONE_TD that was useless.
-* Reference of object including a "/" are no more allowed. It is never used by default but to support setup that introduced it, the "/" will be replaced
- by a "_" automatically when a reference (with a custom numbering mask that use it) is generated.
+* Removed hidden constant MAIN_EXTRAFIELDS_IN_ONE_TD that was useless.
+* Reference of object including a "/" are no more allowed. It is never used by default but to support setup that introduced it, the "/" will be replaced
+ by a "_" automatically when a reference (with a custom numbering mask that use it) is generated.
* Library jflot (replace with chartjs) was removed.
-* Library geoip (replaced with geoip2) was removed.
+* Library geoip (replaced with geoip2) was removed.
* Hidden constant COMMANDE_VALID_AFTER_CLOSE_PROPAL was renamed into ORDER_VALID_AFTER_CLOSE_PROPAL.
* Object field ref_int is deprecated and set to 'not used', method to fetch object by only ref_int is not supported anymore.
* UserGroup class has been refactored with new architecture. Triggers of class UserGroup are now USERGROUP_CREATE, USERGROUP_MODIFY, USERGROUP_DELETE
* A new way to navigate between pages in list is available. To use it (not mandatory), you must:
- - replace line $page = GETPOST('page', 'int') with $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
+ - replace line $page = GETPOST('page', 'int') with $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
- remove input field in form '';'
- add parameter $pagenavastextinput to value 1 when calling print_barre_liste()
WARNING FOR DOLIWAMP USERS ONLY:
Only people that installed Dolibarr using the all-in-one auto-installer for Windows called "DoliWAMP" are concerned by the following warnings:
-
+
* DoliWAMP auto-installer for Windows is no more available on 32 bits systems. Use standard package if you need to use such architecture.
-* It is not possible to migrate from an installation done with the old DoliWAMP auto-installer for Windows by using this new one.
- You must make a backup of your database, make a fresh installation using the new installer and reload your backup.
- Don't forget that DoliWAMP is a good solution to make a quick test of Dolibarr on your local computer but is not recommended as a production
- solution on a local desktop since a local desktop computer has often no backup and security policy, or not as good as on a server (when there is one).
+* It is not possible to migrate from an installation done with the old DoliWAMP auto-installer for Windows by using this new one.
+ You must make a backup of your database, make a fresh installation using the new installer and reload your backup.
+ Don't forget that DoliWAMP is a good solution to make a quick test of Dolibarr on your local computer but is not recommended as a production
+ solution on a local desktop since a local desktop computer has often no backup and security policy, or not as good as on a server (when there is one).
DoliWAMP remains a solution for fast test or demo purposes. Prefer using standard packages for production.
@@ -568,7 +785,7 @@ FIX: #13118
FIX: #13124
FIX: #13131
FIX: #13135
-FIX: #13146
+FIX: #13146
FIX: #13198
FIX: #13175
FIX: #13182
@@ -635,7 +852,7 @@ FIX: Confusion between 'bank reconciled' and 'accounted'. Show both data.
FIX: Count of Stripe payment mode must take test/live into account
FIX: Creation of Stripe card from backoffice must return a clean message
FIX: CVE-2019–17223
-FIX: CVE-2019–17223
+FIX: CVE-2019–17223
FIX: CVE-2020-7994
FIX: CVE Need permission to be able to develop modules
FIX: #13053
@@ -835,7 +1052,7 @@ NEW: #4301
For Developers or integrators:
-NEW: Compatible with PHP 7.4
+NEW: Compatible with PHP 7.4
NEW: Code for extrafields uses the new array $extrafields->attributes
NEW: Can set a filter on object linked in modulebuilder.
NEW: Can defined a position of numbering submodules for thirdparties
@@ -902,9 +1119,9 @@ Following changes may create regressions for some external modules, but were nec
* Removed function dol_micro_time. Use native PHP microtime instead.
* The trigger BON_PRELEVEMENT_CREATE has been renamed into DIRECT_DEBIT_ORDER_CREATE.
* The constant INVOICE_SHOW_POS_IN_EXPORT has been renamed into INVOICE_SHOW_POS.
-* If your logo is no more visible on the menu bar, you must upload a new logo into 'Home-Setup-Company/Organization' to have it visible again.
-* All properties 'libstatut', 'labelstatut', 'labelstatus' were renamed into 'labelStatus'.
-* All properties 'labelstatusshort' and 'labelstatut_short' were renamed into 'labelStatusShort'.
+* If your logo is no more visible on the menu bar, you must upload a new logo into 'Home-Setup-Company/Organization' to have it visible again.
+* All properties 'libstatut', 'labelstatut', 'labelstatus' were renamed into 'labelStatus'.
+* All properties 'labelstatusshort' and 'labelstatut_short' were renamed into 'labelStatusShort'.
* All properties 'type_libelle' were renamed into 'type_label'.
* Renamed property of thirdparty "statut_commercial" into "status_prospect_label"
* The jquery plugin/dependency multiselect has been removed. It was not used by Dolibarr core.
@@ -1054,11 +1271,11 @@ FIX: wrong invoice id for fetchObjetctLinked
***** ChangeLog for 10.0.3 compared to 10.0.2 *****
IMPORTANT : This version fixes a serious bug in saving the units of weight, size, surface and volume on product card.
-The unit were not saved correctly in database making calculation on shipments wrong.
+The unit were not saved correctly in database making calculation on shipments wrong.
Update to this version must be done if you use them and have installed version 10.0.0, 10.0.1 or 10.0.2 and set some products after installing or upgrading to one of this version.
Once update is done you must then edit (manually) the product that has bad unit to set the correct unit to have features restored.
-FIX: #11702
+FIX: #11702
FIX: #11861 No consistent code to manage measuring units
FIX: #11942
FIX: #12026
@@ -1120,7 +1337,7 @@ FIX: wrong test
FIX: XSS
FIX: Payment from POS ware not recorded.
FIX: Can validate invoice with amount including tax of zero for the case of having a final invoice with
- VAT that includes a deposit without vat.
+ VAT that includes a deposit without vat.
***** ChangeLog for 10.0.2 compared to 10.0.1 *****
FIX: #10460 compatibility with MariaDB 10.4
@@ -1223,14 +1440,14 @@ FIX: Wrong variable. Must be PROJECT_HIDE_UNSELECTABLES
***** ChangeLog for 10.0.1 compared to 10.0.0 *****
FIX: #10930
-FIX: #10984
+FIX: #10984
FIX: reposition on "Build backup" button
FIX: #11400
FIX: #11412
-FIX: #11460
+FIX: #11460
FIX: #11463
FIX: #11466
-FIX: #11492
+FIX: #11492
FIX: #11498
FIX: #11505
FIX: #11506
@@ -1239,7 +1456,7 @@ FIX: #11509
FIX: #11537
FIX: #11543
FIX: #11553
-FIX: #11576
+FIX: #11576
FIX: #11584
FIX: #11590
FIX: accounting mode must be taken from global conf, because there's no way to choose a mode with interface
@@ -1332,14 +1549,14 @@ FIX: wrong path sociales/index.php doesnt exist anymore
***** ChangeLog for 10.0.1 compared to 10.0.0 *****
FIX: #10930
-FIX: #10984
+FIX: #10984
FIX: reposition on "Build backup" button
FIX: #11400
FIX: #11412
-FIX: #11460
+FIX: #11460
FIX: #11463
FIX: #11466
-FIX: #11492
+FIX: #11492
FIX: #11498
FIX: #11505
FIX: #11506
@@ -1348,7 +1565,7 @@ FIX: #11509
FIX: #11537
FIX: #11543
FIX: #11553
-FIX: #11576
+FIX: #11576
FIX: #11584
FIX: #11590
FIX: accounting mode must be taken from global conf, because there's no way to choose a mode with interface
@@ -1517,7 +1734,7 @@ NEW: Manage account sell_intra & sell_export in page accoutancy admin default pr
NEW: Manage loan schedule.
NEW: Manage status of member types.
NEW: Mass action "create bills" for validated reception
-NEW: Measuring unit are now defined into an editable dictionary. Add product size/unit into product import.
+NEW: Measuring unit are now defined into an editable dictionary. Add product size/unit into product import.
NEW: Template pdf 'canelle_reception' displays linked reception lines.
NEW: Moral/physic status can be defined at member type level
NEW: Pagination into list of time spent.
@@ -1580,7 +1797,7 @@ NEW: Enhance management of webhooks
NEW: Generation of doc by modulebuilder can include README and CHANGELOG
NEW: massfilesarea feature is possible for external modules
NEW: Show list of enabled modules in dol_print_error().
-NEW: Simplification of CSS styles of default themes.
+NEW: Simplification of CSS styles of default themes.
NEW: Clean code of a lot of deprecated code.
NEW: Add hidden option to set a search entry to the top
NEW: add hidden option DISPLAY_DISCOUNTED_SUPPLIER_PRICE
@@ -1600,8 +1817,8 @@ Following changes may create regressions for some external modules, but were nec
* The PHP extension php-intl is not mandatory and must be installed to have new features working correctly.
* Method GetUrlTrackingStatus were renamed into getUrlTrackingStatus for consistency with naming rules.
* API getListOfCivility has been renamed into getListOfCivilities for consistency with naming rules.
-* Deprecated function img_phone as been removed. You can use img_picto(..., 'call|call_out') instead.;
-* Files for variables of themes were renamed from graph-color.php into theme_vars.inc.php to match naming
+* Deprecated function img_phone as been removed. You can use img_picto(..., 'call|call_out') instead.;
+* Files for variables of themes were renamed from graph-color.php into theme_vars.inc.php to match naming
convention of extension .inc.php for files to be included.
* All methods set_draft() were renamed into setDraft().
* Signatures of methods createFromClone() has been standardized. All methods requires the object User as first parameter.
@@ -1613,7 +1830,7 @@ Following changes may create regressions for some external modules, but were nec
* Deprecated property ->fk_departement is now ->state_id everywhere.
* Removed the method 4 of GETPOST (to get $_COOKIE). It was not used and not recommanded to use in Dolibarr.
* Column llx_facture.facnumber change to llx_facture.ref
-* Variable $dolibarr_main_cookie_cryptkey is no more created at install (it was not used by Dolibarr). A new variable
+* Variable $dolibarr_main_cookie_cryptkey is no more created at install (it was not used by Dolibarr). A new variable
called $dolibarr_main_instance_unique_id is now generated at each installation. It will be used by some future features.
@@ -3385,7 +3602,7 @@ Following changes may create regression for some external modules, but were nece
entities and to review completely the rights of the groups and the users.
* Use getEntity('xxx') instead getEntity('xxx', 1) and use getEntity('xxx', 0) instead getEntity('xxx')
* Some other change were done in the way we read permission of a user when module multicompany is enabled. You can
- retreive the old behavior by adding constant MULTICOMPANY_BACKWARD_COMPATIBILITY to 1.
+ retrieve the old behavior by adding constant MULTICOMPANY_BACKWARD_COMPATIBILITY to 1.
* The hook formObjectOptions was not implemented correctly in previous version. Sometimes, you had to return output
content by doing a print into function, sometimes by returning content into "resprint". This has been fixed to follow
hook specifications so you must return output into "resprint".
@@ -6131,7 +6348,7 @@ For users:
- Fix: [Bug #958] LocalTax2 for Spain fails on Suppliers
- Fix: [ bug #972 ] Auto completion contact field do not take account the min caract number before search
- Fix: [ bug #971 ] html.form.class.php select_contact with autocomplete do not exclude id from exclude array
-- Fix: Expedition creation, can retreive product from other expedition
+- Fix: Expedition creation, can retrieve product from other expedition
For translators:
- Update language files.
diff --git a/README-FR.md b/README-FR.md
index bccb7b0143b..77bb5a3e27a 100644
--- a/README-FR.md
+++ b/README-FR.md
@@ -6,7 +6,7 @@
Dolibarr ERP & CRM est un logiciel moderne pour gérer votre activité (société, association, auto-entrepreneurs, artisans).
Il est simple d'utilisation et modulaire, vous permettant de n'activez que les fonctions dont vous avez besoin (contacts, fournisseurs, factures, commandes, stocks, agenda, ...).
-
+
## LICENCE
diff --git a/README.md b/README.md
index 648d5ef003d..ac8f1d06382 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@


+[](https://php.net/)
+[](https://github.com/Dolibarr/dolibarr)
Dolibarr ERP & CRM is a modern software package that helps manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…).
@@ -13,7 +15,7 @@ You can use it as a standalone application or as a web application to access it
Dolibarr has a large community ready to help you, free forums and [oficially preferred partners ready to offer commercial support should you need it](https://partners.dolibarr.org)
-
+
## LICENSE
diff --git a/build/debian/conf.php.install b/build/debian/conf.php.install
index 6741d7ea544..c373664deef 100644
--- a/build/debian/conf.php.install
+++ b/build/debian/conf.php.install
@@ -232,7 +232,7 @@ $dolibarr_main_prod='0';
# Examples:
# $dolibarr_mailing_limit_sendbycli='0';
-# dolibarr_distrib
+# dolibarr_main_distrib
# A key to identify the distribution used for first installation
-$dolibarr_distrib = 'deb';
+$dolibarr_main_distrib = 'debian';
diff --git a/build/debian/install.forced.php.install b/build/debian/install.forced.php.install
index e55ffae138e..0cb02c2342d 100644
--- a/build/debian/install.forced.php.install
+++ b/build/debian/install.forced.php.install
@@ -24,6 +24,7 @@ $force_install_databaserootpass='__SUPERUSERPASSWORD__';
$force_install_dolibarrlogin='admin';
$force_install_nophpinfo='1';
$force_install_lockinstall='444';
+$force_install_distrib='debian';
// Value to overwrite path to use shared libraries/fonts instead of embedded one.
// If during install, we enable/disable declaration to use non embedded libraries, we must also check they are
diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile
index 2be287c2db9..dca74e9e720 100644
--- a/build/docker/Dockerfile
+++ b/build/docker/Dockerfile
@@ -20,6 +20,9 @@ RUN apt-get update -y \
unzip \
curl \
apt-utils \
+ msmtp \
+ msmtp-mta \
+ mailutils \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/* \
&& docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \
@@ -44,7 +47,17 @@ RUN echo 'xdebug.remote_port=9000' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.remote_connect_back=1' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.profiler_enable=0' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.remote_log="/tmp/xdebug.log"' >> ${PHP_INI_DIR}/php.ini
-#RUN echo '172.17.0.1 docker.host' >> /etc/hosts
+#RUN echo 'localhost docker.host' >> /etc/hosts
+
+# set up sendmail config, to use maildev
+RUN echo "account default" > /etc/msmtprc
+RUN echo "auth off" >> /etc/msmtprc
+RUN echo "port 25" >> /etc/msmtprc
+RUN echo "host mail" >> /etc/msmtprc
+RUN echo "from local@localdomain.com" >> /etc/msmtprc
+RUN echo "domain localhost.localdomain" >> /etc/msmtprc
+RUN echo "sendmail_path=/usr/bin/msmtp -t" >> /usr/local/etc/php/conf.d/php-sendmail.ini
+RUN echo "localhost localhost.localdomain" >> /etc/hosts
EXPOSE 80
diff --git a/build/docker/README.md b/build/docker/README.md
index 2fd278a531f..d469c7c7aae 100644
--- a/build/docker/README.md
+++ b/build/docker/README.md
@@ -16,7 +16,7 @@ And then, you can run :
docker-compose up
-This will run 3 container Docker : Dolibarr, MariaDB and PhpMyAdmin.
+This will run 4 containers Docker : Dolibarr, MariaDB, PhpMyAdmin and MailDev.
The URL to go to the Dolibarr is :
@@ -25,7 +25,10 @@ The URL to go to the Dolibarr is :
The URL to go to PhpMyAdmin is (login/password is root/root) :
http://0.0.0.0:8080
+
+In Dolibarr configuration Email let PHP mail function, To see all mail send by Dolibarr go to maildev
-Setup the database connection during the installation process, please use mariad
-b (name of the database container) as database host.
+ http://0.0.0.0:8081
+
+Setup the database connection during the installation process, please use mariadb (name of the database container) as database host.
Setup documents folder, during the installation process, to /var/documents
diff --git a/build/docker/docker-compose.yml b/build/docker/docker-compose.yml
index 7e4ceda902e..2167f069f25 100644
--- a/build/docker/docker-compose.yml
+++ b/build/docker/docker-compose.yml
@@ -52,3 +52,6 @@ services:
ports:
- "8081:80"
- "25:25"
+ networks:
+ - internal-pod
+ - external-pod
diff --git a/build/exe/doliwamp/install.forced.php.install b/build/exe/doliwamp/install.forced.php.install
index c59b373a7a0..8947154a57b 100644
--- a/build/exe/doliwamp/install.forced.php.install
+++ b/build/exe/doliwamp/install.forced.php.install
@@ -22,6 +22,7 @@ $force_install_databaserootpass='WAMPMYSQLNEWPASSWORD';
$force_install_dolibarrlogin='admin';
$force_install_nophpinfo='1';
$force_install_lockinstall='644';
+$force_install_distrib='doliwamp';
$force_install_module='';
?>
\ No newline at end of file
diff --git a/build/rpm/dolibarr_fedora.spec b/build/rpm/dolibarr_fedora.spec
index 039dafd198f..628ef917c05 100755
--- a/build/rpm/dolibarr_fedora.spec
+++ b/build/rpm/dolibarr_fedora.spec
@@ -181,6 +181,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/datapolicy
%_datadir/dolibarr/htdocs/dav
%_datadir/dolibarr/htdocs/debugbar
+%_datadir/dolibarr/htdocs/delivery
%_datadir/dolibarr/htdocs/don
%_datadir/dolibarr/htdocs/ecm
%_datadir/dolibarr/htdocs/emailcollector
@@ -198,7 +199,6 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/install
%_datadir/dolibarr/htdocs/intracommreport
%_datadir/dolibarr/htdocs/langs/HOWTO-Translation.txt
-%_datadir/dolibarr/htdocs/livraison
%_datadir/dolibarr/htdocs/loan
%_datadir/dolibarr/htdocs/mailmanspip
%_datadir/dolibarr/htdocs/margin
diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec
index 098a041680a..aefc375d961 100755
--- a/build/rpm/dolibarr_generic.spec
+++ b/build/rpm/dolibarr_generic.spec
@@ -261,6 +261,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/datapolicy
%_datadir/dolibarr/htdocs/dav
%_datadir/dolibarr/htdocs/debugbar
+%_datadir/dolibarr/htdocs/delivery
%_datadir/dolibarr/htdocs/don
%_datadir/dolibarr/htdocs/ecm
%_datadir/dolibarr/htdocs/emailcollector
@@ -278,7 +279,6 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/install
%_datadir/dolibarr/htdocs/intracommreport
%_datadir/dolibarr/htdocs/langs/HOWTO-Translation.txt
-%_datadir/dolibarr/htdocs/livraison
%_datadir/dolibarr/htdocs/loan
%_datadir/dolibarr/htdocs/mailmanspip
%_datadir/dolibarr/htdocs/margin
diff --git a/build/rpm/dolibarr_mandriva.spec b/build/rpm/dolibarr_mandriva.spec
index a3f2d1d8d96..bcccb7c02a4 100755
--- a/build/rpm/dolibarr_mandriva.spec
+++ b/build/rpm/dolibarr_mandriva.spec
@@ -177,6 +177,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/custom
%_datadir/dolibarr/htdocs/datapolicy
%_datadir/dolibarr/htdocs/dav
+%_datadir/dolibarr/htdocs/delivery
%_datadir/dolibarr/htdocs/debugbar
%_datadir/dolibarr/htdocs/don
%_datadir/dolibarr/htdocs/ecm
@@ -195,7 +196,6 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/install
%_datadir/dolibarr/htdocs/intracommreport
%_datadir/dolibarr/htdocs/langs/HOWTO-Translation.txt
-%_datadir/dolibarr/htdocs/livraison
%_datadir/dolibarr/htdocs/loan
%_datadir/dolibarr/htdocs/mailmanspip
%_datadir/dolibarr/htdocs/margin
diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec
index 5b1b86b28f4..8a55dd84faa 100755
--- a/build/rpm/dolibarr_opensuse.spec
+++ b/build/rpm/dolibarr_opensuse.spec
@@ -189,6 +189,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/datapolicy
%_datadir/dolibarr/htdocs/dav
%_datadir/dolibarr/htdocs/debugbar
+%_datadir/dolibarr/htdocs/delivery
%_datadir/dolibarr/htdocs/don
%_datadir/dolibarr/htdocs/ecm
%_datadir/dolibarr/htdocs/emailcollector
@@ -206,7 +207,6 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/install
%_datadir/dolibarr/htdocs/intracommreport
%_datadir/dolibarr/htdocs/langs/HOWTO-Translation.txt
-%_datadir/dolibarr/htdocs/livraison
%_datadir/dolibarr/htdocs/loan
%_datadir/dolibarr/htdocs/mailmanspip
%_datadir/dolibarr/htdocs/margin
diff --git a/build/rpm/install.forced.php.fedora b/build/rpm/install.forced.php.fedora
index a8db3e25c9e..4d25010a533 100644
--- a/build/rpm/install.forced.php.fedora
+++ b/build/rpm/install.forced.php.fedora
@@ -17,6 +17,7 @@ $force_install_databaserootpass='__SUPERUSERPASSWORD__';
$force_install_dolibarrlogin='admin';
$force_install_nophpinfo='1';
$force_install_lockinstall='444';
+$force_install_distrib='rpmfedora';
// Value to overwrite path to use shared libraries/fonts instead of embedded one
$force_dolibarr_lib_ADODB_PATH='/usr/share/php/adodb';
diff --git a/build/rpm/install.forced.php.generic b/build/rpm/install.forced.php.generic
index 107ef533310..20ec33a1af0 100644
--- a/build/rpm/install.forced.php.generic
+++ b/build/rpm/install.forced.php.generic
@@ -17,6 +17,7 @@ $force_install_databaserootpass='__SUPERUSERPASSWORD__';
$force_install_dolibarrlogin='admin';
$force_install_nophpinfo='1';
$force_install_lockinstall='444';
+$force_install_distrib='rpmgeneric';
// Value to overwrite path to use shared libraries/fonts instead of embedded one
// We don't force any external lib with generic package
diff --git a/build/rpm/install.forced.php.mandriva b/build/rpm/install.forced.php.mandriva
index 927877b59d0..835f5f45570 100644
--- a/build/rpm/install.forced.php.mandriva
+++ b/build/rpm/install.forced.php.mandriva
@@ -17,6 +17,7 @@ $force_install_databaserootpass='__SUPERUSERPASSWORD__';
$force_install_dolibarrlogin='admin';
$force_install_nophpinfo='1';
$force_install_lockinstall='444';
+$force_install_distrib='rpmmandriva';
// Value to overwrite path to use shared libraries/fonts instead of embedded one
$force_dolibarr_lib_ADODB_PATH='/usr/share/php/adodb';
diff --git a/build/rpm/install.forced.php.opensuse b/build/rpm/install.forced.php.opensuse
index c91836918f4..b3cab5a0e4d 100644
--- a/build/rpm/install.forced.php.opensuse
+++ b/build/rpm/install.forced.php.opensuse
@@ -17,6 +17,7 @@ $force_install_databaserootpass='__SUPERUSERPASSWORD__';
$force_install_dolibarrlogin='admin';
$force_install_nophpinfo='1';
$force_install_lockinstall='444';
+$force_install_distrib='rpmopensuse';
// Value to overwrite path to use shared libraries/fonts instead of embedded one
//$force_dolibarr_lib_ADODB_PATH='/usr/share/php/adodb';
diff --git a/dev/examples/zapier/.editorconfig b/dev/examples/zapier/.editorconfig
new file mode 100644
index 00000000000..9228bbb156b
--- /dev/null
+++ b/dev/examples/zapier/.editorconfig
@@ -0,0 +1,21 @@
+# EditorConfig is awesome: https://editorconfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+charset = utf-8
+end_of_line = lf
+
+[*.js]
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = false
diff --git a/dev/examples/zapier/.gitignore b/dev/examples/zapier/.gitignore
index d81e057e6d3..3e9263e351f 100644
--- a/dev/examples/zapier/.gitignore
+++ b/dev/examples/zapier/.gitignore
@@ -5,3 +5,4 @@ node_modules
.environment
.env
.zapierapprc
+package-lock.json
diff --git a/dev/examples/zapier/README.md b/dev/examples/zapier/README.md
new file mode 100644
index 00000000000..453a5224993
--- /dev/null
+++ b/dev/examples/zapier/README.md
@@ -0,0 +1,68 @@
+# HOW TO BUILD
+
+
+## ENABLE MODULE ZAPIER ON DOLIBARR
+
+This should also enable the module API (required for authentication by Zapier service and to execute action in Dolibarr by Zapier).
+
+Create the Dolibarr login that will be used by Zapier to call APIs. Give the login the permissions on the action you plan to automate.
+
+
+## CREATE A ZAPIER DEVELOPPER ACCOUNT
+
+At first, you need to have a Zapier developper acoount, create it here [Zapier Platform](https://developer.zapier.com/)
+
+
+## INSTALL ZAPIER COMMAND LINE TOOLS WITH LINK TO ZAPIER ONLINE ACCOUNT
+
+### Install Node.js
+
+An easy option to get set up with Node.js is to visit [https://nodejs.org/en/download/](https://nodejs.org/en/download/) and download the official installer for your OS. If you're installing with a package manager it's even easier.
+
+After installation, confirm that Node.js is ready to use:
+ `node --version`
+
+### Install the Zapier CLI
+
+Next let's install the Zapier CLI tools. The CLI will allow you to build your app, deploy it to the Zapier platform, do local testing, manage users and testers, view remote logs, collaborate with your team, and more:
+
+ `cd dev/examples/zapier`
+
+ `npm install -g zapier-platform-cli` to install the CLI globally
+
+ `zapier --version` to return version of the CLI
+
+### Run Zapier Login
+
+Let's configure authentication between your dev environment and the Zapier platform. You'll use the email address and password you use to log in to the Zapier application.
+
+ `zapier login`
+
+This command will set up a .zapierrc file in your home directory.
+
+### Install the Project
+
+In zapier example directory, run:
+
+ `cd dev/examples/zapier`
+
+ `npm install`
+
+### Deploying your App
+
+Let's deploy it! When you're ready to try your code out on the Zapier platform use the push command. Only you will be able to see the app until you invite testers.
+
+ `zapier register` (the first time, choose name for example "Dolibarr")
+
+ `zapier push`
+
+After a push, the Application, with the name you defined during the register step, is available when creating a Zap.
+
+You will find original tutorial here : [https://zapier.com/developer/start/introduction](https://zapier.com/developer/start/introduction)
+
+
+### Create a Zap
+
+Create a ZAP that use the application you registered.
+For authentication, you must enter the login / pass of account used by Zapier to call APIs.
+
diff --git a/dev/examples/zapier/authentication.js b/dev/examples/zapier/authentication.js
index 1c95c76f9c2..fceedd4ab5f 100644
--- a/dev/examples/zapier/authentication.js
+++ b/dev/examples/zapier/authentication.js
@@ -1,6 +1,6 @@
/*jshint esversion: 6 */
-const testAuth = (z , bundle) => {
- const url = bundle.authData.url+'/api/index.php/login';
+const test = (z , bundle) => {
+ const url = bundle.authData.url+'/api/index.php/status';
// Normally you want to make a request to an endpoint that is either specifically designed to test auth, or one that
// every user will have access to, such as an account or profile endpoint like /me.
// In this example, we'll hit httpbin, which validates the Authorization Header against the arguments passed in the URL path
@@ -11,67 +11,92 @@ const testAuth = (z , bundle) => {
// This method can return any truthy value to indicate the credentials are valid.
// Raise an error to show
return promise.then((response) => {
- if (response.status === 401) {
- throw new Error('The Session Key you supplied is invalid');
+ if (response.status === 400) {
+ throw new Error('400 -The Session Key you supplied is invalid');
+ }
+ if (response.status === 403) {
+ throw new Error('403 -The Session Key you supplied is invalid');
}
return response;
});
};
-const getSessionKey = (z, bundle) => {
+// To include the session key header on all outbound requests, simply define a function here.
+// It runs runs before each request is sent out, allowing you to make tweaks to the request in a centralized spot
+const includeSessionKeyHeader = (request, z, bundle) => {
+ if (bundle.authData.sessionKey) {
+ request.headers = request.headers || {};
+ request.headers['DOLAPIKEY'] = bundle.authData.sessionKey;
+ }
+ return request;
+};
+
+// If we get a response and it is a 401, we can raise a special error telling Zapier to retry this after another exchange.
+const sessionRefreshIf401 = (response, z, bundle) => {
+ if (bundle.authData.sessionKey) {
+ if (response.status === 401) {
+ throw new z.errors.RefreshAuthError('Session apikey needs refreshing.');
+ }
+ }
+ return response;
+};
+
+const getSessionKey = async (z, bundle) => {
const url = bundle.authData.url + '/api/index.php/login';
- const promise = z.request({
- method: 'POST',
+ const response = await z.request({
url: url,
+ method: 'POST',
body: {
login: bundle.authData.login,
password: bundle.authData.password,
- }
+ },
});
- return promise.then((response) => {
- if (response.status === 401) {
- throw new Error('The login/password you supplied is invalid');
- }
- const json = JSON.parse(response.content);
- return {
- sessionKey: json.success.token || 'secret'
- };
- });
+ // if (response.status === 401) {
+ // throw new Error('The login/password you supplied is invalid');
+ // }
+ const json = JSON.parse(response.content);
+ return {
+ sessionKey: json.success.token || '',
+ };
};
module.exports = {
- type: 'session',
- // Define any auth fields your app requires here. The user will be prompted to enter this info when
- // they connect their account.
- fields: [
- {
- key: 'url',
- label: 'Url of service',
- required: true,
- type: 'string'
+ config: {
+ type: 'session',
+ sessionConfig: {
+ perform: getSessionKey
},
- {
- key: 'login',
- label: 'Login',
- required: true,
- type: 'string'
- },
- {
- key: 'password',
- label: 'Password',
- required: true,
- type: 'password'
- }
- ],
- // The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this
- // method whenever a user connects their account for the first time.
- test: testAuth,
- // The method that will exchange the fields provided by the user for session credentials.
- sessionConfig: {
- perform: getSessionKey
+ // Define any auth fields your app requires here. The user will be prompted to enter this info when
+ // they connect their account.
+ fields: [
+ {
+ key: 'url',
+ label: 'Url of service without trailing-slash',
+ required: true,
+ type: 'string'
+ },
+ {
+ key: 'login',
+ label: 'Login',
+ required: true,
+ type: 'string'
+ },
+ {
+ key: 'password',
+ label: 'Password',
+ required: true,
+ type: 'password'
+ }
+ ],
+ // The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this
+ // method whenever a user connects their account for the first time.
+ test,
+ // The method that will exchange the fields provided by the user for session credentials.
+ // assuming "login" is a key returned from the test
+ connectionLabel: '{{login}}'
},
- // assuming "login" is a key returned from the test
- connectionLabel: '{{login}}'
+ befores: [includeSessionKeyHeader],
+ afters: [sessionRefreshIf401],
};
diff --git a/dev/examples/zapier/creates/thirdparty.js b/dev/examples/zapier/creates/thirdparty.js
index 82cc39f8fab..3e20fd10e41 100644
--- a/dev/examples/zapier/creates/thirdparty.js
+++ b/dev/examples/zapier/creates/thirdparty.js
@@ -72,7 +72,7 @@ module.exports = {
},
outputFields: [
- {key: 'id', label: 'ID'},
+ {key: 'id', type: "integer", label: 'ID'},
{key: 'name', label: 'Name'},
{key: 'name_alias', label: 'Name alias'},
{key: 'address', label: 'Address'},
@@ -81,8 +81,8 @@ module.exports = {
{key: 'phone', label: 'Phone'},
{key: 'fax', label: 'Fax'},
{key: 'email', label: 'Email'},
- {key: 'client', label: 'Customer/Prospect 0/1/2/3'},
- {key: 'fournisseur', label: 'Supplier 0/1'},
+ {key: 'client', type: "integer", label: 'Customer/Prospect 0/1/2/3'},
+ {key: 'fournisseur', type: "integer", label: 'Supplier 0/1'},
{key: 'code_client', label: 'Customer code'},
{key: 'code_fournisseur', label: 'Supplier code'}
]
diff --git a/dev/examples/zapier/index.js b/dev/examples/zapier/index.js
index fc452a196e6..d1897673b39 100644
--- a/dev/examples/zapier/index.js
+++ b/dev/examples/zapier/index.js
@@ -1,33 +1,39 @@
/*jshint esversion: 6 */
-const triggerThirdparty = require('./triggers/thirdparty');
-const triggerOrder = require('./triggers/order');
const triggerAction = require('./triggers/action');
+const triggerOrder = require('./triggers/order');
+const triggerThirdparty = require('./triggers/thirdparty');
+const triggerTicket = require('./triggers/ticket');
+const triggerUser = require('./triggers/user');
const searchThirdparty = require('./searches/thirdparty');
const createThirdparty = require('./creates/thirdparty');
-const authentication = require('./authentication');
+const {
+ config: authentication,
+ befores = [],
+ afters = [],
+} = require('./authentication');
// To include the session key header on all outbound requests, simply define a function here.
// It runs runs before each request is sent out, allowing you to make tweaks to the request in a centralized spot
-const includeSessionKeyHeader = (request, z, bundle) => {
- if (bundle.authData.sessionKey) {
- request.headers = request.headers || {};
- request.headers['DOLAPIKEY'] = bundle.authData.sessionKey;
- }
- return request;
-};
+// const includeSessionKeyHeader = (request, z, bundle) => {
+// if (bundle.authData.sessionKey) {
+// request.headers = request.headers || {};
+// request.headers['DOLAPIKEY'] = bundle.authData.sessionKey;
+// }
+// return request;
+// };
// If we get a response and it is a 401, we can raise a special error telling Zapier to retry this after another exchange.
-const sessionRefreshIf401 = (response, z, bundle) => {
- if (bundle.authData.sessionKey) {
- if (response.status === 401) {
- throw new z.errors.RefreshAuthError('Session apikey needs refreshing.');
- }
- }
- return response;
-};
+// const sessionRefreshIf401 = (response, z, bundle) => {
+// if (bundle.authData.sessionKey) {
+// if (response.status === 401) {
+// throw new z.errors.RefreshAuthError('Session apikey needs refreshing.');
+// }
+// }
+// return response;
+// };
// We can roll up all our behaviors in an App.
const App = {
@@ -40,11 +46,11 @@ const App = {
// beforeRequest & afterResponse are optional hooks into the provided HTTP client
beforeRequest: [
- includeSessionKeyHeader
+ ...befores
],
afterResponse: [
- sessionRefreshIf401
+ ...afters
],
// If you want to define optional resources to simplify creation of triggers, searches, creates - do that here!
@@ -53,9 +59,11 @@ const App = {
// If you want your trigger to show up, you better include it here!
triggers: {
- [triggerThirdparty.key]: triggerThirdparty,
+ [triggerAction.key]: triggerAction,
[triggerOrder.key]: triggerOrder,
- [triggerAction.key]: triggerAction
+ [triggerThirdparty.key]: triggerThirdparty,
+ [triggerTicket.key]: triggerTicket,
+ [triggerUser.key]: triggerUser,
},
// If you want your searches to show up, you better include it here!
diff --git a/dev/examples/zapier/package-lock.json b/dev/examples/zapier/package-lock.json
deleted file mode 100644
index 7483948d5b8..00000000000
--- a/dev/examples/zapier/package-lock.json
+++ /dev/null
@@ -1,405 +0,0 @@
-{
- "name": "Dolibarr",
- "version": "1.0.2",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "@types/node": {
- "version": "8.10.20",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.20.tgz",
- "integrity": "sha512-M7x8+5D1k/CuA6jhiwuSCmE8sbUWJF0wYsjcig9WrXvwUI5ArEoUBdOXpV4JcEMrLp02/QbDjw+kI+vQeKyQgg==",
- "optional": true
- },
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
- "dev": true
- },
- "bluebird": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
- "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw="
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "browser-stdout": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
- "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
- "dev": true
- },
- "combined-stream": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
- "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
- "requires": {
- "delayed-stream": "~1.0.0"
- }
- },
- "commander": {
- "version": "2.15.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
- "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
- "dev": true
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "dev": true
- },
- "content-disposition": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
- "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
- },
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
- },
- "diff": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
- "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
- "dev": true
- },
- "dotenv": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz",
- "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow=="
- },
- "encoding": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
- "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
- "requires": {
- "iconv-lite": "~0.4.13"
- }
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
- },
- "form-data": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
- "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "1.0.6",
- "mime-types": "^2.1.12"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
- "dev": true
- },
- "glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
- "dev": true,
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "growl": {
- "version": "1.10.5",
- "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
- "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
- "dev": true
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
- },
- "he": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
- "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
- "dev": true
- },
- "iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "dev": true,
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
- "dev": true
- },
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
- },
- "json-tryparse": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/json-tryparse/-/json-tryparse-1.0.5.tgz",
- "integrity": "sha1-Khy6CLTjEjNo+p+2o01GQwBFeyc="
- },
- "jsonschema": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.1.1.tgz",
- "integrity": "sha1-PO3o4+QR03eHLu+8n98mODy8Ptk="
- },
- "lodash": {
- "version": "4.17.11",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
- "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
- },
- "mime-db": {
- "version": "1.38.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
- "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg=="
- },
- "mime-types": {
- "version": "2.1.22",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
- "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
- "requires": {
- "mime-db": "~1.38.0"
- }
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "dev": true,
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
- "dev": true
- },
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "dev": true,
- "requires": {
- "minimist": "0.0.8"
- }
- },
- "mocha": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
- "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
- "dev": true,
- "requires": {
- "browser-stdout": "1.3.1",
- "commander": "2.15.1",
- "debug": "3.1.0",
- "diff": "3.5.0",
- "escape-string-regexp": "1.0.5",
- "glob": "7.1.2",
- "growl": "1.10.5",
- "he": "1.1.1",
- "minimatch": "3.0.4",
- "mkdirp": "0.5.1",
- "supports-color": "5.4.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
- },
- "node-fetch": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.1.tgz",
- "integrity": "sha512-j8XsFGCLw79vWXkZtMSmmLaOk9z5SQ9bV/tkbZVCqvgwzrjAGq66igobLofHtF63NvMTp2WjytpsNTGKa+XRIQ==",
- "requires": {
- "encoding": "^0.1.11",
- "is-stream": "^1.0.1"
- }
- },
- "oauth-sign": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "dev": true,
- "requires": {
- "wrappy": "1"
- }
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
- "dev": true
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "semver": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
- "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
- },
- "should": {
- "version": "13.2.3",
- "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz",
- "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==",
- "dev": true,
- "requires": {
- "should-equal": "^2.0.0",
- "should-format": "^3.0.3",
- "should-type": "^1.4.0",
- "should-type-adaptors": "^1.0.1",
- "should-util": "^1.0.0"
- }
- },
- "should-equal": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz",
- "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==",
- "dev": true,
- "requires": {
- "should-type": "^1.4.0"
- }
- },
- "should-format": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz",
- "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=",
- "dev": true,
- "requires": {
- "should-type": "^1.3.0",
- "should-type-adaptors": "^1.0.1"
- }
- },
- "should-type": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz",
- "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=",
- "dev": true
- },
- "should-type-adaptors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz",
- "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==",
- "dev": true,
- "requires": {
- "should-type": "^1.3.0",
- "should-util": "^1.0.0"
- }
- },
- "should-util": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz",
- "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=",
- "dev": true
- },
- "supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
- "dev": true
- },
- "zapier-platform-core": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/zapier-platform-core/-/zapier-platform-core-8.0.1.tgz",
- "integrity": "sha512-vuAe7JkFQ88AeQ//NwwNEh8ZjiZr30GRWtwYo7Wo/nx1cqZwq+CRc9zJU2WRrhJfJOtOOTUF6w+pArBTtMOC5A==",
- "requires": {
- "@types/node": "8.10.20",
- "bluebird": "3.5.0",
- "content-disposition": "0.5.2",
- "dotenv": "5.0.1",
- "form-data": "2.3.2",
- "lodash": "4.17.11",
- "node-fetch": "1.7.1",
- "oauth-sign": "0.9.0",
- "semver": "5.6.0",
- "zapier-platform-schema": "8.0.1"
- }
- },
- "zapier-platform-schema": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/zapier-platform-schema/-/zapier-platform-schema-8.0.1.tgz",
- "integrity": "sha512-97KJ0xVLtpU4BiXVaMTPQpiA0T6CQIEzWfzAWwJAWbu5336+6DMFUzDWN4bANBeD3CIsRHHPcZkP8n/17U05ag==",
- "requires": {
- "jsonschema": "1.1.1",
- "lodash": "4.17.10"
- },
- "dependencies": {
- "lodash": {
- "version": "4.17.10",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
- "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
- }
- }
- }
- }
-}
diff --git a/dev/examples/zapier/package.json b/dev/examples/zapier/package.json
index 8fbd203f962..5b5827b22b2 100644
--- a/dev/examples/zapier/package.json
+++ b/dev/examples/zapier/package.json
@@ -1,9 +1,9 @@
{
- "name": "Dolibarr",
- "version": "1.0.0",
+ "name": "dolibarr",
+ "version": "1.13.0",
"description": "An app for connecting Dolibarr to the Zapier platform.",
"repository": "Dolibarr/dolibarr",
- "homepage": "https://www.dolibarr.fr/",
+ "homepage": "https://www.dolibarr.org/",
"author": "Frédéric France ",
"license": "BSD-3-Clause",
"main": "index.js",
@@ -15,7 +15,7 @@
"npm": ">=5.6.0"
},
"dependencies": {
- "zapier-platform-core": "8.0.1"
+ "zapier-platform-core": "10.1.1"
},
"devDependencies": {
"mocha": "^5.2.0",
diff --git a/dev/examples/zapier/searches/thirdparty.js b/dev/examples/zapier/searches/thirdparty.js
index c71c2965789..8f72b9270e5 100644
--- a/dev/examples/zapier/searches/thirdparty.js
+++ b/dev/examples/zapier/searches/thirdparty.js
@@ -54,13 +54,20 @@ module.exports = {
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
- {key: 'id', label: 'ID'},
- {key: 'createdAt', label: 'Created At'},
+ {
+ key: 'id',
+ type: "integer",
+ label: 'ID'
+ },
+ {key: 'createdAt', type: "integer", label: 'Created At'},
{key: 'name', label: 'Name'},
{key: 'firstname', label: 'Firstname'},
{key: 'directions', label: 'Directions'},
- {key: 'authorId', label: 'Author ID'},
- {key: 'style', label: 'Style'}
+ {key: 'authorId', type: "integer", label: 'Author ID'},
+ {
+ key: 'style',
+ label: 'Style'
+ }
]
}
};
diff --git a/dev/examples/zapier/triggers/action.js b/dev/examples/zapier/triggers/action.js
index d387d88ec1f..0e152473869 100644
--- a/dev/examples/zapier/triggers/action.js
+++ b/dev/examples/zapier/triggers/action.js
@@ -10,14 +10,14 @@ const subscribeHook = (z, bundle) => {
action: bundle.inputData.action
};
- const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
+ const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: url,
method: 'POST',
- body: JSON.stringify(data)
+ body: data,
};
// You may return a promise or a normal data structure from any perform method.
@@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => {
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
- url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
+ url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
@@ -74,7 +74,7 @@ const getFallbackRealAction = (z, bundle) => {
// For the test poll, you should get some real data, to aid the setup process.
const module = bundle.inputData.module;
const options = {
- url: bundle.authData.url + '/api/index.php/agendaevents/0',
+ url: bundle.authData.url + '/api/index.php/agendaevents/0',
};
return z.request(options).then((response) => [JSON.parse(response.content)]);
@@ -100,7 +100,7 @@ module.exports = {
noun: 'Action',
display: {
label: 'New Agenda',
- description: 'Trigger when a new agenda with action is done in Dolibarr.'
+ description: 'Triggers when a new agenda with action is done in Dolibarr.'
},
// `operation` is where the business logic goes.
@@ -111,6 +111,7 @@ module.exports = {
inputFields: [
{
key: 'action',
+ required: true,
type: 'string',
helpText: 'Which action of agenda this should trigger on.',
choices: {
@@ -145,12 +146,33 @@ module.exports = {
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
- {key: 'id', label: 'ID'},
- {key: 'createdAt', label: 'Created At'},
- {key: 'name', label: 'Name'},
- {key: 'usertodo__name', label: 'UserToDo Name'},
- {key: 'authorId', label: 'Author ID'},
- {key: 'action', label: 'Action'}
+ {
+ key: 'id',
+ type: "integer",
+ label: 'ID'
+ },
+ {
+ key: 'createdAt',
+ type: "integer",
+ label: 'Created At'
+ },
+ {
+ key: 'name',
+ label: 'Name'
+ },
+ {
+ key: 'usertodo__name',
+ label: 'UserToDo Name'
+ },
+ {
+ key: 'authorId',
+ type: "integer",
+ label: 'Author ID'
+ },
+ {
+ key: 'action',
+ label: 'Action'
+ }
]
}
};
diff --git a/dev/examples/zapier/triggers/order.js b/dev/examples/zapier/triggers/order.js
index 6262d734edc..061ce218d10 100644
--- a/dev/examples/zapier/triggers/order.js
+++ b/dev/examples/zapier/triggers/order.js
@@ -17,7 +17,7 @@ const subscribeHook = (z, bundle) => {
const options = {
url: url,
method: 'POST',
- body: JSON.stringify(data)
+ body: data,
};
// You may return a promise or a normal data structure from any perform method.
@@ -90,7 +90,7 @@ module.exports = {
noun: 'Order',
display: {
label: 'New Order',
- description: 'Trigger when a new order with action is done in Dolibarr.'
+ description: 'Triggers when a new order with action is done in Dolibarr.'
},
// `operation` is where the business logic goes.
@@ -101,6 +101,7 @@ module.exports = {
inputFields: [
{
key: 'action',
+ required: true,
type: 'string',
helpText: 'Which action of order this should trigger on.',
choices: {
@@ -136,11 +137,11 @@ module.exports = {
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
- {key: 'id', label: 'ID'},
- {key: 'createdAt', label: 'Created At'},
+ {key: 'id', type: "integer", label: 'ID'},
+ {key: 'createdAt', type: "integer", label: 'Created At'},
{key: 'name', label: 'Name'},
{key: 'directions', label: 'Directions'},
- {key: 'authorId', label: 'Author ID'},
+ {key: 'authorId', type: "integer", label: 'Author ID'},
{key: 'module', label: 'Module'},
{key: 'action', label: 'Action'}
]
diff --git a/dev/examples/zapier/triggers/thirdparty.js b/dev/examples/zapier/triggers/thirdparty.js
index 4b13e23ff1c..4656f836e74 100644
--- a/dev/examples/zapier/triggers/thirdparty.js
+++ b/dev/examples/zapier/triggers/thirdparty.js
@@ -17,7 +17,7 @@ const subscribeHook = (z, bundle) => {
const options = {
url: url,
method: 'POST',
- body: JSON.stringify(data)
+ body: data,
};
// You may return a promise or a normal data structure from any perform method.
@@ -112,7 +112,7 @@ module.exports = {
noun: 'Thirdparty',
display: {
label: 'New Thirdparty',
- description: 'Trigger when a new thirdpaty action is done in Dolibarr.'
+ description: 'Triggers when a new thirdpaty action is done in Dolibarr.'
},
// `operation` is where the business logic goes.
@@ -123,6 +123,7 @@ module.exports = {
inputFields: [
{
key: 'action',
+ required: true,
type: 'string',
helpText: 'Which action of thirdparty this should trigger on.',
choices: {
@@ -159,12 +160,12 @@ module.exports = {
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
- {key: 'id', label: 'ID'},
+ {key: 'id', type: "integer", label: 'ID'},
{key: 'createdAt', label: 'Created At'},
{key: 'name', label: 'Name'},
{key: 'name_alias', label: 'Name alias'},
- {key: 'firstname', label: 'Firstame'},
- {key: 'authorId', label: 'Author ID'},
+ {key: 'firstname', label: 'Firstname'},
+ {key: 'authorId', type: "integer", label: 'Author ID'},
{key: 'action', label: 'Action'},
{key: 'client', label: 'Customer/Prospect 0/1/2/3'},
{key: 'fournisseur', label: 'Supplier 0/1'},
diff --git a/dev/examples/zapier/triggers/ticket.js b/dev/examples/zapier/triggers/ticket.js
new file mode 100644
index 00000000000..c642099bd55
--- /dev/null
+++ b/dev/examples/zapier/triggers/ticket.js
@@ -0,0 +1,237 @@
+const subscribeHook = (z, bundle) => {
+ // `z.console.log()` is similar to `console.log()`.
+ z.console.log('suscribing hook!');
+
+ // bundle.targetUrl has the Hook URL this app should call when an action is created.
+ const data = {
+ url: bundle.targetUrl,
+ event: bundle.event,
+ module: 'ticket',
+ action: bundle.inputData.action
+ };
+
+ const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
+
+ // You can build requests and our client will helpfully inject all the variables
+ // you need to complete. You can also register middleware to control this.
+ const options = {
+ url: url,
+ method: 'POST',
+ body: data,
+ };
+
+ // You may return a promise or a normal data structure from any perform method.
+ return z.request(options).then((response) => JSON.parse(response.content));
+};
+
+const unsubscribeHook = (z, bundle) => {
+ // bundle.subscribeData contains the parsed response JSON from the subscribe
+ // request made initially.
+ z.console.log('unsuscribing hook!');
+
+ // You can build requests and our client will helpfully inject all the variables
+ // you need to complete. You can also register middleware to control this.
+ const options = {
+ url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
+ method: 'DELETE',
+ };
+
+ // You may return a promise or a normal data structure from any perform method.
+ return z.request(options).then((response) => JSON.parse(response.content));
+};
+
+const getTicket = (z, bundle) => {
+ // bundle.cleanedRequest will include the parsed JSON object (if it's not a
+ // test poll) and also a .querystring property with the URL's query string.
+ const ticket = {
+ id: bundle.cleanedRequest.id,
+ track_id: bundle.cleanedRequest.track_id,
+ subject: bundle.cleanedRequest.subject,
+ message: bundle.cleanedRequest.message,
+ lastname: bundle.cleanedRequest.lastname,
+ firstname: bundle.cleanedRequest.firstname,
+ address: bundle.cleanedRequest.address,
+ zip: bundle.cleanedRequest.zip,
+ town: bundle.cleanedRequest.town,
+ email_from: bundle.cleanedRequest.email_from,
+ login: bundle.cleanedRequest.login,
+ authorId: bundle.cleanedRequest.authorId,
+ createdAt: bundle.cleanedRequest.createdAt,
+ action: bundle.cleanedRequest.action
+ };
+
+ return [ticket];
+};
+
+const getFallbackRealTicket = (z, bundle) => {
+ // For the test poll, you should get some real data, to aid the setup process.
+ const module = bundle.inputData.module;
+ const options = {
+ url: bundle.authData.url + '/api/index.php/tickets/0',
+ };
+
+ return z.request(options).then((response) => [JSON.parse(response.content)]);
+};
+
+// const getModulesChoices = (z/*, bundle*/) => {
+// // For the test poll, you should get some real data, to aid the setup process.
+// const options = {
+// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
+// };
+
+// return z.request(options).then((response) => JSON.parse(response.content));
+// };
+// const getModulesChoices = () => {
+
+// return {
+// orders: "Order",
+// invoices: "Invoice",
+// thirdparties: "Thirdparty",
+// users: "User",
+// tickets: "Ticket",
+// contacts: "Contacts"
+// };
+// };
+
+// const getActionsChoices = (z, bundle) => {
+// // For the test poll, you should get some real data, to aid the setup process.
+// const module = bundle.inputData.module;
+// const options = {
+// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
+// };
+
+// return z.request(options).then((response) => JSON.parse(response.content));
+// };
+
+// We recommend writing your triggers separate like this and rolling them
+// into the App definition at the end.
+module.exports = {
+ key: 'ticket',
+
+ // You'll want to provide some helpful display labels and descriptions
+ // for tickets. Zapier will put them into the UX.
+ noun: 'Ticket',
+ display: {
+ label: 'New Ticket',
+ description: 'Triggers when a new ticket action is done in Dolibarr.'
+ },
+
+ // `operation` is where the business logic goes.
+ operation: {
+
+ // `inputFields` can define the fields a ticket could provide,
+ // we'll pass them in as `bundle.inputData` later.
+ inputFields: [
+ {
+ key: 'action',
+ type: 'string',
+ required: true,
+ helpText: 'Which action of ticket this should trigger on.',
+ choices: {
+ create: "Create",
+ modify: "Modify",
+ validate: "Validate",
+ }
+ }
+ ],
+
+ type: 'hook',
+
+ performSubscribe: subscribeHook,
+ performUnsubscribe: unsubscribeHook,
+
+ perform: getTicket,
+ performList: getFallbackRealTicket,
+
+ // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
+ // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
+ // returned records, and have obviously dummy values that we can show to any user.
+ sample: {
+ id: 1,
+ track_id: 'Xaz123er',
+ subject: 'Subject',
+ message: 'Message',
+ createdAt: 1472069465,
+ lastname: 'DOE',
+ firstname: 'John',
+ email: 'john@doe.com',
+ address: 'Park Avenue',
+ zip: '12345',
+ town: 'NEW-YORK',
+ email_from: 'doe.john@example;com',
+ authorId: 1,
+ action: 'create'
+ },
+
+ // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
+ // field definitions. The result will be used to augment the sample.
+ // outputFields: () => { return []; }
+ // Alternatively, a static field definition should be provided, to specify labels for the fields
+ outputFields: [
+ {
+ key: 'id',
+ type: "integer",
+ label: 'ID'
+ },
+ {
+ key: 'track_id',
+ type: "string",
+ label: 'TrackID'
+ },
+ {
+ key: 'subject',
+ type: "string",
+ label: 'Subject'
+ },
+ {
+ key: 'message',
+ type: "string",
+ label: 'Message'
+ },
+ {
+ key: 'createdAt',
+ type: "integer",
+ label: 'Created At'
+ },
+ {
+ key: 'lastname',
+ label: 'Lastname'
+ },
+ {
+ key: 'firstname',
+ label: 'Firstname'
+ },
+ {
+ key: 'email',
+ label: 'Email'
+ },
+ {
+ key: 'address',
+ label: 'Address'
+ },
+ {
+ key: 'zip',
+ label: 'Zip'
+ },
+ {
+ key: 'town',
+ label: 'Town'
+ },
+ {
+ key: 'email_from',
+ type: 'string',
+ label: 'Email from'
+ },
+ {
+ key: 'authorId',
+ type: "integer",
+ label: 'Author ID'
+ },
+ {
+ key: 'action',
+ type: 'string',
+ label: 'Action'
+ }
+ ]
+ }
+};
diff --git a/dev/examples/zapier/triggers/user.js b/dev/examples/zapier/triggers/user.js
new file mode 100644
index 00000000000..92209bb8651
--- /dev/null
+++ b/dev/examples/zapier/triggers/user.js
@@ -0,0 +1,177 @@
+const subscribeHook = (z, bundle) => {
+ // `z.console.log()` is similar to `console.log()`.
+ z.console.log('suscribing hook!');
+
+ // bundle.targetUrl has the Hook URL this app should call when an action is created.
+ const data = {
+ url: bundle.targetUrl,
+ event: bundle.event,
+ module: 'user',
+ action: bundle.inputData.action
+ };
+
+ const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
+
+ // You can build requests and our client will helpfully inject all the variables
+ // you need to complete. You can also register middleware to control this.
+ const options = {
+ url: url,
+ method: 'POST',
+ body: data,
+ };
+
+ // You may return a promise or a normal data structure from any perform method.
+ return z.request(options).then((response) => JSON.parse(response.content));
+};
+
+const unsubscribeHook = (z, bundle) => {
+ // bundle.subscribeData contains the parsed response JSON from the subscribe
+ // request made initially.
+ z.console.log('unsuscribing hook!');
+
+ // You can build requests and our client will helpfully inject all the variables
+ // you need to complete. You can also register middleware to control this.
+ const options = {
+ url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
+ method: 'DELETE',
+ };
+
+ // You may return a promise or a normal data structure from any perform method.
+ return z.request(options).then((response) => JSON.parse(response.content));
+};
+
+const getUser = (z, bundle) => {
+ // bundle.cleanedRequest will include the parsed JSON object (if it's not a
+ // test poll) and also a .querystring property with the URL's query string.
+ const user = {
+ id: bundle.cleanedRequest.id,
+ lastname: bundle.cleanedRequest.lastname,
+ firstname: bundle.cleanedRequest.firstname,
+ address: bundle.cleanedRequest.address,
+ zip: bundle.cleanedRequest.zip,
+ town: bundle.cleanedRequest.town,
+ email: bundle.cleanedRequest.email,
+ login: bundle.cleanedRequest.login,
+ authorId: bundle.cleanedRequest.authorId,
+ createdAt: bundle.cleanedRequest.createdAt,
+ action: bundle.cleanedRequest.action
+ };
+
+ return [user];
+};
+
+const getFallbackRealUser = (z, bundle) => {
+ // For the test poll, you should get some real data, to aid the setup process.
+ const module = bundle.inputData.module;
+ const options = {
+ url: bundle.authData.url + '/api/index.php/users/0',
+ };
+
+ return z.request(options).then((response) => [JSON.parse(response.content)]);
+};
+
+// const getModulesChoices = (z/*, bundle*/) => {
+// // For the test poll, you should get some real data, to aid the setup process.
+// const options = {
+// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
+// };
+
+// return z.request(options).then((response) => JSON.parse(response.content));
+// };
+// const getModulesChoices = () => {
+
+// return {
+// orders: "Order",
+// invoices: "Invoice",
+// thirdparties: "Thirdparty",
+// users: "User",
+// contacts: "Contacts"
+// };
+// };
+
+// const getActionsChoices = (z, bundle) => {
+// // For the test poll, you should get some real data, to aid the setup process.
+// const module = bundle.inputData.module;
+// const options = {
+// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
+// };
+
+// return z.request(options).then((response) => JSON.parse(response.content));
+// };
+
+// We recommend writing your triggers separate like this and rolling them
+// into the App definition at the end.
+module.exports = {
+ key: 'user',
+
+ // You'll want to provide some helpful display labels and descriptions
+ // for users. Zapier will put them into the UX.
+ noun: 'User',
+ display: {
+ label: 'New User',
+ description: 'Triggers when a new user action is done in Dolibarr.'
+ },
+
+ // `operation` is where the business logic goes.
+ operation: {
+
+ // `inputFields` can define the fields a user could provide,
+ // we'll pass them in as `bundle.inputData` later.
+ inputFields: [
+ {
+ key: 'action',
+ required: true,
+ type: 'string',
+ helpText: 'Which action of user this should trigger on.',
+ choices: {
+ create: "Create",
+ modify: "Modify",
+ validate: "Validate",
+ }
+ }
+ ],
+
+ type: 'hook',
+
+ performSubscribe: subscribeHook,
+ performUnsubscribe: unsubscribeHook,
+
+ perform: getUser,
+ performList: getFallbackRealUser,
+
+ // In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
+ // from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
+ // returned records, and have obviously dummy values that we can show to any user.
+ sample: {
+ id: 1,
+ createdAt: 1472069465,
+ lastname: 'DOE',
+ firstname: 'John',
+ email: 'john@doe.com',
+ address: 'Park Avenue',
+ zip: '12345',
+ town: 'NEW-YORK',
+ login: 'doe.john',
+ authorId: 1,
+ action: 'create'
+ },
+
+ // If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
+ // field definitions. The result will be used to augment the sample.
+ // outputFields: () => { return []; }
+ // Alternatively, a static field definition should be provided, to specify labels for the fields
+ outputFields: [
+ {key: 'id', type: "integer", label: 'ID'},
+ {key: 'createdAt', type: "integer", label: 'Created At'},
+ {key: 'lastname', label: 'Lastname'},
+ {key: 'firstname', label: 'Firstname'},
+ {key: 'email', label: 'Email'},
+ {key: 'address', label: 'Address'},
+ {key: 'zip', label: 'Zip'},
+ {key: 'town', label: 'Town'},
+ {key: 'login', label: 'Login'},
+ {key: 'authorId', type: "integer", label: 'Author ID'},
+ {key: 'action', label: 'Action'}
+ ]
+ }
+};
diff --git a/dev/initdata/purge-data.php b/dev/initdata/purge-data.php
index e6a67aa73c8..18256c33766 100755
--- a/dev/initdata/purge-data.php
+++ b/dev/initdata/purge-data.php
@@ -120,8 +120,8 @@ $sqls=array(
"DELETE FROM ".MAIN_DB_PREFIX."expedition where date_creation < '__DATE__'",
),
'delivery'=>array(
- "DELETE FROM ".MAIN_DB_PREFIX."livraisondet WHERE fk_livraison IN (select rowid FROM ".MAIN_DB_PREFIX."livraison where date_creation < '__DATE__')",
- "DELETE FROM ".MAIN_DB_PREFIX."livraison where date_creation < '__DATE__'",
+ "DELETE FROM ".MAIN_DB_PREFIX."deliverydet WHERE fk_delivery IN (select rowid FROM ".MAIN_DB_PREFIX."delivery where date_creation < '__DATE__')",
+ "DELETE FROM ".MAIN_DB_PREFIX."delivery where date_creation < '__DATE__'",
),
'contract'=>array(
"DELETE FROM ".MAIN_DB_PREFIX."contratdet_extrafields WHERE fk_object IN (select rowid FROM ".MAIN_DB_PREFIX."contratdet WHERE fk_contrat IN (select rowid FROM ".MAIN_DB_PREFIX."contrat where datec < '__DATE__'))",
diff --git a/dev/initdemo/mysqldump_dolibarr_12.0.0.sql b/dev/initdemo/mysqldump_dolibarr_12.0.0.sql
index 3cc1db1cf34..a05c05c066e 100644
--- a/dev/initdemo/mysqldump_dolibarr_12.0.0.sql
+++ b/dev/initdemo/mysqldump_dolibarr_12.0.0.sql
@@ -7522,13 +7522,13 @@ INSERT INTO `llx_links` VALUES (1,1,'2018-01-16 16:45:35','http://www.dolicloud.
UNLOCK TABLES;
--
--- Table structure for table `llx_livraison`
+-- Table structure for table `llx_delivery`
--
-DROP TABLE IF EXISTS `llx_livraison`;
+DROP TABLE IF EXISTS `llx_delivery`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `llx_livraison` (
+CREATE TABLE `llx_delivery` (
`rowid` int(11) NOT NULL AUTO_INCREMENT,
`tms` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`ref` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
@@ -7554,61 +7554,61 @@ CREATE TABLE `llx_livraison` (
`import_key` varchar(14) COLLATE utf8_unicode_ci DEFAULT NULL,
`extraparams` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`rowid`),
- UNIQUE KEY `idx_livraison_uk_ref` (`ref`,`entity`),
- KEY `idx_livraison_fk_soc` (`fk_soc`),
- KEY `idx_livraison_fk_user_author` (`fk_user_author`),
- KEY `idx_livraison_fk_user_valid` (`fk_user_valid`),
- CONSTRAINT `fk_livraison_fk_soc` FOREIGN KEY (`fk_soc`) REFERENCES `llx_societe` (`rowid`),
- CONSTRAINT `fk_livraison_fk_user_author` FOREIGN KEY (`fk_user_author`) REFERENCES `llx_user` (`rowid`),
- CONSTRAINT `fk_livraison_fk_user_valid` FOREIGN KEY (`fk_user_valid`) REFERENCES `llx_user` (`rowid`)
+ UNIQUE KEY `idx_delivery_uk_ref` (`ref`,`entity`),
+ KEY `idx_delivery_fk_soc` (`fk_soc`),
+ KEY `idx_delivery_fk_user_author` (`fk_user_author`),
+ KEY `idx_delivery_fk_user_valid` (`fk_user_valid`),
+ CONSTRAINT `fk_delivery_fk_soc` FOREIGN KEY (`fk_soc`) REFERENCES `llx_societe` (`rowid`),
+ CONSTRAINT `fk_delivery_fk_user_author` FOREIGN KEY (`fk_user_author`) REFERENCES `llx_user` (`rowid`),
+ CONSTRAINT `fk_delivery_fk_user_valid` FOREIGN KEY (`fk_user_valid`) REFERENCES `llx_user` (`rowid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Dumping data for table `llx_livraison`
+-- Dumping data for table `llx_delivery`
--
-LOCK TABLES `llx_livraison` WRITE;
-/*!40000 ALTER TABLE `llx_livraison` DISABLE KEYS */;
-/*!40000 ALTER TABLE `llx_livraison` ENABLE KEYS */;
+LOCK TABLES `llx_delivery` WRITE;
+/*!40000 ALTER TABLE `llx_delivery` DISABLE KEYS */;
+/*!40000 ALTER TABLE `llx_delivery` ENABLE KEYS */;
UNLOCK TABLES;
--
--- Table structure for table `llx_livraison_extrafields`
+-- Table structure for table `llx_delivery_extrafields`
--
-DROP TABLE IF EXISTS `llx_livraison_extrafields`;
+DROP TABLE IF EXISTS `llx_delivery_extrafields`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `llx_livraison_extrafields` (
+CREATE TABLE `llx_delivery_extrafields` (
`rowid` int(11) NOT NULL AUTO_INCREMENT,
`tms` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`fk_object` int(11) NOT NULL,
`import_key` varchar(14) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`rowid`),
- KEY `idx_livraison_extrafields` (`fk_object`)
+ KEY `idx_delivery_extrafields` (`fk_object`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Dumping data for table `llx_livraison_extrafields`
+-- Dumping data for table `llx_delivery_extrafields`
--
-LOCK TABLES `llx_livraison_extrafields` WRITE;
-/*!40000 ALTER TABLE `llx_livraison_extrafields` DISABLE KEYS */;
-/*!40000 ALTER TABLE `llx_livraison_extrafields` ENABLE KEYS */;
+LOCK TABLES `llx_delivery_extrafields` WRITE;
+/*!40000 ALTER TABLE `llx_delivery_extrafields` DISABLE KEYS */;
+/*!40000 ALTER TABLE `llx_delivery_extrafields` ENABLE KEYS */;
UNLOCK TABLES;
--
--- Table structure for table `llx_livraisondet`
+-- Table structure for table `llx_deliverydet`
--
-DROP TABLE IF EXISTS `llx_livraisondet`;
+DROP TABLE IF EXISTS `llx_deliverydet`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `llx_livraisondet` (
+CREATE TABLE `llx_deliverydet` (
`rowid` int(11) NOT NULL AUTO_INCREMENT,
- `fk_livraison` int(11) DEFAULT NULL,
+ `fk_delivery` int(11) DEFAULT NULL,
`fk_origin_line` int(11) DEFAULT NULL,
`fk_product` int(11) DEFAULT NULL,
`description` text COLLATE utf8_unicode_ci DEFAULT NULL,
@@ -7617,44 +7617,44 @@ CREATE TABLE `llx_livraisondet` (
`total_ht` double(24,8) DEFAULT 0.00000000,
`rang` int(11) DEFAULT 0,
PRIMARY KEY (`rowid`),
- KEY `idx_livraisondet_fk_expedition` (`fk_livraison`),
- CONSTRAINT `fk_livraisondet_fk_livraison` FOREIGN KEY (`fk_livraison`) REFERENCES `llx_livraison` (`rowid`)
+ KEY `idx_deliverydet_fk_expedition` (`fk_delivery`),
+ CONSTRAINT `fk_deliverydet_fk_delivery` FOREIGN KEY (`fk_delivery`) REFERENCES `llx_delivery` (`rowid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Dumping data for table `llx_livraisondet`
+-- Dumping data for table `llx_deliverydet`
--
-LOCK TABLES `llx_livraisondet` WRITE;
-/*!40000 ALTER TABLE `llx_livraisondet` DISABLE KEYS */;
-/*!40000 ALTER TABLE `llx_livraisondet` ENABLE KEYS */;
+LOCK TABLES `llx_deliverydet` WRITE;
+/*!40000 ALTER TABLE `llx_deliverydet` DISABLE KEYS */;
+/*!40000 ALTER TABLE `llx_deliverydet` ENABLE KEYS */;
UNLOCK TABLES;
--
--- Table structure for table `llx_livraisondet_extrafields`
+-- Table structure for table `llx_deliverydet_extrafields`
--
-DROP TABLE IF EXISTS `llx_livraisondet_extrafields`;
+DROP TABLE IF EXISTS `llx_deliverydet_extrafields`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `llx_livraisondet_extrafields` (
+CREATE TABLE `llx_deliverydet_extrafields` (
`rowid` int(11) NOT NULL AUTO_INCREMENT,
`tms` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`fk_object` int(11) NOT NULL,
`import_key` varchar(14) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`rowid`),
- KEY `idx_livraisondet_extrafields` (`fk_object`)
+ KEY `idx_deliverydet_extrafields` (`fk_object`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Dumping data for table `llx_livraisondet_extrafields`
+-- Dumping data for table `llx_deliverydet_extrafields`
--
-LOCK TABLES `llx_livraisondet_extrafields` WRITE;
-/*!40000 ALTER TABLE `llx_livraisondet_extrafields` DISABLE KEYS */;
-/*!40000 ALTER TABLE `llx_livraisondet_extrafields` ENABLE KEYS */;
+LOCK TABLES `llx_deliverydet_extrafields` WRITE;
+/*!40000 ALTER TABLE `llx_deliverydet_extrafields` DISABLE KEYS */;
+/*!40000 ALTER TABLE `llx_deliverydet_extrafields` ENABLE KEYS */;
UNLOCK TABLES;
--
@@ -12679,7 +12679,7 @@ CREATE TABLE `llx_user` (
LOCK TABLES `llx_user` WRITE;
/*!40000 ALTER TABLE `llx_user` DISABLE KEYS */;
-INSERT INTO `llx_user` VALUES (1,'2012-07-08 13:20:11','2019-11-28 11:52:58',NULL,NULL,'aeinstein',0,NULL,NULL,NULL,1,0,NULL,'11c9c772d6471aa24c27274bdd8a223b',NULL,NULL,'Einstein','Albert','',NULL,'123456789','','','','aeinstein@example.com','','[]','',0,'',1,1,NULL,NULL,NULL,'','2017-10-05 08:32:44','2017-10-03 11:43:50',NULL,'',1,'alberteinstein.jpg',NULL,NULL,14,NULL,NULL,NULL,'','','',NULL,NULL,'aaaaff','',NULL,0,0,NULL,NULL,NULL,44.00000000,'man',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(2,'2012-07-08 13:54:48','2019-11-28 11:52:58',NULL,NULL,'demo',1,NULL,NULL,NULL,1,0,NULL,'fe01ce2a7fbac8fafaed7c982a04e229',NULL,NULL,'Doe','David','Trainee',NULL,'09123123','','','','daviddoe@example.com','','[]','',0,'',1,1,NULL,NULL,NULL,'','2018-07-30 23:10:54','2018-07-30 23:04:17',NULL,'',1,'person9.jpeg',NULL,NULL,11,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,NULL,NULL,NULL,35.00000000,'man',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(3,'2012-07-11 16:18:59','2020-01-21 09:30:27',NULL,NULL,'pcurie',1,NULL,NULL,NULL,1,0,NULL,'ab335b4eb4c3c99334f656e5db9584c9',NULL,NULL,'Curie','Pierre','',NULL,'','','','','pcurie@example.com','','[]','',0,'',1,1,NULL,NULL,2,'','2014-12-21 17:38:55',NULL,NULL,'',1,'pierrecurie.jpg',NULL,NULL,14,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,NULL,NULL,NULL,39.00000000,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(4,'2015-01-23 17:52:27','2019-11-28 11:52:58',NULL,NULL,'bbookkeeper',1,NULL,NULL,NULL,1,0,NULL,'a7d30b58d647fcf59b7163f9592b1dbb',NULL,NULL,'Bookkeeper','Bob','Bookkeeper',NULL,'','','','','bbookkeeper@example.com','','{\"skype\":\"skypebbookkeeper\"}','',0,'',1,1,17,6,NULL,'','2015-02-25 10:18:41','2015-01-23 17:53:20',NULL,'',1,'person8.jpeg',NULL,NULL,11,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,NULL,NULL,NULL,16.00000000,'man',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(10,'2017-10-03 11:47:41','2019-11-28 11:52:58',NULL,NULL,'mcurie',1,NULL,NULL,NULL,1,0,NULL,'52cda011808bb282d1d3625ab607a145',NULL,'t3mnkbhs','Curie','Marie','',NULL,'','','','','mcurie@example.com','','[]','',0,NULL,1,1,NULL,NULL,NULL,'',NULL,NULL,NULL,'',1,'mariecurie.jpg',NULL,NULL,14,NULL,NULL,NULL,'','','',NULL,NULL,'ffaaff','',NULL,0,0,NULL,NULL,NULL,44.00000000,'woman',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(11,'2017-10-05 09:07:52','2019-11-28 11:52:58',NULL,NULL,'zzeceo',1,NULL,NULL,NULL,1,0,NULL,'92af989c4c3a5140fb5d73eb77a52454',NULL,'cq78nf9m','Zeceo','Zack','President - CEO',NULL,'','','','','zzeceo@example.com','','[]','',0,NULL,1,1,NULL,NULL,NULL,'','2017-10-05 22:48:08','2017-10-05 21:18:46',NULL,'',1,'person4.jpeg',NULL,NULL,NULL,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,NULL,NULL,NULL,39.00000000,NULL,NULL,'2019-06-10 00:00:00',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(12,'2017-10-05 09:09:46','2020-01-07 13:47:17',NULL,NULL,'admin',0,NULL,NULL,NULL,1,0,NULL,'f6fdffe48c908deb0f4c3bd36c032e72',NULL,'nd6hgbcr','Adminson','Alice','Admin Technical',NULL,'','','','','aadminson@example.com','','[]','Alice - 123',1,NULL,1,1,NULL,NULL,NULL,'','2020-01-21 10:38:41','2020-01-21 10:35:27',NULL,'',1,'person6.jpeg',NULL,NULL,11,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,2700.00000000,NULL,NULL,39.00000000,'woman',NULL,NULL,NULL,'generic_user_odt','1985-09-15',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(13,'2017-10-05 21:29:35','2019-11-28 11:52:58',NULL,NULL,'ccommercy',1,NULL,NULL,NULL,1,0,NULL,'179858e041af35e8f4c81d68c55fe9da',NULL,'y451ksdv','Commercy','Coraly','Commercial leader',NULL,'','','','','ccommercy@example.com','','[]','',0,NULL,1,1,NULL,NULL,NULL,'',NULL,NULL,NULL,'',1,'person7.jpeg',NULL,NULL,11,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,1890.00000000,NULL,NULL,25.00000000,'woman',NULL,'2018-09-11 00:00:00',NULL,NULL,'1998-12-08',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(14,'2017-10-05 21:33:33','2019-11-28 11:52:58',NULL,NULL,'sscientol',1,NULL,NULL,NULL,1,0,NULL,'39bee07ac42f31c98e79cdcd5e5fe4c5',NULL,'s2hp8bxd','Scientol','Sam','Scientist leader',NULL,'','','','','sscientol@example.com','','[]','',0,NULL,1,1,NULL,NULL,NULL,'',NULL,NULL,NULL,'',1,'person3.jpeg',NULL,NULL,11,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,3500.00000000,NULL,NULL,39.00000000,NULL,NULL,'2018-07-03 00:00:00',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(16,'2017-10-05 22:47:52','2019-11-28 11:52:58',NULL,NULL,'ccommerson',1,NULL,NULL,NULL,1,0,NULL,'d68005ccf362b82d084551b6291792a3',NULL,'cx9y1dk0','Charle1','Commerson','Sale representative',NULL,'','','','','ccommerson@example.com','','[]','',0,NULL,1,1,NULL,NULL,NULL,'','2017-10-05 23:46:24','2017-10-05 23:37:31',NULL,'',1,'person1.jpeg',NULL,NULL,13,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,2900.00000000,NULL,NULL,39.00000000,NULL,NULL,'2019-09-01 00:00:00',NULL,NULL,'1976-02-05',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(17,'2017-10-05 22:48:39','2019-11-28 11:52:58',NULL,NULL,'aleerfok',1,NULL,NULL,NULL,1,0,NULL,'a964065211872fb76f876c6c3e952ea3',NULL,'gw8cb7xj','Leerfok','Amanda','Sale representative',NULL,'','','','','aleerfok@example.com','','[]','',0,NULL,1,1,NULL,NULL,NULL,'','2017-10-05 23:16:06',NULL,NULL,'',0,'person5.jpeg',NULL,NULL,13,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,0,NULL,NULL,NULL,39.00000000,'woman',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,-1,NULL,NULL),(18,'2018-01-22 17:27:02','2019-11-28 11:52:58',NULL,NULL,'ldestailleur',1,NULL,NULL,NULL,1,0,NULL,'1bb7805145a7a5066df9e6d585b8b645',NULL,'87g06wbx','Destailleur','Laurent','Project leader of Dolibarr ERP CRM',NULL,'','','','','ldestailleur@example.com','','[]','