Skip to content

[18.0][ADD] website_sale_delivery_date: module add#4

Open
Bearnard21 wants to merge 3 commits into
18.0from
18.0-t4576-website_sale_delivery_date-module_add
Open

[18.0][ADD] website_sale_delivery_date: module add#4
Bearnard21 wants to merge 3 commits into
18.0from
18.0-t4576-website_sale_delivery_date-module_add

Conversation

@Bearnard21

@Bearnard21 Bearnard21 commented May 31, 2025

Copy link
Copy Markdown

Add the module to manage the time limitations for selected delivery method during the website e-commerce checkout and pass the delivery date to the sale order

Task:4576

Summary by CodeRabbit

  • New Features

    • Added a delivery date selector to the e-commerce checkout, allowing customers to choose their preferred delivery date after selecting a delivery method.
    • Delivery date selection is validated against configurable constraints, including minimum delay, available weekdays, delivery time windows, and cut-off times.
    • The chosen delivery date is saved and visible in the sales backend for order fulfillment.
  • Configuration

    • Delivery methods can now be configured with minimum delivery delays (in days or hours) and weekday-specific delivery rules via the backend.
  • User Interface

    • Enhanced delivery carrier forms and checkout screens to support and display delivery date options and constraints.
    • Integrated a calendar date picker in the checkout process.
  • Documentation

    • Added comprehensive documentation covering configuration, usage, and module context.
    • Included contributor credits and module description.
  • Security

    • Introduced user roles and access rules for managing delivery scheduling features.

Add the module to manage the time limitations for selected delivery method during the website e-commerce checkout and pass the delivery date to the sale order

Task:4576
@coderabbitai

coderabbitai Bot commented May 31, 2025

Copy link
Copy Markdown

Walkthrough

This change introduces a new Odoo module, website_sale_delivery_date, which enhances the e-commerce checkout process by allowing customers to select a delivery date based on configurable constraints. The update adds backend models for delivery scheduling rules, frontend JavaScript for date selection, security access controls, documentation, and user interface extensions for both website and backend configuration.

Changes

Files/Groups Change Summary
website_sale_delivery_date/README.rst, readme/CONTEXT.md, readme/CONFIGURE.md, readme/USAGE.md, readme/CONTRIBUTORS.md, readme/DESCRIPTION.md Added comprehensive documentation covering module description, usage, configuration, context, and contributors.
website_sale_delivery_date/__init__.py, models/__init__.py, controllers/__init__.py Added package initialization files importing relevant submodules for models and controllers.
website_sale_delivery_date/__manifest__.py, pyproject.toml Added module manifest and build configuration specifying dependencies, metadata, assets, and installability.
website_sale_delivery_date/models/delivery_carrier.py Extended delivery.carrier model with fields and logic for minimum delivery delay, delay type, and weekday delivery rules, including delivery constraints calculation and validation.
website_sale_delivery_date/models/delivery_weekday_rule.py Introduced new model delivery.weekday.rule for defining weekday-specific delivery availability, delivery hours, cut-off times, and validation constraints.
website_sale_delivery_date/models/sale_order.py Extended sale.order with methods for validating and setting delivery dates according to carrier constraints, and resetting delivery date on delivery method change.
website_sale_delivery_date/controllers/main.py Added controller extending website sale to provide JSON routes for fetching delivery constraints and setting delivery dates with validation.
website_sale_delivery_date/security/security.xml Defined security groups for delivery users and managers, and added record rule restricting weekday rule access to record creators.
website_sale_delivery_date/views/delivery_carrier_views.xml Extended delivery carrier form view to include configuration for minimum delivery delay and editable weekday rule list.
website_sale_delivery_date/views/delivery_form_template.xml Added website delivery form template extension with delivery date picker input and error display.
website_sale_delivery_date/static/src/js/checkout_delivery_date.esm.js Enhanced checkout widget with delivery date picker, validation logic, and dynamic constraint updates based on selected delivery carrier.
website_sale_delivery_date/static/description/index.html Added static HTML description file with basic structure and meta tags.

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 23

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 63f5aae and 65ec9fd.

