Skip to content

Commit 746d20b

Browse files
[IMP] stock_move_actual_date: add functionality for inventory location report based on actual date
1 parent f8ffab7 commit 746d20b

File tree

8 files changed

+163
-55
lines changed

8 files changed

+163
-55
lines changed

stock_move_actual_date/README.rst

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
.. image:: https://odoo-community.org/readme-banner-image
2-
:target: https://odoo-community.org/get-involved?utm_source=readme
3-
:alt: Odoo Community Association
4-
51
======================
62
Stock Move Actual Date
73
======================
@@ -17,7 +13,7 @@ Stock Move Actual Date
1713
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
1814
:target: https://odoo-community.org/page/development-status
1915
:alt: Beta
20-
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
2117
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
2218
:alt: License: AGPL-3
2319
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--workflow-lightgray.png?logo=github
@@ -41,10 +37,14 @@ It also adds an Actual Date field to the Stock Valuation Layer model,
4137
enabling reporting based on this field. This field is computed and
4238
stored according to the following logic:
4339

44-
- If a posted journal entry exists, its date is used.
45-
- If there is no journal entry, the stock move's actual date is used
46-
- Otherwise, convert create_date (datetime) of the stock.valuation.layer
47-
record to date, with consideration to user's timezone.
40+
- If a posted journal entry exists, its date is used.
41+
- If there is no journal entry, the stock move's actual date is used
42+
- Otherwise, convert create_date (datetime) of the
43+
stock.valuation.layer record to date, with consideration to user's
44+
timezone.
45+
46+
It also provides stock quantity history reporting based on the actual
47+
date.
4848

4949
**Table of contents**
5050

@@ -54,25 +54,25 @@ stored according to the following logic:
5454
Configuration
5555
=============
5656

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

6161
Usage
6262
=====
6363

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

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

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

86+
Use the Actual Date field in the following stock quantity history
87+
reporting scenarios:
88+
89+
1. Go to Inventory > Reporting > Stock and click 'Inventory at Date'.
90+
2. In the wizard, select a date in 'Inventory at Date', and click
91+
'Inventory as of Actual Date' (note that the 'hh:mm:ss' part of the
92+
selection in 'Inventory at Date' is ignored in this context).
93+
94+
Note: You can also use this feature along with
95+
stock_quantity_history_location.
96+
8697
Known issues / Roadmap
8798
======================
8899

@@ -117,10 +128,10 @@ Authors
117128
Contributors
118129
------------
119130

120-
- `Quartile <https://www.quartile.co>`__:
131+
- `Quartile <https://www.quartile.co>`__:
121132

122-
- Aung Ko Ko Lin
123-
- Yoshi Tashiro
133+
- Aung Ko Ko Lin
134+
- Yoshi Tashiro
124135

125136
Maintainers
126137
-----------

stock_move_actual_date/models/stock_move.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,39 @@ def _compute_actual_date(self):
4040
self.with_context(tz=tz), rec.date
4141
)
4242

43+
@api.model
44+
def _read_group(
45+
self,
46+
domain,
47+
groupby=(),
48+
aggregates=(),
49+
having=(),
50+
offset=0,
51+
limit=None,
52+
order=None,
53+
):
54+
if self.env.context.get("use_actual_date"):
55+
tz = self._get_timezone()
56+
domain = [
57+
(
58+
"actual_date",
59+
condition[1],
60+
fields.Date.context_today(self.with_context(tz=tz), condition[2]),
61+
)
62+
if isinstance(condition, list | tuple) and condition[0] == "date"
63+
else condition
64+
for condition in domain
65+
]
66+
return super()._read_group(
67+
domain,
68+
groupby,
69+
aggregates,
70+
having,
71+
offset=offset,
72+
limit=limit,
73+
order=order,
74+
)
75+
4376
def _action_done(self, cancel_backorder=False):
4477
moves = super()._action_done(cancel_backorder)
4578
# i.e. Inventory adjustments with actual date

stock_move_actual_date/readme/DESCRIPTION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ stored according to the following logic:
1111
- If there is no journal entry, the stock move's actual date is used
1212
- Otherwise, convert create_date (datetime) of the stock.valuation.layer
1313
record to date, with consideration to user's timezone.
14+
15+
It also provides stock quantity history reporting based on the actual date.

stock_move_actual_date/readme/USAGE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,13 @@ scenarios:
1919
2. In the wizard, select a date in 'Inventory at Date', and click
2020
'Valuation as of Accounting Date' (note that 'hh:mm:ss' part of the
2121
selection in 'Inventory at Date' is ignored in this context).
22+
23+
Use the Actual Date field in the following stock quantity history reporting scenarios:
24+
25+
1. Go to Inventory > Reporting > Stock and click
26+
'Inventory at Date'.
27+
2. In the wizard, select a date in 'Inventory at Date', and click
28+
'Inventory as of Actual Date' (note that the 'hh:mm:ss' part of the selection
29+
in 'Inventory at Date' is ignored in this context).
30+
31+
Note: You can also use this feature along with stock_quantity_history_location.

