Skip to content

Commit ace44ce

Browse files
committed
FIX stock_period_evaluation: remove active handling and fix tests
IMP metadata and style
1 parent 69b5626 commit ace44ce

28 files changed

+1546
-415
lines changed

stock_period_evaluation/README.rst

Lines changed: 406 additions & 39 deletions
Large diffs are not rendered by default.

stock_period_evaluation/__manifest__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
"name": "Stock Period Evaluation",
99
"summary": "Stock evaluation with FIFO, LIFO and average methods",
1010
"version": "18.0.1.1.0",
11-
"author": "Pordenone Linux User Group (PNLUG), Odoo Community Association (OCA),"
11+
"author": "Pordenone Linux User Group (PNLUG), Odoo Community Association (OCA), "
1212
"Dinamiche Aziendali srl, Sergio Corato",
1313
"category": "Warehouse",
14-
"website": "https://github.com/OCA/stock-logistics-workflow",
14+
"website": "https://github.com/OCA/stock-logistics-reporting",
1515
"license": "AGPL-3",
1616
"maintainers": ["MarcoCalcagni", "Borruso"],
1717
"depends": [
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<odoo noupdate="1">
3-
43
<record id="last_close_date_config_parameter" model="ir.config_parameter">
54
<field name="key">stock_period_evaluation.last_close_date</field>
65
<field name="value">2010-01-01</field>
76
</record>
8-
97
</odoo>

stock_period_evaluation/models/product_product.py

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,10 @@ def _compute_quantities_available(self, to_date=False):
5757
quant_qty = row2[0] * 1.0
5858
product_id = row2[1]
5959
location_id = row2[2]
60-
lot_id = (
61-
row2[3] if self.tracking != "serial" and row2[3] is not None else False
62-
)
63-
package_id = row2[4] if row2[4] and row2[4] is not None else False
64-
owner_id = row2[5] if row2[5] and row2[5] is not None else False
65-
key = "%d_%d_%d_%d_%d" % (
66-
product_id,
67-
location_id,
68-
lot_id,
69-
package_id,
70-
owner_id,
71-
)
60+
lot_id = row2[3] if self.tracking != "serial" and row2[3] is not None else 0
61+
package_id = row2[4] if row2[4] and row2[4] is not None else 0
62+
owner_id = row2[5] if row2[5] and row2[5] is not None else 0
63+
key = f"{product_id}_{location_id}_{lot_id}_{package_id}_{owner_id}"
7264
if key in quan.keys():
7365
quan[key] = quan[key] + quant_qty
7466
else:
@@ -121,18 +113,10 @@ def _compute_quantities_available(self, to_date=False):
121113
move_qty = row[0]
122114
product_id = row[1]
123115
location_id = row[2]
124-
lot_id = (
125-
row[3] if self.tracking != "serial" and row[3] is not None else False
126-
)
127-
package_id = row[4] if row[4] and row[4] is not None else False
128-
owner_id = row[5] if row[5] and row[5] is not None else False
129-
key = "%d_%d_%d_%d_%d" % (
130-
product_id,
131-
location_id,
132-
lot_id,
133-
package_id,
134-
owner_id,
135-
)
116+
lot_id = row[3] if self.tracking != "serial" and row[3] is not None else 0
117+
package_id = row[4] if row[4] and row[4] is not None else 0
118+
owner_id = row[5] if row[5] and row[5] is not None else 0
119+
key = f"{product_id}_{location_id}_{lot_id}_{package_id}_{owner_id}"
136120
if key in move.keys():
137121
move[key] += move_qty
138122
else:
@@ -179,18 +163,10 @@ def _compute_quantities_available(self, to_date=False):
179163
move_qty = row[0]
180164
product_id = row[1]
181165
location_dest_id = row[2]
182-
lot_id = (
183-
row[3] if self.tracking != "serial" and row[3] is not None else False
184-
)
185-
package_id = row[4] if row[4] and row[4] is not None else False
186-
owner_id = row[5] if row[5] and row[5] is not None else False
187-
key = "%d_%d_%d_%d_%d" % (
188-
product_id,
189-
location_dest_id,
190-
lot_id,
191-
package_id,
192-
owner_id,
193-
)
166+
lot_id = row[3] if self.tracking != "serial" and row[3] is not None else 0
167+
package_id = row[4] if row[4] and row[4] is not None else 0
168+
owner_id = row[5] if row[5] and row[5] is not None else 0
169+
key = f"{product_id}_{location_dest_id}_{lot_id}_{package_id}_{owner_id}"
194170
if key in move.keys():
195171
move[key] -= move_qty
196172
else:

stock_period_evaluation/models/stock_close.py

Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
66

77
import logging
8-
from datetime import datetime, time
8+
from datetime import datetime
99

1010
from odoo import _, api, fields, models
1111
from odoo.exceptions import UserError
@@ -77,10 +77,6 @@ class StockClosePeriod(models.Model):
7777
copy=False,
7878
readonly=False,
7979
)
80-
force_archive = fields.Boolean(
81-
default=False,
82-
help="Marks as archive the inventory move lines used during the process.",
83-
)
8480
purchase_ok = fields.Boolean(
8581
default=False,
8682
readonly=True,
@@ -99,11 +95,12 @@ def unlink(self):
9995
if closing.state in ["confirm", "done"]:
10096
raise UserError(
10197
_(
102-
"State in '%s'. You can only delete in state 'Draft' or 'Cancelled'."
98+
"State in '%s'. You can only delete in state "
99+
"'Draft' or 'Cancelled'."
103100
)
104101
% closing.state
105102
)
106-
return super(StockClosePeriod, self).unlink()
103+
return super().unlink()
107104

108105
def action_set_to_draft(self):
109106
for closing in self:
@@ -203,48 +200,6 @@ def _check_qty_available(self):
203200
res = True
204201
return res
205202

206-
def _deactivate_moves(self):
207-
self.ensure_one()
208-
209-
# set active = False on stock_move and stock_move_line
210-
close_date = self.close_date or datetime.combine(self.close_date, time.max)
211-
212-
self.env.cr.execute(
213-
"""
214-
UPDATE
215-
stock_move
216-
SET
217-
active = false
218-
WHERE
219-
date <= date(%s)
220-
AND state = 'done'
221-
AND (
222-
company_id == %s
223-
OR company_id IS NULL
224-
);
225-
""",
226-
(close_date, self.company_id.id),
227-
)
228-
229-
self.env.cr.execute(
230-
"""
231-
UPDATE
232-
stock_move_line
233-
SET
234-
active = false
235-
WHERE
236-
date <= date(%s)
237-
AND state = 'done'
238-
AND (
239-
company_id == %s
240-
OR company_id IS NULL
241-
);
242-
""",
243-
(close_date, self.company_id.id),
244-
)
245-
246-
return True
247-
248203
def action_recalculate_purchase(self):
249204
for closing in self:
250205
if not closing.bypass_negative_qty and not closing._check_qty_available():
@@ -257,8 +212,6 @@ def action_recalculate_purchase(self):
257212

258213
self.env["stock.move.line"].recompute_average_cost_period_purchase(closing)
259214
closing.purchase_ok = True
260-
if closing.force_archive:
261-
closing._deactivate_moves()
262215
closing.work_end = datetime.now()
263216
return True
264217

stock_period_evaluation/models/stock_close_line.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@ class StockClosePeriodLine(models.Model):
3030
required=True,
3131
)
3232
product_name = fields.Char(
33-
string="Product Name",
3433
compute="_compute_product_name",
3534
store=True,
36-
readonly=True
35+
readonly=True,
3736
)
3837
product_code = fields.Char(
3938
related="product_id.default_code", store=True, readonly=True
@@ -98,7 +97,7 @@ class StockClosePeriodLine(models.Model):
9897
string="Company",
9998
store=True,
10099
)
101-
evaluation_details = fields.Text(string="Evaluation Details")
100+
evaluation_details = fields.Text()
102101