⛔ Files ignored due to path filters (1)
  • website_sale_delivery_date/security/ir.model.access.csv is excluded by !**/*.csv
📒 Files selected for processing (18)
  • website_sale_delivery_date/README.rst (1 hunks)
  • website_sale_delivery_date/__init__.py (1 hunks)
  • website_sale_delivery_date/__manifest__.py (1 hunks)
  • website_sale_delivery_date/controllers/__init__.py (1 hunks)
  • website_sale_delivery_date/controllers/main.py (1 hunks)
  • website_sale_delivery_date/models/__init__.py (1 hunks)
  • website_sale_delivery_date/models/delivery_carrier.py (1 hunks)
  • website_sale_delivery_date/models/delivery_weekday_rule.py (1 hunks)
  • website_sale_delivery_date/pyproject.toml (1 hunks)
  • website_sale_delivery_date/readme/CONFIGURE.md (1 hunks)
  • website_sale_delivery_date/readme/CONTEXT.md (1 hunks)
  • website_sale_delivery_date/readme/CONTRIBUTORS.md (1 hunks)
  • website_sale_delivery_date/readme/DESCRIPTION.md (1 hunks)
  • website_sale_delivery_date/readme/USAGE.md (1 hunks)
  • website_sale_delivery_date/security/security.xml (1 hunks)
  • website_sale_delivery_date/static/src/js/website_sale_delivery_date.js (1 hunks)
  • website_sale_delivery_date/views/delivery_carrier_views.xml (1 hunks)
  • website_sale_delivery_date/views/delivery_form_template.xml (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
`**/readme/*.*`: Never ask to add a top header in any file in these locations

**/readme/*.*: Never ask to add a top header in any file in these locations

  • website_sale_delivery_date/readme/CONTRIBUTORS.md
  • website_sale_delivery_date/readme/DESCRIPTION.md
  • website_sale_delivery_date/readme/USAGE.md
  • website_sale_delivery_date/readme/CONTEXT.md
  • website_sale_delivery_date/readme/CONFIGURE.md
`**/README.rst`: Never check this file

**/README.rst: Never check this file

  • website_sale_delivery_date/README.rst
🪛 markdownlint-cli2 (0.17.2)
website_sale_delivery_date/readme/CONTRIBUTORS.md

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)

website_sale_delivery_date/readme/DESCRIPTION.md

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)


5-5: Files should end with a single newline character
null

(MD047, single-trailing-newline)

website_sale_delivery_date/readme/USAGE.md

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)


5-5: Files should end with a single newline character
null

(MD047, single-trailing-newline)

website_sale_delivery_date/readme/CONTEXT.md

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)


9-9: Multiple consecutive blank lines
Expected: 1; Actual: 2

(MD012, no-multiple-blanks)


12-12: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


16-16: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


27-27: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


33-33: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


39-39: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


45-45: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


47-47: Files should end with a single newline character
null

(MD047, single-trailing-newline)

website_sale_delivery_date/readme/CONFIGURE.md

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)


9-9: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


12-12: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


14-14: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)

🪛 LanguageTool
website_sale_delivery_date/readme/DESCRIPTION.md

[uncategorized] ~4-~4: The preposition ‘in’ seems more likely in this position.
Context: ...ly in the website checkout flow. Stored on the generated sale order’s commitment_d...

(AI_HYDRA_LEO_REPLACE_ON_IN)

website_sale_delivery_date/readme/CONTEXT.md

[grammar] ~33-~33: A determiner may be missing.
Context: ...placed Monday at 09:00 can be delivered earliest Tuesday at 11:00 - An order placed Mond...

(THE_SUPERLATIVE)


[grammar] ~34-~34: A determiner may be missing.
Context: ...placed Monday at 12:00 can be delivered earliest Wednesday at 11:00 ### Example 2: Dela...

(THE_SUPERLATIVE)


[grammar] ~45-~45: A determiner may be missing.
Context: ...order placed on Monday can be delivered earliest Tuesday starting from 11:00 The sale o...

(THE_SUPERLATIVE)

🪛 Pylint (3.3.7)
website_sale_delivery_date/controllers/__init__.py

[error] 1-1: Unrecognized option found: readme-template-url, manifest-required-authors, manifest-required-keys, manifest-deprecated-keys, license-allowed, valid-odoo-versions

(E0015)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'api-one-deprecated'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'api-one-multi-together'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'attribute-deprecated'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'class-camelcase'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-view-replace-wo-priority'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'development-status-allowed'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-id-csv'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-xml-fields'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-xml-record-id'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'eval-referenced'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'incoherent-interpreter-exec-perm'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'license-allowed'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-author-string'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-deprecated-key'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-required-author'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-required-key'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-version-format'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-compute'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-inverse'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-required-super'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-search'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'openerp-exception-warning'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'print-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'redundant-modulename-xml'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'rst-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'sql-injection'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-field'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-required'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'use-vim-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'wrong-tabs-instead-of-spaces'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'attribute-string-redundant'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'character-not-valid-in-resource-link'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'consider-merging-classes-inherited'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'context-overridden'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'create-user-wo-reset-password'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-filter-wo-user'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-qweb-replace-wo-priority'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'deprecated-data-xml-node'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'deprecated-openerp-xml-node'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-po-message-definition'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'except-pass'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'file-not-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'invalid-commit'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-maintainers-list'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-newline-extrafiles'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-readme'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-return'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'odoo-addons-relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'old-api7-method-defined'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'po-msgstr-variables'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'po-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'renamed-field-parameter'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'resource-not-exist'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'str-format-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'test-folder-imported'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-contains-variable'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-positional-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'unnecessary-utf8-coding-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'website-manifest-key-not-valid-uri'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-attribute-translatable'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-deprecated-qweb-directive'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-deprecated-tree-attribute'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'external-request-timeout'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'consider-merging-classes-inherited'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'create-user-wo-reset-password'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-filter-wo-user'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'file-not-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'invalid-commit'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-manifest-dependency'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-newline-extrafiles'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-readme'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'no-utf8-coding-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'odoo-addons-relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'old-api7-method-defined'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'too-complex'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'unnecessary-utf8-coding-comment'

(W0012)


[error] 1-1: Plugin 'pylint_odoo' is impossible to load, is it installed ? ('No module named 'pylint_odoo'')

(E0013)

website_sale_delivery_date/__manifest__.py

[error] 1-1: Unrecognized option found: readme-template-url, manifest-required-authors, manifest-required-keys, manifest-deprecated-keys, license-allowed, valid-odoo-versions

(E0015)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'api-one-deprecated'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'api-one-multi-together'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'attribute-deprecated'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'class-camelcase'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-view-replace-wo-priority'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'development-status-allowed'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-id-csv'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-xml-fields'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-xml-record-id'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'eval-referenced'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'incoherent-interpreter-exec-perm'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'license-allowed'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-author-string'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-deprecated-key'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-required-author'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-required-key'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-version-format'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-compute'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-inverse'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-required-super'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-search'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'openerp-exception-warning'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'print-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'redundant-modulename-xml'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'rst-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'sql-injection'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-field'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-required'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'use-vim-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'wrong-tabs-instead-of-spaces'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'attribute-string-redundant'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'character-not-valid-in-resource-link'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'consider-merging-classes-inherited'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'context-overridden'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'create-user-wo-reset-password'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-filter-wo-user'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-qweb-replace-wo-priority'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'deprecated-data-xml-node'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'deprecated-openerp-xml-node'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-po-message-definition'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'except-pass'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'file-not-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'invalid-commit'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-maintainers-list'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-newline-extrafiles'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-readme'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-return'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'odoo-addons-relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'old-api7-method-defined'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'po-msgstr-variables'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'po-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'renamed-field-parameter'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'resource-not-exist'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'str-format-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'test-folder-imported'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-contains-variable'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-positional-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'unnecessary-utf8-coding-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'website-manifest-key-not-valid-uri'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-attribute-translatable'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-deprecated-qweb-directive'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-deprecated-tree-attribute'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'external-request-timeout'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'consider-merging-classes-inherited'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'create-user-wo-reset-password'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-filter-wo-user'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'file-not-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'invalid-commit'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-manifest-dependency'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-newline-extrafiles'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-readme'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'no-utf8-coding-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'odoo-addons-relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'old-api7-method-defined'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'too-complex'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'unnecessary-utf8-coding-comment'

(W0012)


[error] 1-1: Plugin 'pylint_odoo' is impossible to load, is it installed ? ('No module named 'pylint_odoo'')

(E0013)


[warning] 4-29: Statement seems to have no effect

(W0104)

🪛 Biome (1.9.4)
website_sale_delivery_date/static/src/js/website_sale_delivery_date.js

[error] 2-2: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)


[error] 4-4: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 14-14: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 14-14: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)


[error] 15-15: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 16-16: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 41-42: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 41-42: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)


[error] 42-43: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 43-45: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 67-68: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 67-68: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)


[error] 68-69: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 69-71: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

🪛 GitHub Actions: pre-commit
website_sale_delivery_date/static/src/js/website_sale_delivery_date.js

[warning] 4-4: ESLint: Unexpected require() (global-require)


[error] 4-4: ESLint: 'require' is not defined (no-undef)


[error] 14-14: ESLint: 'self' is assigned a value but never used (no-unused-vars)


[error] 16-16: ESLint: '$dateInput' is assigned a value but never used (no-unused-vars)


[error] 41-41: ESLint: 'self' is assigned a value but never used (no-unused-vars)


[error] 67-67: ESLint: 'self' is assigned a value but never used (no-unused-vars)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test with OCB
  • GitHub Check: test with Odoo
🔇 Additional comments (9)
website_sale_delivery_date/models/__init__.py (1)

4-5: Module imports look correct

The model modules delivery_carrier and delivery_weekday_rule are properly imported and ready for Odoo’s model registry.

website_sale_delivery_date/readme/USAGE.md (1)

1-5: Usage documentation is clear and comprehensive
The guide succinctly explains how the delivery date selector integrates with the checkout flow and where the date is stored. No further content changes are necessary.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)


5-5: Files should end with a single newline character
null

(MD047, single-trailing-newline)

website_sale_delivery_date/views/delivery_form_template.xml (1)

1-26: Template correctly extends the delivery form with a date picker
The delivery_form_template properly inherits website_sale.delivery_form and inserts a read-only date input with the expected structure and CSS classes. XML syntax and xpath expression are correct.

website_sale_delivery_date/views/delivery_carrier_views.xml (1)

1-28: Carrier form inheritance adds scheduling configuration fields
The view extension cleanly injects the "Minimum Delivery Delay" fields and the editable weekday rule list into the delivery carrier form. XPath is correct, and the layout will support the new backend models.

website_sale_delivery_date/readme/CONFIGURE.md (1)

1-27: Configuration guide is well-structured and informative
The documentation clearly outlines how to configure delivery delays and weekday rules in Odoo’s UI. Formatting and headings are consistent; no changes needed.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)


9-9: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


12-12: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


14-14: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


27-27: Multiple consecutive blank lines
Expected: 1; Actual: 2

(MD012, no-multiple-blanks)

website_sale_delivery_date/__manifest__.py (1)

4-29: Module manifest is complete and accurate
All metadata fields, dependencies, data files, and asset declarations align with Odoo best practices. No issues detected.

🧰 Tools
🪛 Pylint (3.3.7)

[warning] 4-29: Statement seems to have no effect

(W0104)

website_sale_delivery_date/models/delivery_carrier.py (1)

8-37: LGTM! Clean model extension with proper validation.

The delivery carrier extension is well-implemented with:

  • Appropriate field types and defaults
  • Clear help text for user guidance
  • Proper relationship to weekday rules
  • Necessary validation constraint for non-negative delays

The code follows Odoo best practices for model inheritance.

website_sale_delivery_date/controllers/main.py (1)

139-152: Cut-off check uses today’s time, not the delivery date’s weekday
If a user orders for Friday while today is Monday, Monday’s cut-off should not apply. Compare cut-off against the creation day only if delivery_date.date() == now.date().

website_sale_delivery_date/README.rst (1)

1-220: Skipping review: autogenerated README
As per the coding guidelines, generated README.rst files (via oca-gen-addon-readme) should not be manually reviewed.

Comment on lines +1 to +3
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Pin build-system dependency for reproducible builds

To avoid unexpected breakages when new versions of whool are released, pin the version range of the build requirement. This ensures that CI and downstream consumers always use a known, compatible version.

Apply a diff like the following:

 [build-system]
-requires = ["whool"]
+requires = ["whool>=0.1.0,<1.0.0"]
 build-backend = "whool.buildapi"
🤖 Prompt for AI Agents
In website_sale_delivery_date/pyproject.toml at lines 1 to 3, the build-system
dependency "whool" is not version-pinned, which can cause unpredictable build
issues. Modify the requires line to specify a fixed version or a version range
for "whool" to ensure reproducible builds and consistent environments across CI
and downstream usage.

Comment on lines +1 to +3
- [Cemtix OU](https://www.cetmix.com):
- Mikhial Lapin
- Maksim Shurupov

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Fix contributor organization link

The URL for "Cemtix OU" appears to have a typo (https://www.cetmix.com). Please verify and update it to the correct domain (e.g., https://www.cemtix.com) to ensure the link works.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)

🤖 Prompt for AI Agents
In website_sale_delivery_date/readme/CONTRIBUTORS.md lines 1 to 3, the URL for
"Cemtix OU" is incorrect as it uses "https://www.cetmix.com". Verify the correct
domain and update the URL to "https://www.cemtix.com" or the accurate link to
fix the typo and ensure the link works properly.

Comment on lines +1 to +2
# Copyright Cetmix OU 2025
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Inconsistent license header

The top‐level __init__.py uses LGPL-3.0, whereas subpackages use AGPL-3.0. Please unify the license across the module (AGPL-3.0 is recommended for Odoo addons) to avoid legal conflicts.

🤖 Prompt for AI Agents
In website_sale_delivery_date/__init__.py at lines 1 to 2, the license header
uses LGPL-3.0 while subpackages use AGPL-3.0. Update the license header in this
file to AGPL-3.0 to unify the license across the module and avoid legal
conflicts, matching the recommended license for Odoo addons.

Comment thread website_sale_delivery_date/controllers/__init__.py Outdated
This module extends the Odoo e-commerce checkout flow by adding a delivery date selector after the customer chooses a delivery method. It is designed for companies that want to allow their customers to specify a desired delivery date when placing an order online.

The selected delivery date is captured directly in the website checkout flow.
Stored on the generated sale order’s commitment_date field (also known as the Delivery Date in the sales backend).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Use a clearer preposition

Consider changing:

Stored on the generated sale order’s commitment_date field
to
Stored in the generated sale order’s commitment_date field
for greater clarity.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~4-~4: The preposition ‘in’ seems more likely in this position.
Context: ...ly in the website checkout flow. Stored on the generated sale order’s commitment_d...

(AI_HYDRA_LEO_REPLACE_ON_IN)

🤖 Prompt for AI Agents
In website_sale_delivery_date/readme/DESCRIPTION.md at line 4, replace the
preposition "on" with "in" in the phrase "Stored on the generated sale order’s
commitment_date field" to improve clarity, making it "Stored in the generated
sale order’s commitment_date field".

Comment thread website_sale_delivery_date/controllers/main.py Outdated
Comment thread website_sale_delivery_date/controllers/main.py Outdated
Comment thread website_sale_delivery_date/controllers/main.py Outdated
Comment on lines +111 to +118
weekday = delivery_date.strftime("%A").lower()
weekday_rule = carrier.weekday_rule_ids.filtered(
lambda r: r.weekday == weekday and r.active
)

if not weekday_rule:
raise ValidationError(
_("Delivery is not available on %(weekday)s", weekday=weekday)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

weekday_rule may contain multiple records – pick one or raise conflict
Using a multi-recordset directly (weekday_rule.delivery_start_hour) yields the value of the first record only, which is undefined behaviour when more than one rule matches.

-        weekday_rule = carrier.weekday_rule_ids.filtered(
+        weekday_rules = carrier.weekday_rule_ids.filtered(
             lambda r: r.weekday == weekday and r.active
         )
-
-        if not weekday_rule:
+        if not weekday_rules:
             raise ValidationError(
-                _("Delivery is not available on %(weekday)s", weekday=weekday)
+                _("Delivery is not available on %s") % weekday.capitalize()
             )
+
+        weekday_rule = weekday_rules[0]  # TODO: decide merge/priority strategy
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
weekday = delivery_date.strftime("%A").lower()
weekday_rule = carrier.weekday_rule_ids.filtered(
lambda r: r.weekday == weekday and r.active
)
if not weekday_rule:
raise ValidationError(
_("Delivery is not available on %(weekday)s", weekday=weekday)
weekday = delivery_date.strftime("%A").lower()
weekday_rules = carrier.weekday_rule_ids.filtered(
lambda r: r.weekday == weekday and r.active
)
if not weekday_rules:
raise ValidationError(
_("Delivery is not available on %s") % weekday.capitalize()
)
weekday_rule = weekday_rules[0] # TODO: decide merge/priority strategy
🤖 Prompt for AI Agents
In website_sale_delivery_date/controllers/main.py around lines 111 to 118, the
variable weekday_rule may contain multiple records, but the code uses it as if
it were a single record, which causes undefined behavior. To fix this, check if
weekday_rule contains exactly one record and use that; if it contains multiple
records, raise a conflict error to handle the ambiguity explicitly.

Comment on lines +47 to +58
if carrier.min_delivery_delay_type == "hours":
min_date = now + timedelta(hours=carrier.min_delivery_delay)
else: # days
min_date = now + timedelta(days=carrier.min_delivery_delay)
min_date = min_date.replace(hour=0, minute=0, second=0, microsecond=0)

# Calculate maximum delivery date (e.g., 30 days from now)
max_date = now + timedelta(days=30)

return {
"min_date": min_date.strftime("%Y-%m-%d"),
"max_date": max_date.strftime("%Y-%m-%d"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Return ISO 8601 datetimes to match the widget format
min_date/max_date currently omit time, yet the picker expects a full datetime.

-            "min_date": min_date.strftime("%Y-%m-%d"),
-            "max_date": max_date.strftime("%Y-%m-%d"),
+            "min_date": min_date.strftime("%Y-%m-%d %H:%M"),
+            "max_date": max_date.strftime("%Y-%m-%d %H:%M"),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if carrier.min_delivery_delay_type == "hours":
min_date = now + timedelta(hours=carrier.min_delivery_delay)
else: # days
min_date = now + timedelta(days=carrier.min_delivery_delay)
min_date = min_date.replace(hour=0, minute=0, second=0, microsecond=0)
# Calculate maximum delivery date (e.g., 30 days from now)
max_date = now + timedelta(days=30)
return {
"min_date": min_date.strftime("%Y-%m-%d"),
"max_date": max_date.strftime("%Y-%m-%d"),
if carrier.min_delivery_delay_type == "hours":
min_date = now + timedelta(hours=carrier.min_delivery_delay)
else: # days
min_date = now + timedelta(days=carrier.min_delivery_delay)
min_date = min_date.replace(hour=0, minute=0, second=0, microsecond=0)
# Calculate maximum delivery date (e.g., 30 days from now)
max_date = now + timedelta(days=30)
return {
"min_date": min_date.strftime("%Y-%m-%d %H:%M"),
"max_date": max_date.strftime("%Y-%m-%d %H:%M"),
}
🤖 Prompt for AI Agents
In website_sale_delivery_date/controllers/main.py around lines 47 to 58, the
min_date and max_date are returned as date strings without time, but the widget
requires full ISO 8601 datetime strings. Update the return values to use ISO
8601 format including time by formatting min_date and max_date with the full
datetime string (e.g., using isoformat()) instead of just the date part.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

♻️ Duplicate comments (6)
website_sale_delivery_date/__init__.py (1)

1-2: Inconsistent license header

The license header uses LGPL-3.0 while subpackages use AGPL-3.0. Please unify the license across the module (AGPL-3.0 is recommended for Odoo addons) to avoid legal conflicts.

website_sale_delivery_date/readme/CONTEXT.md (2)

35-36: Grammar issue with determiners persists.

The sentences are missing determiners that would improve readability, as noted in previous reviews.


47-47: Same grammar issue in example results.

The determiner is missing before "Tuesday" as flagged in previous reviews.

website_sale_delivery_date/models/delivery_weekday_rule.py (3)

28-37: Consider using time fields instead of float for better time representation.

Using float fields for time representation can lead to precision issues and is less intuitive than dedicated time fields. The suggested widget="float_time" enhancement from the previous review is still missing.


38-43: Consider adding constraint for cutoff_hour usage.

The help text indicates that cutoff_hour only works with min_delivery_delay_type = days, but there's no constraint enforcing this relationship. The previously suggested constraint validation is still missing.


71-84: Fix inconsistency in hour validation bounds.

There's an inconsistency in validation: delivery_start_hour cannot be >= 24, but delivery_end_hour can be exactly 24. This creates confusion about whether 24:00 (midnight) is allowed.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65ec9fd and ad4fed7.

📒 Files selected for processing (14)
  • website_sale_delivery_date/README.rst (1 hunks)
  • website_sale_delivery_date/__init__.py (1 hunks)
  • website_sale_delivery_date/__manifest__.py (1 hunks)
  • website_sale_delivery_date/controllers/__init__.py (1 hunks)
  • website_sale_delivery_date/controllers/main.py (1 hunks)
  • website_sale_delivery_date/models/__init__.py (1 hunks)
  • website_sale_delivery_date/models/delivery_carrier.py (1 hunks)
  • website_sale_delivery_date/models/delivery_weekday_rule.py (1 hunks)
  • website_sale_delivery_date/models/sale_order.py (1 hunks)
  • website_sale_delivery_date/readme/CONFIGURE.md (1 hunks)
  • website_sale_delivery_date/readme/CONTEXT.md (1 hunks)
  • website_sale_delivery_date/static/description/index.html (1 hunks)
  • website_sale_delivery_date/static/src/js/checkout_delivery_date.esm.js (1 hunks)
  • website_sale_delivery_date/views/delivery_form_template.xml (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
`**/readme/*.*`: Never ask to add a top header in any file in these locations

**/readme/*.*: Never ask to add a top header in any file in these locations

  • website_sale_delivery_date/readme/CONFIGURE.md
  • website_sale_delivery_date/readme/CONTEXT.md
`**/static/description/index.html`: Never check this file.

**/static/description/index.html: Never check this file.

  • website_sale_delivery_date/static/description/index.html
`**/README.rst`: Never check this file

**/README.rst: Never check this file

  • website_sale_delivery_date/README.rst
🪛 markdownlint-cli2 (0.17.2)
website_sale_delivery_date/readme/CONFIGURE.md

1-1: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)


3-3: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


9-9: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


13-13: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


16-16: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


19-19: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)

website_sale_delivery_date/readme/CONTEXT.md

1-1: First line in a file should be a top-level heading
null

(MD041, first-line-heading, first-line-h1)


9-9: Multiple consecutive blank lines
Expected: 1; Actual: 2

(MD012, no-multiple-blanks)


12-12: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


17-17: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


24-24: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


26-26: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


29-29: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


35-35: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


38-38: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)


41-41: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)


47-47: Lists should be surrounded by blank lines
null

(MD032, blanks-around-lists)

🪛 LanguageTool
website_sale_delivery_date/readme/CONTEXT.md

[uncategorized] ~13-~13: A determiner appears to be missing. Consider inserting it.
Context: ... supporting two delay types: Days Minimum delay is interpreted as full calendar d...

(AI_EN_LECTOR_MISSING_DETERMINER)


[grammar] ~35-~35: A determiner may be missing.
Context: ...placed Monday at 09:00 can be delivered earliest Tuesday at 11:00 - An order placed Mond...

(THE_SUPERLATIVE)


[grammar] ~36-~36: A determiner may be missing.
Context: ...placed Monday at 12:00 can be delivered earliest Wednesday at 11:00 *Example 2: Delay T...

(THE_SUPERLATIVE)


[grammar] ~47-~47: A determiner may be missing.
Context: ...order placed on Monday can be delivered earliest Tuesday starting from 11:00 The sale o...

(THE_SUPERLATIVE)

🪛 Pylint (3.3.7)
website_sale_delivery_date/__manifest__.py

[error] 1-1: Unrecognized option found: readme-template-url, manifest-required-authors, manifest-required-keys, manifest-deprecated-keys, license-allowed, valid-odoo-versions

(E0015)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'api-one-deprecated'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'api-one-multi-together'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'attribute-deprecated'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'class-camelcase'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-view-replace-wo-priority'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'development-status-allowed'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-id-csv'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-xml-fields'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-xml-record-id'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'eval-referenced'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'incoherent-interpreter-exec-perm'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'license-allowed'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-author-string'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-deprecated-key'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-required-author'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-required-key'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-version-format'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-compute'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-inverse'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-required-super'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'method-search'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'openerp-exception-warning'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'print-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'redundant-modulename-xml'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'rst-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'sql-injection'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-field'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-required'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'use-vim-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'wrong-tabs-instead-of-spaces'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'attribute-string-redundant'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'character-not-valid-in-resource-link'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'consider-merging-classes-inherited'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'context-overridden'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'create-user-wo-reset-password'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-filter-wo-user'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-qweb-replace-wo-priority'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'deprecated-data-xml-node'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'deprecated-openerp-xml-node'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'duplicate-po-message-definition'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'except-pass'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'file-not-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'invalid-commit'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'manifest-maintainers-list'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-newline-extrafiles'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-readme'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-return'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'odoo-addons-relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'old-api7-method-defined'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'po-msgstr-variables'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'po-syntax-error'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'renamed-field-parameter'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'resource-not-exist'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'str-format-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'test-folder-imported'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-contains-variable'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'translation-positional-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'unnecessary-utf8-coding-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'website-manifest-key-not-valid-uri'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-attribute-translatable'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-deprecated-qweb-directive'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'xml-deprecated-tree-attribute'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'external-request-timeout'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'consider-merging-classes-inherited'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'create-user-wo-reset-password'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'dangerous-filter-wo-user'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'file-not-used'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'invalid-commit'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-manifest-dependency'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-newline-extrafiles'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'missing-readme'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'no-utf8-coding-comment'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'odoo-addons-relative-import'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'old-api7-method-defined'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'too-complex'

(W0012)


[warning] 1-1: Unknown option value for '--enable', expected a valid pylint message and got 'unnecessary-utf8-coding-comment'

(W0012)


[error] 1-1: Plugin 'pylint_odoo' is impossible to load, is it installed ? ('No module named 'pylint_odoo'')

(E0013)


[warning] 4-29: Statement seems to have no effect

(W0104)

🪛 Biome (1.9.4)
website_sale_delivery_date/static/src/js/checkout_delivery_date.esm.js

[error] 36-36: Use Number.parseInt instead of the equivalent global.

ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.parseInt instead.

(lint/style/useNumberNamespace)


[error] 62-62: Use Number.parseInt instead of the equivalent global.

ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.parseInt instead.

(lint/style/useNumberNamespace)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test with Odoo
  • GitHub Check: test with OCB
🔇 Additional comments (21)
website_sale_delivery_date/__init__.py (1)

4-5: LGTM! Proper module initialization

The import statements correctly initialize the controllers and models submodules, following standard Odoo module structure.

website_sale_delivery_date/controllers/__init__.py (2)

1-2: Correct license header

The AGPL-3.0 license header is appropriate for Odoo addons and consistent with the recommended licensing.


4-4: Controller properly imported

The main controller import is correctly enabled, ensuring the custom checkout logic is registered.

website_sale_delivery_date/models/__init__.py (2)

1-2: Consistent license header

The AGPL-3.0 license header is correctly used and consistent with Odoo addon recommendations.


4-6: Well-structured model imports

The model imports are logically organized and support the delivery date functionality:

  • delivery_carrier for carrier-specific constraints
  • delivery_weekday_rule for weekday scheduling rules
  • sale_order for order integration
website_sale_delivery_date/views/delivery_form_template.xml (4)

3-7: Proper template inheritance structure

The template correctly inherits from website_sale.delivery_form with appropriate naming and ID conventions.


16-26: Well-implemented delivery date input

The input field implementation is solid with:

  • Proper data widget attribute for JavaScript integration
  • Accessibility support with aria-describedby
  • Bootstrap form control styling
  • Readonly attribute for date picker behavior
  • Correct binding to order.commitment_date

31-36: Good accessibility implementation

The calendar icon includes proper accessibility attributes with role="img" and aria-label="Calendar".


38-38: Error handling placeholder ready

The error message container is properly positioned and styled for validation feedback integration.

website_sale_delivery_date/readme/CONFIGURE.md (1)

1-28: Comprehensive configuration documentation.

The configuration guide provides clear, step-by-step instructions for setting up delivery method constraints. The documentation effectively explains the minimum delivery delay parameters and their interpretation.

website_sale_delivery_date/__manifest__.py (3)

12-15: Verify module dependencies are available.

The dependencies on "website_sale" and "delivery" modules are appropriate for this functionality.


22-26: JavaScript asset path uses wildcard pattern.

The wildcard pattern "website_sale_delivery_date/static/src/js/*.js" will include all JavaScript files in the directory.


16-21: Verify referenced files exist in the module.

Ensure all data files and view files referenced in the manifest are present in the module structure.

#!/bin/bash
# Verify that all files referenced in the manifest exist
echo "Checking data files..."
fd -t f "security.xml|ir.model.access.csv|delivery_carrier_views.xml|delivery_form_template.xml" website_sale_delivery_date/

echo "Checking JavaScript assets..."
fd -t f "*.js" website_sale_delivery_date/static/src/js/
website_sale_delivery_date/readme/CONTEXT.md (1)

1-23: Comprehensive module context documentation.

The documentation effectively explains the module's purpose, delivery scheduling constraints, and the flexibility of delay types (days vs hours). The examples clearly illustrate how different configurations affect delivery timing.

website_sale_delivery_date/controllers/main.py (4)

12-22: Well-structured controller extending WebsiteSale.

The controller appropriately extends the base WebsiteSale controller and implements a clean JSON API for delivery date constraints.


31-31: Datetime parsing format correctly handles both date and time.

The parsing format "%Y-%m-%d %H:%M" correctly handles the full datetime string from the frontend, addressing the issue from previous reviews.


37-41: Proper error handling for validation errors.

The try-catch block appropriately handles ValidationError exceptions and returns structured JSON responses for the frontend.


18-21: Verify carrier.get_delivery_constraints() method exists.

The code calls carrier.get_delivery_constraints() but this method should be verified to exist in the delivery.carrier model extension.

#!/bin/bash
# Search for the get_delivery_constraints method implementation
ast-grep --pattern 'def get_delivery_constraints($$$)'
website_sale_delivery_date/static/src/js/checkout_delivery_date.esm.js (1)

71-76: Let’s search how the picker is initialized and whether any modern API calls (e.g. flatpickr methods) are exposed:

#!/bin/bash
# Description: Look for datepicker library usage and any API methods
fd -e js -e ts | xargs rg -H -n -A3 -B3 "flatpickr|datepicker|DatePicker"
website_sale_delivery_date/static/description/index.html (1)

1-8: Skipping review as per coding guidelines.
The static/description/index.html file is excluded from review.

website_sale_delivery_date/README.rst (1)

1-210: Skipping review as per coding guidelines.
The README.rst file is excluded from review.

Comment on lines +61 to +64
record.name = (
f"{dict(self.WEEKDAY_SELECTION)[record.weekday]} "
f"({record.delivery_start_hour:02.0f}:00 - "
f"{record.delivery_end_hour:02.0f}:00)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix time formatting in name computation for fractional hours.

The current formatting {record.delivery_start_hour:02.0f}:00 will display "11:00" for both 11.0 and 11.5 hours, which is misleading since 11.5 should be "11:30".

-                f"({record.delivery_start_hour:02.0f}:00 - "
-                f"{record.delivery_end_hour:02.0f}:00)"
+                f"({int(record.delivery_start_hour):02d}:{int((record.delivery_start_hour % 1) * 60):02d} - "
+                f"{int(record.delivery_end_hour):02d}:{int((record.delivery_end_hour % 1) * 60):02d})"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
record.name = (
f"{dict(self.WEEKDAY_SELECTION)[record.weekday]} "
f"({record.delivery_start_hour:02.0f}:00 - "
f"{record.delivery_end_hour:02.0f}:00)"
record.name = (
f"{dict(self.WEEKDAY_SELECTION)[record.weekday]} "
f"({int(record.delivery_start_hour):02d}:{int((record.delivery_start_hour % 1) * 60):02d} - "
f"{int(record.delivery_end_hour):02d}:{int((record.delivery_end_hour % 1) * 60):02d})"
🤖 Prompt for AI Agents
In website_sale_delivery_date/models/delivery_weekday_rule.py around lines 61 to
64, the time formatting in the name computation uses float formatting that
rounds fractional hours to the nearest integer, causing times like 11.5 to
display as "11:00" instead of "11:30". To fix this, convert the fractional hour
into hours and minutes separately, then format the string to show hours and
minutes correctly (e.g., "11:30" for 11.5). Update the formatting logic to
handle fractional hours properly by extracting the integer hour and calculating
minutes from the fractional part.

Comment on lines +43 to +45
weekday = delivery_date.strftime("%A").lower()
raise ValidationError(
_("Delivery is not available on %(weekday)s", weekday=weekday)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Fix capitalization in weekday error message.

The error message uses .lower() on the weekday name but doesn't properly capitalize it for display.

-            weekday = delivery_date.strftime("%A").lower()
+            weekday = delivery_date.strftime("%A")
             raise ValidationError(
                 _("Delivery is not available on %(weekday)s", weekday=weekday)
             )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
weekday = delivery_date.strftime("%A").lower()
raise ValidationError(
_("Delivery is not available on %(weekday)s", weekday=weekday)
weekday = delivery_date.strftime("%A")
raise ValidationError(
_("Delivery is not available on %(weekday)s", weekday=weekday)
)
🤖 Prompt for AI Agents
In website_sale_delivery_date/models/sale_order.py around lines 43 to 45, the
error message uses weekday.lower() which causes the weekday name to be all
lowercase and not properly capitalized for display. Remove the .lower() call and
instead format the weekday string to have the first letter capitalized before
passing it to the error message, ensuring the displayed weekday name looks
correct.

Comment on lines +66 to +79
if weekday_rule.cutoff_hour:
cutoff_time = now.replace(
hour=int(weekday_rule.cutoff_hour),
minute=int((weekday_rule.cutoff_hour % 1) * 60),
second=0,
microsecond=0,
)
if now > cutoff_time:
raise ValidationError(
_(
"Order placed after cut-off time " "%(cutoff_hour)s:00",
cutoff_hour=weekday_rule.cutoff_hour,
)
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix cut-off time validation logic for multi-day delivery scenarios.

The current cut-off time validation only checks against today's cut-off time, but this doesn't work correctly for delivery dates beyond tomorrow. The cut-off should be validated against the day before the delivery date.

-        # Check cut-off time if defined
-        if weekday_rule.cutoff_hour:
-            cutoff_time = now.replace(
-                hour=int(weekday_rule.cutoff_hour),
-                minute=int((weekday_rule.cutoff_hour % 1) * 60),
-                second=0,
-                microsecond=0,
-            )
-            if now > cutoff_time:
+        # Check cut-off time if defined (only applies to next-day delivery)
+        if weekday_rule.cutoff_hour and carrier.min_delivery_delay_type == "days":
+            delivery_date_only = delivery_date.date()
+            min_delivery_date_only = min_delivery_time.date()
+            # Only check cut-off for next-day delivery
+            if delivery_date_only == min_delivery_date_only:
+                cutoff_time = now.replace(
+                    hour=int(weekday_rule.cutoff_hour),
+                    minute=int((weekday_rule.cutoff_hour % 1) * 60),
+                    second=0,
+                    microsecond=0,
+                )
+                if now > cutoff_time:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if weekday_rule.cutoff_hour:
cutoff_time = now.replace(
hour=int(weekday_rule.cutoff_hour),
minute=int((weekday_rule.cutoff_hour % 1) * 60),
second=0,
microsecond=0,
)
if now > cutoff_time:
raise ValidationError(
_(
"Order placed after cut-off time " "%(cutoff_hour)s:00",
cutoff_hour=weekday_rule.cutoff_hour,
)
)
# Check cut-off time if defined (only applies to next-day delivery)
if weekday_rule.cutoff_hour and carrier.min_delivery_delay_type == "days":
delivery_date_only = delivery_date.date()
min_delivery_date_only = min_delivery_time.date()
# Only check cut-off for next-day delivery
if delivery_date_only == min_delivery_date_only:
cutoff_time = now.replace(
hour=int(weekday_rule.cutoff_hour),
minute=int((weekday_rule.cutoff_hour % 1) * 60),
second=0,
microsecond=0,
)
if now > cutoff_time:
raise ValidationError(
_(
"Order placed after cut-off time " "%(cutoff_hour)s:00",
cutoff_hour=weekday_rule.cutoff_hour,
)
)
🤖 Prompt for AI Agents
In website_sale_delivery_date/models/sale_order.py around lines 66 to 79, the
cut-off time validation incorrectly compares the current time to today's cut-off
time, which fails for delivery dates beyond tomorrow. Modify the logic to
calculate the cut-off time based on the day before the delivery date instead of
today, then compare the current time to this adjusted cut-off time to correctly
enforce the validation for multi-day delivery scenarios.

Comment on lines +52 to +53
# Calculate maximum delivery date (e.g., 30 days from now)
max_date = now + timedelta(days=30)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Consider making maximum delivery date configurable.

The hard-coded 30-day maximum delivery date limit should be configurable to allow different carriers to have different booking windows.

+    max_delivery_days = fields.Integer(
+        string="Maximum Delivery Days",
+        default=30,
+        help="Maximum number of days in advance that delivery can be scheduled",
+    )
+
     def get_delivery_constraints(self):
         self.ensure_one()
         now = fields.Datetime.now()
 
         # Calculate minimum delivery date
         if self.min_delivery_delay_type == "hours":
             min_date = now + timedelta(hours=self.min_delivery_delay)
         else:  # days
             min_date = now + timedelta(days=self.min_delivery_delay)
             min_date = min_date.replace(hour=0, minute=0, second=0, microsecond=0)
 
-        # Calculate maximum delivery date (e.g., 30 days from now)
-        max_date = now + timedelta(days=30)
+        # Calculate maximum delivery date
+        max_date = now + timedelta(days=self.max_delivery_days)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Calculate maximum delivery date (e.g., 30 days from now)
max_date = now + timedelta(days=30)
class DeliveryCarrier(models.Model):
_inherit = "delivery.carrier"
+ max_delivery_days = fields.Integer(
+ string="Maximum Delivery Days",
+ default=30,
+ help="Maximum number of days in advance that delivery can be scheduled",
+ )
+
def get_delivery_constraints(self):
self.ensure_one()
now = fields.Datetime.now()
# Calculate minimum delivery date
if self.min_delivery_delay_type == "hours":
min_date = now + timedelta(hours=self.min_delivery_delay)
else: # days
min_date = now + timedelta(days=self.min_delivery_delay)
min_date = min_date.replace(hour=0, minute=0, second=0, microsecond=0)
- # Calculate maximum delivery date (e.g., 30 days from now)
- max_date = now + timedelta(days=30)
+ # Calculate maximum delivery date
+ max_date = now + timedelta(days=self.max_delivery_days)
return {
"min_date": min_date,
"max_date": max_date,
}
🤖 Prompt for AI Agents
In website_sale_delivery_date/models/delivery_carrier.py around lines 52 to 53,
the maximum delivery date is currently hard-coded to 30 days. To fix this,
introduce a configurable field or parameter for the maximum delivery date limit,
allowing different carriers to specify their own booking windows. Replace the
fixed timedelta(days=30) with a value read from this configuration, ensuring the
code dynamically uses the carrier-specific setting.

const carrierEl = this.el.querySelector(
'input[name="o_delivery_radio"]:checked'
);
const carrierId = parseInt(carrierEl.dataset.dmId, 10);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Use Number.parseInt instead of global parseInt.

Modern ES2015+ code should use the Number namespace for consistency and clarity.

-        const carrierId = parseInt(carrierEl.dataset.dmId, 10);
+        const carrierId = Number.parseInt(carrierEl.dataset.dmId, 10);
-        const carrierId = parseInt(dmId, 10);
+        const carrierId = Number.parseInt(dmId, 10);

Also applies to: 62-62

🧰 Tools
🪛 Biome (1.9.4)

[error] 36-36: Use Number.parseInt instead of the equivalent global.

ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.parseInt instead.

(lint/style/useNumberNamespace)

🤖 Prompt for AI Agents
In website_sale_delivery_date/static/src/js/checkout_delivery_date.esm.js at
lines 36 and 62, replace the global parseInt calls with Number.parseInt to
follow modern ES2015+ best practices. This means changing
parseInt(carrierEl.dataset.dmId, 10) to Number.parseInt(carrierEl.dataset.dmId,
10) and similarly for the other instance at line 62.

},

destroy() {
this.picker();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix picker destruction method call.

The current code calls this.picker() which treats picker as a function, but it should likely call a destroy method on the picker instance.

-        this.picker();
+        if (this.picker && typeof this.picker.destroy === 'function') {
+            this.picker.destroy();
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.picker();
if (this.picker && typeof this.picker.destroy === 'function') {
this.picker.destroy();
}
🤖 Prompt for AI Agents
In website_sale_delivery_date/static/src/js/checkout_delivery_date.esm.js at
line 80, the code incorrectly calls this.picker() as a function, but picker is
an instance that requires calling its destroy method to properly clean up.
Replace the call to this.picker() with this.picker.destroy() to correctly invoke
the destroy method on the picker instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants