Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 36 additions & 25 deletions stock_move_actual_date/README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

======================
Stock Move Actual Date
======================
Expand All @@ -17,7 +13,7 @@ Stock Move Actual Date
.. |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/license-AGPL--3-blue.png
.. |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%2Fstock--logistics--workflow-lightgray.png?logo=github
Expand All @@ -41,10 +37,14 @@ It also adds an Actual Date field to the Stock Valuation Layer model,
enabling reporting based on this field. This field is computed and
stored according to the following logic:

- If a posted journal entry exists, its date is used.
- If there is no journal entry, the stock move's actual date is used
- Otherwise, convert create_date (datetime) of the stock.valuation.layer
record to date, with consideration to user's timezone.
- If a posted journal entry exists, its date is used.
- If there is no journal entry, the stock move's actual date is used
- Otherwise, convert create_date (datetime) of the
stock.valuation.layer record to date, with consideration to user's
timezone.

It also provides stock quantity history reporting based on the actual
date.

**Table of contents**

Expand All @@ -54,25 +54,25 @@ stored according to the following logic:
Configuration
=============

- Go to Settings > Users & Companies > Groups.
- Open 'Modify Actual Date' and add the users who are allowed to edit
the actual date of completed records (e.g., pickings, scraps).
- Go to Settings > Users & Companies > Groups.
- Open 'Modify Actual Date' and add the users who are allowed to edit
the actual date of completed records (e.g., pickings, scraps).

Usage
=====

Use the Actual Date field in the following transfer and scrap scenarios:

- If you are late in processing a transfer or scrap in Odoo and wish to
record the transaction with the actual transfer date, fill in the
Actual Date field in the picking or scrap form. The Actual Date of the
picking or scrap is then propagated to its corresponding stock moves
and stock move lines, and is also passed to the journal entry as the
date.
- You can also update the Actual Date of a completed picking or scrap if
you belong to the 'Modify Actual Date' group. This operation updates
the date of the related journal entries, re-proposing a new sequence
to them as necessary.
- If you are late in processing a transfer or scrap in Odoo and wish to
record the transaction with the actual transfer date, fill in the
Actual Date field in the picking or scrap form. The Actual Date of
the picking or scrap is then propagated to its corresponding stock
moves and stock move lines, and is also passed to the journal entry
as the date.
- You can also update the Actual Date of a completed picking or scrap
if you belong to the 'Modify Actual Date' group. This operation
updates the date of the related journal entries, re-proposing a new
sequence to them as necessary.

Use the Actual Date field in the following stock valuation reporting
scenarios:
Expand All @@ -83,6 +83,17 @@ scenarios:
'Valuation as of Accounting Date' (note that 'hh:mm:ss' part of the
selection in 'Inventory at Date' is ignored in this context).

Use the Actual Date field in the following stock quantity history
reporting scenarios:

1. Go to *Inventory > Reporting > Stock* and click 'Inventory at Date'.
2. In the wizard, select a date in 'Inventory at Date', and click
'Inventory as of Actual Date' (note that the 'hh:mm:ss' part of the
selection in 'Inventory at Date' is ignored in this context).

Note: You can also use this feature along with
stock_quantity_history_location.

Known issues / Roadmap
======================

Expand Down Expand Up @@ -117,10 +128,10 @@ Authors
Contributors
------------

- `Quartile <https://www.quartile.co>`__:
- `Quartile <https://www.quartile.co>`__:

- Aung Ko Ko Lin
- Yoshi Tashiro
- Aung Ko Ko Lin
- Yoshi Tashiro

Maintainers
-----------
Expand Down
33 changes: 33 additions & 0 deletions stock_move_actual_date/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,39 @@ def _compute_actual_date(self):
self.with_context(tz=tz), rec.date
)

@api.model
def _read_group(
self,
domain,
groupby=(),
aggregates=(),
having=(),
offset=0,
limit=None,
order=None,
):
if self.env.context.get("use_actual_date"):
tz = self._get_timezone()
domain = [
(
"actual_date",
condition[1],
fields.Date.context_today(self.with_context(tz=tz), condition[2]),
)
if isinstance(condition, list | tuple) and condition[0] == "date"
else condition
for condition in domain
]
return super()._read_group(
domain,
groupby,
aggregates,
having,
offset=offset,
limit=limit,
order=order,
)

def _action_done(self, cancel_backorder=False):
moves = super()._action_done(cancel_backorder)
# i.e. Inventory adjustments with actual date
Expand Down
2 changes: 2 additions & 0 deletions stock_move_actual_date/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ stored according to the following logic:
- If there is no journal entry, the stock move's actual date is used
- Otherwise, convert create_date (datetime) of the stock.valuation.layer
record to date, with consideration to user's timezone.