103102
@api.depends("product_id")
104103
def _compute_product_name(self):
@@ -117,5 +116,5 @@ def _format_value(self, value):
117116
self.env,
118117
value,
119118
self.company_id.currency_id,
120-
lang_code=self.company_id.partner_id.lang
119+
lang_code=self.company_id.partner_id.lang,
121120
)

stock_period_evaluation/models/stock_move.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
class StockMove(models.Model):
1717
_inherit = "stock.move"
1818

19-
# related field to manage closed lines
20-
active = fields.Boolean()
21-
2219
def _get_purchase_price_unit(self):
2320
self.ensure_one()
2421
invoice_lines = self.env["stock.move.line"]._get_right_invoice_lines(
@@ -61,8 +58,6 @@ def _get_purchase_price_unit(self):
6158
class StockMoveLine(models.Model):
6259
_inherit = "stock.move.line"
6360

64-
# add field to manage closed lines
65-
active = fields.Boolean(related="move_id.active", store=True)
6661
company_id = fields.Many2one(related="move_id.company_id", store=True)
6762

6863
def _get_last_closing(self, closing_id, product_id, company_id):
@@ -116,7 +111,6 @@ def _get_cost_stock_move_purchase_average(self, last_close_date, closing_line_id
116111
("product_id", "=", product_id.id),
117112
("date", ">", min_date),
118113
("date", "<=", max_date),
119-
("active", ">=", 0),
120114
("company_id", "=", company_id),
121115
("location_id.usage", "!=", "inventory"),
122116
("location_dest_id.usage", "!=", "inventory"),
@@ -215,7 +209,6 @@ def _search_same_product_value(self, closing_line_id):
215209
)
216210
closing_line_id.cumulative_qty = other_closing_line_id.cumulative_qty
217211
closing_line_id.evaluation_method = other_closing_line_id.evaluation_method
218-
self.env.cr.commit() # pylint: disable=E8102
219212

220213
def _get_cost_stock_move_lifo_fifo(self, closing_line_id, evaluation_method=False):
221214
product_id = closing_line_id.product_id
@@ -306,7 +299,6 @@ def price_calculation(self, line, valuation_type, start_qty, start_price):
306299
("quantity", ">", 0),
307300
("date", "<=", line.close_id.close_date),
308301
("date", ">", line.close_id.last_close_date),
309-
("active", "!=", False),
310302
("company_id", "=", line.close_id.company_id.id),
311303
]
312304
if valuation_type in ["fifo", "purchase"]:
@@ -421,7 +413,7 @@ def _get_tuples(self, line, move_line_ids, valuation_type, start_qty, start_pric
421413

422414
def _fix_zero_values(self, tuples):
423415
fixed_tuples = []
424-
_logger.info("Current tuples are %s" % str(tuples))
416+
_logger.info(f"Current tuples are {tuples}")
425417
for i, raw_tuple in enumerate(tuples):
426418
if not raw_tuple[2]:
427419
# n.b. the order of the tuples is from the newer to the oldest
@@ -448,7 +440,7 @@ def _fix_zero_values(self, tuples):
448440
)
449441
else:
450442
fixed_tuples.append(raw_tuple)
451-
_logger.info("Fixed tuples are %s" % str(fixed_tuples))
443+
_logger.info(f"Fixed tuples are {fixed_tuples}")
452444
return fixed_tuples
453445

