Initial commit: OCA Workflow Process packages (456 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:00 +02:00
commit d366e42934
18799 changed files with 1284507 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# Sale order min quantity
Odoo addon: sale_restricted_qty
## Installation
```bash
pip install odoo-bringout-oca-sale-workflow-sale_restricted_qty
```
## Dependencies
This addon depends on:
- sale_management
## Manifest Information
- **Name**: Sale order min quantity
- **Version**: 16.0.1.0.0
- **Category**: Sales Management
- **License**: AGPL-3
- **Installable**: True
## Source
Based on [OCA/sale-workflow](https://github.com/OCA/sale-workflow) branch 16.0, addon `sale_restricted_qty`.
## License
This package maintains the original AGPL-3 license from the upstream Odoo project.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Reports: doc/REPORTS.md
- Security: doc/SECURITY.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Sale_restricted_qty Module - sale_restricted_qty
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for sale_restricted_qty. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,5 @@
# Dependencies
This addon depends on:
- [sale_management](../../odoo-bringout-oca-ocb-sale_management)

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon sale_restricted_qty or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-oca-sale-workflow-sale_restricted_qty"
# or
uv pip install odoo-bringout-oca-sale-workflow-sale_restricted_qty"
```

View file

@ -0,0 +1,16 @@
# Models
Detected core models and extensions in sale_restricted_qty.
```mermaid
classDiagram
class product_category
class product_product
class product_restricted_qty_mixin
class product_template
class sale_order_line
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: sale_restricted_qty. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon sale_restricted_qty
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,8 @@
# Security
This module does not define custom security rules or access controls beyond Odoo defaults.
Default Odoo security applies:
- Base user access through standard groups
- Model access inherited from dependencies
- No custom row-level security rules

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon sale_restricted_qty
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-oca-sale-workflow-sale_restricted_qty"
version = "16.0.0"
description = "Sale order min quantity - Odoo addon"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-sale-workflow-sale_management>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["sale_restricted_qty"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]

View file

@ -0,0 +1,114 @@
=======================
Sale order min quantity
=======================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:11c109b03c7404989c3814a5675fcc5ae0cb3088674059b409bc202355156177
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
:target: https://github.com/OCA/sale-workflow/tree/16.0/sale_restricted_qty
:alt: OCA/sale-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/sale-workflow-16-0/sale-workflow-16-0-sale_restricted_qty
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows to define min, max and multiple order quantity on product.
Min and Max order quantity is either required or recommanded.
If you check "Force mini/max Qty" on product the min/max qty do not block sale
order.
This can be used if the available stock is less then the min qty
or if you want to sell sample products.
Max qty can be used if we dont want to sale more than available qty
(end of series product)
Setings are defined on product, if values are not set we use settings from
product template.
If settings are not set on product template we use settings from
product category otherwise parent category.
**Table of contents**
.. contents::
:local:
Usage
=====
#. Go to **Sales > Products > Product Variants** and Set "Min Sale Qty".
If you dont want block product sale if qty is less the "Min Sale Qty",
chek "Force Min Qty"
#. Create a sale order and add a sale order line with this product and check
if Qty is less then "Min Qty" A message in displayed "Min Qty Required"
Or "Min Qty Recommanded". Check if Min qty is required you can't
validate order.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-workflow/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_restricted_qty%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Akretion
Contributors
~~~~~~~~~~~~
* Mourad EL HADJ MIMOUN <mourad.elhadj.mimoune@akretion.com>
* `Ooops <https://www.ooops404.com/>`_:
* Ashish Hirpara <https://ashish-hirpara.com>
* `Aion Tech <https://aiontech.company/>`_:
* Simone Rubino <simone.rubino@aion-tech.it>
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-ashishhirapara| image:: https://github.com/ashishhirapara.png?size=40px
:target: https://github.com/ashishhirapara
:alt: ashishhirapara
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-ashishhirapara|
This module is part of the `OCA/sale-workflow <https://github.com/OCA/sale-workflow/tree/16.0/sale_restricted_qty>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1 @@
from . import models

View file

@ -0,0 +1,22 @@
# Copyright 2019 Akretion (<http://www.akretion.com>)
# Copyright 2023 Simone Rubino - Aion Tech
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Sale order min quantity",
"version": "16.0.1.0.0",
"category": "Sales Management",
"author": "Akretion, Odoo Community Association (OCA)",
"contributors": ["Ashish Hirpara"],
"maintainers": ["ashishhirapara"],
"website": "https://github.com/OCA/sale-workflow",
"license": "AGPL-3",
"depends": ["sale_management"],
"data": [
"views/product_category_views.xml",
"views/product_template_views.xml",
"views/product_product_views.xml",
"views/sale_views.xml",
],
"installable": True,
}

View file

@ -0,0 +1,82 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_min_qty
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: sale_order_min_qty
#: code:addons/sale_order_min_qty/models/sale.py:51
#, python-format
msgid "\n"
"* If you want sell quantity less than Min Quantity,Check \"force min quatity\" on product"
msgstr ""
#. module: sale_order_min_qty
#: code:addons/sale_order_min_qty/models/sale.py:48
#, python-format
msgid "Check minimum order quantity for this products: * \n"
""
msgstr ""
#. module: sale_order_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_sale_order_line__force_sale_min_qty
msgid "Force Min Qty"
msgstr "Forsiraj min količinu"
#. module: sale_order_min_qty
#: model:ir.model.fields,help:sale_order_min_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,help:sale_order_min_qty.field_sale_order_line__force_sale_min_qty
msgid "If force min qty is checked, the min quantity is only indicative value."
msgstr "Ako je označeno forsiranje min količine, minimalna količina je samo indikativna vrijednost."
#. module: sale_order_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_sale_order_line__sale_min_qty
msgid "Min Qty"
msgstr "Min količina"
#. module: sale_order_min_qty
#: model_terms:ir.ui.view,arch_db:sale_order_min_qty.view_order_form
msgid "Min Quantity Recommended"
msgstr "Preporučena min količina"
#. module: sale_order_min_qty
#: model_terms:ir.ui.view,arch_db:sale_order_min_qty.view_order_form
msgid "Min Quantity Required"
msgstr "Potrebna min količina"
#. module: sale_order_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_product_product__sale_min_qty
msgid "Min Sale Qty"
msgstr "Min prodajna količina"
#. module: sale_order_min_qty
#: model:ir.model,name:sale_order_min_qty.model_product_product
msgid "Product"
msgstr "Artikal"
#. module: sale_order_min_qty
#: code:addons/sale_order_min_qty/models/sale.py:43
#, python-format
msgid "Product \"%s\": Min Quantity %s."
msgstr "Proizvod \"%s\": Min količina %s."
#. module: sale_order_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_sale_order_line__is_qty_less_min_qty
msgid "Qty < Min Qty"
msgstr "Kol. < Min kol."
#. module: sale_order_min_qty
#: model:ir.model,name:sale_order_min_qty.model_sale_order_line
msgid "Sales Order Line"
msgstr "Stavka prodajne narudžbe"

View file

@ -0,0 +1,453 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_restricted_qty
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-06-17 11:09+0000\n"
"Last-Translator: Claude R Perrin <claude@alpis.fr>\n"
"Language-Team: none\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity bigger than max Quantity,Check \"force max "
"quatity\" on product"
msgstr ""
"\n"
"* Si vous voulez vendre une quantité supérieure à la quantité maximale, "
"cochez « Forcer Qté Max » sur l'article"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity less than Min Quantity,Check \"force min quatity"
"\" on product"
msgstr ""
"\n"
"* Si vous souhaitez vendre une quantité inférieure à la quantité minimale, "
"cochez « Forcer Qté Min » sur l'article"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity not multiple Quantity,Set multiple quantity to 0 "
"on product or product template or product category"
msgstr ""
"\n"
"* Si vous souhaitez vendre la quantité et non plusieurs, définissez la "
"quantité multiple sur 0 sur l'article ou le modèle d'article ou la catégorie "
"d'article"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check maximum order quantity for this products: * \n"
msgstr "Vérifiez la quantité maximale de commande pour ces articles: * \n"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check minimum order quantity for this products: * \n"
msgstr "Vérifiez la quantité minimale de commande pour ces articles: * \n"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check multiple order quantity for this products: * \n"
msgstr "Vérifiez la quantité de commande multiple pour ces articles: * \n"
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__force_sale_max_qty
msgid ""
"Define if user can force sale max qty 'If not set', Odoo will use the value "
"defined in the parent object.Hierarchy is in this order :Product/product "
"Template/product category/parent categoroies "
msgstr ""
"Définir si lutilisateur peut forcer la qté max de commande 'Si ce nest pas "
"défini', Odoo utilisera la valeur définie dans lobjet parent. La hiérarchie "
"suit cet ordre :Produit/Modèle de produit/catégorie de produit/catégories "
"parentes "
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__force_sale_min_qty
msgid ""
"Define if user can force sale min qty 'If not set', Odoo will use the value "
"defined in the parent object.Hierarchy is in this order :Product/product "
"Template/product category/parent categoroies "
msgstr ""
"Définir si lutilisateur peut forcer la qté min de commande 'Si ce nest pas "
"défini', Odoo utilisera la valeur définie dans lobjet parent. La hiérarchie "
"suit cet ordre :Produit/Modèle de produit/catégorie de produit/catégories "
"parentes "
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_max_qty
msgid ""
"Define sale max qty 'If not set, Odoo will use the value defined in the "
"parent object.Hierarchy is in this order :Product/product Template/product "
"category/parent categoroies "
msgstr ""
"Définir la vente max qté 'Selle nest pas définie, Odoo utilisera la valeur "
"définie dans lobjet parent. La hiérarchie suite cet ordre :Produit/Modèle "
"de produit/catégorie de produit/catégories parentes "
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_min_qty
msgid ""
"Define sale min qty 'If not set, Odoo will use the value defined in the "
"parent object.Hierarchy is in this order :Product/product Template/product "
"category/parent categoroies "
msgstr ""
"Définir la vente min qté 'Si elle nest pas définie, Odoo utilisera la "
"valeur définie dans lobjet parent. La hiérarchie suit cet ordre :Produit/"
"Modèle de produit/catégorie de produit/catégories parentes "
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_multiple_qty
msgid ""
"Define sale multiple qty 'If not set', Odoo will use the value defined in "
"the parent object.Hierarchy is in this order :Product/product Template/"
"product category/parent categoroies "
msgstr ""
"Définir la vente multiple 'Si elle nest pas défini', Odoo utilisera la "
"valeur définie dans lobjet parent. La hiérarchie suit cet ordre :Produit/"
"Modèle de produit/catégorie de produit/catégories parentes "
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__force_sale_max_qty
msgid "Force Max Qty"
msgstr "Forcer qté Max"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__force_sale_min_qty
msgid "Force Min Qty"
msgstr "Forcer qté Min"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__force_sale_max_qty
msgid "Force Sale Max Qty"
msgstr "Forcer qté max vendable"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__force_sale_min_qty
msgid "Force Sale Min Qty"
msgstr "Forcer qté min vendable"
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__manual_force_sale_max_qty
msgid ""
"If force max qty is checked, the max quantity is only indicative value.If is "
"not test we check parent value"
msgstr ""
"Si forcer qté max est cochée, la quantité max nest quune valeur "
"indicative. Si cest pas coché, nous vérifions la valeur parente"
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__manual_force_sale_min_qty
msgid ""
"If force min qty is checked, the min quantity is only indicative value.If is "
"not test we check parent value"
msgstr ""
"Si forcer qté min est cochée, la quantité min nest quindicative. Si ce "
"nest pas coché, nous vérifions la valeur parente"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_force_sale_max_qty
msgid "Manual Force Max Qty"
msgstr "Force manuellement Qté max"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_force_sale_min_qty
msgid "Manual Force Min Qty"
msgstr "Force manuellement Qté min"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_max_qty
msgid "Max Qty"
msgstr "Qté max"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Max Quantity Exceeded"
msgstr "Quantité maximale dépassée"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Max Quantity Recommended"
msgstr "Quantité maximale recommandée"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_max_qty
msgid "Max Sale Qty"
msgstr "Qté max vendable"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_min_qty
msgid "Min Qty"
msgstr "Qté Min"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Min Quantity Recommended"
msgstr "Quantité minimale recommandée"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Min Quantity Required"
msgstr "Quantité minimale requise"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_min_qty
msgid "Min Sale Qty"
msgstr "Qty min vendable"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_multiple_qty
msgid "Multiple Qty"
msgstr "Quantité multiple"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Multiple Quantity Required"
msgstr "Quantité multiple requise"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_multiple_qty
msgid "Multiple Sale Qty"
msgstr "Qty vente multiple"
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__not_force
msgid "No"
msgstr "Non"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_not_multiple_qty
msgid "Not Multiple Qty"
msgstr "Pas de qté multiples"
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_template
msgid "Product"
msgstr "Article"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": Min Quantity %(min_qty)s."
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": max Quantity %(max_qty)s."
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": multiple Quantity %(multiple_qty)s."
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_category
msgid "Product Category"
msgstr "Catégorie d'articles"
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_restricted_qty_mixin
msgid "Product Restrict Qty Mixin"
msgstr "Mixin limitations quantités vendables"
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_product
msgid "Product Variant"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_less_min_qty
msgid "Qty < Min Qty"
msgstr "Qté < Qté min"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_bigger_max_qty
msgid "Qty > max Qty"
msgstr "Qté > Qté max"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_max_qty
msgid "Sale Max Qty"
msgstr "Qté max vendable"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Max qty"
msgstr "Qté max vendable"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Miltiple qty"
msgstr "Qté multiple par commande"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_min_qty
msgid "Sale Min Qty"
msgstr "Qté min vendable"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Min qty"
msgstr "Qté min vendable"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_multiple_qty
msgid "Sale Multiple Qty"
msgstr "Qté multiple vendable"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale restricted qty"
msgstr "Limitations des quantités vendables"
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_sale_order_line
msgid "Sales Order Line"
msgstr "Ligne de bon de commande"
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__use_parent
msgid "Use Parent Setting"
msgstr "Utiliser le paramètre parent"
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__force
msgid "Yes"
msgstr "Oui"
#~ msgid "Display Name"
#~ msgstr "Nom affiché"
#~ msgid "ID"
#~ msgstr "ID"
#~ msgid "Last Modified on"
#~ msgstr "Dernière modification le"
#, python-format
#~ msgid "Product \"%s\": Min Quantity %s."
#~ msgstr "Article « %s »: quantité minimale %s."
#, python-format
#~ msgid "Product \"%s\": max Quantity %s."
#~ msgstr "Article « %s »: quantité maximale %s."
#, python-format
#~ msgid "Product \"%s\": multiple Quantity %s."
#~ msgstr "Articles « %s »: quantités multiples %s."
#~ msgid "Product Template"
#~ msgstr "Modèle d'article"

View file

@ -0,0 +1,452 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_restricted_qty
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-05-22 16:36+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.17\n"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity bigger than max Quantity,Check \"force max "
"quatity\" on product"
msgstr ""
"\n"
"* se vuoi vendere una quantità maggiore della Quantità massima, Seleziona "
"\"forza quantità massima\" nel prodotto"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity less than Min Quantity,Check \"force min quatity"
"\" on product"
msgstr ""
"\n"
"* se vuoi vendere una quantità inferiore alla Quantità Minima, Seleziona "
"\"forza quantità minima\" nel prodotto"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity not multiple Quantity,Set multiple quantity to 0 "
"on product or product template or product category"
msgstr ""
"\n"
"* se vuoi vendere quantità non multiple, Imposta quantità multiple a 0 nella "
"Prodotto o Modello Prodotto o Categoria Prodotto"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check maximum order quantity for this products: * \n"
msgstr "Controlla la quantità di vendita massima per questi prodotti: * \n"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check minimum order quantity for this products: * \n"
msgstr "Controlla la quantità di vendita minima per questi prodotti: * \n"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check multiple order quantity for this products: * \n"
msgstr "Controlla la quantità di vendita multipla per questi prodotti: * \n"
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__force_sale_max_qty
msgid ""
"Define if user can force sale max qty 'If not set', Odoo will use the value "
"defined in the parent object.Hierarchy is in this order :Product/product "
"Template/product category/parent categoroies "
msgstr ""
"Definisci se l'utente può forzare la quantità massima di vendita 'Se non "
"impostato', Odoo utilizzerà il valore definito nell'oggetto padre. La "
"gerarchia è in questo ordine: Prodotto/Modello prodotto/categoria prodotto/"
"categorie padre "
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__force_sale_min_qty
msgid ""
"Define if user can force sale min qty 'If not set', Odoo will use the value "
"defined in the parent object.Hierarchy is in this order :Product/product "
"Template/product category/parent categoroies "
msgstr ""
"Definisci se l'utente può forzare la quantità minima di vendita 'Se non "
"impostato', Odoo utilizzerà il valore definito nell'oggetto padre. La "
"gerarchia è in questo ordine: Prodotto/Modello prodotto/categoria prodotto/"
"categorie padre "
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_max_qty
msgid ""
"Define sale max qty 'If not set, Odoo will use the value defined in the "
"parent object.Hierarchy is in this order :Product/product Template/product "
"category/parent categoroies "
msgstr ""
"Definisci la qtà massima di vendita 'Se non impostato', Odoo utilizzerà il "
"valore definito nell'oggetto padre. La gerarchia è in questo ordine: "
"Prodotto/Modello prodotto/categoria prodotto/categorie padre "
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_min_qty
msgid ""
"Define sale min qty 'If not set, Odoo will use the value defined in the "
"parent object.Hierarchy is in this order :Product/product Template/product "
"category/parent categoroies "
msgstr ""
"Definisci la qtà minima di vendita 'Se non impostato', Odoo utilizzerà il "
"valore definito nell'oggetto padre. La gerarchia è in questo ordine: "
"Prodotto/Modello prodotto/categoria prodotto/categorie padre "
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_multiple_qty
msgid ""
"Define sale multiple qty 'If not set', Odoo will use the value defined in "
"the parent object.Hierarchy is in this order :Product/product Template/"
"product category/parent categoroies "
msgstr ""
"Definisci la qtà multipla di vendita 'Se non impostato', Odoo utilizzerà il "
"valore definito nell'oggetto padre. La gerarchia è in questo ordine: "
"Prodotto/Modello prodotto/categoria prodotto/categorie padre "
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__force_sale_max_qty
msgid "Force Max Qty"
msgstr "Forza Qtà Massima"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__force_sale_min_qty
msgid "Force Min Qty"
msgstr "Forza Qtà Minima"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__force_sale_max_qty
msgid "Force Sale Max Qty"
msgstr "Forza Qtà Minima di Vendita"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__force_sale_min_qty
msgid "Force Sale Min Qty"
msgstr "Forza Qtà Massima di Vendita"
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__manual_force_sale_max_qty
msgid ""
"If force max qty is checked, the max quantity is only indicative value.If is "
"not test we check parent value"
msgstr ""
"Se forza qtà massima è selezionata, la quantità massima è solo un valore "
"indicativo. Se non è test controlliamo il valore genitore"
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__manual_force_sale_min_qty
msgid ""
"If force min qty is checked, the min quantity is only indicative value.If is "
"not test we check parent value"
msgstr ""
"Se forza qtà minima è selezionata, la quantità minima è solo un valore "
"indicativo. Se non è test controlliamo il valore genitore"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_force_sale_max_qty
msgid "Manual Force Max Qty"
msgstr "Forza Manualmente Qtà Massima"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_force_sale_min_qty
msgid "Manual Force Min Qty"
msgstr "Forza Manualmente Qtà Minima"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_max_qty
msgid "Max Qty"
msgstr "Quantità Massima"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Max Quantity Exceeded"
msgstr "Quantità Massima Superata"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Max Quantity Recommended"
msgstr "Qtà Massima Consigliata"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_max_qty
msgid "Max Sale Qty"
msgstr "Qtà di Vendita Massima"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_min_qty
msgid "Min Qty"
msgstr "Qtà Minima"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Min Quantity Recommended"
msgstr "Qtà Minima Consigliata"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Min Quantity Required"
msgstr "Qtà Minima Richiesta"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_min_qty
msgid "Min Sale Qty"
msgstr "Qtà di Vendita Minima"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_multiple_qty
msgid "Multiple Qty"
msgstr "Qtà Multiple"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Multiple Quantity Required"
msgstr "Quantità Multipla Richiesta"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_multiple_qty
msgid "Multiple Sale Qty"
msgstr "Quantità di Vendita Multipla"
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__not_force
msgid "No"
msgstr "No"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_not_multiple_qty
msgid "Not Multiple Qty"
msgstr "Qtà Non Multipla"
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_template
msgid "Product"
msgstr "Prodotto"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": Min Quantity %(min_qty)s."
msgstr "Prodotto \"%(product)s\": quantità min. %(min_qty)s."
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": max Quantity %(max_qty)s."
msgstr "Prodotto \"%(product)s\": quantità mas. %(max_qty)s."
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": multiple Quantity %(multiple_qty)s."
msgstr "Prodotto \"%(product)s\": quantità multipla %(multiple_qty)s."
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_category
msgid "Product Category"
msgstr "Categoria prodotto"
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_restricted_qty_mixin
msgid "Product Restrict Qty Mixin"
msgstr "Mixin Limite di Quantità Prodotto"
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_product
msgid "Product Variant"
msgstr "Variante prodotto"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_less_min_qty
msgid "Qty < Min Qty"
msgstr "Qtà < Qtà Minima"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_bigger_max_qty
msgid "Qty > max Qty"
msgstr "Qtà > Qtà Massima"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_max_qty
msgid "Sale Max Qty"
msgstr "Qtà Massima di Vendita"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Max qty"
msgstr "qtà Massima di Vendita"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Miltiple qty"
msgstr "qtà Multipla di Vendita"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_min_qty
msgid "Sale Min Qty"
msgstr "Qtà Minima di Vendita"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Min qty"
msgstr "qtà Minima di Vendita"
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_multiple_qty
msgid "Sale Multiple Qty"
msgstr "Qtà Multipla di Vendita"
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale restricted qty"
msgstr "Quantità di vendita limitata"
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_sale_order_line
msgid "Sales Order Line"
msgstr "Riga ordine di vendita"
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__use_parent
msgid "Use Parent Setting"
msgstr "Usa Impostazioni Genitore"
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__force
msgid "Yes"
msgstr "Sì"
#~ msgid "Display Name"
#~ msgstr "Nome visualizzato"
#~ msgid "ID"
#~ msgstr "ID"
#~ msgid "Last Modified on"
#~ msgstr "Ultima Modifica il"
#, python-format
#~ msgid "Product \"%s\": Min Quantity %s."
#~ msgstr "Prodotto \"%s\": Quantità Minima %s."
#, python-format
#~ msgid "Product \"%s\": max Quantity %s."
#~ msgstr "Prodotto \"%s\": Quantità Massima %s."
#, python-format
#~ msgid "Product \"%s\": multiple Quantity %s."
#~ msgstr "prodotto \"%s\": Quantità Multipla %s."
#~ msgid "Product Template"
#~ msgstr "Modello Prodotto"

View file

@ -0,0 +1,82 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_min_qty
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: sale_order_min_qty
#: code:addons/sale_order_min_qty/models/sale.py:51
#, python-format
msgid "\n"
"* If you want sell quantity less than Min Quantity,Check \"force min quatity\" on product"
msgstr ""
#. module: sale_order_min_qty
#: code:addons/sale_order_min_qty/models/sale.py:48
#, python-format
msgid "Check minimum order quantity for this products: * \n"
""
msgstr ""
#. module: sale_order_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_sale_order_line__force_sale_min_qty
msgid "Force Min Qty"
msgstr ""
#. module: sale_order_min_qty
#: model:ir.model.fields,help:sale_order_min_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,help:sale_order_min_qty.field_sale_order_line__force_sale_min_qty
msgid "If force min qty is checked, the min quantity is only indicative value."
msgstr ""
#. module: sale_order_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_sale_order_line__sale_min_qty
msgid "Min Qty"
msgstr ""
#. module: sale_order_min_qty
#: model_terms:ir.ui.view,arch_db:sale_order_min_qty.view_order_form
msgid "Min Quantity Recommended"
msgstr ""
#. module: sale_order_min_qty
#: model_terms:ir.ui.view,arch_db:sale_order_min_qty.view_order_form
msgid "Min Quantity Required"
msgstr ""
#. module: sale_order_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_product_product__sale_min_qty
msgid "Min Sale Qty"
msgstr ""
#. module: sale_order_min_qty
#: model:ir.model,name:sale_order_min_qty.model_product_product
msgid "Product"
msgstr ""
#. module: sale_order_min_qty
#: code:addons/sale_order_min_qty/models/sale.py:43
#, python-format
msgid "Product \"%s\": Min Quantity %s."
msgstr ""
#. module: sale_order_min_qty
#: model:ir.model.fields,field_description:sale_order_min_qty.field_sale_order_line__is_qty_less_min_qty
msgid "Qty < Min Qty"
msgstr ""
#. module: sale_order_min_qty
#: model:ir.model,name:sale_order_min_qty.model_sale_order_line
msgid "Sales Order Line"
msgstr ""

View file

@ -0,0 +1,392 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_restricted_qty
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity bigger than max Quantity,Check \"force max quatity\" on product"
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity less than Min Quantity,Check \"force min quatity\" on product"
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid ""
"\n"
"* If you want sell quantity not multiple Quantity,Set multiple quantity to 0 on product or product template or product category"
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check maximum order quantity for this products: * \n"
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check minimum order quantity for this products: * \n"
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Check multiple order quantity for this products: * \n"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__force_sale_max_qty
msgid ""
"Define if user can force sale max qty 'If not set', Odoo will use the value "
"defined in the parent object.Hierarchy is in this order :Product/product "
"Template/product category/parent categoroies "
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__force_sale_min_qty
msgid ""
"Define if user can force sale min qty 'If not set', Odoo will use the value "
"defined in the parent object.Hierarchy is in this order :Product/product "
"Template/product category/parent categoroies "
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_max_qty
msgid ""
"Define sale max qty 'If not set, Odoo will use the value defined in the "
"parent object.Hierarchy is in this order :Product/product Template/product "
"category/parent categoroies "
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_min_qty
msgid ""
"Define sale min qty 'If not set, Odoo will use the value defined in the "
"parent object.Hierarchy is in this order :Product/product Template/product "
"category/parent categoroies "
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__sale_multiple_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__sale_multiple_qty
msgid ""
"Define sale multiple qty 'If not set', Odoo will use the value defined in "
"the parent object.Hierarchy is in this order :Product/product "
"Template/product category/parent categoroies "
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__force_sale_max_qty
msgid "Force Max Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__force_sale_min_qty
msgid "Force Min Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__force_sale_max_qty
msgid "Force Sale Max Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__force_sale_min_qty
msgid "Force Sale Min Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_max_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__manual_force_sale_max_qty
msgid ""
"If force max qty is checked, the max quantity is only indicative value.If is"
" not test we check parent value"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_category__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_product__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_min_qty
#: model:ir.model.fields,help:sale_restricted_qty.field_product_template__manual_force_sale_min_qty
msgid ""
"If force min qty is checked, the min quantity is only indicative value.If is"
" not test we check parent value"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_force_sale_max_qty
msgid "Manual Force Max Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_force_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_force_sale_min_qty
msgid "Manual Force Min Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_max_qty
msgid "Max Qty"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Max Quantity Exceeded"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Max Quantity Recommended"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_max_qty
msgid "Max Sale Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_min_qty
msgid "Min Qty"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Min Quantity Recommended"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Min Quantity Required"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_min_qty
msgid "Min Sale Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__sale_multiple_qty
msgid "Multiple Qty"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_order_form
msgid "Multiple Quantity Required"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__manual_sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__manual_sale_multiple_qty
msgid "Multiple Sale Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__not_force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__not_force
msgid "No"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_not_multiple_qty
msgid "Not Multiple Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_template
msgid "Product"
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": Min Quantity %(min_qty)s."
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": max Quantity %(max_qty)s."
msgstr ""
#. module: sale_restricted_qty
#. odoo-python
#: code:addons/sale_restricted_qty/models/sale.py:0
#, python-format
msgid "Product \"%(product)s\": multiple Quantity %(multiple_qty)s."
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_category
msgid "Product Category"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_restricted_qty_mixin
msgid "Product Restrict Qty Mixin"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_product_product
msgid "Product Variant"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_less_min_qty
msgid "Qty < Min Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_sale_order_line__is_qty_bigger_max_qty
msgid "Qty > max Qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_max_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_max_qty
msgid "Sale Max Qty"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Max qty"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Miltiple qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_min_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_min_qty
msgid "Sale Min Qty"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale Min qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_category__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_product__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_restricted_qty_mixin__sale_multiple_qty
#: model:ir.model.fields,field_description:sale_restricted_qty.field_product_template__sale_multiple_qty
msgid "Sale Multiple Qty"
msgstr ""
#. module: sale_restricted_qty
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.min_order_qty_product_product_form_view
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_category_form
#: model_terms:ir.ui.view,arch_db:sale_restricted_qty.view_product_template_form
msgid "Sale restricted qty"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model,name:sale_restricted_qty.model_sale_order_line
msgid "Sales Order Line"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__use_parent
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__use_parent
msgid "Use Parent Setting"
msgstr ""
#. module: sale_restricted_qty
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_category__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_product__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_restricted_qty_mixin__manual_force_sale_min_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_max_qty__force
#: model:ir.model.fields.selection,name:sale_restricted_qty.selection__product_template__manual_force_sale_min_qty__force
msgid "Yes"
msgstr ""

View file

@ -0,0 +1,5 @@
from . import product_restricted_qty_mixin
from . import product_category
from . import product_template
from . import product_product
from . import sale

View file

@ -0,0 +1,65 @@
# Copyright 2019 Akretion
# Copyright 2023 Simone Rubino - Aion Tech
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class ProductCategory(models.Model):
_name = "product.category"
_inherit = ["product.category", "product.restricted.qty.mixin"]
sale_multiple_qty = fields.Float(
recursive=True,
)
sale_min_qty = fields.Float(
recursive=True,
)
force_sale_min_qty = fields.Boolean(
recursive=True,
)
sale_max_qty = fields.Float(
recursive=True,
)
force_sale_max_qty = fields.Boolean(
recursive=True,
)
def _get_sale_restricted_qty(self):
res = super()._get_sale_restricted_qty()
force_sale_min_qty = False
if self.manual_force_sale_min_qty == "force":
force_sale_min_qty = True
elif self.manual_force_sale_min_qty == "not_force":
force_sale_min_qty = False
else:
force_sale_min_qty = self.parent_id.force_sale_min_qty
force_sale_max_qty = False
if self.manual_force_sale_max_qty == "force":
force_sale_max_qty = True
elif self.manual_force_sale_max_qty == "not_force":
force_sale_max_qty = False
else:
force_sale_max_qty = self.parent_id.force_sale_max_qty
res.update(
{
"sale_min_qty": self.manual_sale_min_qty or self.parent_id.sale_min_qty,
"force_sale_min_qty": force_sale_min_qty,
"sale_max_qty": self.manual_sale_max_qty or self.parent_id.sale_max_qty,
"force_sale_max_qty": force_sale_max_qty,
"sale_multiple_qty": self.manual_sale_multiple_qty
or self.parent_id.sale_multiple_qty,
}
)
return res
@api.depends(
"parent_id.force_sale_min_qty",
"parent_id.sale_min_qty",
"parent_id.force_sale_max_qty",
"parent_id.sale_max_qty",
"parent_id.sale_multiple_qty",
)
def _compute_sale_restricted_qty(self):
for rec in self:
rec.update(rec._get_sale_restricted_qty())

View file

@ -0,0 +1,51 @@
# Copyright 2019 Akretion
# @author Mourad EL HADJ MIMOUNE <mourad.elhadj.mimoune@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models
class ProductProduct(models.Model):
_name = "product.product"
_inherit = ["product.product", "product.restricted.qty.mixin"]
def _get_sale_restricted_qty(self):
res = super()._get_sale_restricted_qty()
force_sale_min_qty = False
if self.manual_force_sale_min_qty == "force":
force_sale_min_qty = True
elif self.manual_force_sale_min_qty == "not_force":
force_sale_min_qty = False
else:
force_sale_min_qty = self.product_tmpl_id.force_sale_min_qty
force_sale_max_qty = False
if self.manual_force_sale_max_qty == "force":
force_sale_max_qty = True
elif self.manual_force_sale_max_qty == "not_force":
force_sale_max_qty = False
else:
force_sale_max_qty = self.product_tmpl_id.force_sale_max_qty
res.update(
{
"sale_min_qty": self.manual_sale_min_qty
or self.product_tmpl_id.sale_min_qty,
"force_sale_min_qty": force_sale_min_qty,
"sale_max_qty": self.manual_sale_max_qty
or self.product_tmpl_id.sale_max_qty,
"force_sale_max_qty": force_sale_max_qty,
"sale_multiple_qty": self.manual_sale_multiple_qty
or self.product_tmpl_id.sale_multiple_qty,
}
)
return res
@api.depends(
"product_tmpl_id.force_sale_min_qty",
"product_tmpl_id.sale_min_qty",
"product_tmpl_id.force_sale_max_qty",
"product_tmpl_id.sale_max_qty",
"product_tmpl_id.sale_multiple_qty",
)
def _compute_sale_restricted_qty(self):
for rec in self:
rec.update(rec._get_sale_restricted_qty())

View file

@ -0,0 +1,117 @@
# Copyright 2019 Akretion
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class ProductMinMultipleMixin(models.AbstractModel):
_name = "product.restricted.qty.mixin"
_description = "Product Restrict Qty Mixin"
sale_multiple_qty = fields.Float(
compute="_compute_sale_restricted_qty",
store=True,
help="Define sale multiple qty"
" 'If not set', Odoo will"
" use the value defined in the parent object."
"Hierarchy is in this order :"
"Product/product Template/product category/parent categoroies ",
digits="Product Unit of Measure",
)
manual_sale_multiple_qty = fields.Float(
string="Multiple Sale Qty", digits="Product Unit of Measure"
)
sale_min_qty = fields.Float(
compute="_compute_sale_restricted_qty",
store=True,
help="Define sale min qty"
" 'If not set, Odoo will"
" use the value defined in the parent object."
"Hierarchy is in this order :"
"Product/product Template/product category/parent categoroies ",
digits="Product Unit of Measure",
)
manual_sale_min_qty = fields.Float(
string="Min Sale Qty", digits="Product Unit of Measure"
)
force_sale_min_qty = fields.Boolean(
compute="_compute_sale_restricted_qty",
string="Force Min Qty",
store=True,
help="Define if user can force sale min qty"
" 'If not set', Odoo will"
" use the value defined in the parent object."
"Hierarchy is in this order :"
"Product/product Template/product category/parent categoroies ",
)
manual_force_sale_min_qty = fields.Selection(
[
("use_parent", "Use Parent Setting"),
("force", "Yes"),
("not_force", "No"),
],
string="Manual Force Min Qty",
required=True,
default="use_parent",
help="If force min qty is checked, the min quantity "
"is only indicative value."
"If is not test we check parent value",
)
sale_max_qty = fields.Float(
compute="_compute_sale_restricted_qty",
store=True,
help="Define sale max qty"
" 'If not set, Odoo will"
" use the value defined in the parent object."
"Hierarchy is in this order :"
"Product/product Template/product category/parent categoroies ",
digits="Product Unit of Measure",
)
manual_sale_max_qty = fields.Float(
string="Max Sale Qty", digits="Product Unit of Measure"
)
force_sale_max_qty = fields.Boolean(
compute="_compute_sale_restricted_qty",
string="Force Max Qty",
store=True,
help="Define if user can force sale max qty"
" 'If not set', Odoo will"
" use the value defined in the parent object."
"Hierarchy is in this order :"
"Product/product Template/product category/parent categoroies ",
)
manual_force_sale_max_qty = fields.Selection(
[
("use_parent", "Use Parent Setting"),
("force", "Yes"),
("not_force", "No"),
],
required=True,
default="use_parent",
string="Manual Force Max Qty",
help="If force max qty is checked, the max quantity "
"is only indicative value."
"If is not test we check parent value",
)
def _get_sale_restricted_qty(self):
self.ensure_one()
res = {
"sale_min_qty": self.manual_sale_min_qty,
"force_sale_min_qty": self.manual_force_sale_min_qty == "force",
"sale_max_qty": self.manual_sale_max_qty,
"force_sale_max_qty": self.manual_force_sale_max_qty == "force",
"sale_multiple_qty": self.manual_sale_multiple_qty,
}
return res
@api.depends(
"manual_force_sale_min_qty",
"manual_sale_min_qty",
"manual_force_sale_max_qty",
"manual_sale_max_qty",
"manual_sale_multiple_qty",
)
def _compute_sale_restricted_qty(self):
for rec in self:
rec.update(rec._get_sale_restricted_qty())

View file

@ -0,0 +1,49 @@
# Copyright 2019 Akretion
# @author Mourad EL HADJ MIMOUNE <mourad.elhadj.mimoune@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models
class ProductTemplate(models.Model):
_name = "product.template"
_inherit = ["product.template", "product.restricted.qty.mixin"]
def _get_sale_restricted_qty(self):
res = super()._get_sale_restricted_qty()
force_sale_min_qty = False
if self.manual_force_sale_min_qty == "force":
force_sale_min_qty = True
elif self.manual_force_sale_min_qty == "not_force":
force_sale_min_qty = False
else:
force_sale_min_qty = self.categ_id.force_sale_min_qty
force_sale_max_qty = False
if self.manual_force_sale_max_qty == "force":
force_sale_max_qty = True
elif self.manual_force_sale_max_qty == "not_force":
force_sale_max_qty = False
else:
force_sale_max_qty = self.categ_id.force_sale_max_qty
res.update(
{
"sale_min_qty": self.manual_sale_min_qty or self.categ_id.sale_min_qty,
"force_sale_min_qty": force_sale_min_qty,
"sale_max_qty": self.manual_sale_max_qty or self.categ_id.sale_max_qty,
"force_sale_max_qty": force_sale_max_qty,
"sale_multiple_qty": self.manual_sale_multiple_qty
or self.categ_id.sale_multiple_qty,
}
)
return res
@api.depends(
"categ_id.force_sale_min_qty",
"categ_id.sale_min_qty",
"categ_id.force_sale_max_qty",
"categ_id.sale_max_qty",
"categ_id.sale_multiple_qty",
)
def _compute_sale_restricted_qty(self):
for rec in self:
rec.update(rec._get_sale_restricted_qty())

View file

@ -0,0 +1,189 @@
# Copyright 2019 Akretion
# Copyright 2023 Simone Rubino - Aion Tech
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import float_compare
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
sale_min_qty = fields.Float(
string="Min Qty",
compute="_compute_sale_restricted_qty",
store=True,
digits="Product Unit of Measure",
)
force_sale_min_qty = fields.Boolean(
compute="_compute_sale_restricted_qty", readonly=True, store=True
)
is_qty_less_min_qty = fields.Boolean(
string="Qty < Min Qty", compute="_compute_is_qty_less_min_qty"
)
sale_max_qty = fields.Float(
string="Max Qty",
compute="_compute_sale_restricted_qty",
store=True,
digits="Product Unit of Measure",
)
force_sale_max_qty = fields.Boolean(
compute="_compute_sale_restricted_qty", readonly=True, store=True
)
is_qty_bigger_max_qty = fields.Boolean(
string="Qty > max Qty", compute="_compute_is_qty_bigger_max_qty"
)
sale_multiple_qty = fields.Float(
string="Multiple Qty",
compute="_compute_sale_restricted_qty",
store=True,
digits="Product Unit of Measure",
)
is_qty_not_multiple_qty = fields.Boolean(
string="Not Multiple Qty", compute="_compute_is_qty_not_multiple_qty"
)
@api.constrains(
"product_uom_qty", "sale_min_qty", "sale_max_qty", "sale_multiple_qty"
)
def check_constraint_restricted_qty(self):
msg = ""
invaild_min_lines = []
line_to_test = self.filtered(
lambda sl: not sl.product_id.force_sale_min_qty and sl.is_qty_less_min_qty
)
for line in line_to_test:
invaild_min_lines.append(
_(
'Product "%(product)s": Min Quantity %(min_qty)s.',
product=line.product_id.name,
min_qty=line.sale_min_qty,
)
)
if invaild_min_lines:
msg += _(
"Check minimum order quantity for this products: * \n"
) + "\n ".join(invaild_min_lines)
msg += _(
"\n* If you want sell quantity less than Min Quantity"
',Check "force min quatity" on product'
)
invaild_max_lines = []
line_to_test = self.filtered(
lambda sl: not sl.product_id.force_sale_max_qty and sl.is_qty_bigger_max_qty
)
for line in line_to_test:
invaild_max_lines.append(
_(
'Product "%(product)s": max Quantity %(max_qty)s.',
product=line.product_id.name,
max_qty=line.sale_max_qty,
)
)
if invaild_max_lines:
msg += _(
"Check maximum order quantity for this products: * \n"
) + "\n ".join(invaild_max_lines)
msg += _(
"\n* If you want sell quantity bigger than max Quantity"
',Check "force max quatity" on product'
)
invaild_multiple_lines = []
line_to_test = self.filtered(lambda sl: sl.is_qty_not_multiple_qty)
for line in line_to_test:
invaild_multiple_lines.append(
_(
'Product "%(product)s": multiple Quantity %(multiple_qty)s.',
product=line.product_id.name,
multiple_qty=line.sale_multiple_qty,
)
)
if invaild_multiple_lines:
msg += _(
"Check multiple order quantity for this products: * \n"
) + "\n ".join(invaild_multiple_lines)
msg += _(
"\n* If you want sell quantity not multiple Quantity"
",Set multiple quantity to 0 on product or product template"
" or product category"
)
if msg:
raise ValidationError(msg)
def _get_product_qty_in_product_unit(self):
self.ensure_one()
return self.product_uom._compute_quantity(
self.product_uom_qty, self.product_id.uom_id
)
@api.depends("product_id", "product_uom_qty", "sale_min_qty")
def _compute_is_qty_less_min_qty(self):
for line in self:
rounding = line.product_uom.rounding
product_qty = line._get_product_qty_in_product_unit()
line.is_qty_less_min_qty = (
line.sale_min_qty
and (
float_compare(
product_qty, line.sale_min_qty, precision_rounding=rounding
)
< 0
)
or False
)
@api.depends("product_id", "product_uom_qty", "sale_max_qty")
def _compute_is_qty_bigger_max_qty(self):
for line in self:
rounding = line.product_uom.rounding
product_qty = line._get_product_qty_in_product_unit()
line.is_qty_bigger_max_qty = (
line.sale_max_qty
and (
float_compare(
product_qty, line.sale_max_qty, precision_rounding=rounding
)
> 0
)
or False
)
@api.depends("product_id", "product_uom_qty", "sale_multiple_qty")
def _compute_is_qty_not_multiple_qty(self):
for line in self:
product_qty = line.product_uom._compute_quantity(
line.product_uom_qty, line.product_id.uom_id
)
line.is_qty_not_multiple_qty = (
line.sale_multiple_qty > 0 and product_qty % line.sale_multiple_qty != 0
)
def _get_sale_restricted_qty(self):
"""Overridable function to change qty values (ex: form stock)"""
self.ensure_one()
res = {
"sale_min_qty": (self.product_id and self.product_id.sale_min_qty or 0),
"force_sale_min_qty": (
self.product_id and self.product_id.force_sale_min_qty or False
),
"sale_max_qty": (self.product_id and self.product_id.sale_max_qty or 0),
"force_sale_max_qty": (
self.product_id and self.product_id.force_sale_max_qty or False
),
"sale_multiple_qty": (
self.product_id and self.product_id.sale_multiple_qty or 0
),
}
return res
@api.depends("product_id")
def _compute_sale_restricted_qty(self):
for rec in self:
rec.update(rec._get_sale_restricted_qty())

View file

@ -0,0 +1,8 @@
* Mourad EL HADJ MIMOUN <mourad.elhadj.mimoune@akretion.com>
* `Ooops <https://www.ooops404.com/>`_:
* Ashish Hirpara <https://ashish-hirpara.com>
* `Aion Tech <https://aiontech.company/>`_:
* Simone Rubino <simone.rubino@aion-tech.it>

View file

@ -0,0 +1,13 @@
This module allows to define min, max and multiple order quantity on product.
Min and Max order quantity is either required or recommanded.
If you check "Force mini/max Qty" on product the min/max qty do not block sale
order.
This can be used if the available stock is less then the min qty
or if you want to sell sample products.
Max qty can be used if we dont want to sale more than available qty
(end of series product)
Setings are defined on product, if values are not set we use settings from
product template.
If settings are not set on product template we use settings from
product category otherwise parent category.

View file

@ -0,0 +1,7 @@
#. Go to **Sales > Products > Product Variants** and Set "Min Sale Qty".
If you dont want block product sale if qty is less the "Min Sale Qty",
chek "Force Min Qty"
#. Create a sale order and add a sale order line with this product and check
if Qty is less then "Min Qty" A message in displayed "Min Qty Required"
Or "Min Qty Recommanded". Check if Min qty is required you can't
validate order.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -0,0 +1,461 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Sale order min quantity</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="sale-order-min-quantity">
<h1 class="title">Sale order min quantity</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:11c109b03c7404989c3814a5675fcc5ae0cb3088674059b409bc202355156177
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/sale-workflow/tree/16.0/sale_restricted_qty"><img alt="OCA/sale-workflow" src="https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sale-workflow-16-0/sale-workflow-16-0-sale_restricted_qty"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows to define min, max and multiple order quantity on product.
Min and Max order quantity is either required or recommanded.
If you check “Force mini/max Qty” on product the min/max qty do not block sale
order.
This can be used if the available stock is less then the min qty
or if you want to sell sample products.
Max qty can be used if we dont want to sale more than available qty
(end of series product)</p>
<p>Setings are defined on product, if values are not set we use settings from
product template.
If settings are not set on product template we use settings from
product category otherwise parent category.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<ol class="arabic simple">
<li><dl class="first docutils">
<dt>Go to <strong>Sales &gt; Products &gt; Product Variants</strong> and Set “Min Sale Qty”.</dt>
<dd>If you dont want block product sale if qty is less the “Min Sale Qty”,
chek “Force Min Qty”</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>Create a sale order and add a sale order line with this product and check</dt>
<dd>if Qty is less then “Min Qty” A message in displayed “Min Qty Required”
Or “Min Qty Recommanded”. Check if Min qty is required you cant
validate order.</dd>
</dl>
</li>
</ol>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/sale-workflow/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_restricted_qty%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
<ul class="simple">
<li>Akretion</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li>Mourad EL HADJ MIMOUN &lt;<a class="reference external" href="mailto:mourad.elhadj.mimoune&#64;akretion.com">mourad.elhadj.mimoune&#64;akretion.com</a>&gt;</li>
<li><a class="reference external" href="https://www.ooops404.com/">Ooops</a>:<ul>
<li>Ashish Hirpara &lt;<a class="reference external" href="https://ashish-hirpara.com">https://ashish-hirpara.com</a>&gt;</li>
</ul>
</li>
<li><a class="reference external" href="https://aiontech.company/">Aion Tech</a>:<ul>
<li>Simone Rubino &lt;<a class="reference external" href="mailto:simone.rubino&#64;aion-tech.it">simone.rubino&#64;aion-tech.it</a>&gt;</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/ashishhirapara"><img alt="ashishhirapara" src="https://github.com/ashishhirapara.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/sale-workflow/tree/16.0/sale_restricted_qty">OCA/sale-workflow</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1 @@
from . import test_sale

View file

@ -0,0 +1,189 @@
# Copyright 2019 Akretion
# Update (Migration) 2022 Ooops - Ashish Hirpara <hello@ashish-hirpara.com>
# Copyright 2023 Simone Rubino - Aion Tech
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import odoo.tests.common as common
from odoo.exceptions import ValidationError
from odoo.tests import tagged
@tagged("post_install", "-at_install")
class TestSaleOrderLineMinQty(common.TransactionCase):
def setUp(self):
super(TestSaleOrderLineMinQty, self).setUp()
# Create models
self.sale_order_model = self.env["sale.order"]
self.sale_order_line_model = self.env["sale.order.line"]
self.partner_model = self.env["res.partner"]
self.product_categ_model = self.env["product.category"]
self.product_model = self.env["product.product"]
self.sale_order = self.sale_order_model
# Create partner and product
self.partner = self.partner_model.create({"name": "Test partner"})
self.categ_parent = self.product_categ_model.create(
{
"name": "Test Parent categ",
"manual_sale_min_qty": 10.0,
"manual_force_sale_min_qty": "use_parent",
"manual_sale_max_qty": 100.0,
"manual_force_sale_max_qty": "use_parent",
"manual_sale_multiple_qty": 5.0,
}
)
self.categ = self.product_categ_model.create(
{
"name": "Test categ",
"parent_id": self.categ_parent.id,
"manual_force_sale_min_qty": "use_parent",
"manual_force_sale_max_qty": "use_parent",
}
)
self.product = self.product_model.create(
{
"name": "Test product",
"force_sale_min_qty": False,
"force_sale_max_qty": False,
}
)
def test_check_sale_order_min_qty_required(self):
line_values = {"product_id": self.product.id, "product_uom_qty": 5.0}
self.product.manual_sale_min_qty = 10
# Create sale order line with Qty less than min Qty
with self.assertRaises(ValidationError):
self.sale_order_model.create(
{
"partner_id": self.partner.id,
"order_line": [(0, 0, line_values)],
"pricelist_id": 1,
}
)
line_values["product_uom_qty"] = 12.0
# Create sale order line with Qty great then min Qty
self.sale_order = self.sale_order_model.create(
{"partner_id": self.partner.id, "order_line": [(0, 0, line_values)]}
)
self.sale_order.order_line._compute_sale_restricted_qty()
self.assertFalse(self.sale_order.order_line.is_qty_less_min_qty)
self.assertEqual(self.sale_order.order_line.product_uom_qty, 12.0)
def test_check_sale_order_min_qty_recommended(self):
line_values = {"product_id": self.product.id, "product_uom_qty": 5.0}
self.product.manual_sale_min_qty = 10
# Set Force min Qty to true
self.product.manual_force_sale_min_qty = "force"
# Create sale order line with Qty less than min Qty
self.sale_order = self.sale_order_model.create(
{"partner_id": self.partner.id, "order_line": [(0, 0, line_values)]}
)
self.sale_order.order_line._compute_sale_restricted_qty()
self.assertTrue(self.sale_order.order_line.is_qty_less_min_qty)
self.assertEqual(self.sale_order.order_line.product_uom_qty, 5.0)
def test_check_sale_order_max_qty_required(self):
line_values = {"product_id": self.product.id, "product_uom_qty": 15.0}
self.product.manual_sale_max_qty = 10
# Create sale order line with Qty bigger than max Qty
with self.assertRaises(ValidationError):
sale_order = self.sale_order_model.create(
{"partner_id": self.partner.id, "order_line": [(0, 0, line_values)]}
)
sale_values = self.refrech_sale_values(sale_order)
self.sale_order_model.create(sale_values)
line_values["product_uom_qty"] = 2.0
# Create sale order line with Qty great then max Qty
self.sale_order = self.sale_order_model.create(
{"partner_id": self.partner.id, "order_line": [(0, 0, line_values)]}
)
self.sale_order.order_line._compute_sale_restricted_qty()
self.assertFalse(self.sale_order.order_line.is_qty_bigger_max_qty)
self.assertEqual(self.sale_order.order_line.product_uom_qty, 2.0)
def test_check_sale_order_max_qty_recommended(self):
line_values = {"product_id": self.product.id, "product_uom_qty": 15.0}
self.product.manual_sale_max_qty = 10
# Set Force max Qty to true
self.product.manual_force_sale_max_qty = "force"
# Create sale order line with Qty bigger than max Qty
self.sale_order = self.sale_order_model.create(
{"partner_id": self.partner.id, "order_line": [(0, 0, line_values)]}
)
self.sale_order.order_line._compute_sale_restricted_qty()
self.assertTrue(self.sale_order.order_line.is_qty_bigger_max_qty)
self.assertEqual(self.sale_order.order_line.product_uom_qty, 15.0)
def test_check_sale_order_multiple_qty_required(self):
line_values = {"product_id": self.product.id, "product_uom_qty": 15.0}
self.product.manual_sale_min_qty = 10
self.product.manual_sale_multiple_qty = 10
# Create sale order line with Qty not multiple Qty
with self.assertRaises(ValidationError):
sale_order = self.sale_order_model.create(
{"partner_id": self.partner.id, "order_line": [(0, 0, line_values)]}
)
sale_values = self.refrech_sale_values(sale_order)
self.sale_order_model.create(sale_values)
line_values["product_uom_qty"] = 20
# Create sale order line with Qty multiple Qty
self.sale_order = self.sale_order_model.create(
{"partner_id": self.partner.id, "order_line": [(0, 0, line_values)]}
)
self.sale_order.order_line._compute_sale_restricted_qty()
self.assertFalse(self.sale_order.order_line.is_qty_not_multiple_qty)
self.assertEqual(self.sale_order.order_line.product_uom_qty, 20)
def test_check_restricted_qty_category_hierarchy(self):
# Check Restricted Qty from parent category
self.product.categ_id = self.categ
self.assertEqual(self.product.manual_sale_min_qty, 0)
self.assertEqual(self.product.manual_sale_multiple_qty, 0)
self.product.categ_id.parent_id._compute_sale_restricted_qty()
self.assertEqual(self.product.sale_min_qty, 10)
self.assertEqual(self.product.sale_max_qty, 100)
self.assertEqual(self.product.sale_multiple_qty, 5)
self.categ_parent.manual_force_sale_min_qty = "force"
self.assertEqual(self.product.manual_force_sale_min_qty, "use_parent")
self.assertEqual(self.product.force_sale_min_qty, True)
# Check Restricted Qty from category
self.categ.manual_sale_min_qty = 15
self.categ.manual_sale_multiple_qty = 10
self.categ.manual_force_sale_min_qty = "not_force"
self.assertEqual(self.product.sale_min_qty, 15)
self.assertEqual(self.product.sale_multiple_qty, 10)
self.assertEqual(self.product.force_sale_min_qty, False)
self.categ.manual_sale_max_qty = 200
self.categ.manual_force_sale_max_qty = "not_force"
self.assertEqual(self.product.sale_max_qty, 200)
self.assertEqual(self.product.force_sale_max_qty, False)
def test_check_restricted_qty_tmpl_hierarchy(self):
# Check Restricted from product template
self.product.product_tmpl_id.manual_sale_min_qty = 20
self.product.product_tmpl_id.manual_sale_max_qty = 250
self.product.product_tmpl_id.manual_sale_multiple_qty = 30
self.product.product_tmpl_id._compute_sale_restricted_qty()
self.assertEqual(self.product.manual_sale_min_qty, 0)
self.assertEqual(self.product.sale_min_qty, 20)
self.assertEqual(self.product.manual_sale_max_qty, 0)
self.assertEqual(self.product.sale_max_qty, 250)
self.assertEqual(self.product.manual_sale_multiple_qty, 0)
self.assertEqual(self.product.sale_multiple_qty, 30)
# Check Restricted Qty from product
self.product.manual_sale_min_qty = 25
self.product.manual_sale_max_qty = 150
self.product.manual_sale_multiple_qty = 25
self.assertEqual(self.product.sale_min_qty, 25)
self.assertEqual(self.product.sale_max_qty, 150)
self.assertEqual(self.product.sale_multiple_qty, 25)

View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_product_category_form" model="ir.ui.view">
<field name="model">product.category</field>
<field name="inherit_id" ref="product.product_category_form_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='first']" position="after">
<group
name="sale_restricted_qty"
string="Sale restricted qty"
colspan="4"
>
<group name="sale_min_qty_gr" string="Sale Min qty">
<field name="sale_min_qty" />
<label for="manual_sale_min_qty" class="oe_edit_only" />
<field
name="manual_sale_min_qty"
class="oe_edit_only"
nolabel="1"
/>
<field name="force_sale_min_qty" />
<label for="manual_force_sale_min_qty" class="oe_edit_only" />
<field
name="manual_force_sale_min_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
<group name="sale_max_qty_gr" string="Sale Max qty">
<field name="sale_max_qty" />
<label for="manual_sale_max_qty" class="oe_edit_only" />
<field
name="manual_sale_max_qty"
class="oe_edit_only"
nolabel="1"
/>
<field name="force_sale_max_qty" />
<label for="manual_force_sale_max_qty" class="oe_edit_only" />
<field
name="manual_force_sale_max_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
<group name="sale_multiple_qty_gr" string="Sale Miltiple qty">
<field name="sale_multiple_qty" />
<label for="manual_sale_multiple_qty" class="oe_edit_only" />
<field
name="manual_sale_multiple_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
</group>
</xpath>
</field>
</record>
</odoo>

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
~ Copyright 2023 Simone Rubino - Aion Tech
~ License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="min_order_qty_product_product_form_view" model="ir.ui.view">
<field name="name">product.product.form</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view" />
<field name="arch" type="xml">
<xpath expr="//page[@name='sales']/group[@name='sale']" position="after">
<group
name="sale_restricted_qty"
string="Sale restricted qty"
colspan="4"
>
<group name="sale_min_qty_gr" string="Sale Min qty">
<field name="sale_min_qty" />
<label for="manual_sale_min_qty" class="oe_edit_only" />
<field
name="manual_sale_min_qty"
class="oe_edit_only"
nolabel="1"
/>
<field name="force_sale_min_qty" />
<label for="manual_force_sale_min_qty" class="oe_edit_only" />
<field
name="manual_force_sale_min_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
<group name="sale_max_qty_gr" string="Sale Max qty">
<field name="sale_max_qty" />
<label for="manual_sale_max_qty" class="oe_edit_only" />
<field
name="manual_sale_max_qty"
class="oe_edit_only"
nolabel="1"
/>
<field name="force_sale_max_qty" />
<label for="manual_force_sale_max_qty" class="oe_edit_only" />
<field
name="manual_force_sale_max_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
<group name="sale_multiple_qty_gr" string="Sale Miltiple qty">
<field name="sale_multiple_qty" />
<label for="manual_sale_multiple_qty" class="oe_edit_only" />
<field
name="manual_sale_multiple_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
</group>
</xpath>
</field>
</record>
</odoo>

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_product_template_form" model="ir.ui.view">
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="arch" type="xml">
<group name="description" position="before">
<group
name="sale_restricted_qty"
string="Sale restricted qty"
colspan="4"
>
<group name="sale_min_qty_gr" string="Sale Min qty">
<field name="sale_min_qty" />
<label for="manual_sale_min_qty" class="oe_edit_only" />
<field
name="manual_sale_min_qty"
class="oe_edit_only"
nolabel="1"
/>
<field name="force_sale_min_qty" />
<label for="manual_force_sale_min_qty" class="oe_edit_only" />
<field
name="manual_force_sale_min_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
<group name="sale_max_qty_gr" string="Sale Max qty">
<field name="sale_max_qty" />
<label for="manual_sale_max_qty" class="oe_edit_only" />
<field
name="manual_sale_max_qty"
class="oe_edit_only"
nolabel="1"
/>
<field name="force_sale_max_qty" />
<label for="manual_force_sale_max_qty" class="oe_edit_only" />
<field
name="manual_force_sale_max_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
<group name="sale_multiple_qty_gr" string="Sale Miltiple qty">
<field name="sale_multiple_qty" />
<label for="manual_sale_multiple_qty" class="oe_edit_only" />
<field
name="manual_sale_multiple_qty"
class="oe_edit_only"
nolabel="1"
/>
</group>
</group>
</group>
</field>
</record>
</odoo>

View file

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2019 Akretion
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_order_form" model="ir.ui.view">
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form" />
<field name="arch" type="xml">
<xpath
expr="//field[@name='order_line']/form//field[@name='price_unit']"
position="after"
>
<field name="sale_min_qty" />
<field name="sale_multiple_qty" />
<field name="is_qty_less_min_qty" invisible="1" />
<field name="force_sale_min_qty" invisible="1" />
<field name="sale_max_qty" />
<field name="is_qty_bigger_max_qty" invisible="1" />
<field name="force_sale_max_qty" invisible="1" />
<field name="is_qty_not_multiple_qty" invisible="1" />
<label
colspan="2"
for="sale_min_qty"
string="Min Quantity Recommended"
attrs="{'invisible': ['|', ('is_qty_less_min_qty','=', False),
'&amp;', ('is_qty_less_min_qty','=', True), ('force_sale_min_qty','=', False,)]}"
style="background-color:yellow"
/>
<label
colspan="2"
for="sale_min_qty"
string="Min Quantity Required"
attrs="{'invisible': ['|', ('is_qty_less_min_qty','=', False),
'&amp;', ('is_qty_less_min_qty','=', True), ('force_sale_min_qty','=', True,)]}"
style="background-color:red"
/>
<label
colspan="2"
for="sale_min_qty"
string="Multiple Quantity Required"
attrs="{'invisible': [('is_qty_not_multiple_qty','=', False)]}"
style="background-color:red"
/>
<label
colspan="2"
for="sale_min_qty"
string="Max Quantity Recommended"
attrs="{'invisible': ['|', ('is_qty_bigger_max_qty','=', False),
'&amp;', ('is_qty_bigger_max_qty','=', True), ('force_sale_max_qty','=', False,)]}"
style="background-color:yellow"
/>
<label
colspan="2"
for="sale_min_qty"
string="Max Quantity Exceeded"
attrs="{'invisible': ['|', ('is_qty_bigger_max_qty','=', True),
'&amp;', ('is_qty_bigger_max_qty','=', True), ('force_sale_max_qty','=', True,)]}"
style="background-color:red"
/>
</xpath>
<xpath
expr="//field[@name='order_line']/tree/field[@name='product_uom_qty']"
position="after"
>
<field name="sale_min_qty" optional="hide" />
<field name="is_qty_less_min_qty" invisible="1" />
<field name="force_sale_min_qty" invisible="1" />
<field name="sale_max_qty" optional="hide" />
<field name="is_qty_bigger_max_qty" invisible="1" />
<field name="force_sale_max_qty" invisible="1" />
<field name="is_qty_not_multiple_qty" invisible="1" />
</xpath>
<xpath expr="//field[@name='order_line']/tree" position="attributes">
<attribute
name="decoration-danger"
>is_qty_less_min_qty == True and force_sale_min_qty == False</attribute>
<attribute
name="decoration-warning"
>is_qty_less_min_qty == True and force_sale_min_qty == True</attribute>
<attribute
name="decoration-danger"
>is_qty_bigger_max_qty == True and force_sale_max_qty == False</attribute>
<attribute
name="decoration-warning"
>is_qty_bigger_max_qty == True and force_sale_max_qty == True</attribute>
<attribute
name="decoration-danger"
>is_qty_not_multiple_qty == True</attribute>
</xpath>
</field>
</record>
</odoo>