├── .copier-answers.yml ├── .editorconfig ├── .eslintrc.yml ├── .flake8 ├── .github ├── pull_request_template.md └── workflows │ ├── pre-commit.yml │ └── test.yml ├── .gitignore ├── .isort.cfg ├── .pre-commit-config.yaml ├── .prettierrc.yml ├── .pylintrc ├── .pylintrc-mandatory ├── LICENSE ├── README.md ├── account_customer_wallet ├── README.rst ├── __init__.py ├── __manifest__.py ├── demo │ ├── account_account_demo.xml │ ├── account_journal_demo.xml │ ├── product_product_demo.xml │ └── res_company_demo.xml ├── i18n │ ├── account_customer_wallet.pot │ └── fr.po ├── models │ ├── __init__.py │ ├── account_journal.py │ ├── account_payment.py │ ├── product_template.py │ ├── res_company.py │ ├── res_config_settings.py │ └── res_partner.py ├── readme │ ├── CONFIGURE.rst │ ├── CONTRIBUTORS.rst │ ├── DESCRIPTION.rst │ └── HISTORY.rst ├── static │ └── description │ │ └── index.html ├── tests │ ├── __init__.py │ ├── common.py │ ├── test_balance.py │ └── test_search.py └── views │ ├── account_journal_views.xml │ ├── account_payment_views.xml │ ├── product_template_views.xml │ ├── res_config_settings_views.xml │ └── res_partner_views.xml ├── account_move_payment_mode_sepa ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── account_move_payment_mode_sepa.pot ├── models │ ├── __init__.py │ └── account_move.py ├── readme │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html └── views │ └── report_invoice_document.xml ├── board_signature ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── board_signature.pot ├── models │ ├── __init__.py │ └── res_company.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html └── views │ └── res_company_view.xml ├── company_today ├── README.rst ├── __init__.py ├── __manifest__.py ├── data │ └── ir_cron.xml ├── i18n │ └── company_today.pot ├── models │ ├── __init__.py │ └── res_company.py ├── readme │ ├── CONTRIBUTORS.rst │ ├── CREDITS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html └── tests │ ├── __init__.py │ └── test_today.py ├── contract_delivery_address ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── contract_delivery_address.pot ├── models │ ├── __init__.py │ └── contract.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html └── views │ └── contract.xml ├── delivery_distribution_list ├── README.rst ├── __init__.py ├── __manifest__.py ├── data │ └── ddl_data.xml ├── i18n │ └── delivery_distribution_list.pot ├── models │ ├── __init__.py │ ├── delivery_distribution_line.py │ ├── delivery_distribution_list.py │ ├── res_partner.py │ ├── sale_order.py │ └── stock_picking.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── report │ └── sale_order_report_template.xml ├── security │ ├── delivery_distribution_list_security.xml │ └── ir.model.access.csv ├── static │ └── description │ │ └── index.html ├── tests │ ├── __init__.py │ └── test_delivery_distribution_list.py └── views │ ├── delivery_distribution_line_view.xml │ ├── delivery_distribution_list_view.xml │ ├── res_partner_view.xml │ ├── sale_order_view.xml │ └── stock_picking_view.xml ├── document_hosting ├── README.rst ├── __init__.py ├── __manifest__.py ├── controllers │ ├── __init__.py │ └── main.py ├── i18n │ └── document_hosting.pot ├── models │ ├── __init__.py │ ├── document.py │ ├── res_config_settings.py │ └── website.py ├── readme │ ├── CONTRIBUTORS.rst │ ├── DESCRIPTION.rst │ └── ROADMAP.rst ├── security │ └── ir.model.access.csv ├── static │ └── description │ │ └── index.html └── views │ ├── document_hosting_menu.xml │ ├── document_hosting_views.xml │ ├── document_hosting_website_templates.xml │ └── res_config_settings_views.xml ├── event_track_multi_date ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── event_track_multi_date.pot ├── models │ ├── __init__.py │ ├── event_track.py │ └── event_track_date.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── security │ └── ir.model.access.csv ├── static │ └── description │ │ ├── icon.png │ │ └── index.html └── views │ └── event_track.xml ├── partner_contact_type_default ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── partner_contact_type_default.pot ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html └── views │ └── res_partner_views.xml ├── payment_sepa_dd ├── README.rst ├── __init__.py ├── __manifest__.py ├── controllers │ ├── __init__.py │ └── main.py ├── data │ └── payment_provider_data.xml ├── i18n │ └── payment_sepa_dd.pot ├── models │ ├── __init__.py │ ├── payment_provider.py │ └── payment_transaction.py ├── readme │ ├── CONTRIBUTORS.rst │ ├── DESCRIPTION.rst │ └── ROADMAP.rst ├── static │ ├── description │ │ └── index.html │ └── src │ │ └── js │ │ ├── payment_form.js │ │ └── post_processing.js ├── tests │ ├── __init__.py │ ├── common.py │ ├── test_payment_transaction.py │ └── test_processing_flows.py └── views │ ├── payment_provider_views.xml │ └── templates.xml ├── payment_sepa_dd_payment_mode ├── README.rst ├── __init__.py ├── __manifest__.py ├── controllers │ ├── __init__.py │ └── main.py ├── i18n │ └── payment_sepa_dd_payment_mode.pot ├── models │ ├── __init__.py │ └── sale_order.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst └── static │ └── description │ └── index.html ├── portal_customer_wallet ├── README.rst ├── __init__.py ├── __manifest__.py ├── controllers │ ├── __init__.py │ └── main.py ├── i18n │ └── portal_customer_wallet.pot ├── models │ ├── __init__.py │ └── res_partner.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── src │ │ └── css │ │ └── portal_customer_wallet.css ├── tests │ ├── __init__.py │ ├── common.py │ └── test_monthly_wallet_balance.py └── views │ └── portal_templates.xml ├── product_contract_payment_mode ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── product_contract_payment_mode.pot ├── models │ ├── __init__.py │ └── sale_order.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst └── static │ └── description │ └── index.html ├── product_contract_sale_generation ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── product_contract_sale_generation.pot ├── models │ ├── __init__.py │ ├── contract.py │ ├── sale_order.py │ └── sale_order_line.py ├── readme │ └── DESCRIPTION.rst ├── static │ └── description │ │ ├── icon.png │ │ └── index.html └── views │ └── sale_order.xml ├── product_contract_storable ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── product_contract_storable.pot ├── models │ ├── __init__.py │ └── product_template.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html └── views │ └── product_template.xml ├── resource_work_time_from_contracts ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── resource_work_time_from_contracts.pot ├── models │ ├── __init__.py │ ├── resource_calendar_leaves.py │ ├── resource_mixin.py │ └── resource_resource.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html ├── tests │ ├── __init__.py │ ├── test_work_days_data.py │ ├── test_work_time.py │ └── test_work_time_base.py └── views │ ├── hr_employee.xml │ └── resource_resource.xml ├── sale_order_auto_carrier ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── sale_order_auto_carrier.pot ├── models │ ├── __init__.py │ └── sale_order.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst └── static │ └── description │ └── index.html ├── sale_order_volume ├── README.rst ├── __init__.py ├── __manifest__.py ├── data │ └── pallet_volume_data.xml ├── demo │ └── demo.xml ├── i18n │ └── sale_order_volume.pot ├── models │ ├── __init__.py │ ├── res_config_settings.py │ ├── sale_order.py │ └── sale_order_line.py ├── readme │ ├── CONFIGURE.rst │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── reports │ └── report_saleorder.xml ├── static │ └── description │ │ └── index.html ├── tests │ ├── __init__.py │ └── test_sale_order_volume.py └── views │ ├── res_config_settings_views.xml │ ├── sale_order.xml │ └── shopping_cart.xml ├── setup ├── .setuptools-odoo-make-default-ignore ├── README ├── account_customer_wallet │ ├── odoo │ │ └── addons │ │ │ └── account_customer_wallet │ └── setup.py ├── account_move_payment_mode_sepa │ ├── odoo │ │ └── addons │ │ │ └── account_move_payment_mode_sepa │ └── setup.py ├── board_signature │ ├── odoo │ │ └── addons │ │ │ └── board_signature │ └── setup.py ├── company_today │ ├── odoo │ │ └── addons │ │ │ └── company_today │ └── setup.py ├── contract_delivery_address │ ├── odoo │ │ └── addons │ │ │ └── contract_delivery_address │ └── setup.py ├── delivery_distribution_list │ ├── odoo │ │ └── addons │ │ │ └── delivery_distribution_list │ └── setup.py ├── document_hosting │ ├── odoo │ │ └── addons │ │ │ └── document_hosting │ └── setup.py ├── event_track_multi_date │ ├── odoo │ │ └── addons │ │ │ └── event_track_multi_date │ └── setup.py ├── partner_contact_type_default │ ├── odoo │ │ └── addons │ │ │ └── partner_contact_type_default │ └── setup.py ├── payment_sepa_dd │ ├── odoo │ │ └── addons │ │ │ └── payment_sepa_dd │ └── setup.py ├── payment_sepa_dd_payment_mode │ ├── odoo │ │ └── addons │ │ │ └── payment_sepa_dd_payment_mode │ └── setup.py ├── portal_customer_wallet │ ├── odoo │ │ └── addons │ │ │ └── portal_customer_wallet │ └── setup.py ├── product_contract_payment_mode │ ├── odoo │ │ └── addons │ │ │ └── product_contract_payment_mode │ └── setup.py ├── product_contract_sale_generation │ ├── odoo │ │ └── addons │ │ │ └── product_contract_sale_generation │ └── setup.py ├── product_contract_storable │ ├── odoo │ │ └── addons │ │ │ └── product_contract_storable │ └── setup.py ├── resource_work_time_from_contracts │ ├── odoo │ │ └── addons │ │ │ └── resource_work_time_from_contracts │ └── setup.py ├── sale_order_auto_carrier │ ├── odoo │ │ └── addons │ │ │ └── sale_order_auto_carrier │ └── setup.py ├── sale_order_volume │ ├── odoo │ │ └── addons │ │ │ └── sale_order_volume │ └── setup.py ├── subscription_web_access │ ├── odoo │ │ └── addons │ │ │ └── subscription_web_access │ └── setup.py ├── website_rebrand_coopiteasy │ ├── odoo │ │ └── addons │ │ │ └── website_rebrand_coopiteasy │ └── setup.py ├── website_sale_order_autoconfirm │ ├── odoo │ │ └── addons │ │ │ └── website_sale_order_autoconfirm │ └── setup.py ├── website_sale_product_compatibility │ ├── odoo │ │ └── addons │ │ │ └── website_sale_product_compatibility │ └── setup.py ├── website_sale_product_contract_gift │ ├── odoo │ │ └── addons │ │ │ └── website_sale_product_contract_gift │ └── setup.py ├── website_sale_product_trial │ ├── odoo │ │ └── addons │ │ │ └── website_sale_product_trial │ └── setup.py └── website_sale_restrict_sepa_dd │ ├── odoo │ └── addons │ │ └── website_sale_restrict_sepa_dd │ └── setup.py ├── subscription_web_access ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── subscription_web_access.pot ├── models │ ├── __init__.py │ ├── res_partner.py │ └── res_users.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html └── views │ └── res_partner.xml ├── website_rebrand_coopiteasy ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ ├── fr.po │ ├── nl.po │ └── website_rebrand_coopiteasy.pot ├── readme │ ├── CONTRIBUTORS.rst │ ├── DESCRIPTION.rst │ └── USAGE.rst ├── static │ └── description │ │ └── index.html └── templates │ └── rebrand_coopiteasy.xml ├── website_sale_order_autoconfirm ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ └── website_sale_order_autoconfirm.pot ├── models │ ├── __init__.py │ └── sale_order.py ├── readme │ └── DESCRIPTION.rst └── static │ └── description │ └── index.html ├── website_sale_product_compatibility ├── README.rst ├── __init__.py ├── __manifest__.py ├── controllers │ ├── __init__.py │ └── main.py ├── i18n │ └── website_sale_product_compatibility.pot ├── models │ ├── __init__.py │ └── sale_order.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html └── views │ └── templates.xml ├── website_sale_product_contract_gift ├── README.rst ├── __init__.py ├── __manifest__.py ├── controllers │ ├── __init__.py │ └── main.py ├── i18n │ └── website_sale_product_contract_gift.pot ├── models │ ├── __init__.py │ ├── account_move.py │ ├── contract.py │ ├── product_template.py │ ├── sale_order.py │ └── sale_order_line.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ ├── description │ │ └── index.html │ └── src │ │ └── js │ │ └── website_sale.esm.js ├── tests │ ├── __init__.py │ └── test_gift.py └── views │ ├── product_views.xml │ ├── sale_order_views.xml │ └── templates.xml ├── website_sale_product_trial ├── README.rst ├── __init__.py ├── __manifest__.py ├── controllers │ ├── __init__.py │ └── main.py ├── i18n │ └── website_sale_product_trial.pot ├── models │ ├── __init__.py │ ├── product_template.py │ └── sale_order.py ├── readme │ ├── CONTRIBUTORS.rst │ └── DESCRIPTION.rst ├── static │ └── description │ │ └── index.html ├── tests │ ├── __init__.py │ └── test_trial.py └── views │ ├── product_views.xml │ └── templates.xml └── website_sale_restrict_sepa_dd ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n ├── fr.po └── website_sale_restrict_sepa_dd.pot ├── models ├── __init__.py ├── payment_provider.py ├── product_template.py └── sale_order.py ├── readme ├── CONTRIBUTORS.rst └── DESCRIPTION.rst ├── static └── description │ └── index.html └── views └── product_views.xml /.copier-answers.yml: -------------------------------------------------------------------------------- 1 | # Do NOT update manually; changes here will be overwritten by Copier 2 | _commit: v2.3.1 3 | _src_path: https://github.com/coopiteasy/oca-addons-repo-template 4 | ci: GitHub 5 | convert_readme_fragments_to_markdown: false 6 | enable_checklog_odoo: false 7 | generate_requirements_txt: true 8 | github_check_license: true 9 | github_ci_extra_env: {} 10 | github_enable_codecov: true 11 | github_enable_makepot: true 12 | github_enable_stale_action: true 13 | github_enforce_dev_status_compatibility: true 14 | include_wkhtmltopdf: false 15 | odoo_test_flavor: OCB 16 | odoo_version: 16.0 17 | org_name: Coop IT Easy SC 18 | org_slug: coopiteasy 19 | rebel_module_groups: [] 20 | repo_description: TODO 21 | repo_name: Coop IT Easy Addons 22 | repo_slug: addons 23 | repo_website: https://github.com/coopiteasy/addons 24 | use_pyproject_toml: false 25 | use_ruff: false 26 | 27 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Configuration for known file extensions 2 | [*.{css,js,json,less,md,py,rst,sass,scss,xml,yaml,yml}] 3 | charset = utf-8 4 | end_of_line = lf 5 | indent_size = 4 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{json,yml,yaml,rst,md}] 11 | indent_size = 2 12 | 13 | # Do not configure editor for libs and autogenerated content 14 | [{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}] 15 | charset = unset 16 | end_of_line = unset 17 | indent_size = unset 18 | indent_style = unset 19 | insert_final_newline = false 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 88 3 | max-complexity = 16 4 | # B = bugbear 5 | # B9 = bugbear opinionated (incl line length) 6 | select = C,E,F,W,B,B9 7 | # E203: whitespace before ':' (black behaviour) 8 | # E501: flake8 line length (covered by bugbear B950) 9 | # W503: line break before binary operator (black behaviour) 10 | ignore = E203,E501,W503 11 | per-file-ignores= 12 | __init__.py:F401 13 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | 4 | 5 | ## Odoo task (if applicable) 6 | 7 | 8 | 9 | ## Checklist before approval 10 | 11 | - [ ] Tests are present (or not needed). 12 | - [ ] Credits/copyright have been changed correctly. 13 | - [ ] Change log snippet is present. 14 | - [ ] (If a new module) Moving this to OCA has been considered. 15 | -------------------------------------------------------------------------------- /.github/workflows/pre-commit.yml: -------------------------------------------------------------------------------- 1 | name: pre-commit 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - "16.0*" 7 | push: 8 | branches: 9 | - "16.0" 10 | - "16.0-ocabot-*" 11 | 12 | jobs: 13 | pre-commit: 14 | runs-on: ubuntu-22.04 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: actions/setup-python@v5 18 | with: 19 | python-version: "3.11" 20 | - name: Get python version 21 | run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV 22 | - uses: actions/cache@v4 23 | with: 24 | path: ~/.cache/pre-commit 25 | key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} 26 | - name: Install pre-commit 27 | run: pip install pre-commit 28 | - name: Run pre-commit 29 | run: pre-commit run --all-files --show-diff-on-failure --color=always 30 | env: 31 | # Consider valid a PR that changes README fragments but doesn't 32 | # change the README.rst file itself. It's not really a problem 33 | # because the bot will update it anyway after merge. This way, we 34 | # lower the barrier for functional contributors that want to fix the 35 | # readme fragments, while still letting developers get README 36 | # auto-generated (which also helps functionals when using runboat). 37 | # DOCS https://pre-commit.com/#temporarily-disabling-hooks 38 | SKIP: oca-gen-addon-readme 39 | - name: Check that all files generated by pre-commit are in git 40 | run: | 41 | newfiles="$(git ls-files --others --exclude-from=.gitignore)" 42 | if [ "$newfiles" != "" ] ; then 43 | echo "Please check-in the following files:" 44 | echo "$newfiles" 45 | exit 1 46 | fi 47 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - "16.0*" 7 | push: 8 | branches: 9 | - "16.0" 10 | - "16.0-ocabot-*" 11 | 12 | jobs: 13 | test: 14 | runs-on: ubuntu-22.04 15 | container: ${{ matrix.container }} 16 | name: ${{ matrix.name }} 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | include: 21 | - container: ghcr.io/oca/oca-ci/py3.10-ocb16.0:latest 22 | name: test with OCB 23 | makepot: "true" 24 | services: 25 | postgres: 26 | image: postgres:12.0 27 | env: 28 | POSTGRES_USER: odoo 29 | POSTGRES_PASSWORD: odoo 30 | POSTGRES_DB: odoo 31 | ports: 32 | - 5432:5432 33 | steps: 34 | - uses: actions/checkout@v4 35 | with: 36 | persist-credentials: false 37 | - name: Install addons and dependencies 38 | run: oca_install_addons 39 | - name: Check licenses 40 | run: manifestoo -d . check-licenses 41 | - name: Check development status 42 | run: manifestoo -d . check-dev-status --default-dev-status=Beta 43 | - name: Initialize test db 44 | run: oca_init_test_database 45 | - name: Run tests 46 | run: oca_run_tests 47 | - uses: codecov/codecov-action@v4 48 | with: 49 | token: ${{ secrets.CODECOV_TOKEN }} 50 | - name: Update .pot files 51 | run: oca_export_and_push_pot https://x-access-token:${{ secrets.GIT_PUSH_TOKEN }}@github.com/${{ github.repository }} 52 | if: ${{ matrix.makepot == 'true' && github.event_name == 'push' && github.repository_owner == 'coopiteasy' }} 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | /.venv 5 | /.pytest_cache 6 | /.ruff_cache 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | bin/ 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | eggs/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | *.eggs 27 | 28 | # Windows installers 29 | *.msi 30 | 31 | # Debian packages 32 | *.deb 33 | 34 | # Redhat packages 35 | *.rpm 36 | 37 | # MacOS packages 38 | *.dmg 39 | *.pkg 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .coverage 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | 53 | # Translations 54 | *.mo 55 | 56 | # Pycharm 57 | .idea 58 | 59 | # Eclipse 60 | .settings 61 | 62 | # Visual Studio cache/options directory 63 | .vs/ 64 | .vscode 65 | 66 | # OSX Files 67 | .DS_Store 68 | 69 | # Django stuff: 70 | *.log 71 | 72 | # Mr Developer 73 | .mr.developer.cfg 74 | .project 75 | .pydevproject 76 | 77 | # Rope 78 | .ropeproject 79 | 80 | # Sphinx documentation 81 | docs/_build/ 82 | 83 | # Backup files 84 | *~ 85 | *.swp 86 | 87 | # OCA rules 88 | !static/lib/ 89 | -------------------------------------------------------------------------------- /.isort.cfg: -------------------------------------------------------------------------------- 1 | [settings] 2 | ; see https://github.com/psf/black 3 | multi_line_output=3 4 | include_trailing_comma=True 5 | force_grid_wrap=0 6 | combine_as_imports=True 7 | use_parentheses=True 8 | line_length=88 9 | known_odoo=odoo 10 | known_odoo_addons=odoo.addons 11 | sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER 12 | default_section=THIRDPARTY 13 | ensure_newline_before_comments = True 14 | -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | # Defaults for all prettier-supported languages. 2 | # Prettier will complete this with settings from .editorconfig file. 3 | bracketSpacing: false 4 | printWidth: 88 5 | proseWrap: always 6 | semi: true 7 | trailingComma: "es5" 8 | xmlWhitespaceSensitivity: "strict" 9 | -------------------------------------------------------------------------------- /account_customer_wallet/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /account_customer_wallet/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | { 5 | "name": "Account Customer Wallet", 6 | "summary": """ 7 | Allow customers to pay using a wallet which is tracked by the company.""", 8 | "version": "16.0.1.0.1", 9 | "category": "Accounting & Finance", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC,GRAP", 12 | "license": "AGPL-3", 13 | "application": False, 14 | "depends": [ 15 | "account", 16 | ], 17 | "excludes": [], 18 | "data": [ 19 | "views/account_journal_views.xml", 20 | "views/account_payment_views.xml", 21 | "views/product_template_views.xml", 22 | "views/res_config_settings_views.xml", 23 | "views/res_partner_views.xml", 24 | ], 25 | "demo": [ 26 | "demo/account_account_demo.xml", 27 | "demo/account_journal_demo.xml", 28 | "demo/product_product_demo.xml", 29 | "demo/res_company_demo.xml", 30 | ], 31 | } 32 | -------------------------------------------------------------------------------- /account_customer_wallet/demo/account_account_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Customer Wallet 6 | 111065 7 | liability_current 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /account_customer_wallet/demo/account_journal_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Customer Wallet 6 | WLLT 7 | bank 8 | 9 | 13 | 30 14 | 21 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /account_customer_wallet/demo/product_product_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Wallet Product 8 | service 9 | 10 | 14 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /account_customer_wallet/demo/res_company_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /account_customer_wallet/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import account_journal 2 | from . import account_payment 3 | from . import product_template 4 | from . import res_company 5 | from . import res_config_settings 6 | from . import res_partner 7 | -------------------------------------------------------------------------------- /account_customer_wallet/models/account_journal.py: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | from odoo import fields, models 5 | 6 | 7 | class AccountJournal(models.Model): 8 | _inherit = "account.journal" 9 | 10 | is_customer_wallet_journal = fields.Boolean( 11 | string="Customer Wallet Journal", default=False 12 | ) 13 | 14 | minimum_wallet_amount = fields.Monetary( 15 | default=0.0, 16 | help="Usually 0. You can enter a negative value," 17 | " if you want to accept that the customer wallet" 18 | " is negative. Maybe useful if the sale amount" 19 | " is slightly higher than the wallet amount," 20 | " to avoid charging the customer a small amount.", 21 | ) 22 | -------------------------------------------------------------------------------- /account_customer_wallet/models/account_payment.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022-Today: GRAP (http://www.grap.coop) 2 | # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) 3 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). 4 | 5 | from odoo import _, fields, models 6 | from odoo.exceptions import UserError 7 | 8 | 9 | class AccountPayment(models.Model): 10 | _inherit = "account.payment" 11 | 12 | is_customer_wallet_journal = fields.Boolean( 13 | related="journal_id.is_customer_wallet_journal", 14 | ) 15 | 16 | customer_wallet_balance = fields.Monetary( 17 | string="Customer Wallet Balance", 18 | currency_field="currency_id", 19 | related="partner_id.customer_wallet_balance", 20 | ) 21 | 22 | def action_post(self): 23 | wallet_payments = self.filtered( 24 | lambda x: x.journal_id.is_customer_wallet_journal 25 | ) 26 | 27 | for payment in wallet_payments: 28 | if ( 29 | payment.partner_id 30 | # TODO: The below statement may not actually be true. In any 31 | # case, payments that increase the the balance SHOULD always be 32 | # allowed. We need to figure out exactly how to identify these 33 | # types of payments. 34 | # Inbound payments increase the balance; always allow this. 35 | # and payment.payment_type == "outbound" 36 | and (payment.customer_wallet_balance - payment.amount) 37 | < payment.journal_id.minimum_wallet_amount 38 | ): 39 | raise UserError( 40 | _( 41 | "There is not enough balance in the customer's wallet" 42 | " to perform this payment. \n" 43 | " - Customer : %(partner)s\n" 44 | " - Customer Wallet : %(balance)s\n" 45 | " - Amount Payment : %(amount)s" 46 | ) 47 | % { 48 | "partner": payment.partner_id.display_name, 49 | "balance": payment.customer_wallet_balance, 50 | "amount": payment.amount, 51 | } 52 | ) 53 | return super().action_post() 54 | -------------------------------------------------------------------------------- /account_customer_wallet/models/product_template.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022-Today: GRAP (http://www.grap.coop) 2 | # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) 3 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). 4 | 5 | from odoo import fields, models 6 | 7 | 8 | class ProductTemplate(models.Model): 9 | _inherit = "product.template" 10 | 11 | is_customer_wallet_product = fields.Boolean( 12 | string="Wallet Product", 13 | help="Check this box if this product is used to credit" 14 | " customer wallets. Important note : you should set the" 15 | " the same income and expense account as the journal wallet.", 16 | ) 17 | -------------------------------------------------------------------------------- /account_customer_wallet/models/res_company.py: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Coop IT Easy SC 2 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). 3 | 4 | from odoo import api, fields, models 5 | 6 | 7 | class Company(models.Model): 8 | _inherit = "res.company" 9 | 10 | is_enabled_customer_wallet = fields.Boolean( 11 | compute="_compute_is_enabled_customer_wallet", 12 | string="Is Customer Wallet Enabled", 13 | store=True, 14 | ) 15 | customer_wallet_account_id = fields.Many2one( 16 | comodel_name="account.account", 17 | string="Customer Wallet Account", 18 | ) 19 | 20 | @api.depends("customer_wallet_account_id") 21 | def _compute_is_enabled_customer_wallet(self): 22 | for company in self: 23 | company.is_enabled_customer_wallet = bool( 24 | company.customer_wallet_account_id 25 | ) 26 | -------------------------------------------------------------------------------- /account_customer_wallet/models/res_config_settings.py: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Coop IT Easy SC 2 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). 3 | 4 | from odoo import fields, models 5 | 6 | 7 | class ResConfigSettings(models.TransientModel): 8 | _inherit = "res.config.settings" 9 | 10 | customer_wallet_account_id = fields.Many2one( 11 | comodel_name="account.account", 12 | related="company_id.customer_wallet_account_id", 13 | readonly=False, 14 | string="Customer Wallet Account", 15 | help="The account where all wallet transactions will be recorded", 16 | ) 17 | -------------------------------------------------------------------------------- /account_customer_wallet/readme/CONFIGURE.rst: -------------------------------------------------------------------------------- 1 | Setting this up requires a few careful steps: 2 | 3 | - Make sure your user has access to all accounting features. 4 | - Create an account (Customer Wallet) that is a liability. 5 | - Create a journal (Customer Wallet). Enable the 'Customer Wallet Journal' 6 | toggle, set the Bank Account to the previously created account, and in the 7 | payment methods (both incoming and outgoing), set the Outstanding Receipts and 8 | Outstanding Payments accounts to the previously created account. You may need 9 | to toggle the visibility of these fields in the tables. 10 | - In the Invoicing settings, set the Customer Wallet Account to the previously 11 | created account. 12 | - (Optional) Create a product (Wallet Product), and enable the Wallet Product 13 | toggle. Set the income and expense account to the previously created account. 14 | -------------------------------------------------------------------------------- /account_customer_wallet/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Carmen Bianca Bakker 4 | -------------------------------------------------------------------------------- /account_customer_wallet/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Allow customers to pay using a wallet which is tracked by the company. 2 | -------------------------------------------------------------------------------- /account_customer_wallet/readme/HISTORY.rst: -------------------------------------------------------------------------------- 1 | 12.0.1.2.0 (2022-07-08) 2 | ~~~~~~~~~~~~~~~~~~~~~~~ 3 | 4 | **Misc** 5 | 6 | - `#237 `_ 7 | 8 | 9 | 12.0.1.1.0 (2022-06-23) 10 | **Features** 11 | 12 | - Make ``customer_wallet_balance`` searchable, and add a filter for non-zero 13 | balances. (`#235 `_) 14 | -------------------------------------------------------------------------------- /account_customer_wallet/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from . import common 2 | from . import test_balance 3 | from . import test_search 4 | -------------------------------------------------------------------------------- /account_customer_wallet/views/account_journal_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | account_customer_wallet.view_account_journal_form 5 | account.journal 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /account_customer_wallet/views/account_payment_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | account.payment 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /account_customer_wallet/views/product_template_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | product.template 8 | 9 | 10 | 11 |
12 | 13 |
15 |
16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /account_customer_wallet/views/res_config_settings_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | account_customer_wallet.res_config_settings_view_form 5 | res.config.settings 6 | 7 | 8 | 12 | 16 |
17 |
18 |
19 |
29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /account_customer_wallet/views/res_partner_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | account_customer_wallet.view_partner_form 5 | res.partner 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | account_customer_wallet.partner.search.form 18 | res.partner 19 | 20 | 21 | 22 | 23 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /account_move_payment_mode_sepa/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /account_move_payment_mode_sepa/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Account Move Payment Mode SEPA", 7 | "version": "16.0.1.0.0", 8 | "category": "Banking addons", 9 | "website": "https://github.com/coopiteasy/addons", 10 | "author": "Coop IT Easy SC", 11 | "maintainers": ["victor-champonnois"], 12 | "license": "AGPL-3", 13 | "application": False, 14 | "depends": [ 15 | "account_banking_sepa_direct_debit", 16 | ], 17 | "data": ["views/report_invoice_document.xml"], 18 | } 19 | -------------------------------------------------------------------------------- /account_move_payment_mode_sepa/i18n/account_move_payment_mode_sepa.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * account_move_payment_mode_sepa 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: account_move_payment_mode_sepa 17 | #: model:ir.model.fields,field_description:account_move_payment_mode_sepa.field_account_bank_statement_line__is_sepa_payment 18 | #: model:ir.model.fields,field_description:account_move_payment_mode_sepa.field_account_move__is_sepa_payment 19 | #: model:ir.model.fields,field_description:account_move_payment_mode_sepa.field_account_payment__is_sepa_payment 20 | msgid "Is Sepa Payment" 21 | msgstr "" 22 | 23 | #. module: account_move_payment_mode_sepa 24 | #: model:ir.model,name:account_move_payment_mode_sepa.model_account_move 25 | msgid "Journal Entry" 26 | msgstr "" 27 | -------------------------------------------------------------------------------- /account_move_payment_mode_sepa/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import account_move 2 | -------------------------------------------------------------------------------- /account_move_payment_mode_sepa/models/account_move.py: -------------------------------------------------------------------------------- 1 | from odoo import api, fields, models 2 | 3 | 4 | class AccountMove(models.Model): 5 | _inherit = "account.move" 6 | 7 | is_sepa_payment = fields.Boolean( 8 | compute="_compute_is_sepa_payment", store=True, readonly="True", default=False 9 | ) 10 | 11 | @api.depends("payment_mode_id.payment_method_id") 12 | def _compute_is_sepa_payment(self): 13 | for move in self: 14 | move.is_sepa_payment = False 15 | if move.payment_mode_id.payment_method_id == self.env.ref( 16 | "account_banking_sepa_direct_debit.sepa_direct_debit" 17 | ): 18 | move.is_sepa_payment = True 19 | -------------------------------------------------------------------------------- /account_move_payment_mode_sepa/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Adapt the invoice pdf reports for invoices with SEPA direct debit payment mode. 2 | -------------------------------------------------------------------------------- /account_move_payment_mode_sepa/views/report_invoice_document.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | -------------------------------------------------------------------------------- /board_signature/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import models 6 | -------------------------------------------------------------------------------- /board_signature/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Board signature", 7 | "summary": "Adds board representative's name, function and signature to companies", 8 | "version": "16.0.1.0.0", 9 | "category": "Reporting", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "maintainers": ["mihien"], 13 | "license": "AGPL-3", 14 | "depends": ["base"], 15 | "data": ["views/res_company_view.xml"], 16 | } 17 | -------------------------------------------------------------------------------- /board_signature/i18n/board_signature.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * board_signature 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: board_signature 17 | #: model_terms:ir.ui.view,arch_db:board_signature.view_company_form 18 | msgid "Board Representative" 19 | msgstr "" 20 | 21 | #. module: board_signature 22 | #: model:ir.model.fields,field_description:board_signature.field_res_company__board_representative_function 23 | msgid "Board representative function" 24 | msgstr "" 25 | 26 | #. module: board_signature 27 | #: model:ir.model.fields,field_description:board_signature.field_res_company__board_representative 28 | msgid "Board representative name" 29 | msgstr "" 30 | 31 | #. module: board_signature 32 | #: model:ir.model.fields,field_description:board_signature.field_res_company__board_representative_signature_scan 33 | msgid "Board representative signature" 34 | msgstr "" 35 | 36 | #. module: board_signature 37 | #: model:ir.model,name:board_signature.model_res_company 38 | msgid "Companies" 39 | msgstr "" 40 | -------------------------------------------------------------------------------- /board_signature/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import res_company 6 | -------------------------------------------------------------------------------- /board_signature/models/res_company.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import fields, models 6 | 7 | 8 | class ResCompany(models.Model): 9 | _inherit = "res.company" 10 | board_representative = fields.Char(string="Board representative name") 11 | board_representative_function = fields.Char(string="Board representative function") 12 | board_representative_signature_scan = fields.Binary( 13 | string="Board representative signature" 14 | ) 15 | -------------------------------------------------------------------------------- /board_signature/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Simon Hick 4 | -------------------------------------------------------------------------------- /board_signature/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Adds board representative's name, function and signature to companies 2 | -------------------------------------------------------------------------------- /board_signature/views/res_company_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | res.company.form.board_representative 12 | 13 | res.company 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /company_today/README.rst: -------------------------------------------------------------------------------- 1 | ============= 2 | Company Today 3 | ============= 4 | 5 | .. 6 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 7 | !! This file is generated by oca-gen-addon-readme !! 8 | !! changes will be overwritten. !! 9 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 10 | !! source digest: sha256:4064934b64f26e2db71c16bf3ad0a96aa174d7b8d3b0adf7704bc8f724ebc5f4 11 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 12 | 13 | .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png 14 | :target: https://odoo-community.org/page/development-status 15 | :alt: Beta 16 | .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png 17 | :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html 18 | :alt: License: AGPL-3 19 | .. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Faddons-lightgray.png?logo=github 20 | :target: https://github.com/coopiteasy/addons/tree/16.0/company_today 21 | :alt: coopiteasy/addons 22 | 23 | |badge1| |badge2| |badge3| 24 | 25 | Store today's date on the company module. A cronjob makes sure this field stays 26 | up-to-date. 27 | 28 | **Table of contents** 29 | 30 | .. contents:: 31 | :local: 32 | 33 | Bug Tracker 34 | =========== 35 | 36 | Bugs are tracked on `GitHub Issues `_. 37 | In case of trouble, please check there if your issue has already been reported. 38 | If you spotted it first, help us to smash it by providing a detailed and welcomed 39 | `feedback `_. 40 | 41 | Do not contact contributors directly about support or help with technical issues. 42 | 43 | Credits 44 | ======= 45 | 46 | Authors 47 | ~~~~~~~ 48 | 49 | * Coop IT Easy SC 50 | 51 | Contributors 52 | ~~~~~~~~~~~~ 53 | 54 | * `Coop IT Easy SC `_: 55 | 56 | * Carmen Bianca Bakker 57 | 58 | Other credits 59 | ~~~~~~~~~~~~~ 60 | 61 | The development of this module has been paid for by 62 | `Pro Velo `_. 63 | 64 | Maintainers 65 | ~~~~~~~~~~~ 66 | 67 | This module is part of the `coopiteasy/addons `_ project on GitHub. 68 | 69 | You are welcome to contribute. 70 | -------------------------------------------------------------------------------- /company_today/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import models 6 | -------------------------------------------------------------------------------- /company_today/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Company Today", 7 | "summary": """ 8 | Store today's date on the company model.""", 9 | "version": "16.0.1.0.0", 10 | "category": "Uncategorized", 11 | "website": "https://github.com/coopiteasy/addons", 12 | "author": "Coop IT Easy SC", 13 | "license": "AGPL-3", 14 | "depends": [ 15 | "base", 16 | ], 17 | "data": [ 18 | "data/ir_cron.xml", 19 | ], 20 | } 21 | -------------------------------------------------------------------------------- /company_today/data/ir_cron.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Set today's date on the company 10 | 11 | model.cron_update_today() 12 | 1 13 | days 14 | 19 | -1 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /company_today/i18n/company_today.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * company_today 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: company_today 17 | #: model:ir.model,name:company_today.model_res_company 18 | msgid "Companies" 19 | msgstr "" 20 | 21 | #. module: company_today 22 | #: model:ir.actions.server,name:company_today.compute_today_ir_actions_server 23 | #: model:ir.cron,cron_name:company_today.compute_today 24 | msgid "Set today's date on the company" 25 | msgstr "" 26 | 27 | #. module: company_today 28 | #: model:ir.model.fields,field_description:company_today.field_res_company__today 29 | msgid "Today's Date" 30 | msgstr "" 31 | -------------------------------------------------------------------------------- /company_today/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import res_company 6 | -------------------------------------------------------------------------------- /company_today/models/res_company.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import api, fields, models 6 | 7 | 8 | class Company(models.Model): 9 | _inherit = "res.company" 10 | 11 | today = fields.Date( 12 | string="Today's Date", 13 | default=lambda _: fields.Date.today(), 14 | readonly=True, 15 | ) 16 | 17 | @api.model 18 | def cron_update_today(self): 19 | companies = self.search([]) 20 | companies.write({"today": fields.Date.today()}) 21 | -------------------------------------------------------------------------------- /company_today/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Carmen Bianca Bakker 4 | -------------------------------------------------------------------------------- /company_today/readme/CREDITS.rst: -------------------------------------------------------------------------------- 1 | The development of this module has been paid for by 2 | `Pro Velo `_. 3 | -------------------------------------------------------------------------------- /company_today/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Store today's date on the company module. A cronjob makes sure this field stays 2 | up-to-date. 3 | -------------------------------------------------------------------------------- /company_today/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import test_today 6 | -------------------------------------------------------------------------------- /company_today/tests/test_today.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from freezegun import freeze_time 6 | 7 | from odoo import fields 8 | from odoo.tests.common import TransactionCase 9 | 10 | 11 | class TestToday(TransactionCase): 12 | @classmethod 13 | def setUpClass(cls): 14 | super().setUpClass() 15 | cls.company = cls.env.ref("base.main_company") 16 | 17 | def test_today(self): 18 | self.company.cron_update_today() 19 | self.assertEqual(self.company.today, fields.Date.today()) 20 | 21 | @freeze_time("2022-02-22") 22 | def test_today_different_day(self): 23 | self.company.cron_update_today() 24 | self.assertEqual(self.company.today, fields.Date.today()) 25 | -------------------------------------------------------------------------------- /contract_delivery_address/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import models 6 | -------------------------------------------------------------------------------- /contract_delivery_address/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Contracts Delivery Address", 7 | "summary": "Add contact's default delivery address to contract", 8 | "version": "16.0.1.0.0", 9 | "category": "Contract Management", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "license": "AGPL-3", 13 | "depends": [ 14 | "contract", 15 | ], 16 | "data": [ 17 | "views/contract.xml", 18 | ], 19 | } 20 | -------------------------------------------------------------------------------- /contract_delivery_address/i18n/contract_delivery_address.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * contract_delivery_address 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: contract_delivery_address 17 | #: model:ir.model,name:contract_delivery_address.model_contract_contract 18 | msgid "Contract" 19 | msgstr "" 20 | 21 | #. module: contract_delivery_address 22 | #: model:ir.model.fields,field_description:contract_delivery_address.field_contract_contract__partner_shipping_id 23 | msgid "Delivery Address" 24 | msgstr "" 25 | -------------------------------------------------------------------------------- /contract_delivery_address/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import contract 6 | -------------------------------------------------------------------------------- /contract_delivery_address/models/contract.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import api, fields, models 6 | 7 | 8 | class ContractContract(models.Model): 9 | _inherit = "contract.contract" 10 | 11 | partner_shipping_id = fields.Many2one( 12 | comodel_name="res.partner", 13 | string="Delivery Address", 14 | compute="_compute_partner_shipping_id", 15 | store=True, 16 | readonly=False, 17 | required=True, 18 | precompute=True, 19 | ) 20 | 21 | @api.depends("partner_id.child_ids") 22 | def _compute_partner_shipping_id(self): 23 | for contract in self: 24 | contract.partner_shipping_id = ( 25 | contract.partner_id.address_get(["delivery"])["delivery"] 26 | if contract.partner_id 27 | else False 28 | ) 29 | -------------------------------------------------------------------------------- /contract_delivery_address/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Victor Champonnois 4 | -------------------------------------------------------------------------------- /contract_delivery_address/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Add contact's default delivery address to contract. 2 | This is used to export the list of delivery addresses of all ongoing contracts in order to send the products. 3 | -------------------------------------------------------------------------------- /contract_delivery_address/views/contract.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | contract.contract.form.recurring.sale.form 10 | contract.contract 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /delivery_distribution_list/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /delivery_distribution_list/__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Delivery distribution Management", 3 | "summary": "Manage the distribution of a product through all the deposit points", 4 | "author": "Coop IT Easy SC", 5 | "license": "AGPL-3", 6 | "version": "16.0.1.0.0", 7 | "website": "https://github.com/coopiteasy/addons", 8 | "category": "Sales", 9 | "depends": [ 10 | "sale_management", 11 | "account", 12 | "sale_stock", 13 | ], 14 | "data": [ 15 | "security/delivery_distribution_list_security.xml", 16 | "security/ir.model.access.csv", 17 | "data/ddl_data.xml", 18 | "views/delivery_distribution_list_view.xml", 19 | "views/delivery_distribution_line_view.xml", 20 | "views/res_partner_view.xml", 21 | "views/sale_order_view.xml", 22 | "views/stock_picking_view.xml", 23 | ], 24 | "assets": { 25 | "web.assets_qweb": [ 26 | "report/sale_order_report_template.xml", 27 | ], 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /delivery_distribution_list/data/ddl_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Delivery Distribution List 5 | 6 | DDL/%(year)s/ 7 | 8 | 9 | -------------------------------------------------------------------------------- /delivery_distribution_list/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import delivery_distribution_line 2 | from . import delivery_distribution_list 3 | from . import res_partner 4 | from . import sale_order 5 | from . import stock_picking 6 | -------------------------------------------------------------------------------- /delivery_distribution_list/models/res_partner.py: -------------------------------------------------------------------------------- 1 | from odoo import fields, models 2 | 3 | 4 | class ResPartner(models.Model): 5 | _inherit = "res.partner" 6 | 7 | quantity_to_deliver = fields.Float(string="Default quantity to deliver") 8 | deposit_point = fields.Boolean(string="Deposit/Sale") 9 | carrier_delivery = fields.Boolean(string="Carrier delivery") 10 | carrier_id = fields.Many2one( 11 | "res.partner", 12 | string="Assigned carrier", 13 | domain=[("carrier_delivery", "=", True)], 14 | ) 15 | -------------------------------------------------------------------------------- /delivery_distribution_list/models/sale_order.py: -------------------------------------------------------------------------------- 1 | from odoo import fields, models 2 | 3 | 4 | class SaleOrder(models.Model): 5 | _inherit = "sale.order" 6 | 7 | distribution_carrier_id = fields.Many2one( 8 | "res.partner", string="Assigned carrier", readonly=True 9 | ) 10 | distribution_list_id = fields.Many2one( 11 | "delivery.distribution.list", string="Distribution list", readonly=True 12 | ) 13 | -------------------------------------------------------------------------------- /delivery_distribution_list/models/stock_picking.py: -------------------------------------------------------------------------------- 1 | from odoo import api, fields, models 2 | 3 | 4 | class StockPicking(models.Model): 5 | _inherit = "stock.picking" 6 | 7 | distribution_carrier_id = fields.Many2one( 8 | comodel_name="res.partner", 9 | compute="_compute_distribution_fields", 10 | string="Assigned carrier", 11 | store=True, 12 | ) 13 | distribution_list_id = fields.Many2one( 14 | comodel_name="delivery.distribution.list", 15 | compute="_compute_distribution_fields", 16 | string="Distribution list", 17 | store=True, 18 | ) 19 | 20 | @api.depends("sale_id.distribution_carrier_id", "sale_id.distribution_list_id") 21 | def _compute_distribution_fields(self): 22 | for picking in self: 23 | if picking.sale_id: 24 | picking.distribution_carrier_id = ( 25 | picking.sale_id.distribution_carrier_id 26 | ) 27 | picking.distribution_list_id = picking.sale_id.distribution_list_id 28 | else: 29 | picking.distribution_carrier_id = False 30 | picking.distribution_list_id = False 31 | -------------------------------------------------------------------------------- /delivery_distribution_list/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Houssine Bakkali 4 | -------------------------------------------------------------------------------- /delivery_distribution_list/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | This module manage the distribution of a product through all the sale/deposit 2 | points, it manages the recurring order through the list of distribution. 3 | -------------------------------------------------------------------------------- /delivery_distribution_list/report/sale_order_report_template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | -------------------------------------------------------------------------------- /delivery_distribution_list/security/delivery_distribution_list_security.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Distribution List 6 | 7 | 8 | 9 | Distribution User 10 | 11 | 12 | 13 | 14 | 15 | Distribution Manager 16 | 17 | 21 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /delivery_distribution_list/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | access_delivery_distribution_list_user,delivery.distribution.list,model_delivery_distribution_list,group_distribution_user,1,1,0,0 3 | access_delivery_distribution_list_manager,delivery.distribution.list,model_delivery_distribution_list,group_distribution_manager,1,1,1,1 4 | access_delivery_distribution_line_user,delivery.distribution.line,model_delivery_distribution_line,group_distribution_user,1,1,0,0 5 | access_delivery_distribution_line_manager,delivery.distribution.line,model_delivery_distribution_line,group_distribution_manager,1,1,1,1 6 | -------------------------------------------------------------------------------- /delivery_distribution_list/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import test_delivery_distribution_list 6 | -------------------------------------------------------------------------------- /delivery_distribution_list/views/sale_order_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sale.order.form.ddl 5 | sale.order 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | sale.order.list.select 17 | sale.order 18 | 19 | 20 | 21 | 27 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /delivery_distribution_list/views/stock_picking_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | stock.picking.form 4 | stock.picking 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /document_hosting/README.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | Document Hosting 3 | ================ 4 | 5 | .. 6 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 7 | !! This file is generated by oca-gen-addon-readme !! 8 | !! changes will be overwritten. !! 9 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 10 | !! source digest: sha256:c4afd501de6e58852d12122fcd713ea356fd5e379c5459b4ddbe31fc44ce034b 11 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 12 | 13 | .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png 14 | :target: https://odoo-community.org/page/development-status 15 | :alt: Beta 16 | .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png 17 | :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html 18 | :alt: License: AGPL-3 19 | .. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Faddons-lightgray.png?logo=github 20 | :target: https://github.com/coopiteasy/addons/tree/16.0/document_hosting 21 | :alt: coopiteasy/addons 22 | 23 | |badge1| |badge2| |badge3| 24 | 25 | 26 | **Table of contents** 27 | 28 | .. contents:: 29 | :local: 30 | 31 | Known issues / Roadmap 32 | ====================== 33 | 34 | Don't allow for recursive parent categories (a category cannot be it's own parent) 35 | Add unit tests 36 | 37 | Bug Tracker 38 | =========== 39 | 40 | Bugs are tracked on `GitHub Issues `_. 41 | In case of trouble, please check there if your issue has already been reported. 42 | If you spotted it first, help us to smash it by providing a detailed and welcomed 43 | `feedback `_. 44 | 45 | Do not contact contributors directly about support or help with technical issues. 46 | 47 | Credits 48 | ======= 49 | 50 | Authors 51 | ~~~~~~~ 52 | 53 | * Coop IT Easy SC 54 | 55 | Maintainers 56 | ~~~~~~~~~~~ 57 | 58 | This module is part of the `coopiteasy/addons `_ project on GitHub. 59 | 60 | You are welcome to contribute. 61 | -------------------------------------------------------------------------------- /document_hosting/__init__.py: -------------------------------------------------------------------------------- 1 | from . import controllers 2 | from . import models 3 | -------------------------------------------------------------------------------- /document_hosting/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 - Today Coop IT Easy SC () 2 | # - Rémy Taymans 3 | # - Elouan Le bars 4 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). 5 | 6 | { 7 | "name": "Document Hosting", 8 | "summary": """ 9 | Manage documents that can be published on website with ??. 10 | """, 11 | "author": "Coop IT Easy SC", 12 | "license": "AGPL-3", 13 | "version": "16.0.1.0.0", 14 | "website": "https://github.com/coopiteasy/addons", 15 | "category": "Document", 16 | "depends": ["base", "web", "website", "mail"], 17 | "data": [ 18 | "security/ir.model.access.csv", 19 | "views/document_hosting_menu.xml", 20 | "views/document_hosting_views.xml", 21 | "views/document_hosting_website_templates.xml", 22 | "views/res_config_settings_views.xml", 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /document_hosting/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | from . import main 2 | -------------------------------------------------------------------------------- /document_hosting/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import document 2 | from . import res_config_settings 3 | from . import website 4 | -------------------------------------------------------------------------------- /document_hosting/models/res_config_settings.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 - Today Coop IT Easy SC () 2 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). 3 | 4 | from odoo import fields, models 5 | 6 | 7 | class ResConfigSettings(models.TransientModel): 8 | _inherit = "res.config.settings" 9 | 10 | display_document_page = fields.Boolean( 11 | related="website_id.display_document_page", readonly=False 12 | ) 13 | -------------------------------------------------------------------------------- /document_hosting/models/website.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 - Today Coop IT Easy SC () 2 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). 3 | 4 | 5 | from odoo import fields, models 6 | 7 | 8 | class Website(models.Model): 9 | _inherit = "website" 10 | 11 | display_document_page = fields.Boolean("Display documents on website", default=True) 12 | -------------------------------------------------------------------------------- /document_hosting/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coopiteasy/addons/932886c126fbdcf291d98e6cff84ae1c5461f053/document_hosting/readme/CONTRIBUTORS.rst -------------------------------------------------------------------------------- /document_hosting/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coopiteasy/addons/932886c126fbdcf291d98e6cff84ae1c5461f053/document_hosting/readme/DESCRIPTION.rst -------------------------------------------------------------------------------- /document_hosting/readme/ROADMAP.rst: -------------------------------------------------------------------------------- 1 | Don't allow for recursive parent categories (a category cannot be it's own parent) 2 | Add unit tests 3 | -------------------------------------------------------------------------------- /document_hosting/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink 2 | access_document_hosting,access_document_hosting,model_document_hosting_document,,1,0,0,0 3 | access_document_hosting_category,access_document_hosting_category,model_document_hosting_category,,1,0,0,0 4 | access_document_hosting_user_group,access_document_hosting,model_document_hosting_document,base.group_user,1,1,1,1 5 | access_document_hosting_category_user_group,access_document_hosting_category,model_document_hosting_category,base.group_user,1,1,1,1 6 | -------------------------------------------------------------------------------- /document_hosting/views/document_hosting_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | Document 11 | document_hosting.document 12 | tree,form 13 | 14 | 15 | 16 | 17 | Categories 18 | document_hosting.category 19 | tree,form 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /document_hosting/views/res_config_settings_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | res.config.settings.view.form.inherit.document.hosting 6 | 7 | res.config.settings 8 | 9 | 10 | 11 |

Documents

12 |
17 |
18 |
19 | 20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /event_track_multi_date/README.rst: -------------------------------------------------------------------------------- 1 | ======================== 2 | Multiple Dates per Track 3 | ======================== 4 | 5 | .. 6 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 7 | !! This file is generated by oca-gen-addon-readme !! 8 | !! changes will be overwritten. !! 9 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 10 | !! source digest: sha256:a2cbdf4839cfddd9633dc0ed51360ca73afa6d5e096cb7427c4e47777bbe8549 11 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 12 | 13 | .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png 14 | :target: https://odoo-community.org/page/development-status 15 | :alt: Beta 16 | .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png 17 | :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html 18 | :alt: License: AGPL-3 19 | .. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Faddons-lightgray.png?logo=github 20 | :target: https://github.com/coopiteasy/addons/tree/16.0/event_track_multi_date 21 | :alt: coopiteasy/addons 22 | 23 | |badge1| |badge2| |badge3| 24 | 25 | This module allows to set multiple dates per track. 26 | 27 | **Table of contents** 28 | 29 | .. contents:: 30 | :local: 31 | 32 | Bug Tracker 33 | =========== 34 | 35 | Bugs are tracked on `GitHub Issues `_. 36 | In case of trouble, please check there if your issue has already been reported. 37 | If you spotted it first, help us to smash it by providing a detailed and welcomed 38 | `feedback `_. 39 | 40 | Do not contact contributors directly about support or help with technical issues. 41 | 42 | Credits 43 | ======= 44 | 45 | Authors 46 | ~~~~~~~ 47 | 48 | * Coop IT Easy SC 49 | 50 | Contributors 51 | ~~~~~~~~~~~~ 52 | 53 | * `Coop IT Easy SC `_ 54 | 55 | Maintainers 56 | ~~~~~~~~~~~ 57 | 58 | This module is part of the `coopiteasy/addons `_ project on GitHub. 59 | 60 | You are welcome to contribute. 61 | -------------------------------------------------------------------------------- /event_track_multi_date/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /event_track_multi_date/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Multiple Dates per Track", 7 | "version": "16.0.1.0.0", 8 | "author": "Coop IT Easy SC, Odoo Community Association (OCA)", 9 | "license": "AGPL-3", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "category": "Event", 12 | "summary": "Multiple Dates per Track", 13 | "depends": ["website_event_track"], 14 | "data": [ 15 | "security/ir.model.access.csv", 16 | "views/event_track.xml", 17 | ], 18 | "installable": True, 19 | } 20 | -------------------------------------------------------------------------------- /event_track_multi_date/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import event_track 2 | from . import event_track_date 3 | -------------------------------------------------------------------------------- /event_track_multi_date/models/event_track.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | from odoo import fields, models 7 | 8 | 9 | class EventTrackSession(models.Model): 10 | _inherit = "event.track" 11 | 12 | dates = fields.One2many(comodel_name="event.track.date", inverse_name="track_id") 13 | -------------------------------------------------------------------------------- /event_track_multi_date/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_ 2 | -------------------------------------------------------------------------------- /event_track_multi_date/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | This module allows to set multiple dates per track. 2 | -------------------------------------------------------------------------------- /event_track_multi_date/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | access_event_track_date_registration,event.track.date.registration,event_track_multi_date.model_event_track_date,event.group_event_registration_desk,1,0,0,0 3 | access_event_track_date_user,event.track.date.user,event_track_multi_date.model_event_track_date,event.group_event_user,1,1,1,1 4 | -------------------------------------------------------------------------------- /event_track_multi_date/static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coopiteasy/addons/932886c126fbdcf291d98e6cff84ae1c5461f053/event_track_multi_date/static/description/icon.png -------------------------------------------------------------------------------- /event_track_multi_date/views/event_track.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | event.track 5 | 6 | 7 | 8 | True 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /partner_contact_type_default/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /partner_contact_type_default/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Partner Contact Type Default", 7 | "summary": """ 8 | Set 'contact' as default type when creating a partner as a contact of another 9 | partner.""", 10 | "version": "16.0.1.0.0", 11 | "category": "Customer Relationship Management", 12 | "website": "https://github.com/coopiteasy/addons", 13 | "author": "Coop IT Easy SC", 14 | "maintainers": ["carmenbianca"], 15 | "license": "AGPL-3", 16 | "application": False, 17 | "depends": [ 18 | "base", 19 | "base_view_inheritance_extension", 20 | ], 21 | "data": [ 22 | "views/res_partner_views.xml", 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /partner_contact_type_default/i18n/partner_contact_type_default.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # 4 | msgid "" 5 | msgstr "" 6 | "Project-Id-Version: Odoo Server 16.0\n" 7 | "Report-Msgid-Bugs-To: \n" 8 | "Last-Translator: \n" 9 | "Language-Team: \n" 10 | "MIME-Version: 1.0\n" 11 | "Content-Type: text/plain; charset=UTF-8\n" 12 | "Content-Transfer-Encoding: \n" 13 | "Plural-Forms: \n" 14 | -------------------------------------------------------------------------------- /partner_contact_type_default/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Carmen Bianca BAKKER 4 | -------------------------------------------------------------------------------- /partner_contact_type_default/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Set 'contact' as default type (instead of 'other') when creating a partner as a 2 | contact of another partner. 3 | -------------------------------------------------------------------------------- /partner_contact_type_default/views/res_partner_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | partner_contact_type_default.view_partner_form 5 | res.partner 6 | 7 | 8 | 12 | 13 | { 14 | "default_type": "contact", 15 | } 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /payment_sepa_dd/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | from . import controllers 6 | -------------------------------------------------------------------------------- /payment_sepa_dd/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "SEPA Direct Debit Payment", 7 | "summary": "Pay via SEPA Direct Debit", 8 | "version": "16.0.1.0.1", 9 | "category": "Accounting/Payment Providers", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "maintainers": ["remytms"], 13 | "license": "AGPL-3", 14 | "application": False, 15 | "depends": [ 16 | "payment", 17 | "account_payment", 18 | "account_banking_sepa_direct_debit", 19 | ], 20 | "data": [ 21 | "views/payment_provider_views.xml", 22 | "views/templates.xml", 23 | "data/payment_provider_data.xml", 24 | ], 25 | "assets": { 26 | "web.assets_frontend": [ 27 | "payment_sepa_dd/static/src/js/payment_form.js", 28 | "payment_sepa_dd/static/src/js/post_processing.js", 29 | ], 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /payment_sepa_dd/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import main 5 | -------------------------------------------------------------------------------- /payment_sepa_dd/controllers/main.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | import logging 6 | import pprint 7 | 8 | from odoo import _ 9 | from odoo.exceptions import ValidationError 10 | from odoo.http import Controller, request, route 11 | 12 | from odoo.addons.payment import utils as payment_utils 13 | 14 | _logger = logging.getLogger(__name__) 15 | 16 | 17 | class PaymentSepaDDController(Controller): 18 | _process_url = "/payment/sepa_dd/process" 19 | 20 | @route(_process_url, type="json", auth="public") 21 | def sepa_dd_process_transaction(self, **data): 22 | """Process sepa_dd payment. 23 | Throws ValidationError if something fails. 24 | """ 25 | access_token = data.get("access_token") 26 | reference = data.get("reference") 27 | partner_id = data.get("partner_id") 28 | 29 | # Check that the transaction details have not been altered 30 | if not payment_utils.check_access_token(access_token, reference, partner_id): 31 | raise ValidationError( 32 | _("sepa_dd payment: Received tampered payment request data.") 33 | ) 34 | 35 | _logger.info( 36 | "Handling sepa_dd payment processing with data:\n%s", pprint.pformat(data) 37 | ) 38 | 39 | tx_sudo = ( 40 | request.env["payment.transaction"] 41 | .sudo() 42 | .search([("reference", "=", reference)]) 43 | ) 44 | 45 | tx_sudo._handle_notification_data("sepa_dd", data) 46 | -------------------------------------------------------------------------------- /payment_sepa_dd/data/payment_provider_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | SEPA Direct Debit Payment 11 | 12 | sepa_dd 13 | 14 | 15 |

