diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..1940626
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: mathben963 # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..04d387e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+*~
+*.swp
+*.tmp
+*.bak
+.idea
+venv
+*.log
+config.conf
+*.DS_Store
+*.pyc
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..9fe9487
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,255 @@
+[submodule "addons/MathBenTech_development"]
+ url = https://github.com/ERPLibre/development.git
+ path = addons/MathBenTech_development
+[submodule "addons/MathBenTech_odoo-business-spending-management-quebec-canada"]
+ url = https://github.com/ERPLibre/odoo-business-spending-management-quebec-canada.git
+ path = addons/MathBenTech_odoo-business-spending-management-quebec-canada
+[submodule "addons/MathBenTech_scrummer"]
+ url = https://github.com/ERPLibre/scrummer.git
+ path = addons/MathBenTech_scrummer
+[submodule "addons/muk-it_muk_base"]
+ url = https://github.com/ERPLibre/muk_base.git
+ path = addons/muk-it_muk_base
+[submodule "addons/muk-it_muk_dms"]
+ url = https://github.com/ERPLibre/muk_dms.git
+ path = addons/muk-it_muk_dms
+[submodule "addons/muk-it_muk_docs"]
+ url = https://github.com/ERPLibre/muk_docs.git
+ path = addons/muk-it_muk_docs
+[submodule "addons/muk-it_muk_misc"]
+ url = https://github.com/ERPLibre/muk_misc.git
+ path = addons/muk-it_muk_misc
+[submodule "addons/muk-it_muk_quality"]
+ url = https://github.com/ERPLibre/muk_quality.git
+ path = addons/muk-it_muk_quality
+[submodule "addons/muk-it_muk_web"]
+ url = https://github.com/ERPLibre/muk_web.git
+ path = addons/muk-it_muk_web
+[submodule "addons/muk-it_muk_website"]
+ url = https://github.com/ERPLibre/muk_website.git
+ path = addons/muk-it_muk_website
+[submodule "addons/Numigi_odoo-base-addons"]
+ url = https://github.com/ERPLibre/odoo-base-addons.git
+ path = addons/Numigi_odoo-base-addons
+[submodule "addons/Numigi_odoo-entertainment-addons"]
+ url = https://github.com/ERPLibre/odoo-entertainment-addons.git
+ path = addons/Numigi_odoo-entertainment-addons
+[submodule "addons/Numigi_odoo-git-addons"]
+ url = https://github.com/ERPLibre/odoo-git-addons.git
+ path = addons/Numigi_odoo-git-addons
+[submodule "addons/Numigi_odoo-hr-addons"]
+ url = https://github.com/ERPLibre/odoo-hr-addons.git
+ path = addons/Numigi_odoo-hr-addons
+[submodule "addons/Numigi_odoo-partner-addons"]
+ url = https://github.com/ERPLibre/odoo-partner-addons.git
+ path = addons/Numigi_odoo-partner-addons
+[submodule "addons/Numigi_odoo-product-addons"]
+ url = https://github.com/ERPLibre/odoo-product-addons.git
+ path = addons/Numigi_odoo-product-addons
+[submodule "addons/Numigi_odoo-project-addons"]
+ url = https://github.com/ERPLibre/odoo-project-addons.git
+ path = addons/Numigi_odoo-project-addons
+[submodule "addons/Numigi_odoo-purchase-addons"]
+ url = https://github.com/ERPLibre/odoo-purchase-addons.git
+ path = addons/Numigi_odoo-purchase-addons
+[submodule "addons/Numigi_odoo-stock-addons"]
+ url = https://github.com/ERPLibre/odoo-stock-addons.git
+ path = addons/Numigi_odoo-stock-addons
+[submodule "addons/Numigi_odoo-survey-addons"]
+ url = https://github.com/ERPLibre/odoo-survey-addons.git
+ path = addons/Numigi_odoo-survey-addons
+[submodule "addons/Numigi_odoo-timesheet-addons"]
+ url = https://github.com/ERPLibre/odoo-timesheet-addons.git
+ path = addons/Numigi_odoo-timesheet-addons
+[submodule "addons/Numigi_odoo-web-addons"]
+ url = https://github.com/ERPLibre/odoo-web-addons.git
+ path = addons/Numigi_odoo-web-addons
+[submodule "addons/OCA_account-analytic"]
+ url = https://github.com/ERPLibre/account-analytic.git
+ path = addons/OCA_account-analytic
+[submodule "addons/OCA_account-budgeting"]
+ url = https://github.com/ERPLibre/account-budgeting.git
+ path = addons/OCA_account-budgeting
+[submodule "addons/OCA_account-closing"]
+ url = https://github.com/ERPLibre/account-closing.git
+ path = addons/OCA_account-closing
+[submodule "addons/OCA_account-consolidation"]
+ url = https://github.com/ERPLibre/account-consolidation.git
+ path = addons/OCA_account-consolidation
+[submodule "addons/OCA_account-financial-reporting"]
+ url = https://github.com/ERPLibre/account-financial-reporting.git
+ path = addons/OCA_account-financial-reporting
+[submodule "addons/OCA_account-financial-tools"]
+ url = https://github.com/ERPLibre/account-financial-tools
+ path = addons/OCA_account-financial-tools
+[submodule "addons/OCA_account-fiscal-rule"]
+ url = https://github.com/ERPLibre/account-fiscal-rule.git
+ path = addons/OCA_account-fiscal-rule
+[submodule "addons/OCA_account-invoicing"]
+ url = https://github.com/ERPLibre/account-invoicing.git
+ path = addons/OCA_account-invoicing
+[submodule "addons/OCA_account-invoice-reporting"]
+ url = https://github.com/ERPLibre/account-invoice-reporting.git
+ path = addons/OCA_account-invoice-reporting
+[submodule "addons/OCA_account-payment"]
+ url = https://github.com/ERPLibre/account-payment.git
+ path = addons/OCA_account-payment
+[submodule "addons/OCA_account-reconcile"]
+ url = https://github.com/ERPLibre/account-reconcile.git
+ path = addons/OCA_account-reconcile
+[submodule "addons/OCA_apps-store"]
+ url = https://github.com/ERPLibre/apps-store.git
+ path = addons/OCA_apps-store
+[submodule "addons/OCA_bank-payment"]
+ url = https://github.com/ERPLibre/bank-payment.git
+ path = addons/OCA_bank-payment
+[submodule "addons/OCA_bank-statement-import"]
+ url = https://github.com/ERPLibre/bank-statement-import.git
+ path = addons/OCA_bank-statement-import
+[submodule "addons/OCA_brand"]
+ url = https://github.com/ERPLibre/brand.git
+ path = addons/OCA_brand
+[submodule "addons/OCA_business-requirement"]
+ url = https://github.com/ERPLibre/business-requirement.git
+ path = addons/OCA_business-requirement
+[submodule "addons/OCA_commission"]
+ url = https://github.com/ERPLibre/commission.git
+ path = addons/OCA_commission
+[submodule "addons/OCA_community-data-files"]
+ url = https://github.com/ERPLibre/community-data-files.git
+ path = addons/OCA_community-data-files
+[submodule "addons/OCA_connector-telephony"]
+ url = https://github.com/ERPLibre/connector-telephony.git
+ path = addons/OCA_connector-telephony
+[submodule "addons/OCA_contract"]
+ url = https://github.com/ERPLibre/contract.git
+ path = addons/OCA_contract
+[submodule "addons/OCA_credit-control"]
+ url = https://github.com/ERPLibre/credit-control.git
+ path = addons/OCA_credit-control
+[submodule "addons/OCA_currency"]
+ url = https://github.com/ERPLibre/currency.git
+ path = addons/OCA_currency
+[submodule "addons/OCA_data-protection"]
+ url = https://github.com/ERPLibre/data-protection.git
+ path = addons/OCA_data-protection
+[submodule "addons/OCA_donation"]
+ url = https://github.com/ERPLibre/donation.git
+ path = addons/OCA_donation
+[submodule "addons/OCA_e-commerce"]
+ url = https://github.com/ERPLibre/e-commerce.git
+ path = addons/OCA_e-commerce
+[submodule "addons/OCA_edi"]
+ url = https://github.com/ERPLibre/edi.git
+ path = addons/OCA_edi
+[submodule "addons/OCA_event"]
+ url = https://github.com/ERPLibre/event.git
+ path = addons/OCA_event
+[submodule "addons/OCA_helpdesk"]
+ url = https://github.com/ERPLibre/helpdesk.git
+ path = addons/OCA_helpdesk
+[submodule "addons/OCA_hr"]
+ url = https://github.com/ERPLibre/hr.git
+ path = addons/OCA_hr
+[submodule "addons/OCA_knowledge"]
+ url = https://github.com/ERPLibre/knowledge.git
+ path = addons/OCA_knowledge
+[submodule "addons/OCA_l10n-canada"]
+ url = https://github.com/ERPLibre/l10n-canada.git
+ path = addons/OCA_l10n-canada
+[submodule "addons/OCA_maintenance"]
+ url = https://github.com/ERPLibre/maintenance.git
+ path = addons/OCA_maintenance
+[submodule "addons/OCA_management-system"]
+ url = https://github.com/ERPLibre/management-system.git
+ path = addons/OCA_management-system
+[submodule "addons/OCA_manufacture"]
+ url = https://github.com/ERPLibre/manufacture.git
+ path = addons/OCA_manufacture
+[submodule "addons/OCA_margin-analysis"]
+ url = https://github.com/ERPLibre/margin-analysis.git
+ path = addons/OCA_margin-analysis
+[submodule "addons/OCA_mis-builder"]
+ url = https://github.com/ERPLibre/mis-builder.git
+ path = addons/OCA_mis-builder
+[submodule "addons/OCA_multi-company"]
+ url = https://github.com/ERPLibre/multi-company.git
+ path = addons/OCA_multi-company
+[submodule "addons/OCA_partner-contact"]
+ url = https://github.com/ERPLibre/partner-contact.git
+ path = addons/OCA_partner-contact
+[submodule "addons/OCA_pos"]
+ url = https://github.com/ERPLibre/pos.git
+ path = addons/OCA_pos
+[submodule "addons/OCA_product-attribute"]
+ url = https://github.com/ERPLibre/product-attribute.git
+ path = addons/OCA_product-attribute
+[submodule "addons/OCA_product-pack"]
+ url = https://github.com/ERPLibre/product-pack.git
+ path = addons/OCA_product-pack
+[submodule "addons/OCA_product-variant"]
+ url = https://github.com/ERPLibre/product-variant.git
+ path = addons/OCA_product-variant
+[submodule "addons/OCA_project"]
+ url = https://github.com/ERPLibre/project.git
+ path = addons/OCA_project
+[submodule "addons/OCA_project-reporting"]
+ url = https://github.com/ERPLibre/project-reporting.git
+ path = addons/OCA_project-reporting
+[submodule "addons/OCA_purchase-workflow"]
+ url = https://github.com/ERPLibre/purchase-workflow.git
+ path = addons/OCA_purchase-workflow
+[submodule "addons/OCA_queue"]
+ url = https://github.com/ERPLibre/queue.git
+ path = addons/OCA_queue
+[submodule "addons/OCA_reporting-engine"]
+ url = https://github.com/ERPLibre/reporting-engine.git
+ path = addons/OCA_reporting-engine
+[submodule "addons/OCA_sale-workflow"]
+ url = https://github.com/ERPLibre/sale-workflow.git
+ path = addons/OCA_sale-workflow
+[submodule "addons/OCA_server-auth"]
+ url = https://github.com/ERPLibre/server-auth.git
+ path = addons/OCA_server-auth
+[submodule "addons/OCA_server-brand"]
+ url = https://github.com/ERPLibre/server-brand.git
+ path = addons/OCA_server-brand
+[submodule "addons/OCA_server-env"]
+ url = https://github.com/ERPLibre/server-env.git
+ path = addons/OCA_server-env
+[submodule "addons/OCA_server-tools"]
+ url = https://github.com/ERPLibre/server-tools.git
+ path = addons/OCA_server-tools
+[submodule "addons/OCA_server-ux"]
+ url = https://github.com/ERPLibre/server-ux.git
+ path = addons/OCA_server-ux
+[submodule "addons/OCA_social"]
+ url = https://github.com/ERPLibre/social.git
+ path = addons/OCA_social
+[submodule "addons/OCA_stock-logistics-warehouse"]
+ url = https://github.com/ERPLibre/stock-logistics-warehouse.git
+ path = addons/OCA_stock-logistics-warehouse
+[submodule "addons/OCA_timesheet"]
+ url = https://github.com/ERPLibre/timesheet.git
+ path = addons/OCA_timesheet
+[submodule "addons/OCA_web"]
+ url = https://github.com/ERPLibre/web.git
+ path = addons/OCA_web
+[submodule "addons/OCA_website"]
+ url = https://github.com/ERPLibre/website.git
+ path = addons/OCA_website
+[submodule "addons/OCA_wms"]
+ url = https://github.com/ERPLibre/wms.git
+ path = addons/OCA_wms
+[submodule "addons/odooaktiv_QuotationRevision"]
+ url = https://github.com/ERPLibre/QuotationRevision.git
+ path = addons/odooaktiv_QuotationRevision
+[submodule "addons/openeducat_openeducat_erp"]
+ url = https://github.com/ERPLibre/openeducat_erp.git
+ path = addons/openeducat_openeducat_erp
+[submodule "addons/Smile-SA_odoo_addons"]
+ url = https://github.com/ERPLibre/odoo_addons.git
+ path = addons/Smile-SA_odoo_addons
+[submodule "odoo"]
+ url = https://github.com/ERPLibre/odoo.git
+ path = odoo
diff --git a/HOWTO.md b/HOWTO.md
new file mode 100644
index 0000000..3bf0c31
--- /dev/null
+++ b/HOWTO.md
@@ -0,0 +1,4 @@
+# How to clone me
+
+First,
+pip install -r requirements.txt
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d41b676
--- /dev/null
+++ b/README.md
@@ -0,0 +1,58 @@
+# ERPLibre
+
+## Installation procedure production
+
+##### 1. Clone the project:
+```
+git clone https://github.com/ERPLibre/ERPLibre.git
+```
+##### 2. Modify the parameters
+Modify the file env_var.sh for production installation.
+
+##### 3. Execute the script:
+```
+sudo ./script/odoo_install_production.sh
+```
+
+## Installation procedure locally
+
+##### 1. Clone the project:
+```
+git clone https://github.com/ERPLibre/ERPLibre.git
+```
+
+##### 2. Execute the script:
+```
+sudo ./script/odoo_install_locally.sh
+```
+
+# Execution
+## First run
+```
+source ./venv/bin/activate
+python odoo/odoo-bin -c config.conf --log-level debug
+```
+
+## Update all
+Great idea to run it when update Odoo, update database of each modules.
+```
+python odoo/odoo-bin -c config.conf -d [DATABASE] -u all --log-level debug
+```
+
+## Update module
+```
+python odoo/odoo-bin -c config.conf -d [DATABASE] -u [module] --log-level debug
+```
+
+## Test
+```
+python odoo/odoo-bin -c config.conf -d [DATABASE] -i [module to test] --test-enable --stop-after-init --log-level=test --test-tags [module_name][tags]
+```
+
+# Production
+```
+python odoo/odoo-bin -c config.conf -d [DATABASE] --no-database-list
+```
+
+# Thanks
+Thanks Yenthe Van Ginneken for your guides.
\ No newline at end of file
diff --git a/addons/MathBenTech_development b/addons/MathBenTech_development
new file mode 160000
index 0000000..097a500
--- /dev/null
+++ b/addons/MathBenTech_development
@@ -0,0 +1 @@
+Subproject commit 097a5002dd6ec91512406f3add8bb7cad5372218
diff --git a/addons/MathBenTech_odoo-business-spending-management-quebec-canada b/addons/MathBenTech_odoo-business-spending-management-quebec-canada
new file mode 160000
index 0000000..b295952
--- /dev/null
+++ b/addons/MathBenTech_odoo-business-spending-management-quebec-canada
@@ -0,0 +1 @@
+Subproject commit b295952e5c108833477b3c96b5f84a782f9015bc
diff --git a/addons/MathBenTech_scrummer b/addons/MathBenTech_scrummer
new file mode 160000
index 0000000..9cb9fc4
--- /dev/null
+++ b/addons/MathBenTech_scrummer
@@ -0,0 +1 @@
+Subproject commit 9cb9fc437c28f8c4386e0025e853b18911d174d6
diff --git a/addons/Numigi_odoo-base-addons b/addons/Numigi_odoo-base-addons
new file mode 160000
index 0000000..60bc1e5
--- /dev/null
+++ b/addons/Numigi_odoo-base-addons
@@ -0,0 +1 @@
+Subproject commit 60bc1e5414ff3bf81a6d72831da2eaad94ccbcb2
diff --git a/addons/Numigi_odoo-entertainment-addons b/addons/Numigi_odoo-entertainment-addons
new file mode 160000
index 0000000..82c3325
--- /dev/null
+++ b/addons/Numigi_odoo-entertainment-addons
@@ -0,0 +1 @@
+Subproject commit 82c33255261eff361a91da13b28e4e68a95b25dd
diff --git a/addons/Numigi_odoo-git-addons b/addons/Numigi_odoo-git-addons
new file mode 160000
index 0000000..96db417
--- /dev/null
+++ b/addons/Numigi_odoo-git-addons
@@ -0,0 +1 @@
+Subproject commit 96db417669a631877c1439f617ac8c0cc6edfff9
diff --git a/addons/Numigi_odoo-hr-addons b/addons/Numigi_odoo-hr-addons
new file mode 160000
index 0000000..0034395
--- /dev/null
+++ b/addons/Numigi_odoo-hr-addons
@@ -0,0 +1 @@
+Subproject commit 0034395bcdb38c02749644607f43ccac760dfb49
diff --git a/addons/Numigi_odoo-partner-addons b/addons/Numigi_odoo-partner-addons
new file mode 160000
index 0000000..f0c54ff
--- /dev/null
+++ b/addons/Numigi_odoo-partner-addons
@@ -0,0 +1 @@
+Subproject commit f0c54ffb3409cd8e748ae5db19077c7c966cd57f
diff --git a/addons/Numigi_odoo-product-addons b/addons/Numigi_odoo-product-addons
new file mode 160000
index 0000000..36751bd
--- /dev/null
+++ b/addons/Numigi_odoo-product-addons
@@ -0,0 +1 @@
+Subproject commit 36751bd3c6baced6a0b3f5ddb675d87cb04a745c
diff --git a/addons/Numigi_odoo-project-addons b/addons/Numigi_odoo-project-addons
new file mode 160000
index 0000000..4388a4c
--- /dev/null
+++ b/addons/Numigi_odoo-project-addons
@@ -0,0 +1 @@
+Subproject commit 4388a4ca61b87032e2c3783dc2740b299cd31b6f
diff --git a/addons/Numigi_odoo-purchase-addons b/addons/Numigi_odoo-purchase-addons
new file mode 160000
index 0000000..5d226ca
--- /dev/null
+++ b/addons/Numigi_odoo-purchase-addons
@@ -0,0 +1 @@
+Subproject commit 5d226ca3887c77e31467a192a0fbe4066bf7842c
diff --git a/addons/Numigi_odoo-stock-addons b/addons/Numigi_odoo-stock-addons
new file mode 160000
index 0000000..3fe57c3
--- /dev/null
+++ b/addons/Numigi_odoo-stock-addons
@@ -0,0 +1 @@
+Subproject commit 3fe57c3cad122d5a448239b46fda8bf76ea32493
diff --git a/addons/Numigi_odoo-survey-addons b/addons/Numigi_odoo-survey-addons
new file mode 160000
index 0000000..9e897ba
--- /dev/null
+++ b/addons/Numigi_odoo-survey-addons
@@ -0,0 +1 @@
+Subproject commit 9e897bae38ff0d6d3180296a552d994bb10c0eff
diff --git a/addons/Numigi_odoo-timesheet-addons b/addons/Numigi_odoo-timesheet-addons
new file mode 160000
index 0000000..d2bbb19
--- /dev/null
+++ b/addons/Numigi_odoo-timesheet-addons
@@ -0,0 +1 @@
+Subproject commit d2bbb19dc8f917272694ff0a6231275083fb7e74
diff --git a/addons/Numigi_odoo-web-addons b/addons/Numigi_odoo-web-addons
new file mode 160000
index 0000000..3a4aa46
--- /dev/null
+++ b/addons/Numigi_odoo-web-addons
@@ -0,0 +1 @@
+Subproject commit 3a4aa46439a794429d5939cff561f42c4f312a99
diff --git a/addons/OCA_account-analytic b/addons/OCA_account-analytic
new file mode 160000
index 0000000..7ce9fe2
--- /dev/null
+++ b/addons/OCA_account-analytic
@@ -0,0 +1 @@
+Subproject commit 7ce9fe25a7c977c5338001bc32d58b1cadffe51e
diff --git a/addons/OCA_account-budgeting b/addons/OCA_account-budgeting
new file mode 160000
index 0000000..e175ffa
--- /dev/null
+++ b/addons/OCA_account-budgeting
@@ -0,0 +1 @@
+Subproject commit e175ffa84fb61f70de67a2732292e43bd490cefd
diff --git a/addons/OCA_account-closing b/addons/OCA_account-closing
new file mode 160000
index 0000000..40d40c7
--- /dev/null
+++ b/addons/OCA_account-closing
@@ -0,0 +1 @@
+Subproject commit 40d40c73574bf65c91c879e0607b4ac455df06b2
diff --git a/addons/OCA_account-consolidation b/addons/OCA_account-consolidation
new file mode 160000
index 0000000..741fc50
--- /dev/null
+++ b/addons/OCA_account-consolidation
@@ -0,0 +1 @@
+Subproject commit 741fc50366bd70fceb88a2a3fcb0449b2582ed31
diff --git a/addons/OCA_account-financial-reporting b/addons/OCA_account-financial-reporting
new file mode 160000
index 0000000..1e0f830
--- /dev/null
+++ b/addons/OCA_account-financial-reporting
@@ -0,0 +1 @@
+Subproject commit 1e0f8301ca015b3c4c456401bc30c5f211ccae3f
diff --git a/addons/OCA_account-financial-tools b/addons/OCA_account-financial-tools
new file mode 160000
index 0000000..9721abd
--- /dev/null
+++ b/addons/OCA_account-financial-tools
@@ -0,0 +1 @@
+Subproject commit 9721abd4c9db653e1d009f8a023e9f750523989f
diff --git a/addons/OCA_account-fiscal-rule b/addons/OCA_account-fiscal-rule
new file mode 160000
index 0000000..f396ba6
--- /dev/null
+++ b/addons/OCA_account-fiscal-rule
@@ -0,0 +1 @@
+Subproject commit f396ba6a2e2acebaaff579f0e6991b669812d64d
diff --git a/addons/OCA_account-invoice-reporting b/addons/OCA_account-invoice-reporting
new file mode 160000
index 0000000..320dd9f
--- /dev/null
+++ b/addons/OCA_account-invoice-reporting
@@ -0,0 +1 @@
+Subproject commit 320dd9fce4d212b2dcf5dc4447494964ad1e246d
diff --git a/addons/OCA_account-invoicing b/addons/OCA_account-invoicing
new file mode 160000
index 0000000..9db1c10
--- /dev/null
+++ b/addons/OCA_account-invoicing
@@ -0,0 +1 @@
+Subproject commit 9db1c104341f422b8545c3f2906d83bcb69d46ac
diff --git a/addons/OCA_account-payment b/addons/OCA_account-payment
new file mode 160000
index 0000000..888debe
--- /dev/null
+++ b/addons/OCA_account-payment
@@ -0,0 +1 @@
+Subproject commit 888debebd8e42c1ee5107577ca2f3bc5f38d72e1
diff --git a/addons/OCA_account-reconcile b/addons/OCA_account-reconcile
new file mode 160000
index 0000000..0390b11
--- /dev/null
+++ b/addons/OCA_account-reconcile
@@ -0,0 +1 @@
+Subproject commit 0390b112def3d362d95232d382317511616ee6dd
diff --git a/addons/OCA_apps-store b/addons/OCA_apps-store
new file mode 160000
index 0000000..022d24d
--- /dev/null
+++ b/addons/OCA_apps-store
@@ -0,0 +1 @@
+Subproject commit 022d24db4c6463f38b9f4452fe03c9fb8b3a44ce
diff --git a/addons/OCA_bank-payment b/addons/OCA_bank-payment
new file mode 160000
index 0000000..7e0e572
--- /dev/null
+++ b/addons/OCA_bank-payment
@@ -0,0 +1 @@
+Subproject commit 7e0e572fb4772c8ebacfe52d58c396bdbd9e01f9
diff --git a/addons/OCA_bank-statement-import b/addons/OCA_bank-statement-import
new file mode 160000
index 0000000..1983065
--- /dev/null
+++ b/addons/OCA_bank-statement-import
@@ -0,0 +1 @@
+Subproject commit 198306503b51371c8603fd8defef65fcd82bf954
diff --git a/addons/OCA_brand b/addons/OCA_brand
new file mode 160000
index 0000000..601a8c5
--- /dev/null
+++ b/addons/OCA_brand
@@ -0,0 +1 @@
+Subproject commit 601a8c5c741b3035000f2337feab16325e6b9a49
diff --git a/addons/OCA_business-requirement b/addons/OCA_business-requirement
new file mode 160000
index 0000000..dd74e74
--- /dev/null
+++ b/addons/OCA_business-requirement
@@ -0,0 +1 @@
+Subproject commit dd74e74583861b44c6120473ba0b56c90b887334
diff --git a/addons/OCA_commission b/addons/OCA_commission
new file mode 160000
index 0000000..e679120
--- /dev/null
+++ b/addons/OCA_commission
@@ -0,0 +1 @@
+Subproject commit e679120a6d8f910cba81d949ecddd7b89f48fc01
diff --git a/addons/OCA_community-data-files b/addons/OCA_community-data-files
new file mode 160000
index 0000000..2b17e55
--- /dev/null
+++ b/addons/OCA_community-data-files
@@ -0,0 +1 @@
+Subproject commit 2b17e5567d1bcb8ca377268615f209fdd57dc66e
diff --git a/addons/OCA_connector-telephony b/addons/OCA_connector-telephony
new file mode 160000
index 0000000..6d9df10
--- /dev/null
+++ b/addons/OCA_connector-telephony
@@ -0,0 +1 @@
+Subproject commit 6d9df1037a97dbf791a7f0a717846a63144174bb
diff --git a/addons/OCA_contract b/addons/OCA_contract
new file mode 160000
index 0000000..3e53134
--- /dev/null
+++ b/addons/OCA_contract
@@ -0,0 +1 @@
+Subproject commit 3e531348cb51aeb2cc16c16ab8a2b693756ba47f
diff --git a/addons/OCA_credit-control b/addons/OCA_credit-control
new file mode 160000
index 0000000..a97496a
--- /dev/null
+++ b/addons/OCA_credit-control
@@ -0,0 +1 @@
+Subproject commit a97496a829cadc0d9be07d7825e93062417ab670
diff --git a/addons/OCA_currency b/addons/OCA_currency
new file mode 160000
index 0000000..5c0d54e
--- /dev/null
+++ b/addons/OCA_currency
@@ -0,0 +1 @@
+Subproject commit 5c0d54e37789ecc24bebbe53fa56a92a492575bb
diff --git a/addons/OCA_data-protection b/addons/OCA_data-protection
new file mode 160000
index 0000000..ce4f334
--- /dev/null
+++ b/addons/OCA_data-protection
@@ -0,0 +1 @@
+Subproject commit ce4f334a1077b5c15d457f22daaa48b9f639409e
diff --git a/addons/OCA_donation b/addons/OCA_donation
new file mode 160000
index 0000000..aa6478a
--- /dev/null
+++ b/addons/OCA_donation
@@ -0,0 +1 @@
+Subproject commit aa6478a72c9673ad6458de19aa2362397c613fae
diff --git a/addons/OCA_e-commerce b/addons/OCA_e-commerce
new file mode 160000
index 0000000..d7c99e5
--- /dev/null
+++ b/addons/OCA_e-commerce
@@ -0,0 +1 @@
+Subproject commit d7c99e565f25b495b3c0d252f181d8df4490a757
diff --git a/addons/OCA_edi b/addons/OCA_edi
new file mode 160000
index 0000000..742b131
--- /dev/null
+++ b/addons/OCA_edi
@@ -0,0 +1 @@
+Subproject commit 742b1316773f8a1b224e42c65c3c3a7685481a30
diff --git a/addons/OCA_event b/addons/OCA_event
new file mode 160000
index 0000000..e2bdf12
--- /dev/null
+++ b/addons/OCA_event
@@ -0,0 +1 @@
+Subproject commit e2bdf12c61e9967eeb9abc618c79ca43b464ea7f
diff --git a/addons/OCA_helpdesk b/addons/OCA_helpdesk
new file mode 160000
index 0000000..b53696d
--- /dev/null
+++ b/addons/OCA_helpdesk
@@ -0,0 +1 @@
+Subproject commit b53696d21efbda2ae9ca97bcd529e89d79e3efb4
diff --git a/addons/OCA_hr b/addons/OCA_hr
new file mode 160000
index 0000000..4743acf
--- /dev/null
+++ b/addons/OCA_hr
@@ -0,0 +1 @@
+Subproject commit 4743acf7ab796ea3738743a44c62cd516126ec53
diff --git a/addons/OCA_knowledge b/addons/OCA_knowledge
new file mode 160000
index 0000000..9ae45f7
--- /dev/null
+++ b/addons/OCA_knowledge
@@ -0,0 +1 @@
+Subproject commit 9ae45f798bbefa854b03f612e22291ac1b95568d
diff --git a/addons/OCA_l10n-canada b/addons/OCA_l10n-canada
new file mode 160000
index 0000000..5680b48
--- /dev/null
+++ b/addons/OCA_l10n-canada
@@ -0,0 +1 @@
+Subproject commit 5680b485cdfa0b6f1c2f4e32356b5938a9752c00
diff --git a/addons/OCA_maintenance b/addons/OCA_maintenance
new file mode 160000
index 0000000..4e521ec
--- /dev/null
+++ b/addons/OCA_maintenance
@@ -0,0 +1 @@
+Subproject commit 4e521ec35f6e8b66f86a62db644dadc9206b476e
diff --git a/addons/OCA_management-system b/addons/OCA_management-system
new file mode 160000
index 0000000..479afcc
--- /dev/null
+++ b/addons/OCA_management-system
@@ -0,0 +1 @@
+Subproject commit 479afcc65ee29530e2bcaa7342f93b6783d14d97
diff --git a/addons/OCA_manufacture b/addons/OCA_manufacture
new file mode 160000
index 0000000..ce36844
--- /dev/null
+++ b/addons/OCA_manufacture
@@ -0,0 +1 @@
+Subproject commit ce36844281754a75b527c4ace21837c8a16b75ab
diff --git a/addons/OCA_margin-analysis b/addons/OCA_margin-analysis
new file mode 160000
index 0000000..4a50437
--- /dev/null
+++ b/addons/OCA_margin-analysis
@@ -0,0 +1 @@
+Subproject commit 4a50437ecfa591a72e12255448d38d0fb1037a42
diff --git a/addons/OCA_mis-builder b/addons/OCA_mis-builder
new file mode 160000
index 0000000..5d76972
--- /dev/null
+++ b/addons/OCA_mis-builder
@@ -0,0 +1 @@
+Subproject commit 5d7697296ad90794599373940e6fc6cead8ca1a2
diff --git a/addons/OCA_multi-company b/addons/OCA_multi-company
new file mode 160000
index 0000000..fdb4d25
--- /dev/null
+++ b/addons/OCA_multi-company
@@ -0,0 +1 @@
+Subproject commit fdb4d255b6a3b51925f8a226bfebf2eccabd2786
diff --git a/addons/OCA_partner-contact b/addons/OCA_partner-contact
new file mode 160000
index 0000000..a79e576
--- /dev/null
+++ b/addons/OCA_partner-contact
@@ -0,0 +1 @@
+Subproject commit a79e57685caad7d0dec9318378fdd46862e31be4
diff --git a/addons/OCA_pos b/addons/OCA_pos
new file mode 160000
index 0000000..6a922b3
--- /dev/null
+++ b/addons/OCA_pos
@@ -0,0 +1 @@
+Subproject commit 6a922b3d87491d59128a097f286be1e3f3fc11df
diff --git a/addons/OCA_product-attribute b/addons/OCA_product-attribute
new file mode 160000
index 0000000..ea48097
--- /dev/null
+++ b/addons/OCA_product-attribute
@@ -0,0 +1 @@
+Subproject commit ea48097094462e67d7e1558b333da78c6038b89c
diff --git a/addons/OCA_product-pack b/addons/OCA_product-pack
new file mode 160000
index 0000000..b9eccbd
--- /dev/null
+++ b/addons/OCA_product-pack
@@ -0,0 +1 @@
+Subproject commit b9eccbdb9ae0fdd3ed1138270c3eff3142a015c3
diff --git a/addons/OCA_product-variant b/addons/OCA_product-variant
new file mode 160000
index 0000000..fb4f404
--- /dev/null
+++ b/addons/OCA_product-variant
@@ -0,0 +1 @@
+Subproject commit fb4f4042b3ca0ee6cde6ab0625e2c914b96b174f
diff --git a/addons/OCA_project b/addons/OCA_project
new file mode 160000
index 0000000..4390f1f
--- /dev/null
+++ b/addons/OCA_project
@@ -0,0 +1 @@
+Subproject commit 4390f1ffa9f00058b0d1aa7fae27fb74bbefb83b
diff --git a/addons/OCA_project-reporting b/addons/OCA_project-reporting
new file mode 160000
index 0000000..7f71f08
--- /dev/null
+++ b/addons/OCA_project-reporting
@@ -0,0 +1 @@
+Subproject commit 7f71f086dd732170e7605dfdf80e6cc4969a711e
diff --git a/addons/OCA_purchase-workflow b/addons/OCA_purchase-workflow
new file mode 160000
index 0000000..d174367
--- /dev/null
+++ b/addons/OCA_purchase-workflow
@@ -0,0 +1 @@
+Subproject commit d17436791bcfbe0985af137163564af3fe90bbe1
diff --git a/addons/OCA_queue b/addons/OCA_queue
new file mode 160000
index 0000000..0b71a39
--- /dev/null
+++ b/addons/OCA_queue
@@ -0,0 +1 @@
+Subproject commit 0b71a3951b583f154f170adacf4920e6d7138329
diff --git a/addons/OCA_reporting-engine b/addons/OCA_reporting-engine
new file mode 160000
index 0000000..14fba65
--- /dev/null
+++ b/addons/OCA_reporting-engine
@@ -0,0 +1 @@
+Subproject commit 14fba657a0dbda1258edcf3c92886866e7cecf67
diff --git a/addons/OCA_sale-workflow b/addons/OCA_sale-workflow
new file mode 160000
index 0000000..4b20035
--- /dev/null
+++ b/addons/OCA_sale-workflow
@@ -0,0 +1 @@
+Subproject commit 4b200358312689d944aaaf012c5723bb2bc9cb77
diff --git a/addons/OCA_server-auth b/addons/OCA_server-auth
new file mode 160000
index 0000000..f911c9f
--- /dev/null
+++ b/addons/OCA_server-auth
@@ -0,0 +1 @@
+Subproject commit f911c9f31a064cca3012431b70e60a7b89448138
diff --git a/addons/OCA_server-brand b/addons/OCA_server-brand
new file mode 160000
index 0000000..d8f27b0
--- /dev/null
+++ b/addons/OCA_server-brand
@@ -0,0 +1 @@
+Subproject commit d8f27b04475d3cc74a7bebb1e086f647f5e01569
diff --git a/addons/OCA_server-env b/addons/OCA_server-env
new file mode 160000
index 0000000..19af535
--- /dev/null
+++ b/addons/OCA_server-env
@@ -0,0 +1 @@
+Subproject commit 19af535b3aedd5c1fdfbe911dacfc43ae31edb71
diff --git a/addons/OCA_server-tools b/addons/OCA_server-tools
new file mode 160000
index 0000000..d97aaa9
--- /dev/null
+++ b/addons/OCA_server-tools
@@ -0,0 +1 @@
+Subproject commit d97aaa9fa2f01f64ebf7100668e0901fde35d42f
diff --git a/addons/OCA_server-ux b/addons/OCA_server-ux
new file mode 160000
index 0000000..655b3cc
--- /dev/null
+++ b/addons/OCA_server-ux
@@ -0,0 +1 @@
+Subproject commit 655b3cc291a7e3718371a45ebe6f2e0952896adf
diff --git a/addons/OCA_social b/addons/OCA_social
new file mode 160000
index 0000000..7b0836b
--- /dev/null
+++ b/addons/OCA_social
@@ -0,0 +1 @@
+Subproject commit 7b0836bf7a5c40db332dd90d5ebef619234060ac
diff --git a/addons/OCA_stock-logistics-warehouse b/addons/OCA_stock-logistics-warehouse
new file mode 160000
index 0000000..a591de1
--- /dev/null
+++ b/addons/OCA_stock-logistics-warehouse
@@ -0,0 +1 @@
+Subproject commit a591de15150f7b16c1ef23d2fc30c814874dea27
diff --git a/addons/OCA_timesheet b/addons/OCA_timesheet
new file mode 160000
index 0000000..8625e65
--- /dev/null
+++ b/addons/OCA_timesheet
@@ -0,0 +1 @@
+Subproject commit 8625e65414801780c91e91bf93b2ed32567f8117
diff --git a/addons/OCA_web b/addons/OCA_web
new file mode 160000
index 0000000..b65c492
--- /dev/null
+++ b/addons/OCA_web
@@ -0,0 +1 @@
+Subproject commit b65c492f4011fe4e9dac8c0a26eeef8c43cb1c39
diff --git a/addons/OCA_website b/addons/OCA_website
new file mode 160000
index 0000000..ee5daaa
--- /dev/null
+++ b/addons/OCA_website
@@ -0,0 +1 @@
+Subproject commit ee5daaa970e8e98c940d687b39a9edfb7ed8859b
diff --git a/addons/OCA_wms b/addons/OCA_wms
new file mode 160000
index 0000000..e7a1541
--- /dev/null
+++ b/addons/OCA_wms
@@ -0,0 +1 @@
+Subproject commit e7a1541f8c513cf755bd82780c6c035d2fafc2ce
diff --git a/addons/Smile-SA_odoo_addons b/addons/Smile-SA_odoo_addons
new file mode 160000
index 0000000..2be318c
--- /dev/null
+++ b/addons/Smile-SA_odoo_addons
@@ -0,0 +1 @@
+Subproject commit 2be318c18ac5b0fe2129cc61d86419033ff07d5f
diff --git a/addons/addons/.gitkeep b/addons/addons/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/addons/addons/erplibre_base/__init__.py b/addons/addons/erplibre_base/__init__.py
new file mode 100644
index 0000000..ef5ae35
--- /dev/null
+++ b/addons/addons/erplibre_base/__init__.py
@@ -0,0 +1 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
diff --git a/addons/addons/erplibre_base/__manifest__.py b/addons/addons/erplibre_base/__manifest__.py
new file mode 100644
index 0000000..8c98323
--- /dev/null
+++ b/addons/addons/erplibre_base/__manifest__.py
@@ -0,0 +1,40 @@
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+{
+ 'name': 'ERPLibre base',
+ 'version': '0.1',
+ 'author': "ERPLibre",
+ 'website': 'https://erplibre.ca',
+ 'license': 'AGPL-3',
+ 'category': 'Human Resources',
+ 'summary': 'INSTALL my base',
+ 'description': """
+ERPLibreBase
+===============
+
+""",
+ 'depends': [
+ # Custom ERPLibre
+ # OCA
+ 'web_responsive',
+
+ # OCA server-brand
+ 'disable_odoo_online',
+ 'remove_odoo_enterprise',
+
+ # OCA website
+ 'website_odoo_debranding',
+ 'website_no_crawler',
+
+ # Server-tools
+ 'fetchmail_notify_error_to_sender',
+
+ # Social
+ 'mail_debrand',
+
+ # Partner
+ 'partner_quebec_tz',
+ ],
+ 'data': [],
+ 'installable': True,
+}
diff --git a/addons/addons/erplibre_base/static/description/icon.png b/addons/addons/erplibre_base/static/description/icon.png
new file mode 100644
index 0000000..8489202
Binary files /dev/null and b/addons/addons/erplibre_base/static/description/icon.png differ
diff --git a/addons/addons/erplibre_base/static/description/index.html b/addons/addons/erplibre_base/static/description/index.html
new file mode 100644
index 0000000..ff5d662
--- /dev/null
+++ b/addons/addons/erplibre_base/static/description/index.html
@@ -0,0 +1,485 @@
+
+
+
+
+
+ MathBenTechBase
+
+
+
+
+
MathBenTechBase
+
+
+
+
+
+
diff --git a/addons/addons/erplibre_base_enterprise/__init__.py b/addons/addons/erplibre_base_enterprise/__init__.py
new file mode 100644
index 0000000..ef5ae35
--- /dev/null
+++ b/addons/addons/erplibre_base_enterprise/__init__.py
@@ -0,0 +1 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
diff --git a/addons/addons/erplibre_base_enterprise/__manifest__.py b/addons/addons/erplibre_base_enterprise/__manifest__.py
new file mode 100644
index 0000000..3d1999f
--- /dev/null
+++ b/addons/addons/erplibre_base_enterprise/__manifest__.py
@@ -0,0 +1,84 @@
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+{
+ 'name': 'ERPLibre base enterprise',
+ 'version': '0.1',
+ 'author': "ERPLibre",
+ 'website': 'https://erplibre.ca',
+ 'license': 'AGPL-3',
+ 'category': 'Human Resources',
+ 'summary': 'INSTALL my base enterprise',
+ 'description': """
+ERPLibreBase
+===============
+
+""",
+ 'depends': [
+ # Custom ERPLibre
+ 'erplibre_base',
+
+ 'hr_expense_associate_with_customer',
+ 'hr_expense_tip',
+
+ 'sale_order_line_limit',
+
+ 'res_partner_fix_group_by_company',
+ 'configure_quebec_tax',
+ 'crm_filter_all',
+ 'sale_degroup_tax',
+
+ 'helpdesk_mailing_list',
+
+ # Odoo base
+ 'account',
+
+ 'board',
+
+ 'contacts',
+
+ 'crm',
+
+ 'portal',
+
+ 'payment',
+ 'payment_transfer',
+
+ 'project',
+
+ 'purchase',
+
+ 'hr',
+ 'hr_expense',
+ 'hr_org_chart',
+
+ 'website',
+ 'website_crm',
+
+ 'sale',
+ 'sale_management',
+ 'stock',
+
+ # OCA
+ 'website_form_builder',
+ 'website_snippet_anchor',
+ 'partner_no_vat',
+
+ # Numigi
+ 'project_chatter',
+ # 'project_iteration',
+
+ # Canada
+ 'l10n_ca',
+
+ # Scrummer
+ 'project_agile_sale_timesheet',
+ 'scrummer',
+ 'scrummer_kanban',
+ 'scrummer_scrum',
+ 'scrummer_workflow_security',
+ 'scrummer_workflow_transition_by_project',
+ 'scrummer_workflow_transitions_by_task_type',
+ ],
+ 'data': [],
+ 'installable': True,
+}
diff --git a/addons/addons/erplibre_base_enterprise/static/description/icon.png b/addons/addons/erplibre_base_enterprise/static/description/icon.png
new file mode 100644
index 0000000..8489202
Binary files /dev/null and b/addons/addons/erplibre_base_enterprise/static/description/icon.png differ
diff --git a/addons/addons/erplibre_base_enterprise/static/description/index.html b/addons/addons/erplibre_base_enterprise/static/description/index.html
new file mode 100644
index 0000000..d9f321d
--- /dev/null
+++ b/addons/addons/erplibre_base_enterprise/static/description/index.html
@@ -0,0 +1,485 @@
+
+
+
+
+
+ MathBenTechBaseEnterprise
+
+
+
+
+
MathBenTechBaseEnterprise
+
+
+
+
+
+
diff --git a/addons/addons/erplibre_base_entreprise_mrp/__init__.py b/addons/addons/erplibre_base_entreprise_mrp/__init__.py
new file mode 100644
index 0000000..ef5ae35
--- /dev/null
+++ b/addons/addons/erplibre_base_entreprise_mrp/__init__.py
@@ -0,0 +1 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
diff --git a/addons/addons/erplibre_base_entreprise_mrp/__manifest__.py b/addons/addons/erplibre_base_entreprise_mrp/__manifest__.py
new file mode 100644
index 0000000..e7c3f7a
--- /dev/null
+++ b/addons/addons/erplibre_base_entreprise_mrp/__manifest__.py
@@ -0,0 +1,118 @@
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+{
+ 'name': 'ERPLibre base entreprise MRP',
+ 'version': '0.1',
+ 'author': "ERPLibre",
+ 'website': 'https://erplibre.ca',
+ 'license': 'AGPL-3',
+ 'category': 'Human Resources',
+ 'summary': 'INSTALL my base entreprise MRP',
+ 'description': """
+ERPLibreBase
+===============
+
+""",
+ 'depends': [
+ # Custom ERPLibre
+ 'erplibre_base',
+
+ 'res_partner_fix_group_by_company',
+ 'crm_filter_all',
+
+ 'website_helpdesk',
+ 'website_portal_contact',
+ 'website_portal_address',
+ 'product_manufacturer_model',
+ 'helpdesk_mailing_list',
+ 'helpdesk_join_team',
+
+ # Odoo base
+ 'account',
+
+ 'board',
+
+ 'contacts',
+
+ 'crm',
+
+ 'portal',
+
+ 'payment',
+ 'payment_transfer',
+
+ 'project',
+
+ 'website',
+ 'website_crm',
+
+ # OCA
+ 'website_form_builder',
+ 'website_snippet_anchor',
+ 'partner_no_vat',
+ 'helpdesk_mgmt',
+ 'helpdesk_service_call',
+ 'helpdesk_supplier',
+
+ # Numigi
+ 'project_chatter',
+ # 'project_iteration',
+
+ # Canada
+ 'l10n_ca',
+
+ # Scrummer
+ 'project_agile_sale_timesheet',
+ 'scrummer',
+ 'scrummer_kanban',
+ 'scrummer_scrum',
+ 'scrummer_workflow_security',
+ 'scrummer_workflow_transition_by_project',
+ 'scrummer_workflow_transitions_by_task_type',
+
+ # OCA helpdesk
+ 'helpdesk_mgmt',
+
+ # OCA manufacture
+ 'mrp_auto_assign',
+ 'mrp_bom_component_menu',
+ 'mrp_bom_line_sequence',
+ 'mrp_bom_location',
+ 'mrp_bom_tracking',
+ 'mrp_multi_level',
+ 'mrp_multi_level_estimate',
+ 'mrp_production_putaway_strategy',
+ 'mrp_production_request',
+ 'mrp_production_auto_post_inventory',
+ 'mrp_production_grouped_by_product',
+ 'mrp_stock_orderpoint_manual_procurement',
+ 'mrp_unbuild_tracked_raw_material',
+ 'mrp_workorder_sequence',
+ 'repair_refurbish',
+
+ # OCA stock-logistics-warehouse
+ 'mrp_warehouse_calendar',
+ 'stock_available_mrp',
+ 'stock_orderpoint_mrp_link',
+
+ # OCA contract
+ 'agreement_mrp',
+
+ # OCA account-analytic
+ 'mrp_analytic',
+
+ # ODOO S.A.
+ 'mrp',
+ 'helpdesk_mrp',
+ 'mrp_byproduct',
+ 'mrp_workcenters_machines',
+ 'product_mrp_info',
+ 'purchase_mrp',
+ 'sale_mrp',
+ 'mrp_bom_cost',
+ 'res_partner_supplier_own_mrp_work_centers',
+
+ ],
+ 'data': [],
+ 'installable': True,
+}
diff --git a/addons/addons/erplibre_base_entreprise_mrp/static/description/icon.png b/addons/addons/erplibre_base_entreprise_mrp/static/description/icon.png
new file mode 100644
index 0000000..8489202
Binary files /dev/null and b/addons/addons/erplibre_base_entreprise_mrp/static/description/icon.png differ
diff --git a/addons/addons/erplibre_base_entreprise_mrp/static/description/index.html b/addons/addons/erplibre_base_entreprise_mrp/static/description/index.html
new file mode 100644
index 0000000..af14009
--- /dev/null
+++ b/addons/addons/erplibre_base_entreprise_mrp/static/description/index.html
@@ -0,0 +1,485 @@
+
+
+
+
+
+ MathBenTechBaseHackaton
+
+
+
+
+
MathBenTechBaseHackaton
+
+
+
+
+
+
diff --git a/addons/addons/erplibre_base_hackaton/__init__.py b/addons/addons/erplibre_base_hackaton/__init__.py
new file mode 100644
index 0000000..ef5ae35
--- /dev/null
+++ b/addons/addons/erplibre_base_hackaton/__init__.py
@@ -0,0 +1 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
diff --git a/addons/addons/erplibre_base_hackaton/__manifest__.py b/addons/addons/erplibre_base_hackaton/__manifest__.py
new file mode 100644
index 0000000..a294972
--- /dev/null
+++ b/addons/addons/erplibre_base_hackaton/__manifest__.py
@@ -0,0 +1,73 @@
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+{
+ 'name': 'ERPLibre base hackaton',
+ 'version': '0.1',
+ 'author': "ERPLibre",
+ 'website': 'https://erplibre.ca',
+ 'license': 'AGPL-3',
+ 'category': 'Human Resources',
+ 'summary': 'INSTALL my base hackaton',
+ 'description': """
+ERPLibreBase
+===============
+
+""",
+ 'depends': [
+ # Custom ERPLibre
+ 'erplibre_base',
+
+ 'res_partner_fix_group_by_company',
+ 'crm_filter_all',
+
+ 'helpdesk_service_call',
+ 'website_helpdesk',
+ 'website_portal_contact',
+ 'website_portal_address',
+
+ # Odoo base
+ 'account',
+
+ 'board',
+
+ 'contacts',
+
+ 'crm',
+
+ 'portal',
+
+ 'payment',
+ 'payment_transfer',
+
+ 'project',
+
+ 'website',
+ 'website_crm',
+
+ # OCA
+ 'website_form_builder',
+ 'website_snippet_anchor',
+ 'partner_no_vat',
+
+ # Numigi
+ 'project_chatter',
+ # 'project_iteration',
+
+ # Canada
+ 'l10n_ca',
+
+ # Scrummer
+ 'project_agile_sale_timesheet',
+ 'scrummer',
+ 'scrummer_kanban',
+ 'scrummer_scrum',
+ 'scrummer_workflow_security',
+ 'scrummer_workflow_transition_by_project',
+ 'scrummer_workflow_transitions_by_task_type',
+
+ # OCA helpdesk
+ 'helpdesk_mgmt',
+ ],
+ 'data': [],
+ 'installable': True,
+}
diff --git a/addons/addons/erplibre_base_hackaton/static/description/icon.png b/addons/addons/erplibre_base_hackaton/static/description/icon.png
new file mode 100644
index 0000000..8489202
Binary files /dev/null and b/addons/addons/erplibre_base_hackaton/static/description/icon.png differ
diff --git a/addons/addons/erplibre_base_hackaton/static/description/index.html b/addons/addons/erplibre_base_hackaton/static/description/index.html
new file mode 100644
index 0000000..af14009
--- /dev/null
+++ b/addons/addons/erplibre_base_hackaton/static/description/index.html
@@ -0,0 +1,485 @@
+
+
+
+
+
+ MathBenTechBaseHackaton
+
+
+
+
+
MathBenTechBaseHackaton
+
+
+
+
+
+
diff --git a/addons/addons/erplibre_enterprise_services_for_utility_business/__init__.py b/addons/addons/erplibre_enterprise_services_for_utility_business/__init__.py
new file mode 100644
index 0000000..4cdf2e8
--- /dev/null
+++ b/addons/addons/erplibre_enterprise_services_for_utility_business/__init__.py
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
diff --git a/addons/addons/erplibre_enterprise_services_for_utility_business/__manifest__.py b/addons/addons/erplibre_enterprise_services_for_utility_business/__manifest__.py
new file mode 100644
index 0000000..8afff61
--- /dev/null
+++ b/addons/addons/erplibre_enterprise_services_for_utility_business/__manifest__.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+{
+ 'name': 'ERPLibre Enterprise Services for utility business',
+ 'version': '0.1',
+ 'author': "ERPLibre",
+ 'website': 'https://erplibre.ca',
+ 'license': 'AGPL-3',
+ 'category': 'Other',
+ 'summary': 'Services for utility business',
+ 'description': """
+ERPLibre Enterprise Services for utility business
+====================================================
+All modules needed for enterprise with services for utility business.
+""",
+ 'depends': [
+ # ERPLibre
+ 'erplibre_base_enterprise',
+
+ # Custom ERPLibre
+ 'product_lump_sum',
+ # 'sale_margin_percent',
+ 'sale_report_margin',
+ 'sale_order_margin_percent',
+ 'sale_margin_security',
+ 'sale_product_manufacturer',
+ 'sale_product_manufacturer_model',
+ # 'sale_hide_tax_sale_order_lines', # Bug
+ 'sale_crm_auto_update_lead',
+ 'crm_marge',
+ 'menu_force_project_first',
+ 'crm_working_date',
+ 'helpdesk_service_call',
+ 'website_helpdesk',
+ 'website_portal_contact',
+ 'website_portal_address',
+
+ # OCA sale-workflow
+ 'sale_order_revision',
+ 'sale_double_validation',
+
+ # OCA helpdesk
+ 'helpdesk_mgmt',
+
+ # General
+ 'digest', # KPI
+ ],
+ 'data': [],
+ 'installable': True,
+}
diff --git a/addons/addons/erplibre_enterprise_services_for_utility_business/i18n/fr_CA.po b/addons/addons/erplibre_enterprise_services_for_utility_business/i18n/fr_CA.po
new file mode 100644
index 0000000..bfd6e20
--- /dev/null
+++ b/addons/addons/erplibre_enterprise_services_for_utility_business/i18n/fr_CA.po
@@ -0,0 +1,257 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * sale
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-12-09 22:55+0000\n"
+"PO-Revision-Date: 2019-12-09 22:55+0000\n"
+"Last-Translator: Alexandre Ferreira Benevides \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.sale_order_view_search_inherit_quotation
+msgid "My Quotations"
+msgstr "Mes Soumissions"
+
+#. module: sale
+#: model:ir.model.fields,field_description:sale.field_sale_order__client_order_ref
+msgid "Customer Reference"
+msgstr "Ref. client (PO)"
+
+#. module: sale_cancel_reason
+#: model:sale.order.cancel.reason,name:sale_cancel_reason.cancel_reason_only_quotation
+msgid "Just for Quotation"
+msgstr "Uniquement pour la soumission"
+
+#. module: purchase
+#: model:mail.template,body_html:purchase.email_template_edi_purchase
+msgid ""
+"\n"
+"
\n"
+" Dear ${object.partner_id.name}\n"
+" % if object.partner_id.parent_id:\n"
+" (${object.partner_id.parent_id.name})\n"
+" % endif\n"
+"
\n"
+" Here is in attachment a request for quotation ${object.name}\n"
+" % if object.partner_ref:\n"
+" with reference: ${object.partner_ref}\n"
+" % endif\n"
+" from ${object.company_id.name}.\n"
+"
\n"
+" If you have any questions, please do not hesitate to contact us.\n"
+"
\n"
+" Best regards,\n"
+"
\n"
+"
"
+msgstr ""
+"\n"
+"
\n"
+" Cher(e) ${object.partner_id.name}\n"
+" % if object.partner_id.parent_id:\n"
+" (${object.partner_id.parent_id.name})\n"
+" % endif\n"
+"
\n"
+" Vous trouverez en pièce jointe une demande de soumission ${object.name}\n"
+" % if object.partner_ref:\n"
+" with reference: ${object.partner_ref}\n"
+" % endif\n"
+" de ${object.company_id.name}.\n"
+"
\n"
+" N'hésitez pas à nous contacter si vous avez des questions.\n"
+"
\n"
+" Salutations,\n"
+"
\n"
+"
"
+
+#. module: sale_order_revision
+#: model_terms:ir.ui.view,arch_db:sale_order_revision.view_order_form
+msgid "New Revision of Quotation"
+msgstr "Nouvelle version de la soumission"
+
+#. module: sale_product_set
+#: model_terms:ir.ui.view,arch_db:sale_product_set.product_set_add_form_view
+msgid "Add set in sale order line"
+msgstr "Ajout d'un Set à la soumission"
+
+#. module: crm
+#: model:mail.activity.type,name:crm.mail_activity_demo_followup_quote
+msgid "Follow-up Quote"
+msgstr "Faire suivi de soumission"
+
+#. module: crm
+#: model:mail.activity.type,name:crm.mail_activity_demo_make_quote
+msgid "Make Quote"
+msgstr "Faire soumission"
+
+#. module: crm
+#: model_terms:ir.actions.act_window,help:crm.crm_case_form_view_salesteams_opportunity
+msgid ""
+"You will be able to plan meetings and phone calls from\n"
+" opportunities, convert them into quotations, attach related\n"
+" documents, track all discussions, and much more."
+msgstr ""
+"Vous serez en mesure de planifier des réunions et des appels provenant\n"
+" d'opportunités, de les convertir en soumissions, de joindre des documents\n"
+" connexes, de suivre toutes les discussions et bien plus encore."
+
+#. module: hr
+#: model_terms:hr.job,website_description:hr.job_consultant
+msgid "Analyse needs, write specification documents and quotation"
+msgstr ""
+"Analyser des besoins, écrire des documents de spécification et des soumissions"
+
+#. module: hr
+#: model_terms:hr.job,website_description:hr.job_consultant
+msgid ""
+"We are looking for a motivated and results-driven Functional Consultant! You"
+" will take part in the consulting services we provide to our partners and "
+"customers, on the functional side. Your job start from the quotation to the "
+"customer to the delivery to the customer. You listen the customer and try to"
+" give him the best service. You report to the head of consulting service and"
+" will be coached by a senior consultant."
+msgstr ""
+"Nous sommes à la recherche d'un consultant fonctionnel motivé et axé sur les"
+" résultats ! Vous prendrez part aux services de consultation de niveau "
+"fonctionnel que nous offrons à nos partenaires et clients. Votre travail "
+"débute à la production de soumissions pour les clients et se poursuit jusqu'à la "
+"livraison. Vous êtes à l'écoute du client et lui fournissez le meilleur "
+"service. Vous rapportez au chef du service de consultation et serez formé "
+"par un consultant senior."
+
+#. module: purchase_requisition
+#: code:addons/purchase_requisition/models/purchase_requisition.py:116
+#, python-format
+msgid "Cancelled by the agreement associated to this quotation."
+msgstr "Annulé par le contrat associé à cette soumission."
+
+#. module: purchase_requisition
+#: model_terms:ir.ui.view,arch_db:purchase_requisition.view_purchase_requisition_type_form
+msgid "Data for new quotations"
+msgstr "Données pour nouvelles soumissions"
+
+#. module: purchase_requisition
+#: selection:purchase.requisition.type,line_copy:0
+msgid "Do not create RfQ lines automatically"
+msgstr "Ne pas créer de lignes de demande de soumission automatiquement"
+
+#. module: purchase_requisition
+#: model_terms:ir.actions.act_window,help:purchase_requisition.action_purchase_requisition
+msgid ""
+"In a call for tenders, you can record the products you need to buy\n"
+" and generate the creation of RfQs to vendors. Once the tenders have\n"
+" been registered, you can review and compare them and you can\n"
+" validate some and cancel others."
+msgstr ""
+"Dans le cas d'un appel d'offres, vous pouvez enregistrer les produits que vous souhaitez acheter\n"
+" et générer des demandes de soumission pour les fournisseurs. Une fois les offres\n"
+" enregistrées, vous pouvez les examiner et les comparer, puis en\n"
+" valider certaines et annuler les autres."
+
+#. module: purchase_requisition
+#: model_terms:ir.ui.view,arch_db:purchase_requisition.view_purchase_requisition_form
+msgid "New Quotation"
+msgstr "Nouvelle soumission"
+
+#. module: purchase_requisition
+#: model_terms:ir.ui.view,arch_db:purchase_requisition.view_purchase_requisition_form
+msgid "RFQs/Orders"
+msgstr "Demandes de soumissions/commandes"
+
+#. module: purchase_requisition
+#: model:ir.model.fields,help:purchase_requisition.field_purchase_requisition_type__exclusive
+msgid ""
+"Select only one RFQ (exclusive): when a purchase order is confirmed, cancel the remaining purchase order.\n"
+"\n"
+" Select multiple RFQ: allows multiple purchase orders. On confirmation of a purchase order it does not cancel the remaining orders"
+msgstr ""
+"Sélectionner une seule demande de soumission (exclusive) : lorsqu'un bon de commande est confirmé, annuler les autres bons de commande.\n"
+"\n"
+" Sélectionner plusieurs demandes de soumission : autoriser les demandes de soumission multiples. Lorsqu'un bon de commande est confirmé, les autres bons ne sont pas annulés."
+
+#. module: purchase_requisition
+#: code:addons/purchase_requisition/models/purchase_requisition.py:156
+#, python-format
+msgid ""
+"You have to cancel or validate every RfQ before closing the purchase "
+"requisition."
+msgstr ""
+"Vous devez annuler ou valider chaque demande de soumission avant de clôturer la "
+"demande d'achat."
+
+#. module: sale_crm
+#: model_terms:ir.ui.view,arch_db:sale_crm.crm_case_form_view_oppor
+msgid " Quotation(s) "
+msgstr "Soumission(s) "
+
+#. module: sale_crm
+#: model:ir.ui.menu,name:sale_crm.sale_order_menu_quotations_crm
+msgid "My Quotations"
+msgstr "Mes Soumissions"
+
+#. module: sale_crm
+#: model_terms:ir.ui.view,arch_db:sale_crm.crm_case_form_view_oppor
+msgid "New Quotation"
+msgstr "Nouvelle soumission"
+
+#. module: sale_crm
+#: model:ir.model.fields,field_description:sale_crm.field_crm_lead__sale_number
+msgid "Number of Quotations"
+msgstr "Nombre de soumissions"
+
+#. module: sale_crm
+#: model:ir.actions.act_window,name:sale_crm.sale_action_quotations_new
+msgid "Quotation"
+msgstr "Soumission"
+
+#. module: sale_crm
+#: model:ir.actions.act_window,name:sale_crm.sale_action_quotations
+msgid "Quotations"
+msgstr "Soumissions"
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.report_saleorder_document
+msgid "Quotation Date:"
+msgstr "Date soumission :"
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.view_quotation_tree
+msgid "Quotation Date"
+msgstr "Date de la soumission"
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.onboarding_quotation_layout_step
+msgid "Customize the look of your quotations."
+msgstr "Personnalisez le look de vos soumissions."
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.onboarding_quotation_layout_step
+msgid "Quotation Layout"
+msgstr "Layout des soumissions"
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.sale_onboarding_order_confirmation_step
+msgid "Choose how to confirm quotations and get paid."
+msgstr "Choisissez comment confirmer vos soumissions et être payé."
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.sale_onboarding_sample_quotation_step
+msgid "Send a quotation to test the customer portal."
+msgstr "Envoyer une soumission pour tester le portail client."
+
+#. module: sale_management
+#: model_terms:ir.actions.act_window,help:sale_management.sale_order_template_action
+msgid "Create your quotation template"
+msgstr "Créer votre modèle de soumission"
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.sale_onboarding_sample_quotation_step
+msgid "Sample Quotation"
+msgstr "Modèle de soumission"
\ No newline at end of file
diff --git a/addons/addons/erplibre_enterprise_services_for_utility_business/i18n/mathbentech_enterprise_services_for_utility_business.pot b/addons/addons/erplibre_enterprise_services_for_utility_business/i18n/mathbentech_enterprise_services_for_utility_business.pot
new file mode 100644
index 0000000..16bac57
--- /dev/null
+++ b/addons/addons/erplibre_enterprise_services_for_utility_business/i18n/mathbentech_enterprise_services_for_utility_business.pot
@@ -0,0 +1,224 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * sale
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 12.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-12-09 22:55+0000\n"
+"PO-Revision-Date: 2019-12-09 22:55+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.sale_order_view_search_inherit_quotation
+msgid "My Quotations"
+msgstr ""
+
+#. module: sale
+#: model:ir.model.fields,field_description:sale.field_sale_order__client_order_ref
+msgid "Customer Reference"
+msgstr ""
+
+#. module: sale_cancel_reason
+#: model:sale.order.cancel.reason,name:sale_cancel_reason.cancel_reason_only_quotation
+msgid "Just for Quotation"
+msgstr ""
+
+#. module: purchase
+#: model:mail.template,body_html:purchase.email_template_edi_purchase
+msgid ""
+"\n"
+"
\n"
+" Dear ${object.partner_id.name}\n"
+" % if object.partner_id.parent_id:\n"
+" (${object.partner_id.parent_id.name})\n"
+" % endif\n"
+"
\n"
+" Here is in attachment a request for quotation ${object.name}\n"
+" % if object.partner_ref:\n"
+" with reference: ${object.partner_ref}\n"
+" % endif\n"
+" from ${object.company_id.name}.\n"
+"
\n"
+" If you have any questions, please do not hesitate to contact us.\n"
+"
\n"
+" Best regards,\n"
+"
\n"
+"
"
+msgstr ""
+
+#. module: sale_order_revision
+#: model_terms:ir.ui.view,arch_db:sale_order_revision.view_order_form
+msgid "New Revision of Quotation"
+msgstr ""
+
+#. module: sale_product_set
+#: model_terms:ir.ui.view,arch_db:sale_product_set.product_set_add_form_view
+msgid "Add set in sale order line"
+msgstr ""
+
+#. module: crm
+#: model:mail.activity.type,name:crm.mail_activity_demo_followup_quote
+msgid "Follow-up Quote"
+msgstr ""
+
+#. module: crm
+#: model:mail.activity.type,name:crm.mail_activity_demo_make_quote
+msgid "Make Quote"
+msgstr ""
+
+#. module: crm
+#: model_terms:ir.actions.act_window,help:crm.crm_case_form_view_salesteams_opportunity
+msgid ""
+"You will be able to plan meetings and phone calls from\n"
+" opportunities, convert them into quotations, attach related\n"
+" documents, track all discussions, and much more."
+msgstr ""
+
+#. module: hr
+#: model_terms:hr.job,website_description:hr.job_consultant
+msgid "Analyse needs, write specification documents and quotation"
+msgstr ""
+
+#. module: hr
+#: model_terms:hr.job,website_description:hr.job_consultant
+msgid ""
+"We are looking for a motivated and results-driven Functional Consultant! You"
+" will take part in the consulting services we provide to our partners and "
+"customers, on the functional side. Your job start from the quotation to the "
+"customer to the delivery to the customer. You listen the customer and try to"
+" give him the best service. You report to the head of consulting service and"
+" will be coached by a senior consultant."
+msgstr ""
+
+#. module: purchase_requisition
+#: code:addons/purchase_requisition/models/purchase_requisition.py:116
+#, python-format
+msgid "Cancelled by the agreement associated to this quotation."
+msgstr ""
+
+#. module: purchase_requisition
+#: model_terms:ir.ui.view,arch_db:purchase_requisition.view_purchase_requisition_type_form
+msgid "Data for new quotations"
+msgstr ""
+
+#. module: purchase_requisition
+#: selection:purchase.requisition.type,line_copy:0
+msgid "Do not create RfQ lines automatically"
+msgstr ""
+
+#. module: purchase_requisition
+#: model_terms:ir.actions.act_window,help:purchase_requisition.action_purchase_requisition
+msgid ""
+"In a call for tenders, you can record the products you need to buy\n"
+" and generate the creation of RfQs to vendors. Once the tenders have\n"
+" been registered, you can review and compare them and you can\n"
+" validate some and cancel others."
+msgstr ""
+
+#. module: purchase_requisition
+#: model_terms:ir.ui.view,arch_db:purchase_requisition.view_purchase_requisition_form
+msgid "New Quotation"
+msgstr ""
+
+#. module: purchase_requisition
+#: model_terms:ir.ui.view,arch_db:purchase_requisition.view_purchase_requisition_form
+msgid "RFQs/Orders"
+msgstr ""
+
+#. module: purchase_requisition
+#: model:ir.model.fields,help:purchase_requisition.field_purchase_requisition_type__exclusive
+msgid ""
+"Select only one RFQ (exclusive): when a purchase order is confirmed, cancel the remaining purchase order.\n"
+"\n"
+" Select multiple RFQ: allows multiple purchase orders. On confirmation of a purchase order it does not cancel the remaining orders"
+msgstr ""
+
+#. module: purchase_requisition
+#: code:addons/purchase_requisition/models/purchase_requisition.py:156
+#, python-format
+msgid ""
+"You have to cancel or validate every RfQ before closing the purchase "
+"requisition."
+msgstr ""
+
+#. module: sale_crm
+#: model_terms:ir.ui.view,arch_db:sale_crm.crm_case_form_view_oppor
+msgid " Quotation(s) "
+msgstr ""
+
+#. module: sale_crm
+#: model:ir.ui.menu,name:sale_crm.sale_order_menu_quotations_crm
+msgid "My Quotations"
+msgstr ""
+
+#. module: sale_crm
+#: model_terms:ir.ui.view,arch_db:sale_crm.crm_case_form_view_oppor
+msgid "New Quotation"
+msgstr ""
+
+#. module: sale_crm
+#: model:ir.model.fields,field_description:sale_crm.field_crm_lead__sale_number
+msgid "Number of Quotations"
+msgstr ""
+
+#. module: sale_crm
+#: model:ir.actions.act_window,name:sale_crm.sale_action_quotations_new
+msgid "Quotation"
+msgstr ""
+
+#. module: sale_crm
+#: model:ir.actions.act_window,name:sale_crm.sale_action_quotations
+msgid "Quotations"
+msgstr ""
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.report_saleorder_document
+msgid "Quotation Date:"
+msgstr ""
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.view_quotation_tree
+msgid "Quotation Date"
+msgstr ""
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.onboarding_quotation_layout_step
+msgid "Customize the look of your quotations."
+msgstr ""
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.onboarding_quotation_layout_step
+msgid "Quotation Layout"
+msgstr ""
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.sale_onboarding_order_confirmation_step
+msgid "Choose how to confirm quotations and get paid."
+msgstr ""
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.sale_onboarding_sample_quotation_step
+msgid "Send a quotation to test the customer portal."
+msgstr ""
+
+#. module: sale_management
+#: model_terms:ir.actions.act_window,help:sale_management.sale_order_template_action
+msgid "Create your quotation template"
+msgstr ""
+
+#. module: sale_quotation_builder
+#: model:ir.model,name:sale_quotation_builder.model_sale_order_template
+msgid "Quotation Template"
+msgstr ""
+
+#. module: sale
+#: model_terms:ir.ui.view,arch_db:sale.sale_onboarding_sample_quotation_step
+msgid "Sample Quotation"
+msgstr ""
\ No newline at end of file
diff --git a/addons/muk-it_muk_base b/addons/muk-it_muk_base
new file mode 160000
index 0000000..d888c96
--- /dev/null
+++ b/addons/muk-it_muk_base
@@ -0,0 +1 @@
+Subproject commit d888c9695292295a732fcdd4a7b9820978df5e7f
diff --git a/addons/muk-it_muk_dms b/addons/muk-it_muk_dms
new file mode 160000
index 0000000..020e604
--- /dev/null
+++ b/addons/muk-it_muk_dms
@@ -0,0 +1 @@
+Subproject commit 020e604d635a229c09a07e839d95f8e37706606a
diff --git a/addons/muk-it_muk_docs b/addons/muk-it_muk_docs
new file mode 160000
index 0000000..a8ea02b
--- /dev/null
+++ b/addons/muk-it_muk_docs
@@ -0,0 +1 @@
+Subproject commit a8ea02b9f00ae9fe5d2ea25ac43d23532cc11d45
diff --git a/addons/muk-it_muk_misc b/addons/muk-it_muk_misc
new file mode 160000
index 0000000..37b9d6d
--- /dev/null
+++ b/addons/muk-it_muk_misc
@@ -0,0 +1 @@
+Subproject commit 37b9d6dc20fa686a323057b160015bfc2c2c8143
diff --git a/addons/muk-it_muk_quality b/addons/muk-it_muk_quality
new file mode 160000
index 0000000..1a4c6f2
--- /dev/null
+++ b/addons/muk-it_muk_quality
@@ -0,0 +1 @@
+Subproject commit 1a4c6f25c5e4fe0029d406d6283555bd23a44d27
diff --git a/addons/muk-it_muk_web b/addons/muk-it_muk_web
new file mode 160000
index 0000000..431d86d
--- /dev/null
+++ b/addons/muk-it_muk_web
@@ -0,0 +1 @@
+Subproject commit 431d86d6694e846b407c84f00a31a10f0cf5b83b
diff --git a/addons/muk-it_muk_website b/addons/muk-it_muk_website
new file mode 160000
index 0000000..c1e6c17
--- /dev/null
+++ b/addons/muk-it_muk_website
@@ -0,0 +1 @@
+Subproject commit c1e6c1755d09562f66247832bd01a0d580c43e23
diff --git a/addons/odooaktiv_QuotationRevision b/addons/odooaktiv_QuotationRevision
new file mode 160000
index 0000000..701438f
--- /dev/null
+++ b/addons/odooaktiv_QuotationRevision
@@ -0,0 +1 @@
+Subproject commit 701438f9c59bd657de516d9ef4de1ba6167bf30b
diff --git a/addons/openeducat_openeducat_erp b/addons/openeducat_openeducat_erp
new file mode 160000
index 0000000..4a2a1d9
--- /dev/null
+++ b/addons/openeducat_openeducat_erp
@@ -0,0 +1 @@
+Subproject commit 4a2a1d930d88a127959fd39af22f7d818e08663d
diff --git a/env_var.sh b/env_var.sh
new file mode 100755
index 0000000..b7a945b
--- /dev/null
+++ b/env_var.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+################################################################################
+# Script for installing Odoo on Ubuntu 14.04, 15.04, 16.04 and 18.04 (could be used for other version too)
+# Author: Yenthe Van Ginneken
+#-------------------------------------------------------------------------------
+# This script will install Odoo on your Ubuntu 16.04 server. It can install multiple Odoo instances
+# in one Ubuntu because of the different xmlrpc_ports
+#-------------------------------------------------------------------------------
+################################################################################
+
+OE_USER="odoo"
+OE_HOME="/${OE_USER}"
+OE_HOME_ODOO="${OE_HOME}/odoo"
+OE_HOME_EXT="${OE_HOME_ODOO}/odoo"
+# The default port where this Odoo instance will run under (provided you use the command -c in the terminal)
+# Set to true if you want to install it, false if you don't need it or have it already installed.
+INSTALL_WKHTMLTOPDF="True"
+# Set the default Odoo port (you still have to use -c /etc/odoo-server.conf for example to use this.)
+OE_PORT="8069"
+OE_LONGPOLLING_PORT="8072"
+# set the superadmin password
+OE_SUPERADMIN="admin"
+OE_VERSION="stable_prod_12.0"
+OE_CONFIG="${OE_USER}"
+MINIMAL_ADDONS="False"
+# Set this to True if you want to install Nginx!
+INSTALL_NGINX="True"
+# Set the website name
+WEBSITE_NAME="_"
+GITHUB_TOKEN=""
diff --git a/odoo b/odoo
new file mode 160000
index 0000000..94bcbc9
--- /dev/null
+++ b/odoo
@@ -0,0 +1 @@
+Subproject commit 94bcbc92e5e5a6fd3de7267e3c01f8c11fb045f4
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..ca82ce2
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+giturlparse
+agithub
+gitpython
+PyYAML
+retrying
\ No newline at end of file
diff --git a/run.md b/run.md
new file mode 100644
index 0000000..ba722dc
--- /dev/null
+++ b/run.md
@@ -0,0 +1,5 @@
+== Start database ==
+sudo systemctl start postgresql.service
+
+== Run Odoo ==
+./venv/bin/python ./odoo/odoo-bin -c config.conf
diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..58f64fd
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+./venv/bin/python ./odoo/odoo-bin -c ./config.conf
diff --git a/script/__init__.py b/script/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/script/addons_repo_origin.py b/script/addons_repo_origin.py
new file mode 100644
index 0000000..1112471
--- /dev/null
+++ b/script/addons_repo_origin.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+# dict config contains information about repository of original source
+# level 1: website of git
+# level 2: entity, organization, user
+# level 3: project name
+config = {
+ "github.com": {
+ "odoo": [
+ "odoo",
+ ],
+ }
+}
+config_addons = {
+ "github.com": {
+ "MathBenTech": [
+ "development",
+ "odoo-business-spending-management-quebec-canada",
+ "scrummer",
+ ],
+ "muk-it": [
+ "muk_base",
+ "muk_dms",
+ "muk_docs",
+ "muk_misc",
+ "muk_quality",
+ "muk_web",
+ "muk_website",
+ ],
+ "Numigi": [
+ "odoo-base-addons",
+ "odoo-entertainment-addons",
+ "odoo-git-addons",
+ "odoo-hr-addons",
+ "odoo-partner-addons",
+ "odoo-product-addons",
+ "odoo-project-addons",
+ "odoo-purchase-addons",
+ "odoo-stock-addons",
+ "odoo-survey-addons",
+ "odoo-timesheet-addons",
+ "odoo-web-addons",
+ ],
+ "OCA": [
+ "account-analytic",
+ "account-budgeting",
+ "account-closing",
+ "account-consolidation",
+ "account-financial-reporting",
+ "account-fiscal-rule",
+ "account-invoicing",
+ "account-invoice-reporting",
+ "account-payment",
+ "account-reconcile",
+ "apps-store",
+ "bank-payment",
+ "bank-statement-import",
+ "brand",
+ "business-requirement",
+ "commission",
+ "community-data-files",
+ "connector-telephony",
+ "contract",
+ "credit-control",
+ "currency",
+ "data-protection",
+ "donation",
+ "e-commerce",
+ "edi",
+ "event",
+ "helpdesk",
+ "hr",
+ "knowledge",
+ "l10n-canada",
+ "maintenance",
+ "management-system",
+ "manufacture",
+ "margin-analysis",
+ "mis-builder",
+ "multi-company",
+ "partner-contact",
+ "pos",
+ "product-attribute",
+ "product-pack",
+ "product-variant",
+ "project",
+ "project-reporting",
+ "purchase-workflow",
+ "queue",
+ "reporting-engine",
+ "sale-workflow",
+ "server-auth",
+ "server-brand",
+ "server-env",
+ "server-tools",
+ "server-ux",
+ "social",
+ "stock-logistics-warehouse",
+ "timesheet",
+ "web",
+ "website",
+ "wms",
+ ],
+ "odooaktiv": [
+ "QuotationRevision",
+ ],
+ "openeducat": [
+ "openeducat_erp",
+ ],
+ "Smile-SA": [
+ "odoo_addons",
+ ],
+ }
+}
diff --git a/script/fork_github_repo/README.md b/script/fork_github_repo/README.md
new file mode 100644
index 0000000..f3f4b53
--- /dev/null
+++ b/script/fork_github_repo/README.md
@@ -0,0 +1,4 @@
+Source of fork-github-repo : https://github.com/gene1wood/fork-github-repo
+TODO
+Create python dependency with submodule
+https://shunsvineyard.info/2019/12/23/using-git-submodule-and-develop-mode-to-manage-python-projects/
\ No newline at end of file
diff --git a/script/fork_github_repo/__init__.py b/script/fork_github_repo/__init__.py
new file mode 100644
index 0000000..fd213f4
--- /dev/null
+++ b/script/fork_github_repo/__init__.py
@@ -0,0 +1,273 @@
+from __future__ import print_function
+import argparse
+import os.path
+import shutil
+from agithub.GitHub import GitHub # pip install agithub
+from git import Repo # pip install gitpython
+from giturlparse import parse # pip install giturlparse
+from retrying import retry # pip install retrying
+import yaml # pip install PyYAML
+
+DEFAULT_CONFIG_FILENAME = '~/.github/fork_github_repo.yaml'
+
+
+def github_url_argument(url):
+ """Validate a url as a GitHub repo url and raise argparse exceptions if
+ validation fails
+
+ :param str url: A GitHub repo URL
+ :return: The GitHub repo URL passed in
+ """
+ parsed_url = parse(url)
+ if not parsed_url.valid:
+ raise argparse.ArgumentTypeError('%s is not a valid git URL'
+ % url)
+ if not parsed_url.github:
+ raise argparse.ArgumentTypeError('%s is not a GitHub repo'
+ % parsed_url.url)
+ return url
+
+
+def filename_argument(filename):
+ return os.path.expanduser(filename)
+
+
+def get_config():
+ """Parse command line arguments, extracting the config file name,
+ read the yaml config file and add in the command line arguments,
+ returning the union of config file and command line arguments
+
+ :return: dict of config file settings and command line arguments
+ """
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description='''\
+Fork a GitHub repo, clone that repo to a local directory, add the upstream
+remote, create an optional feature branch and checkout that branch''',
+ epilog='''\
+The config file with a default location of
+~/.github/fork_github_repo.yaml contains the following settings:
+
+- github_token : The `GitHub personal access token with the public_repo scope
+ allowed.
+ https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/
+- repo_dir : The directory path to the directory containing all your cloned
+ repos. If this isn't defined, /tmp is used.
+
+The file is YAML formatted and the contents look like this :
+
+github_token: 0123456789abcdef0123456789abcdef01234567
+repo_dir: ~/Documents/github.com/example/
+organization:
+'''
+ )
+ parser.add_argument(
+ '-c', '--config',
+ help='Filename of the yaml config file (default : %s)'
+ % DEFAULT_CONFIG_FILENAME,
+ default=filename_argument(DEFAULT_CONFIG_FILENAME),
+ type=filename_argument)
+ parser.add_argument('url', help="GitHub URL of the upstream repo to fork",
+ type=github_url_argument)
+ parser.add_argument('branch', nargs='?', default=None,
+ help="Name of the feature branch to create")
+ args = parser.parse_args()
+ if (args.config == filename_argument(DEFAULT_CONFIG_FILENAME)) and (
+ not os.path.isfile(args.config)):
+ parser.error('Please create a config file at %s or point to one with '
+ 'the --config option.' % DEFAULT_CONFIG_FILENAME)
+ if not os.path.isfile(args.config):
+ raise argparse.ArgumentTypeError(
+ 'Could not find config file %s.' % args.config)
+ with open(args.config, 'r') as f:
+ try:
+ config = yaml.safe_load(f)
+ if isinstance(config, dict):
+ config.update(vars(args))
+ return config
+ else:
+ raise argparse.ArgumentTypeError(
+ 'Config contains %s of "%s" but it should be a dict'
+ % (type(config), config))
+ except yaml.YAMLError:
+ raise argparse.ArgumentTypeError(
+ 'Could not parse YAML in %s' % args.config)
+
+
+def get_list_fork_repo(upstream_url, github_token):
+ gh = GitHub(token=github_token)
+ parsed_url = parse(upstream_url)
+ status, user = gh.user.get()
+
+ # response = gh.repos[user['login']][parsed_url.repo].forks.get(sort="newest")
+ response = gh.repos["odoo"][parsed_url.repo].forks.get(sort="newest")
+ print(response)
+
+
+def fork_and_clone_repo(
+ upstream_url, github_token, repo_dir_root, branch_name=None,
+ upstream_name='upstream', organization_name=None, fork_only=False,
+ repo_root=None):
+ """Fork a GitHub repo, clone that repo to a local directory,
+ add the upstream remote, create an optional feature branch and checkout
+ that branch
+
+ :param str upstream_url: GitHub URL of the upstream repo
+ :param str github_token: GitHub auth token
+ :param str repo_dir_root: The local directory path under which clones
+ should be written
+ :param str branch_name: The name of the git feature branch to create
+ :param str upstream_name: The name to use for the remote upstream
+ :param str organization_name: The name the organization that replace actual user
+ :param bool fork_only: Stop after forking and don't clone
+ :param obj repo_root: Repo parent, if not None, use submodule with it
+ :return: github3.Head object representing the new feature branch
+ """
+ # Scope needed is `public_repo` to fork and clone public repos
+ # https://developer.github.com/apps/building-integrations/setting-up-and-registering-oauth-apps/about-scopes-for-oauth-apps/
+ gh = GitHub(token=github_token)
+ parsed_url = parse(upstream_url)
+
+ # Fork the repo
+ status, user = gh.user.get()
+ user_name = user['login'] if not organization_name else organization_name
+ status, forked_repo = gh.repos[user_name][parsed_url.repo].get()
+ if status == 404:
+ status, upstream_repo = (
+ gh.repos[parsed_url.owner][parsed_url.repo].get())
+ if status == 404:
+ print("Unable to find repo %s" % upstream_url)
+ exit(1)
+ args = {}
+ if organization_name:
+ args["organization"] = organization_name
+ status, forked_repo = (
+ gh.repos[parsed_url.owner][parsed_url.repo].forks.post(**args))
+ if status == 404:
+ print("Error when forking repo %s" % forked_repo)
+ exit(1)
+ else:
+ print("Forked %s to %s" % (upstream_url, forked_repo['ssh_url']))
+ elif status == 202:
+ print("Forked repo %s already exists" % forked_repo['full_name'])
+ elif status != 200:
+ print("Status not supported: %s - %s" % (status, forked_repo))
+ exit(1)
+
+ if fork_only:
+ return True
+
+ # Clone the repo
+ repo_dir = os.path.expanduser(os.path.join(repo_dir_root, parsed_url.repo))
+ if repo_root:
+ # TODO validate not already submodule
+ # forked_repo['ssh_url']
+ http_url = f"https://{(forked_repo['ssh_url'][4:]).replace(':', '/')}"
+ try:
+ if branch_name:
+ submodule_repo = retry(
+ wait_exponential_multiplier=1000,
+ stop_max_delay=15000
+ )(repo_root.create_submodule)(repo_dir_root, repo_dir_root,
+ url=http_url,
+ branch=branch_name)
+ else:
+ submodule_repo = retry(
+ wait_exponential_multiplier=1000,
+ stop_max_delay=15000
+ )(repo_root.create_submodule)(repo_dir_root, repo_dir_root,
+ url=http_url)
+ except KeyError as e:
+ if os.path.isdir(repo_dir_root):
+ print(f"Warning, submodule {repo_dir_root} already exist, "
+ f"you need to add it in stage.")
+ else:
+ print(f"\nERROR Cannot create submodule {repo_dir_root}."
+ f"Maybe you need to delete .git/modules/{repo_dir_root}\n")
+ return
+ # # Delete appropriate submodule and recreate_submodule
+ # shutil.rmtree(f".git/modules/{repo_dir_root}", ignore_errors=True)
+ # if branch_name:
+ # submodule_repo = retry(
+ # wait_exponential_multiplier=1000,
+ # stop_max_delay=15000
+ # )(repo_root.create_submodule)(repo_dir_root, repo_dir_root,
+ # url=http_url,
+ # branch=branch_name)
+ # else:
+ # submodule_repo = retry(
+ # wait_exponential_multiplier=1000,
+ # stop_max_delay=15000
+ # )(repo_root.create_submodule)(repo_dir_root, repo_dir_root,
+ # url=http_url)
+ # Update submodule
+ # print(f"Try to fix submodule {repo_dir_root} with update them all.")
+ # retry(
+ # wait_exponential_multiplier=1000,
+ # stop_max_delay=15000
+ # )(repo_root.submodule_update)(recursive=False)
+ # if os.path.isdir(repo_dir_root):
+ # print(f"Submodule {repo_dir_root} fixed.")
+ # else:
+ # # TODO remove submodule
+ # print(f"Error, submodule {repo_dir_root} is configured, but not "
+ # f"existing. Do git submodule update")
+
+ cloned_repo = Repo(repo_dir_root)
+ print("Cloned %s to %s" % (http_url, repo_dir))
+ # sm = cloned_repo.create_submodule('mysubrepo', 'path/to/subrepo',
+ # url=bare_repo.git_dir, branch='master')
+ else:
+ if os.path.isdir(repo_dir):
+ print("Directory %s already exists, assuming it's a clone" % repo_dir)
+ cloned_repo = Repo(repo_dir)
+ else:
+ cloned_repo = retry(
+ wait_exponential_multiplier=1000,
+ stop_max_delay=15000
+ )(Repo.clone_from)(forked_repo['ssh_url'], repo_dir)
+ print("Cloned %s to %s" % (forked_repo['ssh_url'], repo_dir))
+
+ # Create the remote upstream
+ try:
+ upstream_remote = cloned_repo.remote(upstream_name)
+ print('Remote "%s" already exists in %s' % (upstream_name, repo_dir))
+ except ValueError:
+ upstream_remote = retry(
+ wait_exponential_multiplier=1000,
+ stop_max_delay=15000
+ )(cloned_repo.create_remote)(upstream_name, upstream_url)
+ print('Remote "%s" created for %s' % (upstream_name, upstream_url))
+
+ # Fetch the remote upstream
+ retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
+ upstream_remote.fetch)()
+ print('Remote "%s" fetched' % upstream_name)
+
+ # Create and checkout the branch
+ if branch_name is None:
+ return cloned_repo
+ else:
+ if branch_name not in cloned_repo.refs:
+ branch = cloned_repo.create_head(branch_name)
+ print('Branch "%s" created' % branch_name)
+ else:
+ branch = cloned_repo.heads[branch_name]
+ print('Branch "%s" already exists' % branch_name)
+ if branch_name not in cloned_repo.remotes.origin.refs:
+ cloned_repo.remotes.origin.push(refspec='{}:{}'.format(
+ branch.path, branch.path))
+ print('Branch "%s" pushed to origin' % branch_name)
+ else:
+ print('Branch "%s" already exists in remote origin' % branch_name)
+ if branch.tracking_branch() is None:
+ branch.set_tracking_branch(
+ cloned_repo.remotes.origin.refs[branch_name])
+ print('Tracking branch "%s" setup for branch "%s"' % (
+ cloned_repo.remotes.origin.refs[branch_name], branch_name))
+ else:
+ print('Branch "%s" already setup to track "%s"' % (
+ branch_name, cloned_repo.remotes.origin.refs[branch_name]))
+ branch.checkout()
+ print('Branch "%s" checked out' % branch_name)
+ return branch
diff --git a/script/fork_project.py b/script/fork_project.py
new file mode 100644
index 0000000..ce9a958
--- /dev/null
+++ b/script/fork_project.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+import os
+import sys
+import argparse
+import logging
+from git import Repo
+from retrying import retry # pip install retrying
+
+new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
+sys.path.append(new_path)
+
+from script import fork_github_repo
+from script.git_tool import GitTool
+
+_logger = logging.getLogger(__name__)
+CST_GITHUB_TOKEN = "GITHUB_TOKEN"
+
+
+def get_config():
+ """Parse command line arguments, extracting the config file name,
+ returning the union of config file and command line arguments
+
+ :return: dict of config file settings and command line arguments
+ """
+ config = GitTool.get_project_config()
+
+ # TODO update description
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description='''\
+''',
+ epilog='''\
+'''
+ )
+ parser.add_argument('-d', '--dir', dest="dir", default="./",
+ help="Path of repo to change remote, including submodule.")
+ parser.add_argument('--organization', dest="organization", default="ERPLibre",
+ help="Choose organization to fork and change all repo.")
+ parser.add_argument('--github_token', dest="github_token",
+ default=config.get(CST_GITHUB_TOKEN),
+ help="GitHub token generated by user")
+ args = parser.parse_args()
+ return args
+
+
+def main():
+ config = get_config()
+ github_token = config.github_token
+
+ if not github_token:
+ raise ValueError("Missing github_token")
+ repo_root = Repo(config.dir)
+
+ lst_repo = GitTool().get_source_repo_addons(repo_path=config.dir)
+ i = 0
+ total = len(lst_repo)
+ for repo in lst_repo:
+ i += 1
+ print(f"Nb element {i}/{total}")
+ url = repo.get("url")
+ repo_dir_root = repo.get("path")
+ branch_name = None
+ upstream_name = "upstream"
+ organization_name = config.organization
+
+ # Exception, if repo existing, create appropriate remote to keep access
+ # and remove origin
+ # TODO do it
+ # Don't overwrite upstream_name if already exist
+ # Create origin of organization of upstream if not exist
+ # Move actual origin to is organization
+ working_repo = Repo(repo.get("relative_path"))
+
+ dct_remote_name = {a.name: a for a in working_repo.remotes}
+ remote_origin = dct_remote_name.get("origin")
+
+ # for remote in working_repo.remotes:
+ if remote_origin:
+ repo_origin_info = GitTool.get_transformed_repo_info_from_url(
+ remote_origin.url, repo_path=repo.get("relative_path"))
+
+ if repo_origin_info.organization not in dct_remote_name.keys():
+ # Add remote
+ upstream_remote = retry(
+ wait_exponential_multiplier=1000,
+ stop_max_delay=15000
+ )(working_repo.create_remote)(repo_origin_info.organization,
+ repo_origin_info.url_https)
+ print('Remote "%s" created for %s' % (
+ repo_origin_info.organization, repo_origin_info.url_https))
+
+ # Fetch the remote
+ retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
+ upstream_remote.fetch)()
+ print('Remote "%s" fetched' % repo_origin_info.organization)
+ # working_repo.git.remote.remove("origin")
+ upstream_name = organization_name
+ # TODO a la première création, on choisit le URL source en cas de non existance de upstream,
+ # sinon on choisit celui de ERPLibre
+ # [, , ]
+
+ _logger.info(
+ f"Fork {url} on dir {repo_dir_root} for organization {organization_name}")
+
+ fork_github_repo.fork_and_clone_repo(
+ url,
+ github_token,
+ repo_dir_root,
+ branch_name=branch_name,
+ upstream_name=upstream_name,
+ organization_name=organization_name,
+ # fork_only=True,
+ repo_root=repo_root,
+ )
+
+ # Update origin to new repo
+
+ GitTool().generate_odoo_install_locally()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/script/fork_project_ERPLibre.py b/script/fork_project_ERPLibre.py
new file mode 100644
index 0000000..ffa0441
--- /dev/null
+++ b/script/fork_project_ERPLibre.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+import os
+import sys
+import argparse
+import logging
+from git import Repo
+
+new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
+sys.path.append(new_path)
+
+from script.git_tool import GitTool
+
+_logger = logging.getLogger(__name__)
+CST_GITHUB_TOKEN = "GITHUB_TOKEN"
+
+
+def get_config():
+ """Parse command line arguments, extracting the config file name,
+ returning the union of config file and command line arguments
+
+ :return: dict of config file settings and command line arguments
+ """
+ config = GitTool.get_project_config()
+
+ # TODO update description
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description='''\
+''',
+ epilog='''\
+'''
+ )
+ parser.add_argument('-d', '--dir', dest="dir", default="./",
+ help="Path of repo to change remote, including submodule.")
+ parser.add_argument('--organization', dest="organization", default="ERPLibre",
+ help="Choose organization to fork and change all repo.")
+ parser.add_argument("--skip_fork", action="store_true",
+ help="Ignore fork to generate only dependancies like "
+ ".gitmodules and odoo_install_locally.sh")
+ parser.add_argument('-f', "--force", action="store_true",
+ help="Force rewrite remote.")
+ parser.add_argument('--github_token', dest="github_token",
+ default=config.get(CST_GITHUB_TOKEN),
+ help="GitHub token generated by user")
+ args = parser.parse_args()
+ return args
+
+
+def main():
+ config = get_config()
+ github_token = config.github_token
+ git_tool = GitTool()
+
+ if not github_token:
+ raise ValueError("Missing github_token")
+
+ organization_name = config.organization
+ lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, add_repo_root=True)
+ lst_repo_organization = [git_tool.get_transformed_repo_info_from_url(
+ a.get("url"), repo_path=config.dir, organization_force=organization_name,
+ is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"))
+ for a in lst_repo]
+ i = 0
+ total = len(lst_repo)
+ for repo in lst_repo:
+ i += 1
+ print(f"Nb element {i}/{total}")
+ url = repo.get("url")
+
+ working_repo = Repo(repo.get("relative_path"))
+
+ dct_remote_name = {a.name: a for a in working_repo.remotes}
+ remote_origin = dct_remote_name.get("origin")
+ remote_erplibre = dct_remote_name.get("ERPLibre")
+ remote_organization = dct_remote_name.get(organization_name)
+
+ if not config.skip_fork:
+ if not remote_erplibre:
+ repo_info = git_tool.get_transformed_repo_info_from_url(
+ url, organization_force="ERPLibre",
+ is_submodule=repo.get("is_submodule"),
+ sub_path=repo.get("sub_path"))
+ git_tool.add_and_fetch_remote(repo_info)
+
+ git_tool.fork_repo(url, github_token,
+ organization_name=organization_name,
+ )
+
+ repo_info = git_tool.get_transformed_repo_info_from_url(
+ url, organization_force=organization_name,
+ is_submodule=repo.get("is_submodule"), sub_path=repo.get("sub_path"))
+ if remote_origin:
+ working_repo.git.remote("remove", "origin")
+ repo_info.organization = "origin"
+ git_tool.add_and_fetch_remote(repo_info)
+ if config.force and remote_organization:
+ working_repo.git.remote("remove", organization_name)
+
+ repo_info.organization = organization_name
+ git_tool.add_and_fetch_remote(repo_info)
+
+ # Update origin to new repo
+ git_tool.generate_git_modules(lst_repo_organization, repo_path=config.dir)
+ git_tool.generate_odoo_install_locally()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/script/git_change_remote.py b/script/git_change_remote.py
new file mode 100755
index 0000000..4679d96
--- /dev/null
+++ b/script/git_change_remote.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+import os
+import sys
+import argparse
+import logging
+from git import Repo
+
+from retrying import retry # pip install retrying
+
+new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
+sys.path.append(new_path)
+
+from script import fork_github_repo
+from script import git_tool
+
+_logger = logging.getLogger(__name__)
+CST_GITHUB_TOKEN = "GITHUB_TOKEN"
+
+
+def get_config():
+ """Parse command line arguments, extracting the config file name,
+ returning the union of config file and command line arguments
+
+ :return: dict of config file settings and command line arguments
+ """
+ config = git_tool.GitTool.get_project_config()
+
+ # TODO update description
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description='''\
+''',
+ epilog='''\
+'''
+ )
+ parser.add_argument('-d', '--dir', dest="dir", default="./",
+ help="Path of repo to change remote, including submodule.")
+ parser.add_argument('--github_token', dest="github_token",
+ default=config.get(CST_GITHUB_TOKEN),
+ help="GitHub token generated by user")
+ parser.add_argument("--open_web_browser", action="store_true",
+ help="Open web browser for each repo.")
+ parser.add_argument("--generate_only_install_locally", action="store_true",
+ help="Only generate script odoo_install_locally.sh.")
+ parser.add_argument("--generate_repo_source_from_building", action="store_true",
+ help=f"Only generate "
+ f"{git_tool.CST_FILE_SOURCE_REPO_ADDONS_ODOO}")
+ parser.add_argument("--sync_to", dest="sync_to",
+ help=f"Only synchronize matching repo, use path compare to "
+ f"repo.")
+ args = parser.parse_args()
+ return args
+
+
+def main():
+ # repo = Repo(root_path)
+ # lst_repo = get_all_repo()
+ config = get_config()
+
+ if config.generate_only_install_locally:
+ gt = git_tool.GitTool()
+ gt.generate_odoo_install_locally()
+ return
+
+ if config.generate_repo_source_from_building:
+ gt = git_tool.GitTool()
+ gt.generate_repo_source_from_building()
+ return
+
+ if config.sync_to:
+ gt = git_tool.GitTool()
+ result = gt.get_matching_repo(repo_compare_to=config.sync_to,
+ force_normalize_compare=True)
+ gt.sync_to(result)
+ return
+
+ # repo_root = Repo(".")
+ lst_repo = git_tool.GitTool.get_repo_info_submodule(repo_path=config.dir)
+ i = 0
+ total = len(lst_repo)
+ for repo in lst_repo:
+ i += 1
+ print(f"Nb element {i}/{total}")
+ url = repo.get("url")
+ repo_dir_root = repo.get("path")
+ upstream_name = "MathBenTech"
+ organization_name = "ERPLibre"
+
+ if config.open_web_browser:
+ git_tool.GitTool.open_repo_web_browser(repo.get("url_https"))
+
+ # Create the remote upstream
+ split_url = url.split("/")
+ split_url[-2] = upstream_name
+ upstream_url = "/".join(split_url)
+
+ cloned_repo = Repo(repo_dir_root)
+ # Checkout branch 12.0
+ # try:
+ # cloned_repo.git.checkout(cloned_repo.head.commit.hexsha)
+ # cloned_repo.delete_head("12.0")
+ # cloned_repo.git.checkout("MathBenTech/12.0", b="12.0", force=True)
+ # except:
+ # # cloned_repo.git.checkout("MathBenTech/12.0", b="12.0", force=True)
+ # print(f"Cannot change branch for {repo_dir_root}")
+ # # try:
+ # # cloned_repo.git.checkout("12.0")
+ # # except:
+ # # print(f"ERROR, missing branch 12.0 for {repo_dir_root}")
+
+ _logger.info(
+ f"Fork {url} on dir {repo_dir_root} for organization {organization_name}")
+
+ try:
+ upstream_remote = cloned_repo.remote(upstream_name)
+ print('Remote "%s" already exists in %s' %
+ (upstream_name, repo_dir_root))
+ except ValueError:
+ upstream_remote = retry(
+ wait_exponential_multiplier=1000,
+ stop_max_delay=15000
+ )(cloned_repo.create_remote)(upstream_name, upstream_url)
+ print('Remote "%s" created for %s' % (upstream_name, upstream_url))
+
+ try:
+ # Fetch the remote upstream
+ retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
+ upstream_remote.fetch)()
+ print('Remote "%s" fetched' % upstream_name)
+ except Exception:
+ print(f"ERROR git {repo_dir_root} remote {upstream_name} not exist.")
+ upstream_remote.remove(cloned_repo, upstream_name)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/script/git_change_remote_https_to_git.py b/script/git_change_remote_https_to_git.py
new file mode 100755
index 0000000..5b055bb
--- /dev/null
+++ b/script/git_change_remote_https_to_git.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# © 2020 TechnoLibre (http://www.technolibre.ca)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+import argparse
+import logging
+import os
+import sys
+
+from git import Repo
+
+new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
+sys.path.append(new_path)
+
+from script.git_tool import GitTool
+
+_logger = logging.getLogger(__name__)
+
+
+def get_config():
+ """Parse command line arguments, extracting the config file name,
+ returning the union of config file and command line arguments
+
+ :return: dict of config file settings and command line arguments
+ """
+
+ # TODO update description
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description='''\
+''',
+ epilog='''\
+'''
+ )
+ parser.add_argument('-d', '--dir', dest="dir", default="./",
+ help="Path of repo to change remote, including submodule.")
+ parser.add_argument('-f', '--upstream', dest="upstream", default="origin",
+ help="Upstream name to change address https to git.")
+ # TODO support all_upstream
+ # parser.add_argument("--all_upstream", action="store_true",
+ # help="Replace for all existing upstream for each repo.")
+ parser.add_argument("--git_to_https", action="store_true",
+ help="Replace all repo git to https.")
+ args = parser.parse_args()
+ return args
+
+
+def main():
+ git_tool = GitTool()
+ config = get_config()
+
+ upstream_name = config.upstream
+ lst_repo = git_tool.get_repo_info_submodule(config.dir, add_root=True,
+ upstream=upstream_name)
+ i = 0
+ total = len(lst_repo)
+ for repo in lst_repo:
+ i += 1
+ print(f"Nb element {i}/{total}")
+ repo_sm = Repo(repo.get("name"))
+ remote_upstream_name = [a for a in repo_sm.remotes if upstream_name == a.name]
+ new_url = repo.get("url_https") if config.git_to_https else repo.get("url_git")
+
+ for remote in remote_upstream_name:
+ remote.set_url(new_url)
+ print('Remote "%s" created for %s' % (upstream_name, new_url))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/script/git_tool.py b/script/git_tool.py
new file mode 100644
index 0000000..77699a7
--- /dev/null
+++ b/script/git_tool.py
@@ -0,0 +1,495 @@
+#!/usr/bin/env python
+# © 2020 TechnoLibre (http://www.technolibre.ca)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+import os
+from . import addons_repo_origin
+import webbrowser
+from retrying import retry # pip install retrying
+from agithub.GitHub import GitHub # pip install agithub
+from giturlparse import parse # pip install giturlparse
+
+from git import Repo
+from typing import List
+
+CST_FILE_SOURCE_REPO_ADDONS_ODOO = "source_repo_addons_odoo.csv"
+CST_GITHUB_TOKEN = "GITHUB_TOKEN"
+
+
+class Struct(object):
+ def __init__(self, **entries):
+ self.__dict__.update(entries)
+
+
+class GitTool:
+ @staticmethod
+ def get_url(url: str) -> object:
+ """
+ Transform an url in git and https.
+ :param url: The url to transform in https and git
+ :return: (url, url_https, url_git)
+ """
+ if "https" in url:
+ url_git = f"git@{url[8:].replace('/', ':', 1)}"
+ url_https = url
+ else:
+ url_https = f"https://{(url[4:]).replace(':', '/')}"
+ url_git = url
+
+ return url, url_https, url_git
+
+ def get_transformed_repo_info_from_url(self, url: str, repo_path: str = "./",
+ get_obj: bool = True,
+ is_submodule: bool = True,
+ organization_force: str = None,
+ sub_path: str = "addons") -> object:
+ """
+
+ :param url:
+ :param repo_path:
+ :param get_obj:
+ :param is_submodule:
+ :param path:
+ :param organization_force: Keep repo_path and change organization
+ :return:
+ """
+ _, url_https, url_git = self.get_url(url)
+ url_split = url_https.split("/")
+ organization = url_split[3]
+ repo_name = url_split[4]
+ if repo_name[-4:] == ".git":
+ repo_name = repo_name[:-4]
+ if is_submodule:
+ if not sub_path or sub_path == ".":
+ path = f"{repo_name}"
+ else:
+ path = f"{sub_path}/{organization}_{repo_name}"
+ else:
+ path = f"{repo_path}"
+ if repo_path[-1] == "/":
+ relative_path = f"{repo_path}{path}"
+ else:
+ relative_path = f"{repo_path}/{path}"
+ relative_path = os.path.normpath(relative_path)
+
+ if organization_force:
+ organization = organization_force
+ url_split = url_https.split("/")
+ url_split[3] = organization
+ url_https = "/".join(url_split)
+ url, _, url_git = self.get_url(url_https)
+
+ d = {
+ "url": url,
+ "url_git": url_git,
+ "url_https": url_https,
+ "organization": organization,
+ "repo_name": repo_name,
+ "path": path,
+ "relative_path": relative_path,
+ "is_submodule": is_submodule,
+ "sub_path": sub_path,
+ }
+ if get_obj:
+ return Struct(**d)
+ return d
+
+ @staticmethod
+ def get_repo_info_submodule(repo_path: str = "./", add_root: bool = False,
+ upstream: str = "origin") -> list:
+ """
+ Get information about submodule from repo_path
+ :param repo_path: path of repo to get information about submodule
+ :param add_root: add information about root repository
+ :param upstream: Use this upstream of root
+ :return:
+ [{
+ "url": original_url,
+ "url_https": url in https,
+ "url_git": url in git,
+ "path": path of the submodule
+ "relative_path": relative path of the submodule
+ "name": name of the submodule
+ }]
+ """
+ filename = f"{repo_path}/.gitmodules"
+ lst_repo = []
+ with open(filename) as file:
+ txt = file.readlines()
+
+ name = ""
+ url = ""
+ no_line = 0
+ first_execution = True
+ for line in txt:
+ no_line += 1
+ if line[:12] == "[submodule \"":
+ if not first_execution:
+ data = {
+ "url": url,
+ "url_https": url_https,
+ "url_git": url_git,
+ "path": path,
+ "relative_path": f"{repo_path}/{path}",
+ "name": name,
+ }
+ lst_repo.append(data)
+ name = line[12:-3]
+ first_execution = False
+ continue
+ elif line[:7] == "\turl = ":
+ url = line[7:-1]
+ if "https" in url:
+ url_git = f"git@{url[8:].replace('/', ':', 1)}"
+ url_https = url
+ else:
+ url_https = f"https://{(url[4:]).replace(':', '/')}"
+ url_git = url
+ continue
+ elif line[:8] == "\tpath = ":
+ path = line[8:-1]
+ else:
+ if not line.strip():
+ continue
+ raise Exception(".gitmodules seems not correctly formatted.")
+
+ if not first_execution:
+ # Get last item
+ data = {
+ "url": url,
+ "url_https": url_https,
+ "url_git": url_git,
+ "path": path,
+ "relative_path": f"{repo_path}/{path}",
+ "name": name,
+ }
+ lst_repo.append(data)
+
+ if add_root:
+ repo_root = Repo(repo_path)
+ url = repo_root.git.remote("get-url", "origin")
+ if "https" in url:
+ url_git = f"git@{url[8:].replace('/', ':', 1)}"
+ url_https = url
+ else:
+ url_https = f"https://{(url[4:]).replace(':', '/')}"
+ url_git = url
+
+ data = {
+ "url": url,
+ "url_https": url_https,
+ "url_git": url_git,
+ "path": repo_path,
+ "name": "",
+ }
+ lst_repo.insert(0, data)
+ # Sort
+ lst_repo = sorted(lst_repo, key=lambda k: k.get("name"))
+ return lst_repo
+
+ @staticmethod
+ def get_repo_info_from_data_structure(repo_path="./", ignore_odoo=False):
+ """
+ Deprecated, read file addons_repo_origin to obtains repo list.
+ :return:
+ [{
+ "url": original_url,
+ "url_https": url in https,
+ "url_git": url in git,
+ "path": path of the submodule
+ "relative_path": relative path of the submodule
+ "name": name of the submodule
+ }]
+ """
+ dct_config = {
+ "addons": addons_repo_origin.config_addons
+ }
+ if not ignore_odoo:
+ dct_config[""] = addons_repo_origin.config
+ result = []
+ for c_path, dct_config in dct_config.items():
+ for server, dct_organization in dct_config.items():
+ for organization, lst_repo in dct_organization.items():
+ for repo in lst_repo:
+ url = f"https://{server}/{organization}/{repo}.git"
+ url_https = f"https://{server}/{organization}/{repo}.git"
+ url_git = f"git@{server}:{organization}/{repo}.git"
+ if not c_path:
+ path = f"{repo}"
+ else:
+ path = f"{c_path}/{organization}_{repo}"
+
+ name = path
+ result.append(
+ {
+ "url": url,
+ "url_https": url_https,
+ "url_git": url_git,
+ "relative_path": f"{repo_path}/{path}",
+ "path": path,
+ "name": name,
+ }
+ )
+ return result
+
+ @staticmethod
+ def get_project_config(repo_path="./"):
+ """
+ Get information about configuration in env_var.sh
+ :param repo_path: path of repo to get information env_var.sh
+ :return:
+ {
+ CST_GITHUB_TOKEN: TOKEN,
+ }
+ """
+ filename = f"{repo_path}env_var.sh"
+ with open(filename) as file:
+ txt = file.readlines()
+ txt = [a[:-1] for a in txt if "=" in a]
+
+ lst_filter = [CST_GITHUB_TOKEN]
+ dct_config = {}
+ # Take filtered value and get bash string values
+ for f in lst_filter:
+ for v in txt:
+ if f in v:
+ lst_v = v.split("=")
+ if len(lst_v) > 1:
+ dct_config[CST_GITHUB_TOKEN] = v.split("=")[1][1:-1]
+ return dct_config
+
+ @staticmethod
+ def open_repo_web_browser(dct_repo):
+ url = dct_repo.get("url_https")
+ if url:
+ webbrowser.open_new_tab(url)
+
+ def generate_repo_source_from_building(self, repo_path="./"):
+ """
+ Generate csv file with information about all source addons repo of Odoo
+ :param repo_path: Path to build repo source
+ :return:
+ """
+ file_name = f"{repo_path}{CST_FILE_SOURCE_REPO_ADDONS_ODOO}"
+ lst_repo_info = self.get_repo_info_from_data_structure(ignore_odoo=True)
+ lst_result = [f"{a.get('url_https')}\n" for a in lst_repo_info]
+ with open(file_name, "w") as file:
+ file.writelines(lst_result)
+
+ def generate_odoo_install_locally(self, repo_path="./"):
+ # lst_repo = self.get_repo_info_from_data_structure(ignore_odoo=True)
+ lst_repo = self.get_repo_info_submodule(repo_path=repo_path)
+ lst_result = []
+ for repo in lst_repo:
+ # Exception, ignore addons/OCA_web and root
+ if "addons/OCA_web" == repo.get("path") or \
+ "odoo" == repo.get("path"):
+ continue
+ str_repo = f' printf "${{OE_HOME}}/{repo.get("path")}," >> ' \
+ f'${{OE_CONFIG_FILE}}\n'
+ lst_result.append(str_repo)
+ with open(f"{repo_path}script/odoo_install_locally.sh") as file:
+ all_lines = file.readlines()
+ # search place to add/replace lines
+ index = 0
+ find_index = False
+ index_find = 0
+ for line in all_lines:
+ if not find_index and "if [ $MINIMAL_ADDONS = \"False\" ]; then\n" == line:
+ index_find = index + 1
+ for insert_line in lst_result:
+ all_lines.insert(index_find, insert_line)
+ index_find += 1
+ find_index = True
+ # Delete all next line until meet fi
+ if find_index and "fi\n" == line:
+ # slice it
+ all_lines = all_lines[0:index_find] + all_lines[index:]
+ break
+ index += 1
+
+ # create file
+ with open(f"{repo_path}script/odoo_install_locally.sh", mode="w") as file:
+ file.writelines(all_lines)
+
+ def generate_git_modules(self, lst_repo: List[Struct], repo_path: str = "./"):
+ lst_modules = []
+ for repo in lst_repo:
+ if repo.is_submodule:
+ lst_modules.append(f"[submodule \"{repo.path}\"]\n"
+ f"\turl = {repo.url_https}\n"
+ f"\tpath = {repo.path}\n")
+
+ # create file
+ with open(f"{repo_path}.gitmodules", mode="w") as file:
+ file.writelines(lst_modules)
+
+ def get_source_repo_addons(self, repo_path="./", add_repo_root=False):
+ """
+ Read file CST_FILE_SOURCE_REPO_ADDONS_ODOO and return structure of data
+ :param repo_path: path to find file CST_FILE_SOURCE_REPO_ADDONS_ODOO
+ :param add_repo_root: force adding repo root in the list
+ :return:
+ [{
+ "url": original_url,
+ "url_https": url in https,
+ "url_git": url in git,
+ "path": path of the submodule
+ "relative_path": relative path of the submodule
+ "name": name of the submodule
+ }]
+ """
+ file_name = f"{repo_path}{CST_FILE_SOURCE_REPO_ADDONS_ODOO}"
+ lst_result = []
+ if add_repo_root:
+ # TODO what to do if origin not exist?
+ repo = Repo(repo_path)
+ url = [a for a in repo.remotes][0].url
+ repo_info = self.get_transformed_repo_info_from_url(url,
+ repo_path=repo_path,
+ get_obj=False,
+ is_submodule=False)
+ lst_result.append(repo_info)
+ with open(file_name) as file:
+ all_lines = file.readlines()
+ if all_lines:
+ # Ignore first line
+ all_lines = all_lines[1:]
+ for line in all_lines:
+ # Separate information with path in tuple
+ line_split = line[:-1].split(',')
+ if len(line_split) != 2:
+ print(f"Error with line {line}, suppose to have only 1 ','.")
+ exit(1)
+ url, path = line_split
+ repo_info = self.get_transformed_repo_info_from_url(url,
+ repo_path=repo_path,
+ get_obj=False,
+ sub_path=path)
+ lst_result.append(repo_info)
+ return lst_result
+
+ def get_matching_repo(self, actual_repo="./", repo_compare_to="./",
+ force_normalize_compare=False):
+ """
+ Compare repo with .gitmodules files
+ :param actual_repo:
+ :param repo_compare_to:
+ :param force_normalize_compare: update name of compare repo
+ :return:
+ """
+ lst_repo_info_actual = self.get_repo_info_submodule(actual_repo)
+ dct_repo_info_actual = {a.get("name"): a for a in lst_repo_info_actual}
+ set_actual = set(dct_repo_info_actual.keys())
+ # set_actual_repo = set(
+ # [a[a.find("_") + 1:] for a in dct_repo_info_actual.keys()])
+
+ dct_repo_info_actual_adapted = {key[key.find("_") + 1:]: item for key, item in
+ dct_repo_info_actual.items()}
+ set_actual_repo = set(dct_repo_info_actual_adapted.keys())
+
+ lst_repo_info_compare = self.get_repo_info_submodule(repo_compare_to)
+ if force_normalize_compare:
+ for repo_info in lst_repo_info_compare:
+ url_https = repo_info.get("url_https")
+ url_split = url_https.split("/")
+ organization = url_split[3]
+ repo_name = url_split[4][:-4]
+ # name = f"addons/{organization}_{repo_name}"
+ name = f"{repo_name}"
+ repo_info["name"] = name
+
+ dct_repo_info_compare = {a.get("name"): a for a in lst_repo_info_compare}
+ set_compare = set(dct_repo_info_compare.keys())
+
+ # TODO finish the match
+ # lst_same_name = set_actual.intersection(set_compare)
+ # lst_missing_name = set_compare.difference(set_actual)
+
+ lst_same_name_normalize = set_actual_repo.intersection(set_compare)
+ lst_missing_name_normalize = set_compare.difference(set_actual_repo)
+ lst_over_name_normalize = set_actual_repo.difference(set_compare)
+ print(f"Has {len(lst_same_name_normalize)} sames, "
+ f"{len(lst_missing_name_normalize)} missing, "
+ f"{len(lst_over_name_normalize)} more.")
+
+ lst_match = []
+ for key in lst_same_name_normalize:
+ lst_match.append((
+ dct_repo_info_actual_adapted[key],
+ dct_repo_info_compare[key]
+ ))
+
+ return lst_match
+
+ @staticmethod
+ def sync_to(lst_compare_repo_info):
+ i = 0
+ total = len(lst_compare_repo_info)
+ lst_same = []
+ lst_diff = []
+ for original, compare_to in lst_compare_repo_info:
+ i += 1
+ print(f"Nb element {i}/{total}")
+ repo_original = Repo(original.get("relative_path"))
+ commit_original = repo_original.head.object.hexsha
+ repo_compare = Repo(compare_to.get("relative_path"))
+ commit_compare = repo_compare.head.object.hexsha
+ if commit_original != commit_compare:
+ print(f"DIFF - {original.get('name')}")
+ lst_diff.append((original, compare_to))
+ repo_original.git.checkout(commit_compare)
+ else:
+ print(f"SAME - {original.get('name')}")
+ lst_same.append((original, compare_to))
+ print(f"finish same {len(lst_same)}, diff {len(lst_diff)}")
+
+ @staticmethod
+ def add_and_fetch_remote(repo_info: Struct):
+ working_repo = Repo(repo_info.relative_path)
+ if repo_info.organization in [a.name for a in working_repo.remotes]:
+ print(f"Remote \"{repo_info.organization}\" already exist "
+ f"in {repo_info.relative_path}")
+ return
+ # Add remote
+ upstream_remote = retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
+ working_repo.create_remote)(repo_info.organization, repo_info.url_https)
+ print('Remote "%s" created for %s' % (
+ repo_info.organization, repo_info.url_https))
+
+ # Fetch the remote
+ retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
+ upstream_remote.fetch)()
+ print('Remote "%s" fetched' % repo_info.organization)
+
+ def fork_repo(self, upstream_url: str, github_token: str,
+ organization_name: str = ""):
+ # https://developer.github.com/apps/building-integrations/setting-up-and-registering-oauth-apps/about-scopes-for-oauth-apps/
+ gh = GitHub(token=github_token)
+ parsed_url = parse(upstream_url)
+
+ # Fork the repo
+ status, user = gh.user.get()
+ user_name = user['login'] if not organization_name else organization_name
+ status, forked_repo = gh.repos[user_name][parsed_url.repo].get()
+ if status == 404:
+ status, upstream_repo = (
+ gh.repos[parsed_url.owner][parsed_url.repo].get())
+ if status == 404:
+ print("Unable to find repo %s" % upstream_url)
+ exit(1)
+ args = {}
+ if organization_name:
+ args["organization"] = organization_name
+ status, forked_repo = (
+ gh.repos[parsed_url.owner][parsed_url.repo].forks.post(**args))
+ if status == 404:
+ print("Error when forking repo %s" % forked_repo)
+ exit(1)
+ else:
+ print("Forked %s to %s" % (upstream_url, forked_repo['ssh_url']))
+ elif status == 202:
+ print("Forked repo %s already exists" % forked_repo['full_name'])
+ elif status != 200:
+ print("Status not supported: %s - %s" % (status, forked_repo))
+ exit(1)
+ return forked_repo
diff --git a/script/list_repo_diff.py b/script/list_repo_diff.py
new file mode 100644
index 0000000..dd9fa11
--- /dev/null
+++ b/script/list_repo_diff.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+import os
+import sys
+import webbrowser
+import argparse
+import logging
+from git import Repo
+
+from retrying import retry # pip install retrying
+
+new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..'))
+sys.path.append(new_path)
+
+from script.git_tool import GitTool
+from script import fork_github_repo
+
+_logger = logging.getLogger(__name__)
+CST_GITHUB_TOKEN = "GITHUB_TOKEN"
+
+
+def get_config():
+ """Parse command line arguments, extracting the config file name,
+ returning the union of config file and command line arguments
+
+ :return: dict of config file settings and command line arguments
+ """
+ # TODO update description
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description='''\
+''',
+ epilog='''\
+'''
+ )
+ parser.add_argument('-d', '--dir', dest="dir", default="./",
+ help="Path of repo to change remote, including submodule.")
+ args = parser.parse_args()
+ return args
+
+
+def main():
+ config = get_config()
+ lst_repo = GitTool.get_repo_info_submodule(repo_path=config.dir)
+ branch_search = "12.0"
+ # repo = Repo(root_path)
+ # repo_root = Repo(".")
+ lst_result = []
+
+ i = 0
+ total = len(lst_repo)
+ for repo in lst_repo:
+ i += 1
+ print(f"Nb element {i}/{total}")
+ repo_dir_root = repo.get("path")
+ remote_path = f"{config.dir}/{repo_dir_root}"
+ repo_root = Repo(remote_path)
+ repo_branch_search_sha = [a.object.hexsha for a in repo_root.branches if
+ branch_search in a.name]
+ if repo_branch_search_sha:
+ repo_branch_search_sha = repo_branch_search_sha[0]
+ else:
+ print(f"Error, missing branch {branch_search} in {remote_path}")
+ continue
+ lst_result.append((remote_path, repo_root.head.commit.hexsha,
+ repo_root.head.commit.hexsha != repo_branch_search_sha))
+
+ # print(repo_root)
+
+ # # Create the remote upstream
+ # split_url = url.split("/")
+ # split_url[-2] = upstream_name
+ # upstream_url = "/".join(split_url)
+ #
+ # cloned_repo = Repo(repo_dir_root)
+ # try:
+ # upstream_remote = cloned_repo.remote(upstream_name)
+ # print('Remote "%s" already exists in %s' %
+ # (upstream_name, repo_dir_root))
+ # except ValueError:
+ # upstream_remote = retry(
+ # wait_exponential_multiplier=1000,
+ # stop_max_delay=15000
+ # )(cloned_repo.create_remote)(upstream_name, upstream_url)
+ # print('Remote "%s" created for %s' % (upstream_name, upstream_url))
+ #
+ # try:
+ # # Fetch the remote upstream
+ # retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
+ # upstream_remote.fetch)()
+ # print('Remote "%s" fetched' % upstream_name)
+ # except Exception:
+ # print(f"ERROR git {repo_dir_root} remote {upstream_name} not exist.")
+ # upstream_remote.remove(upstream_remote, upstream_name)
+
+ i = 0
+ i_len = len(lst_result)
+ for path, hash, diff in lst_result:
+ i += 1
+ if diff:
+ print(f"{i:02d}/{i_len} {diff} {path}\t{hash}")
+
+ # lst_repo = GitTool.get_repo_info_from_data_structure()
+ # for repo in lst_repo:
+ # repo_dir_root = repo.get("path")
+ # repo_root = Repo(remote_path)
+ # repo_root.git.checkout()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/script/odoo_install_OSX_dependancy.sh b/script/odoo_install_OSX_dependancy.sh
new file mode 100755
index 0000000..f6e3398
--- /dev/null
+++ b/script/odoo_install_OSX_dependancy.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+################################################################################
+# Script for installing Odoo on OSX
+# Author: Alexandre Ferreira Benevides
+#-------------------------------------------------------------------------------
+# This script will install dependency for Odoo on your OSX server.
+#-------------------------------------------------------------------------------
+################################################################################
+
+OE_USER=$(whoami)
+
+#--------------------------------------------------
+# Install PostgreSQL Server
+#--------------------------------------------------
+echo "\n---- Install PostgreSQL Server ----"
+brew install postgresql
+
+echo "\n---- Creating the ODOO PostgreSQL User ----"
+sudo su - postgres -c "createuser -s ${OE_USER}" 2> /dev/null || true
+
+#--------------------------------------------------
+# Install Dependencies
+#--------------------------------------------------
+echo "\n--- Installing Python 3 + pip3 --"
+brew install git python3 wget
+brew link git
+brew link wget
+echo "\n---- Installing nodeJS NPM and rtlcss for LTR support ----"
+brew install nodejs npm
+sudo npm install -g rtlcss
+
+#--------------------------------------------------
+# Install Wkhtmltopdf if needed
+#--------------------------------------------------
+echo "\n---- Installing Wkhtmltopdf if needed ----"
+if [ ! -f "wkhtmltox-0.12.5-1.macos-carbon.pkg" ]; then
+ sudo wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox-0.12.5-1.macos-carbon.pkg
+ sudo sudo installer -pkg wkhtmltox-0.12.5-1.macos-carbon.pkg -target /
+else echo "Wkhtmltopdf already installed"
+fi
+
+# ===============================================================================================
+# !!!! FOR OSX there is a problem with python 3.7.5 with PILLOW, use 3.6.9 instead and works fine
+# install python 3.6.9
+# brew install pyenv
+# pyenv install 3.6.9
+# then redoo link:
+# unlink /usr/local/bin/python3
+# ln -s ~/.pyenv/versions/3.6.9/bin/python3.6 /usr/local/bin/python3
+# ===============================================================================================
+echo "\n---- Installing venv if not already existing (rm -r venv if already exists) ----"
+~/.pyenv/versions/3.6.9/bin/python3.6 -m venv venv
diff --git a/script/odoo_install_daemon.sh b/script/odoo_install_daemon.sh
new file mode 100755
index 0000000..9d03565
--- /dev/null
+++ b/script/odoo_install_daemon.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+################################################################################
+# Script for installing Odoo on Ubuntu 14.04, 15.04, 16.04 and 18.04 (could be used for other version too)
+# Author: Yenthe Van Ginneken
+#-------------------------------------------------------------------------------
+# This script will install Odoo on your Ubuntu 16.04 server. It can install multiple Odoo instances
+# in one Ubuntu because of the different xmlrpc_ports
+#-------------------------------------------------------------------------------
+################################################################################
+
+. ../env_var.sh
+
+#OE_USER="odoo"
+#OE_HOME="/${OE_USER}/odoo"
+#OE_HOME_EXT="/${OE_USER}/odoo/odoo/odoo"
+## The default port where this Odoo instance will run under (provided you use the command -c in the terminal)
+## Set to true if you want to install it, false if you don't need it or have it already installed.
+#INSTALL_WKHTMLTOPDF="True"
+## Set the default Odoo port (you still have to use -c /etc/odoo-server.conf for example to use this.)
+#OE_PORT="8069"
+## set the superadmin password
+#OE_SUPERADMIN="admin"
+#OE_CONFIG="${OE_USER}"
+
+#--------------------------------------------------
+# Adding ODOO as a deamon with SystemD
+#--------------------------------------------------
+echo -e "\n* Create init file"
+sudo rm -f /tmp/${OE_CONFIG}
+cat < /tmp/${OE_CONFIG}
+[Unit]
+Description=${OE_USER}
+Requires=postgresql.service
+After=network.target network-online.target postgresql.service
+
+[Service]
+Type=simple
+SyslogIdentifier=${OE_USER}
+PermissionsStartOnly=true
+User=${OE_USER}
+Group=${OE_USER}
+Restart=always
+RestartSec=5
+PIDFile=${OE_HOME_ODOO}/venv/service.pid
+ExecStart=${OE_HOME_ODOO}/venv/run.sh
+StandardOutput=journal+console
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+echo -e "* Security Init File"
+sudo cp /tmp/${OE_CONFIG} /etc/systemd/system/${OE_CONFIG}.service
+sudo chmod 755 /etc/systemd/system/${OE_CONFIG}.service
+sudo chown root: /etc/systemd/system/${OE_CONFIG}.service
+
+echo -e "* Start ODOO on Startup"
+sudo systemctl daemon-reload
+sudo systemctl enable ${OE_CONFIG}.service
+
+sudo su ${OE_USER} -c "sudo rm -f /tmp/${OE_USER}run.sh"
+cat < /tmp/${OE_USER}run.sh
+#!/usr/bin/env bash
+cd ${OE_HOME_ODOO}
+source ./venv/bin/activate
+python3 ${OE_HOME_ODOO}/odoo/odoo-bin -c ${OE_HOME_ODOO}/config.conf
+EOF
+
+echo -e "* Security Run File"
+sudo cp /tmp/${OE_USER}run.sh ${OE_HOME_ODOO}/venv/run.sh
+sudo chmod 755 ${OE_HOME_ODOO}/venv/run.sh
+sudo chown ${OE_USER}: ${OE_HOME_ODOO}/venv/run.sh
+
+echo "-----------------------------------------------------------"
+echo "Done! The Odoo server is up and running. Specifications:"
+echo "Port: ${OE_PORT}"
+echo "Port Long Polling: ${OE_LONGPOLLING_PORT}"
+echo "User service: ${OE_USER}"
+echo "User PostgreSQL: ${OE_USER}"
+echo "Code location: ${OE_USER}"
+echo "Addons folder: ${OE_USER}/${OE_CONFIG}/addons/"
+echo "Start Odoo service: sudo systemctl start ${OE_CONFIG}"
+echo "Stop Odoo service: sudo systemctl stop ${OE_CONFIG}"
+echo "Restart Odoo service: sudo systemctl restart ${OE_CONFIG}"
+echo "-----------------------------------------------------------"
+
+echo -e "* Starting Odoo Service"
+sudo systemctl restart ${OE_CONFIG}.service
diff --git a/script/odoo_install_debian_dependancy.sh b/script/odoo_install_debian_dependancy.sh
new file mode 100755
index 0000000..f3754e8
--- /dev/null
+++ b/script/odoo_install_debian_dependancy.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+################################################################################
+# Script for installing Odoo on Ubuntu 14.04, 15.04, 16.04 and 18.04 (could be used for other version too)
+# Author: Yenthe Van Ginneken
+#-------------------------------------------------------------------------------
+# This script will install Odoo on your Ubuntu 16.04 server. It can install multiple Odoo instances
+# in one Ubuntu because of the different xmlrpc_ports
+#-------------------------------------------------------------------------------
+################################################################################
+
+. ../env_var.sh
+
+OE_USER=$(whoami)
+# The default port where this Odoo instance will run under (provided you use the command -c in the terminal)
+# Set to true if you want to install it, false if you don't need it or have it already installed.
+#INSTALL_WKHTMLTOPDF="True"
+
+##
+### WKHTMLTOPDF download links
+## === Ubuntu Trusty x64 & x32 === (for other distributions please replace these two links,
+## in order to have correct version of wkhtmltopdf installed, for a danger note refer to
+## https://github.com/odoo/odoo/wiki/Wkhtmltopdf ):
+WKHTMLTOX_X64=https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.trusty_amd64.deb
+WKHTMLTOX_X32=https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.trusty_i386.deb
+
+#--------------------------------------------------
+# Update Server
+#--------------------------------------------------
+echo -e "\n---- Update Server ----"
+
+# add-apt-repository can install add-apt-repository Ubuntu 18.x
+sudo apt-get install software-properties-common -y
+# universe package is for Ubuntu 18.x
+sudo add-apt-repository universe
+# libpng12-0 dependency for wkhtmltopdf
+sudo add-apt-repository "deb http://mirrors.kernel.org/ubuntu/ xenial main"
+sudo apt-get update
+sudo apt-get upgrade -y
+
+#--------------------------------------------------
+# Install PostgreSQL Server
+#--------------------------------------------------
+echo -e "\n---- Install PostgreSQL Server ----"
+sudo apt-get install postgresql -y
+
+echo -e "\n---- Creating the ODOO PostgreSQL User ----"
+sudo su - postgres -c "createuser -s $OE_USER" 2> /dev/null || true
+
+#--------------------------------------------------
+# Install Dependencies
+#--------------------------------------------------
+echo -e "\n--- Installing Python 3 + pip3 --"
+sudo apt-get install git python3 python3-pip build-essential wget python3-dev python3-venv python3-wheel libxslt-dev libzip-dev libldap2-dev libsasl2-dev python3-setuptools node-less libpng12-0 gdebi -y
+
+echo -e "\n---- Installing nodeJS NPM and rtlcss for LTR support ----"
+sudo apt-get install nodejs npm -y
+sudo npm install -g rtlcss
+
+if [ ${INSTALL_NGINX} = "True" ]; then
+ sudo apt install nginx -y
+fi
+
+#--------------------------------------------------
+# Install Wkhtmltopdf if needed
+#--------------------------------------------------
+if [ ${INSTALL_WKHTMLTOPDF} = "True" ]; then
+ INSTALLED=$(dpkg -s wkhtmltox|grep installed)
+ if [ "" == "${INSTALLED}" ]; then
+ echo -e "\n---- Install wkhtml and place shortcuts on correct place for ODOO 12 ----"
+ #pick up correct one from x64 & x32 versions:
+ if [ "`getconf LONG_BIT`" == "64" ];then
+ _url=$WKHTMLTOX_X64
+ else
+ _url=$WKHTMLTOX_X32
+ fi
+ sudo wget ${_url}
+ sudo gdebi --n `basename ${_url}`
+ sudo ln -s /usr/local/bin/wkhtmltopdf /usr/bin
+ sudo ln -s /usr/local/bin/wkhtmltoimage /usr/bin
+ fi
+else
+ echo "Wkhtmltopdf isn't installed due to the choice of the user!"
+fi
diff --git a/script/odoo_install_dev.sh b/script/odoo_install_dev.sh
new file mode 100755
index 0000000..2f5f67b
--- /dev/null
+++ b/script/odoo_install_dev.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+################################################################################
+# Script for installing Odoo locally for dev
+# Author: Alexandre Ferreira Benevides
+################################################################################
+
+. ../env_var.sh
+
+if [[ "${OSTYPE}" == "linux-gnu" ]]; then
+ OS=$(lsb_release -si)
+ if [[ "${OS}" == "Ubuntu" ]]; then
+ echo "\n---- linux-gnu installation process started ----"
+ ./odoo_install_debian_dependancy.sh
+ ./odoo_install_locally.sh
+ else
+ echo "Your Linux system is not supported."
+ fi
+elif [[ "${OSTYPE}" == "darwin"* ]]; then
+ echo "\n---- Darwin installation process started ----"
+ ./odoo_install_OSX_dependancy.sh
+ ./odoo_install_locally.sh
+fi
diff --git a/script/odoo_install_locally.sh b/script/odoo_install_locally.sh
new file mode 100755
index 0000000..2ebaf2e
--- /dev/null
+++ b/script/odoo_install_locally.sh
@@ -0,0 +1,168 @@
+#!/bin/bash
+################################################################################
+# Script for installing Odoo on Ubuntu 14.04, 15.04, 16.04 and 18.04 (could be used for other version too)
+# Author: Yenthe Van Ginneken
+#-------------------------------------------------------------------------------
+# This script will install Odoo on your Ubuntu 16.04 server. It can install multiple Odoo instances
+# in one Ubuntu because of the different xmlrpc_ports
+#-------------------------------------------------------------------------------
+# Make a new file:
+# sudo nano odoo-install.sh
+# Place this content in it and then make the file executable:
+# sudo chmod +x odoo-install.sh
+# Execute the script to install Odoo:
+# ./odoo-install
+################################################################################
+
+. ./env_var.sh
+
+OE_USER=$(whoami)
+OE_HOME=$PWD
+OE_HOME_EXT="${OE_HOME}/odoo"
+# The default port where this Odoo instance will run under (provided you use the command -c in the terminal)
+# Set to true if you want to install it, false if you don't need it or have it already installed.
+#INSTALL_WKHTMLTOPDF="True"
+# Set the default Odoo port (you still have to use -c /etc/odoo-server.conf for example to use this.)
+#OE_PORT="8069"
+#OE_LONGPOLLING_PORT="8072"
+# Choose the Odoo version which you want to install. For example: 12.0, 11.0, 10.0 or saas-18. When using 'master' the master version will be installed.
+# IMPORTANT! This script contains extra libraries that are specifically needed for Odoo 12.0
+#OE_VERSION="stable_prod_12.0"
+# set the superadmin password
+#OE_SUPERADMIN="admin"
+OE_CONFIG_FILE="${OE_HOME}/config.conf"
+#OE_CONFIG="${OE_USER}"
+#MINIMAL_ADDONS="False"
+#INSTALL_NGINX="True"
+
+echo -e "* Create server config file"
+
+touch ${OE_CONFIG_FILE}
+echo -e "* Creating server config file"
+printf '[options] \n; This is the password that allows database operations:\n' > ${OE_CONFIG_FILE}
+printf "admin_passwd = ${OE_SUPERADMIN}\n" >> ${OE_CONFIG_FILE}
+printf "db_host = False\n" >> ${OE_CONFIG_FILE}
+printf "db_port = False\n" >> ${OE_CONFIG_FILE}
+printf "db_user = ${OE_USER}\n" >> ${OE_CONFIG_FILE}
+printf "db_password = False\n" >> ${OE_CONFIG_FILE}
+printf "xmlrpc_port = ${OE_PORT}\n" >> ${OE_CONFIG_FILE}
+printf "longpolling_port = ${OE_LONGPOLLING_PORT}\n" >> ${OE_CONFIG_FILE}
+
+printf "addons_path = ${OE_HOME_EXT}/addons,${OE_HOME}/addons/addons," >> ${OE_CONFIG_FILE}
+printf "${OE_HOME}/addons/OCA_web," >> ${OE_CONFIG_FILE}
+if [ $MINIMAL_ADDONS = "False" ]; then
+ printf "${OE_HOME}/addons/MathBenTech_development," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/MathBenTech_odoo-business-spending-management-quebec-canada," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/MathBenTech_scrummer," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-base-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-entertainment-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-git-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-hr-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-partner-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-product-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-project-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-purchase-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-stock-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-survey-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-timesheet-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Numigi_odoo-web-addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-analytic," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-budgeting," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-closing," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-consolidation," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-financial-reporting," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-financial-tools," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-fiscal-rule," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-invoice-reporting," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-invoicing," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-payment," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_account-reconcile," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_apps-store," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_bank-payment," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_bank-statement-import," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_brand," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_business-requirement," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_commission," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_community-data-files," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_connector-telephony," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_contract," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_credit-control," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_currency," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_data-protection," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_donation," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_e-commerce," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_edi," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_event," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_helpdesk," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_hr," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_knowledge," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_l10n-canada," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_maintenance," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_management-system," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_manufacture," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_margin-analysis," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_mis-builder," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_multi-company," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_partner-contact," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_pos," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_product-attribute," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_product-pack," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_product-variant," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_project," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_project-reporting," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_purchase-workflow," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_queue," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_reporting-engine," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_sale-workflow," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_server-auth," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_server-brand," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_server-env," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_server-tools," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_server-ux," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_social," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_stock-logistics-warehouse," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_timesheet," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_website," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/OCA_wms," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/Smile-SA_odoo_addons," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/muk-it_muk_base," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/muk-it_muk_dms," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/muk-it_muk_docs," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/muk-it_muk_misc," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/muk-it_muk_quality," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/muk-it_muk_web," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/muk-it_muk_website," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/odooaktiv_QuotationRevision," >> ${OE_CONFIG_FILE}
+ printf "${OE_HOME}/addons/openeducat_openeducat_erp," >> ${OE_CONFIG_FILE}
+fi
+printf "\n" >> ${OE_CONFIG_FILE}
+
+printf "workers = 0\n" >> ${OE_CONFIG_FILE}
+printf "max_cron_threads = 2\n" >> ${OE_CONFIG_FILE}
+
+if [ ${INSTALL_NGINX} = "True" ]; then
+ printf "xmlrpc_interface = 127.0.0.1\n" >> ${OE_CONFIG_FILE}
+ printf "netrpc_interface = 127.0.0.1\n" >> ${OE_CONFIG_FILE}
+ printf "proxy_mode = True\n" >> ${OE_CONFIG_FILE}
+fi
+
+echo -e "\n---- Install Odoo with addons module ----"
+git submodule update --init
+
+echo -e "\n---- Create Virtual environment Python ----"
+cd ${OE_HOME}
+python3 -m venv venv
+cd -
+
+echo -e "\n---- Install python packages/requirements ----"
+${OE_HOME}/venv/bin/pip3 install --upgrade pip
+${OE_HOME}/venv/bin/pip3 install wheel phonenumbers
+${OE_HOME}/venv/bin/pip3 install -r "${OE_HOME}/odoo/requirements.txt"
+${OE_HOME}/venv/bin/pip3 install -r "${OE_HOME}/requirements.txt"
+
+# For dev/testing
+${OE_HOME}/venv/bin/pip3 install websocket-client
+
+echo -e "\n---- Add link dependency in site-packages of Python ----"
+ln -fs ${OE_HOME_EXT}/odoo ${OE_HOME}/venv/lib/python3.7/site-packages/
+ln -fs ${OE_HOME_EXT}/odoo ${OE_HOME}/venv/lib/python3.6/site-packages/
diff --git a/script/odoo_install_production.sh b/script/odoo_install_production.sh
new file mode 100755
index 0000000..8b5b165
--- /dev/null
+++ b/script/odoo_install_production.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+################################################################################
+# Script for installing Odoo on Ubuntu 14.04, 15.04, 16.04 and 18.04 (could be used for other version too)
+# Author: Yenthe Van Ginneken
+#-------------------------------------------------------------------------------
+# This script will install Odoo on your Ubuntu 16.04 server. It can install multiple Odoo instances
+# in one Ubuntu because of the different xmlrpc_ports
+#-------------------------------------------------------------------------------
+################################################################################
+
+. ../env_var.sh
+
+./odoo_install_debian_dependancy.sh
+
+echo -e "\n---- Create ODOO system user ----"
+sudo adduser --system --quiet --shell=/bin/bash --home=/${OE_USER} --gecos 'ODOO' --group ${OE_USER}
+#The user should also be added to the sudo'ers group.
+sudo adduser ${OE_USER} sudo
+
+echo -e "\n---- Creating the ODOO PostgreSQL User ----"
+sudo su - postgres -c "createuser -s ${OE_USER}" 2> /dev/null || true
+
+#echo -e "\n---- Create Log directory ----"
+#sudo mkdir /var/log/${OE_USER}
+#sudo chown ${OE_USER}:${OE_USER} /var/log/${OE_USER}
+
+echo -e "\n---- Setting permissions on home folder ----"
+sudo mkdir -p ${OE_HOME}
+sudo chown -R ${OE_USER}:${OE_USER} ${OE_HOME}
+
+#--------------------------------------------------
+# Install ODOO
+#--------------------------------------------------
+echo -e "\n==== Clone this installation ===="
+REMOTE_URL_GIT=`git remote get-url origin`
+BRANCH_GIT=`git rev-parse --abbrev-ref HEAD`
+sudo su ${OE_USER} -c "git clone --branch ${BRANCH_GIT} ${REMOTE_URL_GIT} ${OE_HOME_ODOO}"
+sudo cp ../env_var.sh ${OE_HOME_ODOO}
+sudo chown -R ${OE_USER}:${OE_USER} ${OE_HOME_ODOO}/env_var.sh
+
+LAST_PWD=$PWD
+cd ${OE_HOME_ODOO}
+sudo su ${OE_USER} -c "./odoo_install_locally.sh"
+cd ${LAST_PWD}
+#echo -e "\n* Updating server config file"
+#sudo su ${OE_USER} -c "printf 'logfile = /var/log/${OE_USER}/${OE_CONFIG}.log\n' >> /${OE_USER}/odoo/config.conf"
+
+#--------------------------------------------------
+# Adding ODOO as a daemon
+#--------------------------------------------------
+./odoo_install_daemon.sh
+
+#--------------------------------------------------
+# Install Nginx if needed
+#--------------------------------------------------
+./odoo_install_production_nginx.sh
\ No newline at end of file
diff --git a/script/odoo_install_production_nginx.sh b/script/odoo_install_production_nginx.sh
new file mode 100755
index 0000000..9665557
--- /dev/null
+++ b/script/odoo_install_production_nginx.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+################################################################################
+# Script for installing Odoo on Ubuntu 14.04, 15.04, 16.04 and 18.04 (could be used for other version too)
+# Author: Yenthe Van Ginneken
+#-------------------------------------------------------------------------------
+# This script will install Odoo on your Ubuntu 16.04 server. It can install multiple Odoo instances
+# in one Ubuntu because of the different xmlrpc_ports
+#-------------------------------------------------------------------------------
+################################################################################
+
+. ../env_var.sh
+
+#--------------------------------------------------
+# Install Nginx if needed
+#--------------------------------------------------
+if [ ${INSTALL_NGINX} = "True" ]; then
+ echo -e "\n---- Installing and setting up Nginx ----"
+ cat < /tmp/nginx${OE_USER}
+upstream odoo${OE_USER} {
+ server 127.0.0.1:${OE_PORT};
+}
+upstream odoo${OE_USER}chat {
+ server 127.0.0.1:${OE_LONGPOLLING_PORT};
+}
+
+server {
+ listen 80;
+
+ server_name ${WEBSITE_NAME};
+
+ # Add Headers for odoo proxy mode
+ proxy_set_header X-Forwarded-Host \$host;
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto \$scheme;
+ proxy_set_header X-Real-IP \$remote_addr;
+ add_header X-Frame-Options "SAMEORIGIN";
+ add_header X-XSS-Protection "1; mode=block";
+
+ # odoo request log files
+ access_log /var/log/nginx/${OE_USER}-access.log;
+ error_log /var/log/nginx/${OE_USER}-error.log;
+
+ # Increase proxy buffer size
+ proxy_buffers 16 64k;
+ proxy_buffer_size 128k;
+
+ proxy_read_timeout 720s;
+ proxy_connect_timeout 720s;
+ proxy_send_timeout 720s;
+
+ # Force timeouts if the backend dies
+ proxy_next_upstream error timeout invalid_header http_500 http_502
+ http_503;
+
+ types {
+ text/less less;
+ text/scss scss;
+ }
+
+ # Enable data compression
+ gzip on;
+ gzip_min_length 1100;
+ gzip_buffers 4 32k;
+ gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript application/pdf image/jpeg image/png;
+ gzip_vary on;
+ client_header_buffer_size 4k;
+ large_client_header_buffers 4 64k;
+ client_max_body_size 1024M;
+
+ location / {
+ proxy_pass http://odoo${OE_USER};
+ # by default, do not forward anything
+ proxy_redirect off;
+ }
+
+ location /longpolling {
+ proxy_pass http://odoo${OE_USER}chat;
+ }
+
+ # cache some static data in memory for 60mins.
+ location ~ /[a-zA-Z0-9_-]*/static/ {
+ proxy_cache_valid 200 302 60m;
+ proxy_cache_valid 404 1m;
+ proxy_buffering on;
+ expires 864000;
+ proxy_pass http://odoo${OE_USER};
+ }
+}
+EOF
+
+ sudo mv -f /tmp/nginx${OE_USER} /etc/nginx/sites-available/${WEBSITE_NAME}
+ sudo ln -fs /etc/nginx/sites-available/${WEBSITE_NAME} /etc/nginx/sites-enabled/${WEBSITE_NAME}
+ sudo rm -f /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default
+ sudo systemctl restart nginx
+ echo "Done! The Nginx server is up and running. Configuration can be found at /etc/nginx/sites-enabled/${WEBSITE_NAME}"
+ echo "Run manually certbot : sudo certbot --nginx"
+else
+ echo "Nginx isn't installed due to choice of the user!"
+fi
diff --git a/source_repo_addons_odoo.csv b/source_repo_addons_odoo.csv
new file mode 100644
index 0000000..12e7adc
--- /dev/null
+++ b/source_repo_addons_odoo.csv
@@ -0,0 +1,86 @@
+url,path
+https://github.com/MathBenTech/development.git,addons
+https://github.com/MathBenTech/odoo-business-spending-management-quebec-canada.git,addons
+https://github.com/MathBenTech/scrummer.git,addons
+https://github.com/muk-it/muk_base.git,addons
+https://github.com/muk-it/muk_dms.git,addons
+https://github.com/muk-it/muk_docs.git,addons
+https://github.com/muk-it/muk_misc.git,addons
+https://github.com/muk-it/muk_quality.git,addons
+https://github.com/muk-it/muk_web.git,addons
+https://github.com/muk-it/muk_website.git,addons
+https://github.com/Numigi/odoo-base-addons.git,addons
+https://github.com/Numigi/odoo-entertainment-addons.git,addons
+https://github.com/Numigi/odoo-git-addons.git,addons
+https://github.com/Numigi/odoo-hr-addons.git,addons
+https://github.com/Numigi/odoo-partner-addons.git,addons
+https://github.com/Numigi/odoo-product-addons.git,addons
+https://github.com/Numigi/odoo-project-addons.git,addons
+https://github.com/Numigi/odoo-purchase-addons.git,addons
+https://github.com/Numigi/odoo-stock-addons.git,addons
+https://github.com/Numigi/odoo-survey-addons.git,addons
+https://github.com/Numigi/odoo-timesheet-addons.git,addons
+https://github.com/Numigi/odoo-web-addons.git,addons
+https://github.com/OCA/account-analytic.git,addons
+https://github.com/OCA/account-budgeting.git,addons
+https://github.com/OCA/account-closing.git,addons
+https://github.com/OCA/account-consolidation.git,addons
+https://github.com/OCA/account-financial-reporting.git,addons
+https://github.com/OCA/account-financial-tools,addons
+https://github.com/OCA/account-fiscal-rule.git,addons
+https://github.com/OCA/account-invoicing.git,addons
+https://github.com/OCA/account-invoice-reporting.git,addons
+https://github.com/OCA/account-payment.git,addons
+https://github.com/OCA/account-reconcile.git,addons
+https://github.com/OCA/apps-store.git,addons
+https://github.com/OCA/bank-payment.git,addons
+https://github.com/OCA/bank-statement-import.git,addons
+https://github.com/OCA/brand.git,addons
+https://github.com/OCA/business-requirement.git,addons
+https://github.com/OCA/commission.git,addons
+https://github.com/OCA/community-data-files.git,addons
+https://github.com/OCA/connector-telephony.git,addons
+https://github.com/OCA/contract.git,addons
+https://github.com/OCA/credit-control.git,addons
+https://github.com/OCA/currency.git,addons
+https://github.com/OCA/data-protection.git,addons
+https://github.com/OCA/donation.git,addons
+https://github.com/OCA/e-commerce.git,addons
+https://github.com/OCA/edi.git,addons
+https://github.com/OCA/event.git,addons
+https://github.com/OCA/helpdesk.git,addons
+https://github.com/OCA/hr.git,addons
+https://github.com/OCA/knowledge.git,addons
+https://github.com/OCA/l10n-canada.git,addons
+https://github.com/OCA/maintenance.git,addons
+https://github.com/OCA/management-system.git,addons
+https://github.com/OCA/manufacture.git,addons
+https://github.com/OCA/margin-analysis.git,addons
+https://github.com/OCA/mis-builder.git,addons
+https://github.com/OCA/multi-company.git,addons
+https://github.com/OCA/partner-contact.git,addons
+https://github.com/OCA/pos.git,addons
+https://github.com/OCA/product-attribute.git,addons
+https://github.com/OCA/product-pack.git,addons
+https://github.com/OCA/product-variant.git,addons
+https://github.com/OCA/project.git,addons
+https://github.com/OCA/project-reporting.git,addons
+https://github.com/OCA/purchase-workflow.git,addons
+https://github.com/OCA/queue.git,addons
+https://github.com/OCA/reporting-engine.git,addons
+https://github.com/OCA/sale-workflow.git,addons
+https://github.com/OCA/server-auth.git,addons
+https://github.com/OCA/server-brand.git,addons
+https://github.com/OCA/server-env.git,addons
+https://github.com/OCA/server-tools.git,addons
+https://github.com/OCA/server-ux.git,addons
+https://github.com/OCA/social.git,addons
+https://github.com/OCA/stock-logistics-warehouse.git,addons
+https://github.com/OCA/timesheet.git,addons
+https://github.com/OCA/web.git,addons
+https://github.com/OCA/website.git,addons
+https://github.com/OCA/wms.git,addons
+https://github.com/odooaktiv/QuotationRevision.git,addons
+https://github.com/openeducat/openeducat_erp.git,addons
+https://github.com/Smile-SA/odoo_addons.git,addons
+https://github.com/odoo/odoo.git,.