454446
@staticmethod
@@ -603,7 +595,6 @@ def _recompute_cost_stock_move_purchase(self, closing_id):
603595
closing_id, closing_line_id, last_close_date, product_id
604596
)
605597

606-
self.env.cr.commit() # pylint: disable=E8102
607598
_logger.info("[1/2] Finish recompute average cost product")
608599

609600
def _write_results(self, closing_id):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["whool"]
3+
build-backend = "whool.buildapi"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
**User Access Configuration**
2+
3+
1. **Security Groups**:
4+
5+
- **Stock Period Evaluation Manager**
6+
(`stock_period_evaluation.group_stock_period_evaluation_manager`):
7+
- Full access to create, edit, validate, and delete closing
8+
periods
9+
- Access to import wizard and all reporting functions
10+
- Can force evaluation methods for cost calculation
11+
- **Stock Period Evaluation User Read Only**
12+
(`stock_period_evaluation.group_stock_period_evaluation_user_readonly`):
13+
- View-only access to closing periods and reports
14+
- Cannot modify or create new periods
15+
16+
2. **User Assignment**:
17+
18+
Go to *Settings \> Users & Companies \> Users*:
19+
20+
- Select the user to configure
21+
- Assign appropriate Stock Period Evaluation group
22+
23+
**System Parameters**
24+
25+
The module uses a system parameter for default configuration:
26+
27+
- **Default Last Close Date**: `stock_period_evaluation.last_close_date`
28+
- Default value: 2010-01-01
29+
- Can be modified via *Settings \> Technical \> System Parameters*
30+
- Used when no previous closing period is selected
31+
32+
**Performance Settings**
33+
34+
Consider these optional configurations for large databases:
35+
36+
- **Bypass Negative Quantities**: Enable to skip products with negative
37+
stock during calculations
38+
- **No Recompute Lines**: Skip recalculation of quantities for existing
39+
lines to improve performance

stock_period_evaluation/readme/CONFIGURE.rst

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)