16 | Your order has been saved. 17 | Your payment by SEPA Direct Debit will be processed soon. 18 |

19 |
20 | 21 | SEPA Direct Debit terms and conditions. 22 | 23 |
24 | 25 |
26 | -------------------------------------------------------------------------------- /payment_sepa_dd/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | # from . import sale_order 5 | from . import payment_provider 6 | from . import payment_transaction 7 | -------------------------------------------------------------------------------- /payment_sepa_dd/models/payment_provider.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import api, fields, models 6 | 7 | 8 | class PaymentProvider(models.Model): 9 | _inherit = "payment.provider" 10 | 11 | code = fields.Selection( 12 | selection_add=[("sepa_dd", "SEPA Direct Debit")], 13 | ondelete={"sepa_dd": "set default"}, 14 | ) 15 | sepa_dd_terms = fields.Html(string="SEPA Direct Debit Terms", translate=True) 16 | 17 | @api.depends("code") 18 | def _compute_view_configuration_fields(self): 19 | """Override of payment to hide the credentials page.""" 20 | result = super()._compute_view_configuration_fields() 21 | self.filtered(lambda p: p.code == "sepa_dd").update( 22 | { 23 | "show_credentials_page": False, 24 | "show_payment_icon_ids": False, 25 | "show_pre_msg": False, 26 | "show_done_msg": False, 27 | "show_cancel_msg": False, 28 | } 29 | ) 30 | return result 31 | -------------------------------------------------------------------------------- /payment_sepa_dd/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Rémy Taymans 4 | -------------------------------------------------------------------------------- /payment_sepa_dd/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Pay via SEPA Direct Debit. 2 | -------------------------------------------------------------------------------- /payment_sepa_dd/readme/ROADMAP.rst: -------------------------------------------------------------------------------- 1 | * Add tests that check mandate creation 2 | -------------------------------------------------------------------------------- /payment_sepa_dd/static/src/js/post_processing.js: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | // 3 | // SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | // From payment_custom/static/src/js/post_processing.js 6 | 7 | odoo.define("payment_sepa_dd.post_processing", (require) => { 8 | "use strict"; 9 | 10 | const paymentPostProcessing = require("payment.post_processing"); 11 | 12 | paymentPostProcessing.include({ 13 | /** 14 | * Don't wait for the transaction to be confirmed before 15 | * redirecting customers to the landing route because sepa_dd 16 | * transactions remain in the state 'pending' forever. 17 | * 18 | * @override method from `payment.post_processing` 19 | * @param {Object} display_values_list - The post-processing 20 | * values of the transactions 21 | */ 22 | processPolledData: function (display_values_list) { 23 | // In almost every case, there will be a single transaction 24 | // to display. If there are more than one transaction, the 25 | // last one will most likely be the one that counts. We 26 | // use that one to redirect the user to the landing page. 27 | if ( 28 | display_values_list.length > 0 && 29 | display_values_list[0].provider_code === "sepa_dd" 30 | ) { 31 | window.location = display_values_list[0].landing_route; 32 | } else { 33 | return this._super(...arguments); 34 | } 35 | }, 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /payment_sepa_dd/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import common 5 | from . import test_payment_transaction 6 | from . import test_processing_flows 7 | -------------------------------------------------------------------------------- /payment_sepa_dd/tests/common.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from odoo.addons.payment.tests.common import PaymentCommon 5 | 6 | 7 | class PaymentSepaDDCommon(PaymentCommon): 8 | @classmethod 9 | def setUpClass(cls): 10 | super().setUpClass() 11 | 12 | cls.provider = cls._prepare_provider(code="sepa_dd") 13 | cls.iban = "BE41817358676710" 14 | 15 | def setUp(self): 16 | super().setUp() 17 | self.notification_data = { 18 | "reference": self.reference, 19 | "sepa_dd_accept": "sepa_dd_accept", 20 | "sepa_dd_iban": self.iban, 21 | } 22 | -------------------------------------------------------------------------------- /payment_sepa_dd/tests/test_payment_transaction.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo.exceptions import ValidationError 6 | from odoo.tests import tagged 7 | 8 | from odoo.addons.payment.tests.http_common import PaymentHttpCommon 9 | from odoo.addons.payment_sepa_dd.tests.common import PaymentSepaDDCommon 10 | 11 | 12 | @tagged("-at_install", "post_install") 13 | class TestPaymentTransaction(PaymentSepaDDCommon, PaymentHttpCommon): 14 | def test_processing_notification_data(self): 15 | """Test that processing transaction set transaction as pending.""" 16 | tx = self._create_transaction("direct") 17 | tx._process_notification_data(self.notification_data) 18 | self.assertEqual(tx.state, "pending") 19 | 20 | def test_processing_notification_data_no_iban(self): 21 | tx = self._create_transaction("direct") 22 | del self.notification_data["sepa_dd_iban"] 23 | with self.assertRaises(ValidationError): 24 | tx._process_notification_data(self.notification_data) 25 | 26 | def test_processing_notification_data_wrong_iban(self): 27 | tx = self._create_transaction("direct") 28 | self.notification_data["sepa_dd_iban"] = "AAAA" 29 | with self.assertRaises(ValidationError): 30 | tx._process_notification_data(self.notification_data) 31 | 32 | def test_processing_notification_data_no_accept(self): 33 | tx = self._create_transaction("direct") 34 | del self.notification_data["sepa_dd_accept"] 35 | with self.assertRaises(ValidationError): 36 | tx._process_notification_data(self.notification_data) 37 | 38 | def test_processing_notification_mandate_creation(self): 39 | """Test that processing transaction set transaction as pending.""" 40 | tx = self._create_transaction("direct") 41 | tx._process_notification_data(self.notification_data) 42 | # TODO: check that mandate exists 43 | -------------------------------------------------------------------------------- /payment_sepa_dd/tests/test_processing_flows.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from unittest.mock import patch 5 | 6 | from odoo.tests import tagged 7 | from odoo.tools import mute_logger 8 | 9 | from odoo.addons.payment import utils as payment_utils 10 | from odoo.addons.payment.tests.http_common import PaymentHttpCommon 11 | from odoo.addons.payment_sepa_dd.tests.common import PaymentSepaDDCommon 12 | 13 | 14 | @tagged("-at_install", "post_install") 15 | class TestProcessingFlows(PaymentSepaDDCommon, PaymentHttpCommon): 16 | def test_access_token(self): 17 | """Test that access token are correctly generated.""" 18 | tx = self._create_transaction(flow="direct") 19 | with mute_logger("odoo.addons.payment.models.payment_transaction"), patch( 20 | "odoo.addons.payment.utils.generate_access_token", 21 | new=self._generate_test_access_token, 22 | ): 23 | processing_values = tx._get_processing_values() 24 | 25 | with patch( 26 | "odoo.addons.payment.utils.generate_access_token", 27 | new=self._generate_test_access_token, 28 | ): 29 | self.assertTrue( 30 | payment_utils.check_access_token( 31 | processing_values["access_token"], self.reference, self.partner.id 32 | ) 33 | ) 34 | -------------------------------------------------------------------------------- /payment_sepa_dd/views/payment_provider_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | payment.provider.form 11 | payment.provider 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | {'invisible': [('code', '=', 'sepa_dd')]} 23 | 24 | 25 | 26 | 27 | {'required': [('state', '!=', 'disabled'), ('code', 'not in', ['none', 'custom', 'sepa_dd'])]} 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /payment_sepa_dd/views/templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | from . import controllers 6 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Payment SEPA Direct Debit Payment Mode", 7 | "summary": "Manage payment mode with payment_sepa_dd", 8 | "version": "16.0.1.0.0", 9 | "category": "Banking addons", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "maintainers": ["remytms"], 13 | "license": "AGPL-3", 14 | "depends": [ 15 | "payment_sepa_dd", 16 | "account_payment_sale", 17 | "website_sale", 18 | ], 19 | "auto_install": True, 20 | } 21 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import main 5 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/controllers/main.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo.http import request 6 | 7 | from odoo.addons.website_sale.controllers.main import PaymentPortal 8 | 9 | 10 | class PaymentPortalSEPADD(PaymentPortal): 11 | def _validate_transaction_for_order(self, transaction, sale_order_id): 12 | """ 13 | Set the corresponding payment mode for the order if using SEPA DD. 14 | """ 15 | if transaction.provider_id.code == "sepa_dd": 16 | # Set SEPA Direct Debit payment_mode_id 17 | order = request.env["sale.order"].sudo().browse(sale_order_id).exists() 18 | order.payment_mode_id = order.get_sepa_dd_payment_mode() 19 | 20 | return super()._validate_transaction_for_order(transaction, sale_order_id) 21 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/i18n/payment_sepa_dd_payment_mode.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * payment_sepa_dd_payment_mode 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: payment_sepa_dd_payment_mode 17 | #: model:ir.model,name:payment_sepa_dd_payment_mode.model_sale_order 18 | msgid "Sales Order" 19 | msgstr "" 20 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import sale_order 5 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/models/sale_order.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | from odoo import api, models 7 | 8 | 9 | class SaleOrder(models.Model): 10 | _inherit = "sale.order" 11 | 12 | @api.model 13 | def get_sepa_dd_payment_mode(self): 14 | return self.env["account.payment.mode"].search( 15 | [("payment_method_id.code", "=", "sepa_direct_debit")], 16 | limit=1, 17 | ) 18 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Rémy Taymans 4 | -------------------------------------------------------------------------------- /payment_sepa_dd_payment_mode/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Manage payment mode with ``payment_sepa_dd``. 2 | 3 | This is a glue module between ``payment_sepa_dd`` and ``account_payment_sale``. 4 | -------------------------------------------------------------------------------- /portal_customer_wallet/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import controllers 6 | from . import models 7 | -------------------------------------------------------------------------------- /portal_customer_wallet/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Portal Customer Wallet", 7 | "summary": """ 8 | My Home displays expenditures using customer wallet""", 9 | "version": "16.0.1.0.0", 10 | "category": "Website", 11 | "website": "https://github.com/coopiteasy/addons", 12 | "author": "Coop IT Easy SC", 13 | "maintainers": ["carmenbianca"], 14 | "license": "AGPL-3", 15 | "application": False, 16 | "depends": [ 17 | "portal", 18 | "website", 19 | "account_customer_wallet", 20 | ], 21 | "excludes": [], 22 | "data": [ 23 | "views/portal_templates.xml", 24 | ], 25 | "demo": [], 26 | "assets": { 27 | "web.assets_frontend": [ 28 | "portal_customer_wallet/static/src/css/portal_customer_wallet.css" 29 | ], 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /portal_customer_wallet/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import main 6 | -------------------------------------------------------------------------------- /portal_customer_wallet/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import res_partner 6 | -------------------------------------------------------------------------------- /portal_customer_wallet/models/res_partner.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from collections import defaultdict 6 | 7 | from odoo import models 8 | 9 | 10 | class ResPartner(models.Model): 11 | _inherit = "res.partner" 12 | 13 | def customer_wallet_payments_per_month(self): 14 | """Return a dictionary with (year, month) keys. The value is the amount 15 | spent using the customer wallet for every month. 16 | """ 17 | self.ensure_one() 18 | # Like in account_customer_wallet, search against all partners in family. 19 | all_partners_in_family = self.get_all_partners_in_family() 20 | wallet_account_id = self.env.company.customer_wallet_account_id 21 | move_lines = self.env["account.move.line"].search( 22 | [ 23 | ("partner_id", "in", all_partners_in_family), 24 | ("account_id", "=", wallet_account_id.id), 25 | # Negative balances = fill up the customer wallet. We're only 26 | # interested in customer wallet spendings here, so let's skip 27 | # them. 28 | ("balance", ">", 0), 29 | ] 30 | ) 31 | per_month_dict = defaultdict(int) 32 | for move_line in move_lines: 33 | date = move_line.move_id.date 34 | per_month_dict[(date.year, date.month)] += move_line.balance 35 | return per_month_dict 36 | -------------------------------------------------------------------------------- /portal_customer_wallet/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Carmen Bianca BAKKER 4 | -------------------------------------------------------------------------------- /portal_customer_wallet/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | My Home displays expenditures using customer wallet 2 | -------------------------------------------------------------------------------- /portal_customer_wallet/static/src/css/portal_customer_wallet.css: -------------------------------------------------------------------------------- 1 | /* TODO: Maybe do something here? I'm not a front-end designer. - Carmen */ 2 | 3 | .wallet_row_year { 4 | } 5 | 6 | .wallet_row_month { 7 | } 8 | -------------------------------------------------------------------------------- /portal_customer_wallet/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import common 6 | from . import test_monthly_wallet_balance 7 | -------------------------------------------------------------------------------- /portal_customer_wallet/tests/test_monthly_wallet_balance.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | import datetime 6 | 7 | from .common import TestCommon 8 | 9 | 10 | class TestMonthlyBalance(TestCommon): 11 | def test_credit_is_not_counted(self): 12 | """credit = increasing customer wallet budget. Not counted.""" 13 | self._create_move(credit=100) 14 | self.assertFalse(self.partner_id.customer_wallet_payments_per_month()) 15 | 16 | def test_one_payment(self): 17 | """Simple case.""" 18 | self._create_move(debit=10, date=datetime.date(2023, 1, 1)) 19 | result = self.partner_id.customer_wallet_payments_per_month() 20 | self.assertEqual(result[(2023, 1)], 10) 21 | 22 | def test_two_payments(self): 23 | """More complex case.""" 24 | self._create_move(debit=10, date=datetime.date(2023, 1, 1)) 25 | self._create_move(debit=5, date=datetime.date(2023, 1, 31)) 26 | result = self.partner_id.customer_wallet_payments_per_month() 27 | self.assertEqual(result[(2023, 1)], 15) 28 | 29 | def test_multiple_months(self): 30 | """Separate months have separate keys.""" 31 | self._create_move(debit=10, date=datetime.date(2023, 1, 1)) 32 | self._create_move(debit=20, date=datetime.date(2023, 2, 1)) 33 | result = self.partner_id.customer_wallet_payments_per_month() 34 | self.assertEqual(result[(2023, 1)], 10) 35 | self.assertEqual(result[(2023, 2)], 20) 36 | self.assertEqual(len(result), 2) 37 | 38 | def test_multiple_years(self): 39 | """Identical months in different years have separate keys.""" 40 | self._create_move(debit=10, date=datetime.date(2023, 1, 1)) 41 | self._create_move(debit=20, date=datetime.date(2024, 1, 1)) 42 | result = self.partner_id.customer_wallet_payments_per_month() 43 | self.assertEqual(result[(2023, 1)], 10) 44 | self.assertEqual(result[(2024, 1)], 20) 45 | -------------------------------------------------------------------------------- /portal_customer_wallet/views/portal_templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 44 | 45 | -------------------------------------------------------------------------------- /product_contract_payment_mode/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | -------------------------------------------------------------------------------- /product_contract_payment_mode/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Product Contract Payment Mode", 7 | "summary": "Create contract with right payment mode", 8 | "version": "16.0.1.0.0", 9 | "category": "Contract Management", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "maintainers": ["remytms"], 13 | "license": "AGPL-3", 14 | "depends": [ 15 | "product_contract", 16 | "contract_payment_mode", 17 | ], 18 | "auto_install": True, 19 | } 20 | -------------------------------------------------------------------------------- /product_contract_payment_mode/i18n/product_contract_payment_mode.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * product_contract_payment_mode 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: product_contract_payment_mode 17 | #: model:ir.model,name:product_contract_payment_mode.model_sale_order 18 | msgid "Sales Order" 19 | msgstr "" 20 | -------------------------------------------------------------------------------- /product_contract_payment_mode/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import sale_order 5 | -------------------------------------------------------------------------------- /product_contract_payment_mode/models/sale_order.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | from odoo import models 7 | 8 | 9 | class SaleOrder(models.Model): 10 | _inherit = "sale.order" 11 | 12 | def _prepare_contract_value(self, contract_template): 13 | self.ensure_one() 14 | values = super()._prepare_contract_value(contract_template) 15 | values["payment_mode_id"] = self.payment_mode_id.id 16 | return values 17 | -------------------------------------------------------------------------------- /product_contract_payment_mode/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Rémy Taymans 4 | -------------------------------------------------------------------------------- /product_contract_payment_mode/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Create contract with right payment mode. 2 | 3 | This is a glue module between ``product_contract`` and ``contract_payment_mode``. 4 | -------------------------------------------------------------------------------- /product_contract_sale_generation/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import models 6 | -------------------------------------------------------------------------------- /product_contract_sale_generation/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Product Contract Sale Generation", 7 | "summary": "Prevent loop between product_contract and contract_sale_generation", 8 | "version": "16.0.1.0.0", 9 | "category": "Contract Management", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "license": "AGPL-3", 13 | "depends": [ 14 | "product_contract", 15 | "contract_sale_generation", 16 | ], 17 | "data": [ 18 | "views/sale_order.xml", 19 | ], 20 | "auto_install": True, 21 | } 22 | -------------------------------------------------------------------------------- /product_contract_sale_generation/i18n/product_contract_sale_generation.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * product_contract_sale_generation 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: product_contract_sale_generation 17 | #: model:ir.model,name:product_contract_sale_generation.model_contract_contract 18 | msgid "Contract" 19 | msgstr "" 20 | 21 | #. module: product_contract_sale_generation 22 | #: model:ir.model.fields,field_description:product_contract_sale_generation.field_sale_order__created_from_contract 23 | msgid "Created From Contract" 24 | msgstr "" 25 | 26 | #. module: product_contract_sale_generation 27 | #: model:ir.model,name:product_contract_sale_generation.model_sale_order 28 | msgid "Sales Order" 29 | msgstr "" 30 | 31 | #. module: product_contract_sale_generation 32 | #: model:ir.model,name:product_contract_sale_generation.model_sale_order_line 33 | msgid "Sales Order Line" 34 | msgstr "" 35 | -------------------------------------------------------------------------------- /product_contract_sale_generation/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import contract 6 | from . import sale_order 7 | from . import sale_order_line 8 | -------------------------------------------------------------------------------- /product_contract_sale_generation/models/contract.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import models 6 | 7 | 8 | class ContractContract(models.Model): 9 | _inherit = "contract.contract" 10 | 11 | def _prepare_recurring_sales_values(self, date_ref=False): 12 | sale_order_vals_list = super()._prepare_recurring_sales_values(date_ref) 13 | for sale_order_vals in sale_order_vals_list: 14 | sale_order_vals["created_from_contract"] = True 15 | return sale_order_vals_list 16 | -------------------------------------------------------------------------------- /product_contract_sale_generation/models/sale_order.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import fields, models 6 | 7 | 8 | class SaleOrder(models.Model): 9 | _inherit = "sale.order" 10 | 11 | created_from_contract = fields.Boolean(default=False, readonly=True) 12 | 13 | def action_create_contract(self): 14 | for order in self: 15 | if order.created_from_contract: 16 | return False 17 | else: 18 | return super().action_create_contract() 19 | -------------------------------------------------------------------------------- /product_contract_sale_generation/models/sale_order_line.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import models 6 | 7 | 8 | class SaleOrder(models.Model): 9 | _inherit = "sale.order.line" 10 | 11 | def _compute_qty_to_invoice(self): 12 | res = super()._compute_qty_to_invoice() 13 | for line in self: 14 | if line.order_id.created_from_contract: 15 | # put back the right quantity to invoice 16 | line.filtered("product_id.is_contract").update( 17 | {"qty_to_invoice": line.product_uom_qty} 18 | ) 19 | return res 20 | -------------------------------------------------------------------------------- /product_contract_sale_generation/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Prevent loop between ``product_contract`` and ``contract_sale_generation``. 2 | 3 | When using both the ``product_contract`` and the ``contract_sale_generation`` modules, a sale order generated from a contract will create another contract on confirmation. 4 | This module prevents this from happening. 5 | 6 | Without this module, a sale order with a product having ``is_contract`` as true, when confirmed, creates a contract. 7 | This contract contains the same product (with ``is_contract`` as true). 8 | If this contract is set to generate sale orders, then it will generate sale orders with this same product. 9 | When these sale order are confirmed, they will create a contract, and so on. 10 | 11 | With this module installed, this loop is broken: if a sale order was generated from a contract, confirming it will not create a new contract. 12 | -------------------------------------------------------------------------------- /product_contract_sale_generation/static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coopiteasy/addons/932886c126fbdcf291d98e6cff84ae1c5461f053/product_contract_sale_generation/static/description/icon.png -------------------------------------------------------------------------------- /product_contract_sale_generation/views/sale_order.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | sale.order.form (in product_contract_sale_generation) 10 | sale.order 11 | 12 | 13 | 14 | 15 | 16 | 20 | {"invisible": ["|", ("created_from_contract", "=", True), ("need_contract_creation", "=", False)]} 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /product_contract_storable/README.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Product Contract Storable 3 | ========================= 4 | 5 | .. 6 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 7 | !! This file is generated by oca-gen-addon-readme !! 8 | !! changes will be overwritten. !! 9 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 10 | !! source digest: sha256:bdaf083defd1f00c535c0b59c8601cb38de7f3922ab7f0f7d9a898fa2c804592 11 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 12 | 13 | .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png 14 | :target: https://odoo-community.org/page/development-status 15 | :alt: Beta 16 | .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png 17 | :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html 18 | :alt: License: AGPL-3 19 | .. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Faddons-lightgray.png?logo=github 20 | :target: https://github.com/coopiteasy/addons/tree/16.0/product_contract_storable 21 | :alt: coopiteasy/addons 22 | 23 | |badge1| |badge2| |badge3| 24 | 25 | Allow product contract to be of type other than services. 26 | 27 | **Table of contents** 28 | 29 | .. contents:: 30 | :local: 31 | 32 | Bug Tracker 33 | =========== 34 | 35 | Bugs are tracked on `GitHub Issues `_. 36 | In case of trouble, please check there if your issue has already been reported. 37 | If you spotted it first, help us to smash it by providing a detailed and welcomed 38 | `feedback `_. 39 | 40 | Do not contact contributors directly about support or help with technical issues. 41 | 42 | Credits 43 | ======= 44 | 45 | Authors 46 | ~~~~~~~ 47 | 48 | * Coop IT Easy SC 49 | 50 | Contributors 51 | ~~~~~~~~~~~~ 52 | 53 | * `Coop IT Easy SC `_: 54 | 55 | * Victor Champonnois 56 | 57 | Maintainers 58 | ~~~~~~~~~~~ 59 | 60 | This module is part of the `coopiteasy/addons `_ project on GitHub. 61 | 62 | You are welcome to contribute. 63 | -------------------------------------------------------------------------------- /product_contract_storable/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | -------------------------------------------------------------------------------- /product_contract_storable/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Product Contract Storable", 7 | "summary": "Allow product contract to be of type other than services", 8 | "version": "16.0.1.0.0", 9 | "category": "Sale", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "license": "AGPL-3", 13 | "depends": [ 14 | "product_contract", 15 | ], 16 | "data": [ 17 | "views/product_template.xml", 18 | ], 19 | } 20 | -------------------------------------------------------------------------------- /product_contract_storable/i18n/product_contract_storable.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * product_contract_storable 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: product_contract_storable 17 | #: model:ir.model,name:product_contract_storable.model_product_template 18 | msgid "Product" 19 | msgstr "" 20 | -------------------------------------------------------------------------------- /product_contract_storable/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from . import product_template 6 | -------------------------------------------------------------------------------- /product_contract_storable/models/product_template.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import models 6 | 7 | 8 | class ContractContract(models.Model): 9 | _inherit = "product.template" 10 | 11 | def _check_contract_product_type(self): 12 | pass 13 | -------------------------------------------------------------------------------- /product_contract_storable/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Victor Champonnois 4 | -------------------------------------------------------------------------------- /product_contract_storable/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Allow product contract to be of type other than services. 2 | -------------------------------------------------------------------------------- /product_contract_storable/views/product_template.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | account.invoice.select.contract 10 | product.template 11 | 15 | 16 | 17 | {'invisible': False} 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | { 5 | "name": "Resource Work Time From Contracts", 6 | "summary": ( 7 | "Take the contracts of an employee into account when computing work " 8 | "time per day" 9 | ), 10 | "version": "16.0.1.0.0", 11 | "license": "AGPL-3", 12 | "author": "Coop IT Easy SC", 13 | "website": "https://github.com/coopiteasy/addons", 14 | "category": "Human Resources", 15 | "depends": [ 16 | "hr_contract", 17 | ], 18 | "data": [ 19 | "views/hr_employee.xml", 20 | "views/resource_resource.xml", 21 | ], 22 | "demo": [], 23 | } 24 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/i18n/resource_work_time_from_contracts.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * resource_work_time_from_contracts 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: resource_work_time_from_contracts 17 | #: model:ir.model,name:resource_work_time_from_contracts.model_resource_mixin 18 | msgid "Resource Mixin" 19 | msgstr "" 20 | 21 | #. module: resource_work_time_from_contracts 22 | #: model:ir.model,name:resource_work_time_from_contracts.model_resource_calendar_leaves 23 | msgid "Resource Time Off Detail" 24 | msgstr "" 25 | 26 | #. module: resource_work_time_from_contracts 27 | #: model:ir.model,name:resource_work_time_from_contracts.model_resource_resource 28 | msgid "Resources" 29 | msgstr "" 30 | 31 | #. module: resource_work_time_from_contracts 32 | #: model:ir.model.fields,field_description:resource_work_time_from_contracts.field_hr_employee__resource_calendar_id 33 | #: model:ir.model.fields,field_description:resource_work_time_from_contracts.field_resource_calendar_leaves__calendar_id 34 | #: model:ir.model.fields,field_description:resource_work_time_from_contracts.field_resource_mixin__resource_calendar_id 35 | msgid "Working Hours" 36 | msgstr "" 37 | 38 | #. module: resource_work_time_from_contracts 39 | #: model:ir.model.fields,field_description:resource_work_time_from_contracts.field_resource_resource__calendar_id 40 | msgid "Working Time" 41 | msgstr "" 42 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import resource_calendar_leaves 2 | from . import resource_mixin 3 | from . import resource_resource 4 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/models/resource_calendar_leaves.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | from odoo import fields, models 5 | 6 | 7 | class ResourceCalendarLeaves(models.Model): 8 | 9 | _inherit = "resource.calendar.leaves" 10 | 11 | # force this field to be equal to the resource_calendar_id of the resource 12 | # (which should be equal to the one of the company). this ensures that all 13 | # leaves for all resources are defined in the same resource calendar, 14 | # which is needed to compute working hours while taking leaves into 15 | # account. 16 | calendar_id = fields.Many2one( 17 | "resource.calendar", 18 | related="resource_id.calendar_id", 19 | readonly=True, 20 | store=True, 21 | ) 22 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/models/resource_resource.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | from odoo import fields, models 5 | 6 | 7 | class ResourceResource(models.Model): 8 | 9 | _inherit = "resource.resource" 10 | 11 | # force this field to be equal to the resource_calendar_id of the company. 12 | calendar_id = fields.Many2one( 13 | "resource.calendar", 14 | related="company_id.resource_calendar_id", 15 | readonly=True, 16 | store=True, 17 | ) 18 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * hugues de keyzer 4 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Take the contracts of an employee into account when computing work time per 2 | day. 3 | 4 | When this module is installed, the number of hours an employee is supposed to 5 | work is only computed from their contracts. Without contracts, the work time 6 | per day is 0, instead of using the default company’s working hours. 7 | 8 | The start and end dates of contracts are taken into account, but the status 9 | (state) of contracts are ignored. 10 | 11 | For this module to work properly, the company’s working hours should encompass 12 | all possible work days (including weekend days if there are contracts with 13 | weekend days), and each day should have working hours that correspond to the 14 | working hours used in all contracts. This is because the company’s working 15 | hours are used to compute leaves, and the number of hours per day is computed 16 | from it. 17 | 18 | For example, if the company working hours define 8 hours per day, from 8 to 12 19 | and 13 to 17, all contracts’ working hours should be set from 8 to 12 and/or 20 | from 13 to 17 for the corresponding days. Half days are thus supported. 21 | 22 | If there are contracts with working hours that don’t match the company’s 23 | working hours, the number of days for leaves will be computed incorrectly. 24 | 25 | This module also makes the working hours (resource calendar) of an employee 26 | always equal to the company’s working hours, and hides its field on the 27 | employee form view. 28 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from . import test_work_days_data 2 | from . import test_work_time 3 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/views/hr_employee.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | hr.employee.form (in resource_work_time_from_contracts) 9 | hr.employee 10 | 11 | 12 | 13 | True 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /resource_work_time_from_contracts/views/resource_resource.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | resource.resource.tree (in resource_work_time_from_contracts) 9 | resource.resource 10 | 11 | 12 | 13 | True 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /sale_order_auto_carrier/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /sale_order_auto_carrier/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | { 5 | "name": "Partner Automatic Carrier", 6 | "summary": "Compute automatically the carrier on a sale order", 7 | "version": "16.0.1.0.0", 8 | "license": "AGPL-3", 9 | "author": "Coop IT Easy SC", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "depends": [ 12 | "website_sale_delivery", 13 | ], 14 | "demo": [], 15 | } 16 | -------------------------------------------------------------------------------- /sale_order_auto_carrier/i18n/sale_order_auto_carrier.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * sale_order_auto_carrier 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: sale_order_auto_carrier 17 | #: model:ir.model,name:sale_order_auto_carrier.model_sale_order 18 | msgid "Sales Order" 19 | msgstr "" 20 | -------------------------------------------------------------------------------- /sale_order_auto_carrier/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import sale_order 2 | -------------------------------------------------------------------------------- /sale_order_auto_carrier/models/sale_order.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | from odoo import models 5 | 6 | 7 | class SalePartner(models.Model): 8 | _inherit = "sale.order" 9 | 10 | def action_confirm(self): 11 | for order in self: 12 | if order: 13 | order._check_carrier_quotation() 14 | return super().action_confirm() 15 | -------------------------------------------------------------------------------- /sale_order_auto_carrier/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Victor Champonnois 4 | -------------------------------------------------------------------------------- /sale_order_auto_carrier/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | This modules computes delivery cost on sale order confirmation. Unlike sale_order_carrier_auto_assign, it is not only based on the carrier defined on the partner. Instead it runs the automated carrier assignment defined in website_sale_delivery. This allows to add carrier based on carrier's configuration. In case several delivery methods fit the sale order, the first one in sequence order is used. 2 | 3 | This module is useful to add delivery costs on sale order that are automatically created by contracts. In order for this to work with contract-generated sale orders, contract should be configured as "Sale Autoconfirm". 4 | -------------------------------------------------------------------------------- /sale_order_volume/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /sale_order_volume/__manifest__.py: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # 3 | # Copyright (C) 2017- Coop IT Easy. 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU Affero General Public License as 7 | # published by the Free Software Foundation, either version 3 of the 8 | # License, or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU Affero General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Affero General Public License 16 | # along with this program. If not, see . 17 | # 18 | ############################################################################## 19 | { 20 | "name": "Sale Order Volume", 21 | "version": "16.0.1.0.0", 22 | "depends": ["sale", "stock", "website_sale"], 23 | "author": "Coop IT Easy SC", 24 | "license": "AGPL-3", 25 | "category": "Sale", 26 | "website": "https://github.com/coopiteasy/addons", 27 | "summary": """ 28 | Computes the volume of products per 29 | category ordered and display it on 30 | """, 31 | "data": [ 32 | "data/pallet_volume_data.xml", 33 | "views/sale_order.xml", 34 | "views/shopping_cart.xml", 35 | "reports/report_saleorder.xml", 36 | "views/res_config_settings_views.xml", 37 | ], 38 | "demo": ["demo/demo.xml"], 39 | "installable": True, 40 | } 41 | -------------------------------------------------------------------------------- /sale_order_volume/data/pallet_volume_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sale_order_volume.pallet_volume 5 | 1.75 6 | 7 | 8 | -------------------------------------------------------------------------------- /sale_order_volume/demo/demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 0.3 9 | 10 | 11 | 3 12 | 13 | 14 | 1.2 15 | 16 | 17 | -------------------------------------------------------------------------------- /sale_order_volume/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import res_config_settings 2 | from . import sale_order_line 3 | from . import sale_order 4 | -------------------------------------------------------------------------------- /sale_order_volume/models/res_config_settings.py: -------------------------------------------------------------------------------- 1 | from odoo import fields, models 2 | 3 | 4 | class ResConfigSettings(models.TransientModel): 5 | _inherit = "res.config.settings" 6 | 7 | pallet_volume = fields.Float( 8 | string="Pallet Volume (m³)", 9 | help="Pallet Volume in cubic meter", 10 | config_parameter="sale_order_volume.pallet_volume", 11 | digits=(3, 2), 12 | ) 13 | -------------------------------------------------------------------------------- /sale_order_volume/models/sale_order.py: -------------------------------------------------------------------------------- 1 | # © 2016 Robin Keunen, Coop IT Easy SCRL. 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). 3 | 4 | from odoo import api, fields, models 5 | 6 | 7 | def _compute_pallet_count(volume, pallet_volume): 8 | if not pallet_volume: 9 | return 0 10 | quotient, remainder = divmod(volume, pallet_volume) 11 | if remainder: 12 | return quotient + 1 13 | return quotient 14 | 15 | 16 | class SaleOrder(models.Model): 17 | _inherit = "sale.order" 18 | 19 | volume = fields.Float( 20 | string="Order Volume (m³)", compute="_compute_order_volume", store=True 21 | ) 22 | 23 | pallet_count = fields.Integer( 24 | string="Order # Pallets", compute="_compute_order_volume", store=True 25 | ) 26 | 27 | @api.depends("order_line", "order_line.volume") 28 | def _compute_order_volume(self): 29 | 30 | for order in self: 31 | order_lines = order.order_line.filtered( 32 | lambda ol: ol.state not in ["cancel"] 33 | ) 34 | 35 | order.volume = sum(ol.volume for ol in order_lines) 36 | order.pallet_count = _compute_pallet_count( 37 | order.volume, float(self.get_default_pallet_volume()) 38 | ) 39 | 40 | @api.model 41 | def get_default_pallet_volume(self): 42 | return ( 43 | self.env["ir.config_parameter"] 44 | .sudo() 45 | .get_param("sale_order_volume.pallet_volume") 46 | or 0 47 | ) 48 | -------------------------------------------------------------------------------- /sale_order_volume/models/sale_order_line.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import api, fields, models 6 | 7 | 8 | class SaleOrderLine(models.Model): 9 | _inherit = "sale.order.line" 10 | 11 | volume = fields.Float(compute="_compute_volume", store=True) 12 | 13 | @api.depends("product_id.volume", "product_uom_qty") 14 | def _compute_volume(self): 15 | for line in self: 16 | line.volume = line.product_id.volume * line.product_uom_qty 17 | -------------------------------------------------------------------------------- /sale_order_volume/readme/CONFIGURE.rst: -------------------------------------------------------------------------------- 1 | Pallet Volume 2 | ~~~~~~~~~~~~~ 3 | 4 | On Settings > General Settings > Sale (or Sales > Configuration > Settings), 5 | set a default pallet volume in "Volumes" section. 6 | -------------------------------------------------------------------------------- /sale_order_volume/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * Robin Keunen 2 | * Elouan Le Bars 3 | * Vincent Van Rossem 4 | -------------------------------------------------------------------------------- /sale_order_volume/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Computes the volume of products (and its corresponding number of pallets) ordered and display it on 2 | 3 | - sale order page, 4 | - sale order report, 5 | - website shop cart website page. 6 | 7 | Pallet volume is configurable. 8 | -------------------------------------------------------------------------------- /sale_order_volume/reports/report_saleorder.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 28 | 29 | -------------------------------------------------------------------------------- /sale_order_volume/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from . import test_sale_order_volume 2 | -------------------------------------------------------------------------------- /sale_order_volume/tests/test_sale_order_volume.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Coop IT Easy SC 2 | # Robin Keunen 3 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). 4 | 5 | from odoo.tests import TransactionCase 6 | 7 | 8 | class SaleOrderVolumeCase(TransactionCase): 9 | def test_sale_order_volumes(self): 10 | sale_order = self.browse_ref("sale.sale_order_4") 11 | product = self.browse_ref("product.product_delivery_01") 12 | 13 | # trigger 14 | order_line = sale_order.order_line.filtered(lambda ol: ol.product_id == product) 15 | order_line.product_uom_qty = 3 16 | 17 | self.assertEqual(sale_order.volume, 15.6) 18 | # (15.6 (volume) // 1.75 (pallet volume)) + 1 = 9 19 | self.assertEqual(sale_order.pallet_count, 9) 20 | -------------------------------------------------------------------------------- /sale_order_volume/views/res_config_settings_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | res.config.settings.view.form.inherit.sale.order.volume 7 | res.config.settings 8 | 9 | 10 | 11 |