stock_move_actual_date/static/description/index.html

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
55
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
6-
<title>README.rst</title>
6+
<title>Stock Move Actual Date</title>
77
<style type="text/css">
88

99
/*
@@ -360,21 +360,16 @@
360360
</style>
361361
</head>
362362
<body>
363-
<div class="document">
363+
<div class="document" id="stock-move-actual-date">
364+
<h1 class="title">Stock Move Actual Date</h1>
364365

365-
366-
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
367-
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
368-
</a>
369-
<div class="section" id="stock-move-actual-date">
370-
<h1>Stock Move Actual Date</h1>
371366
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
372367
!! This file is generated by oca-gen-addon-readme !!
373368
!! changes will be overwritten. !!
374369
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375370
!! source digest: sha256:542dce805f57e02c2591a7f294a99014d5403db35500251cf01cdb3e8b6a7372
376371
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377-
<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>
372+
<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>
378373
<p>This module adds an Actual Date field to the stock picking, stock scrap,
379374
stock move, and stock move line models. This field allows users to
380375
record the actual date on which a stock transfer or stock scrap took
@@ -385,9 +380,12 @@ <h1>Stock Move Actual Date</h1>
385380
<ul class="simple">
386381
<li>If a posted journal entry exists, its date is used.</li>
387382
<li>If there is no journal entry, the stock move’s actual date is used</li>
388-
<li>Otherwise, convert create_date (datetime) of the stock.valuation.layer
389-
record to date, with consideration to user’s timezone.</li>
383+
<li>Otherwise, convert create_date (datetime) of the
384+
stock.valuation.layer record to date, with consideration to user’s
385+
timezone.</li>
390386
</ul>
387+
<p>It also provides stock quantity history reporting based on the actual
388+
date.</p>
391389
<p><strong>Table of contents</strong></p>
392390
<div class="contents local topic" id="contents">
393391
<ul class="simple">
@@ -404,27 +402,27 @@ <h1>Stock Move Actual Date</h1>
404402
</ul>
405403
</div>
406404
<div class="section" id="configuration">
407-
<h2><a class="toc-backref" href="#toc-entry-1">Configuration</a></h2>
405+
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
408406
<ul class="simple">
409407
<li>Go to Settings &gt; Users &amp; Companies &gt; Groups.</li>
410408
<li>Open ‘Modify Actual Date’ and add the users who are allowed to edit
411409
the actual date of completed records (e.g., pickings, scraps).</li>
412410
</ul>
413411
</div>
414412
<div class="section" id="usage">
415-
<h2><a class="toc-backref" href="#toc-entry-2">Usage</a></h2>
413+
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
416414
<p>Use the Actual Date field in the following transfer and scrap scenarios:</p>
417415
<ul class="simple">
418416
<li>If you are late in processing a transfer or scrap in Odoo and wish to
419417
record the transaction with the actual transfer date, fill in the
420-
Actual Date field in the picking or scrap form. The Actual Date of the
421-
picking or scrap is then propagated to its corresponding stock moves
422-
and stock move lines, and is also passed to the journal entry as the
423-
date.</li>
424-
<li>You can also update the Actual Date of a completed picking or scrap if
425-
you belong to the ‘Modify Actual Date’ group. This operation updates
426-
the date of the related journal entries, re-proposing a new sequence
427-
to them as necessary.</li>
418+
Actual Date field in the picking or scrap form. The Actual Date of
419+
the picking or scrap is then propagated to its corresponding stock
420+
moves and stock move lines, and is also passed to the journal entry
421+
as the date.</li>
422+
<li>You can also update the Actual Date of a completed picking or scrap
423+
if you belong to the ‘Modify Actual Date’ group. This operation
424+
updates the date of the related journal entries, re-proposing a new
425+
sequence to them as necessary.</li>
428426
</ul>
429427
<p>Use the Actual Date field in the following stock valuation reporting
430428
scenarios:</p>
@@ -435,9 +433,19 @@ <h2><a class="toc-backref" href="#toc-entry-2">Usage</a></h2>
435433
‘Valuation as of Accounting Date’ (note that ‘hh:mm:ss’ part of the
436434
selection in ‘Inventory at Date’ is ignored in this context).</li>
437435
</ol>
436+
<p>Use the Actual Date field in the following stock quantity history
437+
reporting scenarios:</p>
438+
<ol class="arabic simple">
439+
<li>Go to Inventory &gt; Reporting &gt; Stock and click ‘Inventory at Date’.</li>
440+
<li>In the wizard, select a date in ‘Inventory at Date’, and click
441+
‘Inventory as of Actual Date’ (note that the ‘hh:mm:ss’ part of the
442+
selection in ‘Inventory at Date’ is ignored in this context).</li>
443+
</ol>
444+
<p>Note: You can also use this feature along with
445+
stock_quantity_history_location.</p>
438446
</div>
439447
<div class="section" id="known-issues-roadmap">
440-
<h2><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h2>
448+
<h1><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h1>
441449
<p>Updating the Actual Date of a completed receipt picking for a foreign
442450
currency purchase does not trigger a recalculation of the amounts in the
443451
associated journal entries, even if the currency rate for the new date
@@ -448,23 +456,23 @@ <h2><a class="toc-backref" href="#toc-entry-3">Known issues / Roadmap</a></h2>
448456
timezone will be assigned.</p>
449457
</div>
450458
<div class="section" id="bug-tracker">
451-
<h2><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h2>
459+
<h1><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h1>
452460
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-workflow/issues">GitHub Issues</a>.
453461
In case of trouble, please check there if your issue has already been reported.
454462
If you spotted it first, help us to smash it by providing a detailed and welcomed
455463
<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>
456464
<p>Do not contact contributors directly about support or help with technical issues.</p>
457465
</div>
458466
<div class="section" id="credits">
459-
<h2><a class="toc-backref" href="#toc-entry-5">Credits</a></h2>
467+
<h1><a class="toc-backref" href="#toc-entry-5">Credits</a></h1>
460468
<div class="section" id="authors">
461-
<h3><a class="toc-backref" href="#toc-entry-6">Authors</a></h3>
469+
<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
462470
<ul class="simple">
463471
<li>Quartile</li>
464472
</ul>
465473
</div>
466474
<div class="section" id="contributors">
467-
<h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
475+
<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
468476
<ul class="simple">
469477
<li><a class="reference external" href="https://www.quartile.co">Quartile</a>:<ul>
470478
<li>Aung Ko Ko Lin</li>
@@ -474,7 +482,7 @@ <h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
474482
</ul>
475483
</div>
476484
<div class="section" id="maintainers">
477-
<h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
485+
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
478486
<p>This module is maintained by the OCA.</p>
479487
<a class="reference external image-reference" href="https://odoo-community.org">
480488
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
@@ -489,6 +497,5 @@ <h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
489497
</div>
490498
</div>
491499
</div>
492-
</div>
493500
</body>
494501
</html>

stock_move_actual_date/tests/test_stock_move_actual_date.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright 2025 Quartile (https://www.quartile.co)
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
33

4-
from datetime import date
4+
from datetime import date, datetime
55

66
from freezegun import freeze_time
77

@@ -177,3 +177,33 @@ def test_fifo_svl_actual_date(self):
177177
date(2025, 3, 10),
178178
"SVL accounting date should match the move actual date.",
179179
)
180+
181+
def test_open_qty_at_actual_date(self):
182+
self.env.user.tz = "Asia/Tokyo"
183+
_, _ = self.create_picking(date(2025, 7, 1))
184+
wizard = self.env["stock.quantity.history"].create(
185+
# 2025-06-30 23:00:00 JST
186+
{"inventory_datetime": datetime(2025, 6, 30, 14, 0, 0)}
187+
)
188+
action = wizard.open_at_date()
189+
self.assertEqual(
190+
self.product_1.with_context(**action["context"]).qty_available, 0.0
191+
)
192+
self.product_1.invalidate_recordset()
193+
action = wizard.open_qty_at_actual_date()
194+
self.assertEqual(
195+
self.product_1.with_context(**action["context"]).qty_available, 0.0
196+
)
197+
wizard = self.env["stock.quantity.history"].create(
198+
# 2025-07-01 00:00:00 JST
199+
{"inventory_datetime": datetime(2025, 6, 30, 15, 0, 0)}
200+
)
201+
action = wizard.open_at_date()
202+
self.assertEqual(
203+
self.product_1.with_context(**action["context"]).qty_available, 0.0
204+
)
205+
self.product_1.invalidate_recordset()
206+
action = wizard.open_qty_at_actual_date()
207+
self.assertEqual(
208+
self.product_1.with_context(**action["context"]).qty_available, 10.0
209+
)

stock_move_actual_date/wizard/stock_quantity_history.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from odoo import models
55
from odoo.tools.misc import format_datetime
6+
from odoo.tools.safe_eval import safe_eval
67

78

89
class StockQuantityHistory(models.TransientModel):
@@ -18,3 +19,10 @@ def open_at_actual_date(self):
1819
]
1920
action["display_name"] = format_datetime(self.env, self.inventory_datetime)
2021
return action
22+
23+
def open_qty_at_actual_date(self):
24+
action = self.open_at_date()
25+
ctx = action["context"]
26+
ctx = safe_eval(ctx) if isinstance(ctx, str) else ctx
27+
ctx["use_actual_date"] = True
28+
return action

stock_move_actual_date/wizard/stock_quantity_history.xml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@
1111
string="Valuation as of Actual Date"
1212
type="object"
1313
class="btn-primary"
14-
invisible="not context.get('active_model', 'stock.valuation.layer')"
14+
invisible="context.get('active_model') != 'stock.valuation.layer'"
15+
/>
16+
<button
17+
name="open_qty_at_actual_date"
18+
string="Inventory as of Actual Date"
19+
type="object"
20+
class="btn-primary"
21+
invisible="context.get('active_model') != 'product.product'"
1522
/>
1623
</xpath>
1724
</field>

0 commit comments

Comments
 (0)