It also provides stock quantity history reporting based on the actual date.
9 changes: 9 additions & 0 deletions stock_move_actual_date/readme/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@ scenarios:
2. In the wizard, select a date in 'Inventory at Date', and click
'Valuation as of Accounting Date' (note that 'hh:mm:ss' part of the
selection in 'Inventory at Date' is ignored in this context).

Use the Actual Date field in the following stock quantity history reporting scenarios:

1. Go to *Inventory > Reporting > Stock* and click 'Inventory at Date'.
2. In the wizard, select a date in 'Inventory at Date', and click
'Inventory as of Actual Date' (note that the 'hh:mm:ss' part of the selection
in 'Inventory at Date' is ignored in this context).

Note: You can also use this feature along with stock_quantity_history_location.
63 changes: 35 additions & 28 deletions stock_move_actual_date/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<title>Stock Move Actual Date</title>
<style type="text/css">

/*
Expand Down Expand Up @@ -360,21 +360,16 @@
</style>
</head>
<body>
<div class="document">
<div class="document" id="stock-move-actual-date">
<h1 class="title">Stock Move Actual Date</h1>


<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="stock-move-actual-date">
<h1>Stock Move Actual Date</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:542dce805f57e02c2591a7f294a99014d5403db35500251cf01cdb3e8b6a7372
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/stock-logistics-workflow/tree/18.0/stock_move_actual_date"><img alt="OCA/stock-logistics-workflow" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-workflow-18-0/stock-logistics-workflow-18-0-stock_move_actual_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/stock-logistics-workflow&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<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/stock-logistics-workflow/tree/18.0/stock_move_actual_date"><img alt="OCA/stock-logistics-workflow" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-workflow-18-0/stock-logistics-workflow-18-0-stock_move_actual_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/stock-logistics-workflow&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module adds an Actual Date field to the stock picking, stock scrap,
stock move, and stock move line models. This field allows users to
record the actual date on which a stock transfer or stock scrap took
Expand All @@ -385,9 +380,12 @@ <h1>Stock Move Actual Date</h1>
<ul class="simple">
<li>If a posted journal entry exists, its date is used.</li>
<li>If there is no journal entry, the stock move’s actual date is used</li>
<li>Otherwise, convert create_date (datetime) of the stock.valuation.layer
record to date, with consideration to user’s timezone.</li>
<li>Otherwise, convert create_date (datetime) of the
stock.valuation.layer record to date, with consideration to user’s
timezone.</li>
</ul>
<p>It also provides stock quantity history reporting based on the actual
date.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
Expand All @@ -404,27 +402,27 @@ <h1>Stock Move Actual Date</h1>
</ul>
</div>
<div class="section" id="configuration">
<h2><a class="toc-backref" href="#toc-entry-1">Configuration</a></h2>
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<ul class="simple">
<li>Go to Settings &gt; Users &amp; Companies &gt; Groups.</li>
<li>Open ‘Modify Actual Date’ and add the users who are allowed to edit
the actual date of completed records (e.g., pickings, scraps).</li>
</ul>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#toc-entry-2">Usage</a></h2>
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
<p>Use the Actual Date field in the following transfer and scrap scenarios:</p>
<ul class="simple">
<li>If you are late in processing a transfer or scrap in Odoo and wish to
record the transaction with the actual transfer date, fill in the
Actual Date field in the picking or scrap form. The Actual Date of the
picking or scrap is then propagated to its corresponding stock moves
and stock move lines, and is also passed to the journal entry as the
date.</li>
<li>You can also update the Actual Date of a completed picking or scrap if
you belong to the ‘Modify Actual Date’ group. This operation updates
the date of the related journal entries, re-proposing a new sequence
to them as necessary.</li>
Actual Date field in the picking or scrap form. The Actual Date of
the picking or scrap is then propagated to its corresponding stock
moves and stock move lines, and is also passed to the journal entry
as the date.</li>
<li>You can also update the Actual Date of a completed picking or scrap
if you belong to the ‘Modify Actual Date’ group. This operation
updates the date of the related journal entries, re-proposing a new
sequence to them as necessary.</li>
</ul>
<p>Use the Actual Date field in the following stock valuation reporting
scenarios:</p>
Expand All @@ -435,9 +433,19 @@ <h2><a class="toc-backref" href="#toc-entry-2">Usage</a></h2>
‘Valuation as of Accounting Date’ (note that ‘hh:mm:ss’ part of the
selection in ‘Inventory at Date’ is ignored in this context).</li>
</ol>
<p>Use the Actual Date field in the following stock quantity history
reporting scenarios:</p>
<ol class="arabic simple">
<li>Go to <em>Inventory &gt; Reporting &gt; Stock</em> and click ‘Inventory at Date’.</li>
<li>In the wizard, select a date in ‘Inventory at Date’, and click
‘Inventory as of Actual Date’ (note that the ‘hh:mm:ss’ part of the
selection in ‘Inventory at Date’ is ignored in this context).</li>
</ol>
<p>Note: You can also use this feature along with
stock_quantity_history_location.</p>
</div>
<div class="section" id="known-issues-roadmap">
<h2><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h2>
<h1><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h1>
<p>Updating the Actual Date of a completed receipt picking for a foreign
currency purchase does not trigger a recalculation of the amounts in the
associated journal entries, even if the currency rate for the new date
Expand All @@ -448,23 +456,23 @@ <h2><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h2>
timezone will be assigned.</p>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h2>
<h1><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-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/stock-logistics-workflow/issues/new?body=module:%20stock_move_actual_date%0Aversion:%2018.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">
<h2><a class="toc-backref" href="#toc-entry-5">Credits</a></h2>
<h1><a class="toc-backref" href="#toc-entry-5">Credits</a></h1>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-6">Authors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
<ul class="simple">
<li>Quartile</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://www.quartile.co">Quartile</a>:<ul>
<li>Aung Ko Ko Lin</li>
Expand All @@ -474,7 +482,7 @@ <h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
<h2><a class="toc-backref" href="#toc-entry-8">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" />
Expand All @@ -489,6 +497,5 @@ <h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
</div>
</div>
</div>
</div>
</body>
</html>
32 changes: 31 additions & 1 deletion stock_move_actual_date/tests/test_stock_move_actual_date.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright 2025 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from datetime import date
from datetime import date, datetime

from freezegun import freeze_time

Expand Down Expand Up @@ -177,3 +177,33 @@ def test_fifo_svl_actual_date(self):
date(2025, 3, 10),
"SVL accounting date should match the move actual date.",
)

def test_open_qty_at_actual_date(self):
self.env.user.tz = "Asia/Tokyo"
_, _ = self.create_picking(date(2025, 7, 1))
wizard = self.env["stock.quantity.history"].create(
# 2025-06-30 23:00:00 JST
{"inventory_datetime": datetime(2025, 6, 30, 14, 0, 0)}
)
action = wizard.open_at_date()
self.assertEqual(
self.product_1.with_context(**action["context"]).qty_available, 0.0
)
self.product_1.invalidate_recordset()
action = wizard.open_qty_at_actual_date()
self.assertEqual(
self.product_1.with_context(**action["context"]).qty_available, 0.0
)
wizard = self.env["stock.quantity.history"].create(
# 2025-07-01 00:00:00 JST
{"inventory_datetime": datetime(2025, 6, 30, 15, 0, 0)}
)
action = wizard.open_at_date()
self.assertEqual(
self.product_1.with_context(**action["context"]).qty_available, 0.0
)
self.product_1.invalidate_recordset()
action = wizard.open_qty_at_actual_date()
self.assertEqual(
self.product_1.with_context(**action["context"]).qty_available, 10.0
)
8 changes: 8 additions & 0 deletions stock_move_actual_date/wizard/stock_quantity_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from odoo import models
from odoo.tools.misc import format_datetime
from odoo.tools.safe_eval import safe_eval


class StockQuantityHistory(models.TransientModel):
Expand All @@ -18,3 +19,10 @@ def open_at_actual_date(self):
]
action["display_name"] = format_datetime(self.env, self.inventory_datetime)
return action

def open_qty_at_actual_date(self):
action = self.open_at_date()
ctx = action["context"]
ctx = safe_eval(ctx) if isinstance(ctx, str) else ctx
ctx["use_actual_date"] = True
return action
9 changes: 8 additions & 1 deletion stock_move_actual_date/wizard/stock_quantity_history.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@
string="Valuation as of Actual Date"
type="object"
class="btn-primary"
invisible="not context.get('active_model', 'stock.valuation.layer')"
invisible="context.get('active_model') != 'stock.valuation.layer'"
/>
<button
name="open_qty_at_actual_date"
string="Inventory as of Actual Date"
type="object"
class="btn-primary"
invisible="context.get('active_model') != 'product.product'"
/>
</xpath>
</field>
Expand Down