Volumes

12 |
13 |
17 |
18 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | -------------------------------------------------------------------------------- /sale_order_volume/views/sale_order.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | view.sale.order.form.inherit 9 | sale.order 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /sale_order_volume/views/shopping_cart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 33 | 34 | 44 | 45 | -------------------------------------------------------------------------------- /setup/.setuptools-odoo-make-default-ignore: -------------------------------------------------------------------------------- 1 | # addons listed in this file are ignored by 2 | # setuptools-odoo-make-default (one addon per line) 3 | -------------------------------------------------------------------------------- /setup/README: -------------------------------------------------------------------------------- 1 | To learn more about this directory, please visit 2 | https://pypi.python.org/pypi/setuptools-odoo 3 | -------------------------------------------------------------------------------- /setup/account_customer_wallet/odoo/addons/account_customer_wallet: -------------------------------------------------------------------------------- 1 | ../../../../account_customer_wallet -------------------------------------------------------------------------------- /setup/account_customer_wallet/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/account_move_payment_mode_sepa/odoo/addons/account_move_payment_mode_sepa: -------------------------------------------------------------------------------- 1 | ../../../../account_move_payment_mode_sepa -------------------------------------------------------------------------------- /setup/account_move_payment_mode_sepa/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/board_signature/odoo/addons/board_signature: -------------------------------------------------------------------------------- 1 | ../../../../board_signature -------------------------------------------------------------------------------- /setup/board_signature/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/company_today/odoo/addons/company_today: -------------------------------------------------------------------------------- 1 | ../../../../company_today -------------------------------------------------------------------------------- /setup/company_today/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/contract_delivery_address/odoo/addons/contract_delivery_address: -------------------------------------------------------------------------------- 1 | ../../../../contract_delivery_address -------------------------------------------------------------------------------- /setup/contract_delivery_address/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/delivery_distribution_list/odoo/addons/delivery_distribution_list: -------------------------------------------------------------------------------- 1 | ../../../../delivery_distribution_list -------------------------------------------------------------------------------- /setup/delivery_distribution_list/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/document_hosting/odoo/addons/document_hosting: -------------------------------------------------------------------------------- 1 | ../../../../document_hosting -------------------------------------------------------------------------------- /setup/document_hosting/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/event_track_multi_date/odoo/addons/event_track_multi_date: -------------------------------------------------------------------------------- 1 | ../../../../event_track_multi_date -------------------------------------------------------------------------------- /setup/event_track_multi_date/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/partner_contact_type_default/odoo/addons/partner_contact_type_default: -------------------------------------------------------------------------------- 1 | ../../../../partner_contact_type_default -------------------------------------------------------------------------------- /setup/partner_contact_type_default/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/payment_sepa_dd/odoo/addons/payment_sepa_dd: -------------------------------------------------------------------------------- 1 | ../../../../payment_sepa_dd -------------------------------------------------------------------------------- /setup/payment_sepa_dd/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/payment_sepa_dd_payment_mode/odoo/addons/payment_sepa_dd_payment_mode: -------------------------------------------------------------------------------- 1 | ../../../../payment_sepa_dd_payment_mode -------------------------------------------------------------------------------- /setup/payment_sepa_dd_payment_mode/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/portal_customer_wallet/odoo/addons/portal_customer_wallet: -------------------------------------------------------------------------------- 1 | ../../../../portal_customer_wallet -------------------------------------------------------------------------------- /setup/portal_customer_wallet/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/product_contract_payment_mode/odoo/addons/product_contract_payment_mode: -------------------------------------------------------------------------------- 1 | ../../../../product_contract_payment_mode -------------------------------------------------------------------------------- /setup/product_contract_payment_mode/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/product_contract_sale_generation/odoo/addons/product_contract_sale_generation: -------------------------------------------------------------------------------- 1 | ../../../../product_contract_sale_generation -------------------------------------------------------------------------------- /setup/product_contract_sale_generation/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/product_contract_storable/odoo/addons/product_contract_storable: -------------------------------------------------------------------------------- 1 | ../../../../product_contract_storable -------------------------------------------------------------------------------- /setup/product_contract_storable/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/resource_work_time_from_contracts/odoo/addons/resource_work_time_from_contracts: -------------------------------------------------------------------------------- 1 | ../../../../resource_work_time_from_contracts -------------------------------------------------------------------------------- /setup/resource_work_time_from_contracts/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/sale_order_auto_carrier/odoo/addons/sale_order_auto_carrier: -------------------------------------------------------------------------------- 1 | ../../../../sale_order_auto_carrier -------------------------------------------------------------------------------- /setup/sale_order_auto_carrier/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/sale_order_volume/odoo/addons/sale_order_volume: -------------------------------------------------------------------------------- 1 | ../../../../sale_order_volume -------------------------------------------------------------------------------- /setup/sale_order_volume/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/subscription_web_access/odoo/addons/subscription_web_access: -------------------------------------------------------------------------------- 1 | ../../../../subscription_web_access -------------------------------------------------------------------------------- /setup/subscription_web_access/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/website_rebrand_coopiteasy/odoo/addons/website_rebrand_coopiteasy: -------------------------------------------------------------------------------- 1 | ../../../../website_rebrand_coopiteasy -------------------------------------------------------------------------------- /setup/website_rebrand_coopiteasy/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/website_sale_order_autoconfirm/odoo/addons/website_sale_order_autoconfirm: -------------------------------------------------------------------------------- 1 | ../../../../website_sale_order_autoconfirm -------------------------------------------------------------------------------- /setup/website_sale_order_autoconfirm/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/website_sale_product_compatibility/odoo/addons/website_sale_product_compatibility: -------------------------------------------------------------------------------- 1 | ../../../../website_sale_product_compatibility -------------------------------------------------------------------------------- /setup/website_sale_product_compatibility/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/website_sale_product_contract_gift/odoo/addons/website_sale_product_contract_gift: -------------------------------------------------------------------------------- 1 | ../../../../website_sale_product_contract_gift -------------------------------------------------------------------------------- /setup/website_sale_product_contract_gift/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/website_sale_product_trial/odoo/addons/website_sale_product_trial: -------------------------------------------------------------------------------- 1 | ../../../../website_sale_product_trial -------------------------------------------------------------------------------- /setup/website_sale_product_trial/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/website_sale_restrict_sepa_dd/odoo/addons/website_sale_restrict_sepa_dd: -------------------------------------------------------------------------------- 1 | ../../../../website_sale_restrict_sepa_dd -------------------------------------------------------------------------------- /setup/website_sale_restrict_sepa_dd/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /subscription_web_access/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /subscription_web_access/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | { 5 | "name": "Subscription Web Access", 6 | "summary": "Compute whether a partner has ongoing contracts", 7 | "version": "16.0.1.0.0", 8 | "license": "AGPL-3", 9 | "author": "Coop IT Easy SC", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "depends": [ 12 | "contract", 13 | "website_sale_product_trial", 14 | ], 15 | "data": [ 16 | "views/res_partner.xml", 17 | ], 18 | } 19 | -------------------------------------------------------------------------------- /subscription_web_access/i18n/subscription_web_access.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * subscription_web_access 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: subscription_web_access 17 | #: model:ir.model,name:subscription_web_access.model_res_partner 18 | msgid "Contact" 19 | msgstr "" 20 | 21 | #. module: subscription_web_access 22 | #: model:ir.model.fields,field_description:subscription_web_access.field_res_partner__is_web_subscribed 23 | #: model:ir.model.fields,field_description:subscription_web_access.field_res_users__is_web_subscribed 24 | msgid "Is Web Subscribed" 25 | msgstr "" 26 | 27 | #. module: subscription_web_access 28 | #: model_terms:ir.ui.view,arch_db:subscription_web_access.view_res_partner_filter 29 | msgid "Subscribed" 30 | msgstr "" 31 | 32 | #. module: subscription_web_access 33 | #: model:ir.model.fields,field_description:subscription_web_access.field_res_partner__subscriber 34 | #: model:ir.model.fields,field_description:subscription_web_access.field_res_users__subscriber 35 | msgid "Subscriber" 36 | msgstr "" 37 | 38 | #. module: subscription_web_access 39 | #: model:ir.model,name:subscription_web_access.model_res_users 40 | msgid "User" 41 | msgstr "" 42 | 43 | #. module: subscription_web_access 44 | #: model_terms:ir.ui.view,arch_db:subscription_web_access.view_res_partner_filter 45 | msgid "With web access" 46 | msgstr "" 47 | -------------------------------------------------------------------------------- /subscription_web_access/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import res_partner 2 | from . import res_users 3 | -------------------------------------------------------------------------------- /subscription_web_access/models/res_partner.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Coop IT Easy SC 2 | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). 3 | 4 | from odoo import api, fields, models 5 | 6 | 7 | class ResPartner(models.Model): 8 | _inherit = "res.partner" 9 | 10 | is_web_subscribed = fields.Boolean( 11 | compute="_compute_subscription_status", 12 | store=True, 13 | ) 14 | 15 | subscriber = fields.Boolean( 16 | compute="_compute_subscription_status", 17 | store=True, 18 | ) 19 | 20 | @api.depends( 21 | "contract_ids.contract_line_ids.state", 22 | "contract_ids.contract_line_ids.product_id.is_trial", 23 | ) 24 | def _compute_subscription_status(self): 25 | for rec in self: 26 | rec.is_web_subscribed = False 27 | rec.subscriber = False 28 | for contract in rec.contract_ids: 29 | for line in contract.contract_line_ids: 30 | if line.state == "in-progress" or line.state == "upcoming-close": 31 | rec.is_web_subscribed = True 32 | if not line.product_id.is_trial: 33 | rec.subscriber = True 34 | -------------------------------------------------------------------------------- /subscription_web_access/models/res_users.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Coop IT Easy SCRL fs 2 | # Robin Keunen 3 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). 4 | import json 5 | 6 | from odoo import api, models 7 | 8 | 9 | class ResUsers(models.Model): 10 | _inherit = "res.users" 11 | 12 | @api.model 13 | def get_subscription(self, user_id): 14 | user = self.env["res.users"].browse(user_id) 15 | if not user: 16 | return json.dumps({"error": "user not found"}) 17 | 18 | partner = user.partner_id 19 | if not partner: 20 | return json.dumps( 21 | { 22 | "id": user_id, 23 | "start": "", 24 | "end": "", 25 | "subscription": "", 26 | "subscribed": False, 27 | } 28 | ) 29 | 30 | # todo : this is the same code as in res.partner._compute_subscription_status(). 31 | # this could be refactored either as a computed field (something like 32 | # ongoing_contract_line_id) or as a method (something like 33 | # .get_ongoing_contract_line()). 34 | # both should return an empty contract.line recordset 35 | # in case there is no ongoing contract line. 36 | for contract in partner.contract_ids: 37 | for line in contract.contract_line_ids: 38 | if line.state == "in-progress" or line.state == "upcoming-close": 39 | return json.dumps( 40 | { 41 | "id": user_id, 42 | "start": line.date_start, 43 | "end": line.date_end, 44 | "subscription": line.contract_id.name, 45 | "subscribed": partner.is_web_subscribed, 46 | }, 47 | default=str, # needed to convert dates to strings 48 | ) 49 | return json.dumps( 50 | { 51 | "id": user_id, 52 | "start": "", 53 | "end": "", 54 | "subscription": "", 55 | "subscribed": partner.is_web_subscribed, 56 | } 57 | ) 58 | -------------------------------------------------------------------------------- /subscription_web_access/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_ 2 | -------------------------------------------------------------------------------- /subscription_web_access/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | - Adds a computed field "is_web_subscribed" and "subscriber" on partner. 2 | - Add a method on the user returning a json with subscription details. This is used by the external website on which the user is logged in, so that this website can check the subscription status and display the content. 3 | -------------------------------------------------------------------------------- /subscription_web_access/views/res_partner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | res.partner 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | res.partner 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Coop IT Easy Website Branding", 7 | "summary": "Replace default Odoo website branding by Coop IT Easy branding", 8 | "version": "16.0.1.0.0", 9 | "category": "Website", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "license": "AGPL-3", 13 | "depends": [ 14 | "website", 15 | ], 16 | "data": [ 17 | "templates/rebrand_coopiteasy.xml", 18 | ], 19 | } 20 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/i18n/fr.po: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * website_rebrand_coopiteasy 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 12.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: <>\n" 10 | "Language-Team: \n" 11 | "Language: fr\n" 12 | "MIME-Version: 1.0\n" 13 | "Content-Type: text/plain; charset=UTF-8\n" 14 | "Content-Transfer-Encoding: 8bit\n" 15 | "Plural-Forms: \n" 16 | 17 | #. module: website_rebrand_coopiteasy 18 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 19 | msgid "" 20 | ",\n" 21 | " provided by" 22 | msgstr "" 23 | ",\n" 24 | " fourni par" 25 | 26 | #. module: website_rebrand_coopiteasy 27 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 28 | msgid "Coop IT Easy" 29 | msgstr "" 30 | 31 | #. module: website_rebrand_coopiteasy 32 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 33 | msgid "OCA" 34 | msgstr "" 35 | 36 | #. module: website_rebrand_coopiteasy 37 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 38 | msgid "Odoo" 39 | msgstr "" 40 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/i18n/nl.po: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * website_rebrand_coopiteasy 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 12.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: <>\n" 10 | "Language-Team: \n" 11 | "Language: nl\n" 12 | "MIME-Version: 1.0\n" 13 | "Content-Type: text/plain; charset=UTF-8\n" 14 | "Content-Transfer-Encoding: 8bit\n" 15 | "Plural-Forms: \n" 16 | 17 | #. module: website_rebrand_coopiteasy 18 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 19 | msgid "" 20 | ",\n" 21 | " provided by" 22 | msgstr "" 23 | ",\n" 24 | " verzorgd door" 25 | 26 | #. module: website_rebrand_coopiteasy 27 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 28 | msgid "Coop IT Easy" 29 | msgstr "" 30 | 31 | #. module: website_rebrand_coopiteasy 32 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 33 | msgid "OCA" 34 | msgstr "" 35 | 36 | #. module: website_rebrand_coopiteasy 37 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 38 | msgid "Odoo" 39 | msgstr "" 40 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/i18n/website_rebrand_coopiteasy.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * website_rebrand_coopiteasy 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: website_rebrand_coopiteasy 17 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 18 | msgid "" 19 | ",\n" 20 | " provided by" 21 | msgstr "" 22 | 23 | #. module: website_rebrand_coopiteasy 24 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 25 | msgid "Coop IT Easy" 26 | msgstr "" 27 | 28 | #. module: website_rebrand_coopiteasy 29 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 30 | msgid "OCA" 31 | msgstr "" 32 | 33 | #. module: website_rebrand_coopiteasy 34 | #: model_terms:ir.ui.view,arch_db:website_rebrand_coopiteasy.brand_promotion 35 | msgid "Odoo" 36 | msgstr "" 37 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * hugues de keyzer 4 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Replace the default Odoo website branding by a Coop IT Easy branding. 2 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/readme/USAGE.rst: -------------------------------------------------------------------------------- 1 | When editing the website main page, the toolbar contains a "Customize" tab 2 | that contains a "Page Options" section. This module adds a "Coop IT Easy 3 | Branding" toggle that allows to enable or disable the Coop IT Easy rebranding. 4 | -------------------------------------------------------------------------------- /website_rebrand_coopiteasy/templates/rebrand_coopiteasy.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 17 | 18 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /website_sale_order_autoconfirm/README.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Website Sale Order SEPA AutoConfirm 3 | =================================== 4 | 5 | .. 6 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 7 | !! This file is generated by oca-gen-addon-readme !! 8 | !! changes will be overwritten. !! 9 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 10 | !! source digest: sha256:dd19756be576cce8471fda1f68e9ec59d9b32fbc238061a44172ac005dfab5df 11 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 12 | 13 | .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png 14 | :target: https://odoo-community.org/page/development-status 15 | :alt: Beta 16 | .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png 17 | :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html 18 | :alt: License: AGPL-3 19 | .. |badge3| image:: https://img.shields.io/badge/github-coopiteasy%2Faddons-lightgray.png?logo=github 20 | :target: https://github.com/coopiteasy/addons/tree/16.0/website_sale_order_autoconfirm 21 | :alt: coopiteasy/addons 22 | 23 | |badge1| |badge2| |badge3| 24 | 25 | Autoconfirm Sale orders created via ecommerce with SEPA products. 26 | 27 | **Table of contents** 28 | 29 | .. contents:: 30 | :local: 31 | 32 | Bug Tracker 33 | =========== 34 | 35 | Bugs are tracked on `GitHub Issues `_. 36 | In case of trouble, please check there if your issue has already been reported. 37 | If you spotted it first, help us to smash it by providing a detailed and welcomed 38 | `feedback `_. 39 | 40 | Do not contact contributors directly about support or help with technical issues. 41 | 42 | Credits 43 | ======= 44 | 45 | Authors 46 | ~~~~~~~ 47 | 48 | * Coop IT Easy SC 49 | 50 | Maintainers 51 | ~~~~~~~~~~~ 52 | 53 | This module is part of the `coopiteasy/addons `_ project on GitHub. 54 | 55 | You are welcome to contribute. 56 | -------------------------------------------------------------------------------- /website_sale_order_autoconfirm/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | -------------------------------------------------------------------------------- /website_sale_order_autoconfirm/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Website Sale Order SEPA AutoConfirm", 7 | "summary": "Autoconfirm Sale orders created via ecommerce with SEPA products", 8 | "version": "16.0.1.0.0", 9 | "category": "Website", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "license": "AGPL-3", 13 | "depends": [ 14 | "website_sale", 15 | ], 16 | } 17 | -------------------------------------------------------------------------------- /website_sale_order_autoconfirm/i18n/website_sale_order_autoconfirm.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * website_sale_order_autoconfirm 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: website_sale_order_autoconfirm 17 | #: model:ir.model,name:website_sale_order_autoconfirm.model_sale_order 18 | msgid "Sales Order" 19 | msgstr "" 20 | -------------------------------------------------------------------------------- /website_sale_order_autoconfirm/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import sale_order 2 | -------------------------------------------------------------------------------- /website_sale_order_autoconfirm/models/sale_order.py: -------------------------------------------------------------------------------- 1 | from odoo import models 2 | 3 | 4 | class SaleOrder(models.Model): 5 | _inherit = "sale.order" 6 | 7 | def action_quotation_sent(self): 8 | # In the ecommerce flow, this method is called after the payment step, 9 | # the SO is then marked as sent. We override this method 10 | # in order to autoconfirm the ecommerce SO. 11 | result = super().action_quotation_sent() 12 | if self.website_id: 13 | self.action_confirm() 14 | # silence W8110 15 | return result 16 | -------------------------------------------------------------------------------- /website_sale_order_autoconfirm/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Autoconfirm Sale orders created via ecommerce with SEPA products. 2 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | from . import controllers 6 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Website Sale Product Compatibility", 7 | "summary": """ 8 | Generic module to add compatibility check between products.""", 9 | "version": "16.0.1.0.0", 10 | "category": "E-Commerce", 11 | "website": "https://github.com/coopiteasy/addons", 12 | "author": "Coop IT Easy SC", 13 | "maintainers": ["remytms"], 14 | "license": "AGPL-3", 15 | "application": False, 16 | "depends": [ 17 | "website_sale", 18 | ], 19 | "data": [ 20 | "views/templates.xml", 21 | ], 22 | } 23 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import main 5 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/controllers/main.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import http 6 | from odoo.http import request 7 | 8 | from odoo.addons.website_sale.controllers.main import WebsiteSale 9 | 10 | 11 | class WebsiteSaleProductCompatibility(WebsiteSale): 12 | @http.route( 13 | ["/shop/cart/update"], 14 | type="http", 15 | auth="public", 16 | methods=["POST"], 17 | website=True, 18 | ) 19 | def cart_update( 20 | self, 21 | product_id, 22 | add_qty=1, 23 | set_qty=0, 24 | product_custom_attribute_values=None, 25 | no_variant_attribute_values=None, 26 | express=False, 27 | **kwargs 28 | ): 29 | sale_order = request.website.sale_get_order(force_create=True) 30 | if sale_order.state != "draft": 31 | request.session["sale_order_id"] = None 32 | sale_order = request.website.sale_get_order(force_create=True) 33 | 34 | warning = sale_order.check_product_compatibility(int(product_id)) 35 | 36 | request.session["website_sale_cart_warning"] = warning 37 | 38 | if warning: 39 | return request.redirect("/shop/cart") 40 | 41 | return super().cart_update( 42 | product_id=product_id, 43 | add_qty=add_qty, 44 | set_qty=set_qty, 45 | product_custom_attribute_values=product_custom_attribute_values, 46 | no_variant_attribute_values=no_variant_attribute_values, 47 | express=express, 48 | **kwargs 49 | ) 50 | 51 | @http.route(["/shop/cart"], type="http", auth="public", website=True, sitemap=False) 52 | def cart(self, access_token=None, revive="", **post): 53 | warning = "" 54 | if "website_sale_cart_warning" in request.session: 55 | warning = request.session["website_sale_cart_warning"] 56 | del request.session["website_sale_cart_warning"] 57 | response = super().cart(access_token=access_token, revive=revive, **post) 58 | response.qcontext.update( 59 | { 60 | "website_sale_cart_warning": warning, 61 | } 62 | ) 63 | return response 64 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/i18n/website_sale_product_compatibility.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * website_sale_product_compatibility 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: website_sale_product_compatibility 17 | #: model:ir.model,name:website_sale_product_compatibility.model_sale_order 18 | msgid "Sales Order" 19 | msgstr "" 20 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import sale_order 5 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/models/sale_order.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | from odoo import models 7 | 8 | 9 | class SaleOrder(models.Model): 10 | _inherit = "sale.order" 11 | 12 | def check_product_compatibility(self, product_id): 13 | """Override this function to detect incompatibility between 14 | products. 15 | 16 | Warning: self.ensure_one() 17 | 18 | If an empty string is returned then the product_id is compatible 19 | and will be added to the sale order. If a warning string is 20 | returned then the product is considered not compatible with the 21 | order and the product will not be added to the order. 22 | 23 | By default this method always return no warning message. 24 | 25 | :product_id: The id of the product to check compatibility. 26 | :rtype: str 27 | :return: warning message to be shown on the web interface. 28 | """ 29 | self.ensure_one() 30 | return "" 31 | 32 | def _cart_update(self, product_id, line_id=None, add_qty=0, set_qty=0, **kwargs): 33 | """Prevent incompatible product to be added to the cart.""" 34 | self.ensure_one() 35 | warning = self.check_product_compatibility(product_id) 36 | if warning: 37 | add_qty = None 38 | set_qty = 0 39 | values = super()._cart_update( 40 | product_id=product_id, 41 | line_id=line_id, 42 | add_qty=add_qty, 43 | set_qty=set_qty, 44 | **kwargs, 45 | ) 46 | values["warning"] = warning 47 | return values 48 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Rémy Taymans 4 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | This is a utility module that can be used by other modules to check 2 | whether different products are allowed to be added to the same 3 | e-commerce sale order. 4 | 5 | This module works only if the user is redirected to the basket after 6 | adding a product to it. If not no message will be displayed to the user. 7 | -------------------------------------------------------------------------------- /website_sale_product_compatibility/views/templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | from . import controllers 6 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Website Sale Product Contract Gift", 7 | "summary": """ 8 | Configure product contract to be a gift to someone else.""", 9 | "version": "16.0.1.0.2", 10 | "category": "Website", 11 | "website": "https://github.com/coopiteasy/addons", 12 | "author": "Coop IT Easy SC", 13 | "maintainers": ["remytms"], 14 | "license": "AGPL-3", 15 | "application": False, 16 | "depends": [ 17 | "website_sale_product_compatibility", 18 | "product_contract", 19 | "delivery", 20 | "account_payment_sale", 21 | ], 22 | "data": [ 23 | "views/product_views.xml", 24 | "views/templates.xml", 25 | "views/sale_order_views.xml", 26 | ], 27 | "assets": { 28 | "web.assets_frontend": [ 29 | "website_sale_product_contract_gift/static/src/js/website_sale.esm.js", 30 | ], 31 | }, 32 | } 33 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import main 5 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import product_template 5 | from . import sale_order 6 | from . import sale_order_line 7 | from . import contract 8 | from . import account_move 9 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/models/account_move.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | from odoo import models 7 | from odoo.tools import email_normalize 8 | 9 | 10 | class AccountMove(models.Model): 11 | _inherit = "account.move" 12 | 13 | def create_user_for_gift(self): 14 | for invoice in self: 15 | partner_id = invoice.partner_id 16 | is_gift = any( 17 | invoice.line_ids.contract_line_id.contract_id.mapped("is_gift") 18 | ) 19 | if not partner_id.user_id and is_gift: 20 | # TODO: send email to the reciever of the gift 21 | self.env["res.users"].with_context( 22 | no_reset_password=True 23 | )._create_user_from_template( 24 | { 25 | "email": email_normalize(partner_id.email), 26 | "login": email_normalize(partner_id.email), 27 | "partner_id": partner_id.id, 28 | } 29 | ) 30 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/models/contract.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | from odoo import fields, models 7 | 8 | 9 | class ContractContract(models.Model): 10 | _inherit = "contract.contract" 11 | 12 | is_gift = fields.Boolean() 13 | 14 | def _recurring_create_invoice(self, date_ref=False): 15 | invoices = super()._recurring_create_invoice(date_ref=date_ref) 16 | invoices.create_user_for_gift() 17 | return invoices 18 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/models/product_template.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import fields, models 6 | 7 | 8 | class ProductTemplate(models.Model): 9 | _inherit = "product.template" 10 | 11 | is_gift = fields.Boolean() 12 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/models/sale_order_line.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import fields, models 6 | 7 | 8 | class SaleOrderLine(models.Model): 9 | _inherit = "sale.order.line" 10 | 11 | gift_contract_id = fields.Many2one( 12 | comodel_name="contract.contract", string="Gift Contract", copy=False 13 | ) 14 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Rémy Taymans 4 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Configure product contract to be a gift to someone else. 2 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/static/src/js/website_sale.esm.js: -------------------------------------------------------------------------------- 1 | /** @odoo-module **/ 2 | 3 | import publicWidget from "@web/legacy/js/public/public_widget"; 4 | 5 | publicWidget.registry.websiteSaleCartGift = publicWidget.Widget.extend({ 6 | selector: ".oe_website_sale .oe_cart", 7 | events: { 8 | "click #gift_form_confirm_button": "_onClickConfirm", 9 | }, 10 | 11 | // -------------------------------------------------------------------------- 12 | // Handlers 13 | // -------------------------------------------------------------------------- 14 | 15 | /** 16 | * @private 17 | */ 18 | _onClickConfirm: function () { 19 | var $form = $("form[name='gift_date']"); 20 | $form.submit(); 21 | }, 22 | }); 23 | 24 | export default publicWidget.registry.websiteSaleCartGift; 25 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import test_gift 5 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/views/product_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | product.template.common.is_gift.form 6 | product.template 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /website_sale_product_contract_gift/views/sale_order_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sale.order.product.contract.gift.form 6 | sale.order 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /website_sale_product_trial/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | from . import controllers 6 | -------------------------------------------------------------------------------- /website_sale_product_trial/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Website Sale Product Trial", 7 | "summary": """ 8 | Configure product contract to be a trial subscription.""", 9 | "version": "16.0.1.0.0", 10 | "category": "Website", 11 | "website": "https://github.com/coopiteasy/addons", 12 | "author": "Coop IT Easy SC", 13 | "maintainers": ["remytms"], 14 | "license": "AGPL-3", 15 | "application": False, 16 | "depends": [ 17 | "website_sale_product_compatibility", 18 | "product", 19 | "delivery", 20 | ], 21 | "excludes": [], 22 | "data": [ 23 | "views/product_views.xml", 24 | "views/templates.xml", 25 | ], 26 | "demo": [], 27 | "qweb": [], 28 | } 29 | -------------------------------------------------------------------------------- /website_sale_product_trial/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import main 5 | -------------------------------------------------------------------------------- /website_sale_product_trial/controllers/main.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import http 6 | from odoo.http import request 7 | 8 | from odoo.addons.website_sale.controllers.main import WebsiteSale 9 | 10 | 11 | class WebsiteSaleProductTrial(WebsiteSale): 12 | @http.route( 13 | "/shop/payment/validate", 14 | type="http", 15 | auth="public", 16 | website=True, 17 | sitemap=False, 18 | ) 19 | def shop_payment_validate(self, sale_order_id=None, **post): 20 | result = super().shop_payment_validate(sale_order_id=sale_order_id, **post) 21 | if "my/order" in result.location: 22 | result.location = "/shop/main/confirmation" 23 | return result 24 | 25 | @http.route( 26 | "/shop/main/confirmation", 27 | type="http", 28 | auth="public", 29 | website=True, 30 | sitemap=False, 31 | ) 32 | def shop_main_confirmation(self): 33 | """General confirmation for product. Used to skip view of the 34 | invoice.""" 35 | return request.render("website_sale_product_trial.main_confirmation", {}) 36 | -------------------------------------------------------------------------------- /website_sale_product_trial/i18n/website_sale_product_trial.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * website_sale_product_trial 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 16.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: website_sale_product_trial 17 | #. odoo-python 18 | #: code:addons/website_sale_product_trial/models/sale_order.py:0 19 | #, python-format 20 | msgid "Cannot add product trial in an order that contains other products." 21 | msgstr "" 22 | 23 | #. module: website_sale_product_trial 24 | #: model:ir.model.fields,field_description:website_sale_product_trial.field_product_product__is_trial 25 | #: model:ir.model.fields,field_description:website_sale_product_trial.field_product_template__is_trial 26 | msgid "Is Trial" 27 | msgstr "" 28 | 29 | #. module: website_sale_product_trial 30 | #: model_terms:ir.ui.view,arch_db:website_sale_product_trial.main_confirmation 31 | msgid "Order Confirmed" 32 | msgstr "" 33 | 34 | #. module: website_sale_product_trial 35 | #: model:ir.model,name:website_sale_product_trial.model_product_template 36 | msgid "Product" 37 | msgstr "" 38 | 39 | #. module: website_sale_product_trial 40 | #: model:ir.model,name:website_sale_product_trial.model_sale_order 41 | msgid "Sales Order" 42 | msgstr "" 43 | 44 | #. module: website_sale_product_trial 45 | #: model_terms:ir.ui.view,arch_db:website_sale_product_trial.main_confirmation 46 | msgid "Shop - Order Confirmed" 47 | msgstr "" 48 | 49 | #. module: website_sale_product_trial 50 | #: model_terms:ir.ui.view,arch_db:website_sale_product_trial.main_confirmation 51 | msgid "Thank you for your order." 52 | msgstr "" 53 | -------------------------------------------------------------------------------- /website_sale_product_trial/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import product_template 5 | from . import sale_order 6 | -------------------------------------------------------------------------------- /website_sale_product_trial/models/product_template.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import fields, models 6 | 7 | 8 | class ProductTemplate(models.Model): 9 | _inherit = "product.template" 10 | 11 | is_trial = fields.Boolean() 12 | -------------------------------------------------------------------------------- /website_sale_product_trial/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Rémy Taymans 4 | -------------------------------------------------------------------------------- /website_sale_product_trial/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Configure product to be a trial subscription. 2 | -------------------------------------------------------------------------------- /website_sale_product_trial/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import test_trial 5 | -------------------------------------------------------------------------------- /website_sale_product_trial/tests/test_trial.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2025 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | 6 | from odoo.tests import common 7 | 8 | 9 | class TestTrialContractBase(common.TransactionCase): 10 | @classmethod 11 | def setUpClass(cls): 12 | super().setUpClass() 13 | cls.product_1 = cls.env.ref("product.product_product_1") 14 | cls.product_1.is_trial = True 15 | cls.product_2 = cls.env.ref("product.product_product_2") 16 | cls.product_2.is_trial = False 17 | cls.product_3 = cls.env.ref("product.product_product_3") 18 | cls.product_3.is_trial = True 19 | 20 | 21 | class TestTrialContract(TestTrialContractBase): 22 | def test_is_product_compatible_empty(self): 23 | self.assertTrue( 24 | self.env["sale.order"]._is_product_compatible( 25 | self.env["product.product"], 26 | ) 27 | ) 28 | 29 | def test_is_product_compatible_mixed(self): 30 | self.assertFalse( 31 | self.env["sale.order"]._is_product_compatible( 32 | self.product_1 | self.product_2 33 | ) 34 | ) 35 | 36 | def test_is_product_compatible_only_trial(self): 37 | self.assertTrue(self.env["sale.order"]._is_product_compatible(self.product_1)) 38 | self.assertFalse( 39 | self.env["sale.order"]._is_product_compatible( 40 | self.product_1 | self.product_3 41 | ) 42 | ) 43 | 44 | def test_is_product_compatible_only_non_trial(self): 45 | self.assertTrue(self.env["sale.order"]._is_product_compatible(self.product_2)) 46 | -------------------------------------------------------------------------------- /website_sale_product_trial/views/product_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | product.template.common.is_gift.form 6 | product.template 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /website_sale_product_trial/views/templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /website_sale_restrict_sepa_dd/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import models 5 | -------------------------------------------------------------------------------- /website_sale_restrict_sepa_dd/__manifest__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | { 6 | "name": "Restrict SEPA Direct Debit Payment", 7 | "summary": "Restrict payment by SEPA Direct Debit for some products", 8 | "version": "16.0.1.0.1", 9 | "category": "Website", 10 | "website": "https://github.com/coopiteasy/addons", 11 | "author": "Coop IT Easy SC", 12 | "maintainers": ["remytms"], 13 | "license": "AGPL-3", 14 | "depends": [ 15 | "payment_sepa_dd", 16 | "website_sale_product_compatibility", 17 | ], 18 | "data": [ 19 | "views/product_views.xml", 20 | ], 21 | } 22 | -------------------------------------------------------------------------------- /website_sale_restrict_sepa_dd/models/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | from . import product_template 5 | from . import payment_provider 6 | from . import sale_order 7 | -------------------------------------------------------------------------------- /website_sale_restrict_sepa_dd/models/payment_provider.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import api, models 6 | 7 | 8 | class PaymentProvider(models.Model): 9 | _inherit = "payment.provider" 10 | 11 | @api.model 12 | def _get_compatible_providers( 13 | self, *args, sale_order_id=None, website_id=None, **kwargs 14 | ): 15 | """Override of payment to exclude SEPA Direct Debit if product 16 | does not allow it. 17 | 18 | :param int sale_order_id: The sale order to be paid, if any, as 19 | a `sale.order` id 20 | :param int website_id: The provided website, as a `website` id 21 | :return: The compatible providers 22 | :rtype: recordset of `payment.provider` 23 | """ 24 | compatible_providers = super()._get_compatible_providers( 25 | *args, sale_order_id=sale_order_id, website_id=website_id, **kwargs 26 | ) 27 | order = self.env["sale.order"].browse(sale_order_id).exists() 28 | # Allow SEPA Direct Debit only if all products allow SEPA DD payment 29 | allow_sepa_dd_payment = all( 30 | order.order_line.mapped("product_id").mapped("allow_sepa_dd_payment") 31 | ) 32 | # Allow only SEPA Direct Debit if at least one product must be payed 33 | # by SEPA Direct Debit 34 | only_sepa_dd_payment = any( 35 | order.order_line.mapped("product_id").mapped("only_sepa_dd_payment") 36 | ) 37 | if not allow_sepa_dd_payment and not only_sepa_dd_payment: 38 | # Exclude sepa_dd 39 | compatible_providers = compatible_providers.filtered( 40 | lambda p: p.code != "sepa_dd" 41 | ) 42 | elif allow_sepa_dd_payment and only_sepa_dd_payment: 43 | # Get only sepa_dd 44 | compatible_providers = compatible_providers.filtered( 45 | lambda p: p.code == "sepa_dd" 46 | ) 47 | elif not allow_sepa_dd_payment and only_sepa_dd_payment: 48 | # Product are not compatible between each other. No payement 49 | # provider can be used. 50 | compatible_providers = self.env["payment.provider"] 51 | 52 | return compatible_providers 53 | -------------------------------------------------------------------------------- /website_sale_restrict_sepa_dd/models/product_template.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Coop IT Easy SC 2 | # 3 | # SPDX-License-Identifier: AGPL-3.0-or-later 4 | 5 | from odoo import _, api, fields, models 6 | from odoo.exceptions import ValidationError 7 | 8 | 9 | class SaleOrder(models.Model): 10 | _inherit = "product.template" 11 | 12 | allow_sepa_dd_payment = fields.Boolean(string="Allow SEPA Direct Debit Payment") 13 | only_sepa_dd_payment = fields.Boolean(string="Only SEPA Direct Debit Payment") 14 | 15 | @api.constrains("allow_sepa_dd_payment", "only_sepa_dd_payment") 16 | def _check_allow_sepa_dd_payment(self): 17 | """Ensure that allow_sepa_dd_payment is set if 18 | only_sepa_dd_payment is set. 19 | """ 20 | for product in self: 21 | if product.only_sepa_dd_payment and not product.allow_sepa_dd_payment: 22 | raise ValidationError( 23 | _( 24 | "Allow SEPA Direct Debit Payment must be enabled to " 25 | "enable Only SEPA Direct Debit Payment." 26 | ) 27 | ) 28 | 29 | @api.onchange("only_sepa_dd_payment") 30 | def _onchange_only_sepa_dd_payment(self): 31 | if self.only_sepa_dd_payment: 32 | self.allow_sepa_dd_payment = True 33 | 34 | @api.onchange("allow_sepa_dd_payment") 35 | def _onchange_allow_sepa_dd_payment(self): 36 | if not self.allow_sepa_dd_payment: 37 | self.only_sepa_dd_payment = False 38 | -------------------------------------------------------------------------------- /website_sale_restrict_sepa_dd/readme/CONTRIBUTORS.rst: -------------------------------------------------------------------------------- 1 | * `Coop IT Easy SC `_: 2 | 3 | * Rémy Taymans 4 | -------------------------------------------------------------------------------- /website_sale_restrict_sepa_dd/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | Restrict payment by SEPA Direct Debit for some products. 2 | -------------------------------------------------------------------------------- /website_sale_restrict_sepa_dd/views/product_views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | product.template.common.allow_sepa_dd_payment.form 6 | product.template 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | --------------------------------------------------------------------------------