Add oca-purchase submodule with 96 purchase modules moved from oca-workflow-process

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ernad Husremovic 2025-08-30 18:00:40 +02:00
parent b0628ee8ea
commit 7378b233e9
3994 changed files with 334316 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# Purchase Delivery Split Date
Odoo addon: purchase_delivery_split_date
## Installation
```bash
pip install odoo-bringout-oca-purchase-workflow-purchase_delivery_split_date
```
## Dependencies
This addon depends on:
- purchase_stock
## Manifest Information
- **Name**: Purchase Delivery Split Date
- **Version**: 16.0.1.0.4
- **Category**: Purchase Management
- **License**: AGPL-3
- **Installable**: True
## Source
Based on [OCA/purchase-workflow](https://github.com/OCA/purchase-workflow) branch 16.0, addon `purchase_delivery_split_date`.
## 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 Purchase_delivery_split_date Module - purchase_delivery_split_date
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 purchase_delivery_split_date. 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:
- [purchase_stock](https://github.com/bringout/oca-ocb-warehouse/tree/0ee5ffef60413a71dceb350918ad3fb572ec1875/odoo-bringout-oca-ocb-purchase_stock)

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 purchase_delivery_split_date or install in UI.

View file

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

View file

@ -0,0 +1,14 @@
# Models
Detected core models and extensions in purchase_delivery_split_date.
```mermaid
classDiagram
class purchase_order
class purchase_order_line
class stock_picking
```
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: purchase_delivery_split_date. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon purchase_delivery_split_date
- 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 purchase_delivery_split_date
```

View file

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

View file

@ -0,0 +1,133 @@
============================
Purchase Delivery Split Date
============================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:3e3f54ca15929d813a29aa8e331f10ab492c9349d06311d262f01100a8ba5a89
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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%2Fpurchase--workflow-lightgray.png?logo=github
:target: https://github.com/OCA/purchase-workflow/tree/16.0/purchase_delivery_split_date
:alt: OCA/purchase-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/purchase-workflow-16-0/purchase-workflow-16-0-purchase_delivery_split_date
: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/purchase-workflow&target_branch=16.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
When this module is installed, each Purchase Order you confirm will
generate one Incoming Shipment for each schedule date indicated in the
Purchase Order Lines.
Once the Purchase Order has been confirmed, subsequent changes made to the
scheduled dates in the PO lines will produce a reorganization of the
corresponding stock moves in the Incoming Shipments, creating/deleting new
Incoming Shipments when needed, to ensure that each Incoming Shipment
contains moves to be received in the same date.
This module is also designed for extensibility, so that you can define
in other modules new criteria to split deliveries.
**Table of contents**
.. contents::
:local:
Usage
=====
When a Purchase Order is confirmed, shipments will be grouped by same scheduled date.
Changelog
=========
12.0.2.1.0 (2020-04-30)
~~~~~~~~~~~~~~~~~~~~~~~
* [FIX] when adding a new line on a confirmed PO, split the delivery (this was
done only if a date was changed on an existing line)
* [IMP] when the quantity on a line is changed, the onchange would reset the
planned date -> change this to prevent setting a date earlier than the one on
the line, since if we are using this module the user probably has manually
set the date first
12.0.2.0.0 (2020-04-10)
~~~~~~~~~~~~~~~~~~~~~~~
* Improve the module: when changing the date on a purchase line, this will
cause a split or a merge of the pickings, to keep 1 picking per date.
11.0.1.0.0 (2018-09-16)
~~~~~~~~~~~~~~~~~~~~~~~
* Migration to 11.0.
(`#461 <https://github.com/OCA/purchase-workflow/issues/461>`_)
* When the scheduled date is changed in the PO after confirmation the
pickings are reorganized so as to force that every picking will have only
moves to be delivered on the same date.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/purchase-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/purchase-workflow/issues/new?body=module:%20purchase_delivery_split_date%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
~~~~~~~
* Numerigraphe
* ForgeFlow
* Camptocamp
Contributors
~~~~~~~~~~~~
* Philippe Rossi <pr@numerigraphe.com> (initial patch against v6.0)
* Lionel Sausin <ls@numerigraphe.com> (modularization for v7+)
* Jordi Ballester Alomar <jordi.ballester@forgeflow.com> (modularization v8, v9)
* Lois Rilo <lois.rilo@forgeflow.com> (migration to v10)
* Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
* Pimolnat Suntian <pimolnats@ecosoft.co.th>
* Mallory Marcot <contact@mallory-marcot.com>
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.
This module is part of the `OCA/purchase-workflow <https://github.com/OCA/purchase-workflow/tree/16.0/purchase_delivery_split_date>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View file

@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import models

View file

@ -0,0 +1,17 @@
# Copyright 2014-2016 Numérigraphe SARL
# Copyright 2017 ForgeFlow, S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Purchase Delivery Split Date",
"version": "16.0.1.0.4",
"summary": "Allows Purchase Order you confirm to generate one Incoming "
"Shipment for each expected date indicated in the Purchase Order Lines",
"author": "Numerigraphe, ForgeFlow, Camptocamp, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/purchase-workflow",
"category": "Purchase Management",
"license": "AGPL-3",
"depends": ["purchase_stock"],
"installable": True,
"application": False,
}

View file

@ -0,0 +1,29 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
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: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr "Stavka naloga za nabavu"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Stavka naloga za nabavu"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transfer"

View file

@ -0,0 +1,34 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2017-02-24 13:09+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n"
"Language: ca\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"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr ""
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr ""
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transferència"

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
# Rudolf Schnapka <rs@techno-flex.de>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2020-07-22 12:19+0000\n"
"Last-Translator: c2cdidier <didier.donze@camptocamp.com>\n"
"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n"
"Language: de\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 3.10\n"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr "Bestellung"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Bestellposition"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transfer"

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
# Pedro M. Baeza <pedro.baeza@gmail.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2023-07-20 10:15+0000\n"
"Last-Translator: Ivorra78 <informatica@totmaterial.es>\n"
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n"
"Language: es\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: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr "orden de compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Línea orden de compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transferir"

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# Juan González <bifomania@protonmail.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2017-02-24 13:09+0000\n"
"Last-Translator: Juan González <bifomania@protonmail.com>, 2017\n"
"Language-Team: Spanish (Mexico) (https://www.transifex.com/oca/teams/23907/"
"es_MX/)\n"
"Language: es_MX\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"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "Línea de orden de compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Línea de orden de compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr ""

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# Henry Garcia <henry@yaroslab.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-07-15 06:42+0000\n"
"PO-Revision-Date: 2017-07-15 06:42+0000\n"
"Last-Translator: Henry Garcia <henry@yaroslab.com>, 2017\n"
"Language-Team: Spanish (Peru) (https://www.transifex.com/oca/teams/23907/"
"es_PE/)\n"
"Language: es_PE\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"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "Linea de orden de compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Linea de orden de compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transferir"

View file

@ -0,0 +1,35 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# Timo Talvitie <timo.talvitie@vizucom.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-02 12:10+0000\n"
"PO-Revision-Date: 2017-03-02 12:10+0000\n"
"Last-Translator: Timo Talvitie <timo.talvitie@vizucom.com>, 2017\n"
"Language-Team: Finnish (https://www.transifex.com/oca/teams/23907/fi/)\n"
"Language: fi\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"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "Ostotilausrivi"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Ostotilausrivi"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr ""

View file

@ -0,0 +1,35 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2020-07-22 12:19+0000\n"
"Last-Translator: c2cdidier <didier.donze@camptocamp.com>\n"
"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\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 3.10\n"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr "Commande d'achat"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Ligne de commande d'achat"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transférer"

View file

@ -0,0 +1,34 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2017-02-24 13:09+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n"
"Language: gl\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"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr ""
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr ""
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transferencia"

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# Bole <bole@dajmi5.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-07-11 12:52+0000\n"
"PO-Revision-Date: 2017-07-11 12:52+0000\n"
"Last-Translator: Bole <bole@dajmi5.com>, 2017\n"
"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n"
"Language: hr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "Stavka naloga za nabavu"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Stavka naloga za nabavu"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transfer"

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
# Paolo Valier <paolo.valier@hotmail.it>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2023-12-20 15:38+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\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: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr "Ordine di acquisto"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Riga ordine di acquisto"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Trasferimento"

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# Peter Hageman <hageman.p@gmail.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-22 02:44+0000\n"
"PO-Revision-Date: 2017-06-22 02:44+0000\n"
"Last-Translator: Peter Hageman <hageman.p@gmail.com>, 2017\n"
"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/"
"teams/23907/nl_NL/)\n"
"Language: nl_NL\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"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "Inkooporderregel"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Inkooporderregel"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Verplaatsen"

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2022-10-03 15:53+0000\n"
"Last-Translator: Douglas Custódio <douglascstd@yahoo.com>\n"
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/"
"teams/23907/pt_BR/)\n"
"Language: pt_BR\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.3.2\n"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr "Pedido de Compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Linha do Pedido de Compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Transferir"

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# Pedro Castro Silva <pedrocs@sossia.pt>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2017-02-24 13:09+0000\n"
"Last-Translator: Pedro Castro Silva <pedrocs@sossia.pt>, 2017\n"
"Language-Team: Portuguese (Portugal) (https://www.transifex.com/oca/"
"teams/23907/pt_PT/)\n"
"Language: pt_PT\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"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "Linha de Encomenda de Compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Linha de Encomenda de Compra"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr ""

View file

@ -0,0 +1,29 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
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: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
msgid "Purchase Order"
msgstr ""
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr ""
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr ""

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# Dorin Hongu <dhongu@gmail.com>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2017-02-24 13:09+0000\n"
"Last-Translator: Dorin Hongu <dhongu@gmail.com>, 2017\n"
"Language-Team: Romanian (https://www.transifex.com/oca/teams/23907/ro/)\n"
"Language: ro\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?"
"2:1));\n"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "Linie comandă achiziție"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Linie comandă achiziție"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr ""

View file

@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 13:09+0000\n"
"PO-Revision-Date: 2017-02-24 13:09+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n"
"Language: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3);\n"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "Postavka nabavnega naloga"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Postavka nabavnega naloga"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "Premestitev"

View file

@ -0,0 +1,33 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_delivery_split_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2019-09-01 16:00+0000\n"
"Last-Translator: 黎伟杰 <674416404@qq.com>\n"
"Language-Team: none\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 3.8\n"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order
#, fuzzy
msgid "Purchase Order"
msgstr "采购订单行"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "采购订单行"
#. module: purchase_delivery_split_date
#: model:ir.model,name:purchase_delivery_split_date.model_stock_picking
msgid "Transfer"
msgstr "调拨"

View file

@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import purchase_order, purchase_order_line, stock_picking

View file

@ -0,0 +1,58 @@
# Copyright 2014-2016 Numérigraphe SARL
# Copyright 2017 ForgeFlow, S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from itertools import groupby
from odoo import fields, models
class PurchaseOrder(models.Model):
_inherit = "purchase.order"
def _check_split_pickings(self):
# Avoid one search query per order
purchases_moves = self.env["stock.move"].search(
[
("purchase_line_id", "in", self.order_line.ids),
("state", "not in", ("cancel", "done")),
]
)
for order in self:
moves = purchases_moves.filtered(
lambda move: move.purchase_line_id.id in order.order_line.ids
)
pickings = moves.mapped("picking_id")
pickings_by_date = {}
for pick in pickings:
pickings_by_date[pick.scheduled_date.date()] = pick
order_lines = moves.mapped("purchase_line_id")
date_groups = groupby(
order_lines, lambda l: l._get_group_keys(l.order_id, l)
)
for key, lines in date_groups:
date_key = fields.Date.from_string(key[0]["date_planned"])
for line in lines:
for move in line.move_ids:
if move.state in ("cancel", "done"):
continue
if (
move.picking_id.scheduled_date.date() != date_key
or pickings_by_date.get(date_key) != move.picking_id
):
if date_key not in pickings_by_date:
copy_vals = line._first_picking_copy_vals(key, line)
new_picking = move.picking_id.sudo().copy(copy_vals)
pickings_by_date[date_key] = new_picking
move._do_unreserve()
move.update(
{
"picking_id": pickings_by_date[date_key],
"date_deadline": date_key,
}
)
move._action_assign()
pickings.filtered(lambda picking: not picking.move_ids).write(
{"state": "cancel"}
)

View file

@ -0,0 +1,109 @@
# Copyright 2014-2016 Numérigraphe SARL
# Copyright 2017 ForgeFlow, S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from itertools import groupby
from odoo import api, fields, models
class PurchaseOrderLine(models.Model):
_inherit = "purchase.order.line"
@api.model
def _get_group_keys(self, order, line, picking=False):
"""Define the key that will be used to group. The key should be
defined as a tuple of dictionaries, with each element containing a
dictionary element with the field that you want to group by. This
method is designed for extensibility, so that other modules can add
additional keys or replace them by others."""
date = fields.Date.context_today(self.env.user, line.date_planned)
# Split date value to obtain only the attributes year, month and day
key = ({"date_planned": fields.Date.to_string(date)},)
return key
@api.model
def _first_picking_copy_vals(self, key, lines):
"""The data to be copied to new pickings is updated with data from the
grouping key. This method is designed for extensibility, so that
other modules can store more data based on new keys."""
vals = {"move_ids": []}
for key_element in key:
if "date_planned" in key_element.keys():
vals["scheduled_date"] = key_element["date_planned"]
return vals
def _get_sorted_keys(self, line):
"""Return a tuple of keys to use in order to sort the order lines.
This method is designed for extensibility, so that other modules can
add additional keys or replace them by others."""
return (line.date_planned,)
def _create_stock_moves(self, picking):
"""Group the receptions in one picking per group key"""
moves = self.env["stock.move"]
# Group the order lines by group key
order_lines = sorted(
self.filtered(
lambda l: not l.display_type
and l.product_id.type in ["product", "consu"]
),
key=lambda l: self._get_sorted_keys(l),
)
date_groups = groupby(
order_lines, lambda l: self._get_group_keys(l.order_id, l, picking=picking)
)
first_picking = False
# If a picking is provided, use it for the first group only
if picking:
first_picking = picking
key, lines = next(date_groups)
po_lines = self.env["purchase.order.line"]
for line in list(lines):
po_lines += line
picking._update_picking_from_group_key(key)
moves += super(PurchaseOrderLine, po_lines)._create_stock_moves(
first_picking
)
for key, lines in date_groups:
# If a picking is provided, clone it for each key for modularity
if picking:
copy_vals = self._first_picking_copy_vals(key, lines)
picking = first_picking.sudo().copy(copy_vals)
po_lines = self.env["purchase.order.line"]
for line in list(lines):
po_lines += line
moves += super(PurchaseOrderLine, po_lines)._create_stock_moves(picking)
return moves
def write(self, values):
res = super().write(values)
if "date_planned" in values:
self.mapped("order_id")._check_split_pickings()
return res
def create(self, values):
line = super().create(values)
if line.order_id.state == "purchase":
line.order_id._check_split_pickings()
return line
def _compute_price_unit_and_date_planned_and_name(self):
"""
If the line product quantity is changed and a seller is found,
the date_planned is updated from the supplier (in _get_date_planned())
"""
date_planned_by_record = dict()
for line in self:
date_planned_by_record[line.id] = line.date_planned
res = super()._compute_price_unit_and_date_planned_and_name()
for line in self:
if (
date_planned_by_record[line.id]
and line.date_planned <= date_planned_by_record[line.id]
):
line.date_planned = date_planned_by_record[line.id]
return res

View file

@ -0,0 +1,19 @@
# Copyright 2014-2016 Numérigraphe SARL
# Copyright 2017 ForgeFlow, S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import models
class StockPicking(models.Model):
_inherit = "stock.picking"
def _update_picking_from_group_key(self, key):
"""The picking is updated with data from the grouping key.
This method is designed for extensibility, so that other modules
can store more data based on new keys."""
for rec in self:
for key_element in key:
if "date_planned" in key_element.keys():
rec.scheduled_date = key_element["date_planned"]
return False

View file

@ -0,0 +1,8 @@
* Philippe Rossi <pr@numerigraphe.com> (initial patch against v6.0)
* Lionel Sausin <ls@numerigraphe.com> (modularization for v7+)
* Jordi Ballester Alomar <jordi.ballester@forgeflow.com> (modularization v8, v9)
* Lois Rilo <lois.rilo@forgeflow.com> (migration to v10)
* Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
* Pimolnat Suntian <pimolnats@ecosoft.co.th>
* Mallory Marcot <contact@mallory-marcot.com>

View file

@ -0,0 +1,13 @@
When this module is installed, each Purchase Order you confirm will
generate one Incoming Shipment for each schedule date indicated in the
Purchase Order Lines.
Once the Purchase Order has been confirmed, subsequent changes made to the
scheduled dates in the PO lines will produce a reorganization of the
corresponding stock moves in the Incoming Shipments, creating/deleting new
Incoming Shipments when needed, to ensure that each Incoming Shipment
contains moves to be received in the same date.
This module is also designed for extensibility, so that you can define
in other modules new criteria to split deliveries.

View file

@ -0,0 +1,26 @@
12.0.2.1.0 (2020-04-30)
~~~~~~~~~~~~~~~~~~~~~~~
* [FIX] when adding a new line on a confirmed PO, split the delivery (this was
done only if a date was changed on an existing line)
* [IMP] when the quantity on a line is changed, the onchange would reset the
planned date -> change this to prevent setting a date earlier than the one on
the line, since if we are using this module the user probably has manually
set the date first
12.0.2.0.0 (2020-04-10)
~~~~~~~~~~~~~~~~~~~~~~~
* Improve the module: when changing the date on a purchase line, this will
cause a split or a merge of the pickings, to keep 1 picking per date.
11.0.1.0.0 (2018-09-16)
~~~~~~~~~~~~~~~~~~~~~~~
* Migration to 11.0.
(`#461 <https://github.com/OCA/purchase-workflow/issues/461>`_)
* When the scheduled date is changed in the PO after confirmation the
pickings are reorganized so as to force that every picking will have only
moves to be delivered on the same date.

View file

@ -0,0 +1,2 @@
When a Purchase Order is confirmed, shipments will be grouped by same scheduled date.

View file

@ -0,0 +1,482 @@
<!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>Purchase Delivery Split Date</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
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: gray; } /* 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, pre.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="purchase-delivery-split-date">
<h1 class="title">Purchase Delivery Split Date</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:3e3f54ca15929d813a29aa8e331f10ab492c9349d06311d262f01100a8ba5a89
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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/purchase-workflow/tree/16.0/purchase_delivery_split_date"><img alt="OCA/purchase-workflow" src="https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/purchase-workflow-16-0/purchase-workflow-16-0-purchase_delivery_split_date"><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/purchase-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>When this module is installed, each Purchase Order you confirm will
generate one Incoming Shipment for each schedule date indicated in the
Purchase Order Lines.</p>
<p>Once the Purchase Order has been confirmed, subsequent changes made to the
scheduled dates in the PO lines will produce a reorganization of the
corresponding stock moves in the Incoming Shipments, creating/deleting new
Incoming Shipments when needed, to ensure that each Incoming Shipment
contains moves to be received in the same date.</p>
<p>This module is also designed for extensibility, so that you can define
in other modules new criteria to split deliveries.</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="#changelog" id="toc-entry-2">Changelog</a><ul>
<li><a class="reference internal" href="#section-1" id="toc-entry-3">12.0.2.1.0 (2020-04-30)</a></li>
<li><a class="reference internal" href="#section-2" id="toc-entry-4">12.0.2.0.0 (2020-04-10)</a></li>
<li><a class="reference internal" href="#section-3" id="toc-entry-5">11.0.1.0.0 (2018-09-16)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-6">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-7">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-8">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-9">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-10">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<p>When a Purchase Order is confirmed, shipments will be grouped by same scheduled date.</p>
</div>
<div class="section" id="changelog">
<h1><a class="toc-backref" href="#toc-entry-2">Changelog</a></h1>
<div class="section" id="section-1">
<h2><a class="toc-backref" href="#toc-entry-3">12.0.2.1.0 (2020-04-30)</a></h2>
<ul class="simple">
<li>[FIX] when adding a new line on a confirmed PO, split the delivery (this was
done only if a date was changed on an existing line)</li>
<li>[IMP] when the quantity on a line is changed, the onchange would reset the
planned date -&gt; change this to prevent setting a date earlier than the one on
the line, since if we are using this module the user probably has manually
set the date first</li>
</ul>
</div>
<div class="section" id="section-2">
<h2><a class="toc-backref" href="#toc-entry-4">12.0.2.0.0 (2020-04-10)</a></h2>
<ul class="simple">
<li>Improve the module: when changing the date on a purchase line, this will
cause a split or a merge of the pickings, to keep 1 picking per date.</li>
</ul>
</div>
<div class="section" id="section-3">
<h2><a class="toc-backref" href="#toc-entry-5">11.0.1.0.0 (2018-09-16)</a></h2>
<ul class="simple">
<li>Migration to 11.0.
(<a class="reference external" href="https://github.com/OCA/purchase-workflow/issues/461">#461</a>)</li>
<li>When the scheduled date is changed in the PO after confirmation the
pickings are reorganized so as to force that every picking will have only
moves to be delivered on the same date.</li>
</ul>
</div>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-6">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/purchase-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/purchase-workflow/issues/new?body=module:%20purchase_delivery_split_date%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-7">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-8">Authors</a></h2>
<ul class="simple">
<li>Numerigraphe</li>
<li>ForgeFlow</li>
<li>Camptocamp</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-9">Contributors</a></h2>
<ul class="simple">
<li>Philippe Rossi &lt;<a class="reference external" href="mailto:pr&#64;numerigraphe.com">pr&#64;numerigraphe.com</a>&gt; (initial patch against v6.0)</li>
<li>Lionel Sausin &lt;<a class="reference external" href="mailto:ls&#64;numerigraphe.com">ls&#64;numerigraphe.com</a>&gt; (modularization for v7+)</li>
<li>Jordi Ballester Alomar &lt;<a class="reference external" href="mailto:jordi.ballester&#64;forgeflow.com">jordi.ballester&#64;forgeflow.com</a>&gt; (modularization v8, v9)</li>
<li>Lois Rilo &lt;<a class="reference external" href="mailto:lois.rilo&#64;forgeflow.com">lois.rilo&#64;forgeflow.com</a>&gt; (migration to v10)</li>
<li>Alexandre Fayolle &lt;<a class="reference external" href="mailto:alexandre.fayolle&#64;camptocamp.com">alexandre.fayolle&#64;camptocamp.com</a>&gt;</li>
<li>Pimolnat Suntian &lt;<a class="reference external" href="mailto:pimolnats&#64;ecosoft.co.th">pimolnats&#64;ecosoft.co.th</a>&gt;</li>
<li>Mallory Marcot &lt;<a class="reference external" href="mailto:contact&#64;mallory-marcot.com">contact&#64;mallory-marcot.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-10">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>This module is part of the <a class="reference external" href="https://github.com/OCA/purchase-workflow/tree/16.0/purchase_delivery_split_date">OCA/purchase-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,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import test_purchase_delivery

View file

@ -0,0 +1,309 @@
# Copyright 2014-2016 Numérigraphe SARL
# Copyright 2017 ForgeFlow, S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from freezegun import freeze_time
from odoo.fields import Datetime
from odoo.tests.common import Form, TransactionCase
class TestDeliverySingle(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.product_model = cls.env["product.product"]
# Create products:
cls.p1 = cls.product1 = cls.product_model.create(
{
"name": "Test Product 1",
"type": "product",
"default_code": "PROD1",
"standard_price": 10,
}
)
cls.p2 = cls.product2 = cls.product_model.create(
{
"name": "Test Product 2",
"type": "product",
"default_code": "PROD2",
"standard_price": 10,
}
)
cls.p3 = cls.product2 = cls.product_model.create(
{
"name": "Test Product 3",
"type": "product",
"default_code": "PROD3",
"standard_price": 10,
}
)
cls.service_1 = cls.product_model.create(
{
"name": "Test Service 1",
"type": "service",
"default_code": "SERV1",
"standard_price": 20,
}
)
# Two dates which we can use to test the features:
cls.date_sooner = "2015-01-01"
cls.date_later = "2015-12-13"
cls.date_3rd = "2015-12-31"
cls.po = cls.env["purchase.order"].create(
{
"partner_id": cls.env.ref("base.res_partner_3").id,
"order_line": [
(
0,
0,
{
"product_id": cls.p1.id,
"product_uom": cls.p1.uom_id.id,
"name": cls.p1.name,
"price_unit": cls.p1.standard_price,
"date_planned": cls.date_sooner,
"product_qty": 42.0,
},
),
(
0,
0,
{
"product_id": cls.p2.id,
"product_uom": cls.p2.uom_id.id,
"name": cls.p2.name,
"price_unit": cls.p2.standard_price,
"date_planned": cls.date_sooner,
"product_qty": 12.0,
},
),
(
0,
0,
{
"product_id": cls.p1.id,
"product_uom": cls.p1.uom_id.id,
"name": cls.p1.name,
"price_unit": cls.p1.standard_price,
"date_planned": cls.date_sooner,
"product_qty": 1.0,
},
),
],
}
)
def test_check_single_date(self):
"""Tests with single date."""
self.assertEqual(
len(self.po.picking_ids),
0,
"There must not be pickings for the PO when draft",
)
self.po.button_confirm()
self.assertEqual(
len(self.po.picking_ids),
1,
"There must be 1 picking for the PO when confirmed",
)
self.assertEqual(
str(self.po.picking_ids[0].scheduled_date)[:10],
self.date_sooner,
"The picking must be planned at the expected date",
)
def test_adding_line(self):
# A modification on line product quantity will recompute the
# date_planned field with the seller (supplierinfo) lead time
# Check if the original date planned is kept if new date_planned is before
# We first add a seller to the product
self.env["product.supplierinfo"].create(
{
"partner_id": self.env.ref("base.res_partner_3").id,
"product_tmpl_id": self.p1.product_tmpl_id.id,
}
)
# Set today earlier as planned date
today = "2015-12-01"
self.po.date_order = today
self.po.order_line[0].date_planned = self.date_later
# Then change the line quantity
with freeze_time(today):
self.po.order_line[0].product_qty = 43.0
# We check the later planned date is kept
self.assertEqual(
Datetime.to_datetime("2015-12-13"), self.po.order_line[0].date_planned
)
def test_check_multiple_dates(self):
"""Tests changing the date of the first line."""
self.po.order_line[0].date_planned = self.date_later
self.assertEqual(
len(self.po.picking_ids),
0,
"There must not be pickings for the PO when draft",
)
self.po.button_confirm()
self.assertEqual(
len(self.po.picking_ids),
2,
"There must be 2 pickings for the PO when confirmed. %s found"
% len(self.po.picking_ids),
)
sorted_pickings = sorted(self.po.picking_ids, key=lambda x: x.scheduled_date)
self.assertEqual(
str(sorted_pickings[0].scheduled_date)[:10],
self.date_sooner,
"The first picking must be planned at the soonest date",
)
self.assertEqual(
str(sorted_pickings[1].scheduled_date)[:10],
self.date_later,
"The second picking must be planned at the latest date",
)
def test_purchase_line_date_change(self):
self.po.order_line[0].date_planned = self.date_later
self.po.button_confirm()
moves = self.env["stock.move"].search(
[("purchase_line_id", "=", self.po.order_line[0].id)]
)
line = self.po.order_line[0]
line.write({"date_planned": self.date_3rd})
self.assertEqual(moves.date_deadline.strftime("%Y-%m-%d"), self.date_3rd)
def test_group_multiple_picking_same_date(self):
"""Check multiple picking with same planned date are also merged
This can happen if another module changes the picking planned date
before the _check_split_pickings is being called from the write method.
"""
self.po.order_line[0].date_planned = self.date_later
self.po.button_confirm()
moves = self.env["stock.move"].search(
[("purchase_line_id", "in", self.po.order_line.ids)]
)
pickings = moves.mapped("picking_id")
self.assertEqual(len(pickings), 2)
pickings[1].scheduled_date = pickings[0].scheduled_date
self.po.order_line[0].date_planned = self.date_sooner
self.assertEqual(len(moves.mapped("picking_id")), 1)
self.assertEqual(len(pickings.filtered(lambda r: r.state == "cancel")), 1)
def test_purchase_line_date_change_split_picking(self):
self.po.button_confirm()
line1 = self.po.order_line[0]
line2 = self.po.order_line[1]
move1 = self.env["stock.move"].search([("purchase_line_id", "=", line1.id)])
move2 = self.env["stock.move"].search([("purchase_line_id", "=", line2.id)])
line1.write({"date_planned": self.date_later})
self.assertEqual(
len(self.po.picking_ids),
2,
"There must be 2 pickings when I change the date",
)
self.assertEqual(move1.date_deadline.strftime("%Y-%m-%d"), self.date_later)
self.assertEqual(move2.date_deadline.strftime("%Y-%m-%d"), self.date_sooner)
self.assertNotEqual(move1.picking_id, move2.picking_id)
line2.write({"date_planned": self.date_later})
self.assertEqual(
move1.picking_id,
move2.picking_id,
"If I change the other line to the same date as the first, "
"both moves must be in the same picking",
)
def test_purchase_line_created_afer_confirm(self):
"""Check new line created when order is confirmed.
When a new line is added on an already `purchased` order
If it is planned for a non yet existing date in the purchase, a
new picking should be created.
"""
self.po.button_confirm()
self.assertEqual(self.po.state, "purchase")
new_date = "2016-01-30"
moves_before = self.env["stock.move"].search(
[("purchase_line_id", "in", self.po.order_line.ids)]
)
self.assertEqual(len(moves_before.mapped("picking_id")), 1)
self.po.order_line = [
(
0,
0,
{
"product_id": self.p3.id,
"product_uom": self.p3.uom_id.id,
"name": self.p3.name,
"price_unit": self.p3.standard_price,
"date_planned": new_date,
"product_qty": 2.0,
},
),
]
moves_after = self.env["stock.move"].search(
[("purchase_line_id", "in", self.po.order_line.ids)]
)
self.assertEqual(len(moves_after.mapped("picking_id")), 2)
def test_purchase_line_date_change_tz_aware(self):
"""Check that the grouping is time zone aware.
Datetime are always stored in utc in the database.
"""
self.po.order_line[2].unlink()
self.po.button_confirm()
line1 = self.po.order_line[0]
line2 = self.po.order_line[1]
self.env.user.tz = "Europe/Brussels"
self.assertEqual(len(self.po.picking_ids), 1)
line1.write({"date_planned": "2021-05-05 03:00:00"})
self.assertEqual(len(self.po.picking_ids), 2)
# Time difference of at least +1 so should be same day (1 picking)
line2.write({"date_planned": "2021-05-04 23:00:00"})
self.assertEqual(len(self.po.picking_ids), 1)
self.env.user.tz = "Etc/UTC"
line1.write({"date_planned": "2021-05-05 03:00:00"})
self.assertEqual(len(self.po.picking_ids), 2)
# No time difference so will be another day (2 pickings)
line2.write({"date_planned": "2021-05-04 23:00:00"})
self.assertEqual(len(self.po.picking_ids), 2)
def test_create_from_form(self):
partner_purchase = self.env["res.partner"].create(
{"name": "Partner 1 of purchase on create from form"}
)
with Form(self.env["purchase.order"]) as purchase_form:
purchase_form.partner_id = partner_purchase
self.assertEqual(purchase_form.partner_id, partner_purchase)
def test_po_with_services(self):
"""Test that no empty pickings are created because of service lines."""
prev_count = self.env["stock.picking"].search_count([])
self.env["purchase.order.line"].create(
{
"order_id": self.po.id,
"product_id": self.service_1.id,
"product_uom": self.service_1.uom_id.id,
"name": self.service_1.name,
"price_unit": self.service_1.standard_price,
"date_planned": self.date_later,
"product_qty": 15.0,
}
)
self.po.button_confirm()
post_count = self.env["stock.picking"].search_count([])
new_pickings = post_count - prev_count
self.assertEqual(new_pickings, 1)

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-oca-purchase-workflow-purchase_delivery_split_date"
version = "16.0.0"
description = "Purchase Delivery Split Date - Allows Purchase Order you confirm to generate one Incoming Shipment for each expected date indicated in the Purchase Order Lines"
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-purchase-workflow-purchase_stock>=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 = ["purchase_delivery_split_date"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]