[MIG] stock_inventory_valuation_report: Migration to 14.0

Co-authored-by: dessanhemrayev <dessanhemrayev@gmail.com>
Co-authored-by: Alessandro Uffreduzzi <alessandro.uffreduzzi@pytech.it>
This commit is contained in:
Andrey Solodovnikov
2023-10-17 13:07:31 +03:00
committed by Alessandro Uffreduzzi
parent e6c3bbe3c9
commit 620d63c01f
15 changed files with 334 additions and 230 deletions

View File

@@ -7,7 +7,7 @@ Stock Inventory Valuation Report
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f52dbe5b051ec99d9ee7a63c214cf404ccafa168d8be97ae1d9af05ce83951f2
!! source digest: sha256:7e81cc55bfaa7140318103e270fb5e41e7ee0ab5c82d8ce7ae587f6586adafa0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -17,13 +17,13 @@ Stock Inventory Valuation Report
: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--reporting-lightgray.png?logo=github
:target: https://github.com/OCA/stock-logistics-reporting/tree/12.0/stock_inventory_valuation_report
:target: https://github.com/OCA/stock-logistics-reporting/tree/14.0/stock_inventory_valuation_report
:alt: OCA/stock-logistics-reporting
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/stock-logistics-reporting-12-0/stock-logistics-reporting-12-0-stock_inventory_valuation_report
:target: https://translation.odoo-community.org/projects/stock-logistics-reporting-14-0/stock-logistics-reporting-14-0-stock_inventory_valuation_report
: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/stock-logistics-reporting&target_branch=12.0
:target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-reporting&target_branch=14.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -41,8 +41,8 @@ Usage
To use this module, you need to:
#. Go to Inventory > Reporting > Inventory Valuation.
#. Select Compute (Current Inventory or At a Specific Date).
#. Choose Retrieve the inventory valuation or View report or Export PDF or Export XLSX or Cancel.
#. Select Inventory At Date.
#. You can now choose a few additional options: "View report", "Export PDF" and "Export XLSX".
Bug Tracker
===========
@@ -50,7 +50,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-reporting/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/stock-logistics-reporting/issues/new?body=module:%20stock_inventory_valuation_report%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/OCA/stock-logistics-reporting/issues/new?body=module:%20stock_inventory_valuation_report%0Aversion:%2014.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.
@@ -65,7 +65,13 @@ Authors
Contributors
~~~~~~~~~~~~
* Pimolnat Suntian <pimolnats@ecosoft.co.th>
* `Pimolnat Suntian <pimolnats@ecosoft.co.th>`_
* `Ooops404 <https://ooops404.com>`_
* `Francesco Foresti <francesco.foresti@ooops404.com>`_
* `Cetmix <https://cetmix.com>`_
* `Andrey Solodovnikov <andrejsolodovnikov@gmail.com>`_
* `PyTech SRL <https://www.pytech.it>`_
* `Alessandro Uffreduzzi <alessandro.uffreduzzi@pytech.it>`_
Maintainers
~~~~~~~~~~~
@@ -80,6 +86,6 @@ 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/stock-logistics-reporting <https://github.com/OCA/stock-logistics-reporting/tree/12.0/stock_inventory_valuation_report>`_ project on GitHub.
This module is part of the `OCA/stock-logistics-reporting <https://github.com/OCA/stock-logistics-reporting/tree/14.0/stock_inventory_valuation_report>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -14,8 +14,8 @@
"report_xlsx_helper",
],
"data": [
"data/paper_format.xml",
"data/report_data.xml",
"data/paperformat_data.xml",
"security/ir.model.access.csv",
"reports/stock_inventory_valuation_report.xml",
"wizard/stock_quantity_history_view.xml",
],

View File

@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="paperformat_inventory_valuation_report" model="report.paperformat">

View File

@@ -1,33 +0,0 @@
<odoo>
<record id="action_stock_inventory_valuation_report_html" model="ir.actions.client">
<field name="name">Inventory Valuation Report</field>
<field name="tag">stock_inventory_valuation_report_backend</field>
<field
name="context"
eval="{'active_model': 'report.stock.inventory.valuation.report'}"
/>
</record>
<report
string="Stock Inventory Valuation Report PDF"
id="action_stock_inventory_valuation_report_pdf"
model="report.stock.inventory.valuation.report"
name="stock_inventory_valuation_report.report_stock_inventory_valuation_report_pdf"
file="stock_inventory_valuation_report.report_stock_inventory_valuation_report_pdf"
report_type="qweb-pdf"
print_report_name="'Inventory Valuation Report - [%s]' % object.date"
paperformat="stock_inventory_valuation_report.paperformat_inventory_valuation_report"
/>
<report
string="Stock Inventory Valuation Report XLSX"
id="action_stock_inventory_valuation_report_xlsx"
model="report.stock.inventory.valuation.report"
name="s_i_v_r.report_stock_inventory_valuation_report_xlsx"
file="Inventory Valuation Report"
report_type="xlsx"
attachment_use="False"
/>
</odoo>

View File

@@ -1 +1,7 @@
* Pimolnat Suntian <pimolnats@ecosoft.co.th>
* `Pimolnat Suntian <pimolnats@ecosoft.co.th>`_
* `Ooops404 <https://ooops404.com>`_
* `Francesco Foresti <francesco.foresti@ooops404.com>`_
* `Cetmix <https://cetmix.com>`_
* `Andrey Solodovnikov <andrejsolodovnikov@gmail.com>`_
* `PyTech SRL <https://www.pytech.it>`_
* `Alessandro Uffreduzzi <alessandro.uffreduzzi@pytech.it>`_

View File

@@ -1,5 +1,5 @@
To use this module, you need to:
#. Go to Inventory > Reporting > Inventory Valuation.
#. Select Compute (Current Inventory or At a Specific Date).
#. Choose Retrieve the inventory valuation or View report or Export PDF or Export XLSX or Cancel.
#. Select Inventory At Date.
#. You can now choose a few additional options: "View report", "Export PDF" and "Export XLSX".

View File

@@ -2,12 +2,15 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.osv import expression
class StockInventoryValuationView(models.TransientModel):
_name = "stock.inventory.valuation.view"
_description = "Stock Inventory Valuation View"
report_id = fields.Many2one("report.stock.inventory.valuation.report")
name = fields.Char()
reference = fields.Char()
barcode = fields.Char()
@@ -34,62 +37,71 @@ class StockInventoryValuationReport(models.TransientModel):
company_id = fields.Many2one(
comodel_name="res.company",
)
compute_at_date = fields.Integer()
date = fields.Datetime()
inventory_datetime = fields.Datetime(required=True, default=fields.Datetime.now)
# Data fields, used to browse report data
results = fields.Many2many(
results = fields.One2many(
comodel_name="stock.inventory.valuation.view",
inverse_name="report_id",
compute="_compute_results",
help="Use compute fields, so there is nothing store in database",
)
@api.multi
@api.depends("inventory_datetime")
def _compute_results(self):
"""
Generate report lines, one per product present at the time
"""
self.ensure_one()
if not self.compute_at_date:
self.date = fields.Datetime.now()
domain = [("type", "=", "product")]
product_id = self.env.context.get("product_id")
product_tmpl_id = self.env.context.get("product_tmpl_id")
if product_id:
domain = expression.AND([domain, [("id", "=", product_id)]])
elif product_tmpl_id:
domain = expression.AND(
[domain, [("product_tmpl_id", "=", product_tmpl_id)]]
)
products = (
self.env["product.product"]
.with_context(
dict(to_date=self.date, company_owned=True, create=False, edit=False)
to_date=self.inventory_datetime,
company_owned=True,
create=False,
edit=False,
)
.search([("type", "=", "product"), ("qty_available", "!=", 0)])
)
ReportLine = self.env["stock.inventory.valuation.view"]
for product in products:
standard_price = product.standard_price
if self.date:
standard_price = product.get_history_price(
self.env.user.company_id.id, date=self.date
)
line = {
"name": product.name,
"reference": product.default_code,
"barcode": product.barcode,
"qty_at_date": product.qty_at_date,
"uom_id": product.uom_id,
"currency_id": product.currency_id,
"cost_currency_id": product.cost_currency_id,
"standard_price": standard_price,
"stock_value": product.qty_at_date * standard_price,
"cost_method": product.cost_method,
}
if product.qty_at_date != 0:
self.results += ReportLine.new(line)
.search(domain)
# 'quantity_svl' is not stored, can't be used in search
).filtered(lambda pp: pp.quantity_svl != 0)
results = self.env["stock.inventory.valuation.view"]
if products:
for product in products:
vals = {
"name": product.name,
"reference": product.default_code,
"barcode": product.barcode,
"qty_at_date": product.quantity_svl,
"uom_id": product.uom_id,
"currency_id": product.currency_id,
"cost_currency_id": product.cost_currency_id,
"standard_price": product.standard_price,
"stock_value": product.value_svl,
"cost_method": product.cost_method,
}
results |= results.new(vals)
self.results = results
@api.multi
def print_report(self, report_type="qweb"):
self.ensure_one()
action = (
report_type == "xlsx"
and self.env.ref(
"stock_inventory_valuation_report."
"action_stock_inventory_valuation_report_xlsx"
"action_stock_inventory_valuation_report_xlsx",
raise_if_not_found=False,
)
or self.env.ref(
"stock_inventory_valuation_report."
"action_stock_inventory_valuation_report_pdf"
"action_stock_inventory_valuation_report_pdf",
raise_if_not_found=False,
)
)
return action.report_action(self, config=False)
@@ -103,7 +115,7 @@ class StockInventoryValuationReport(models.TransientModel):
result["html"] = self.env.ref(
"stock_inventory_valuation_report."
"report_stock_inventory_valuation_report_html"
).render(rcontext)
)._render(rcontext)
return result
@api.model

View File

@@ -1,5 +1,56 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="action_stock_inventory_valuation_report_html" model="ir.actions.client">
<field name="name">Inventory Valuation Report</field>
<field name="tag">stock_inventory_valuation_report_backend</field>
<field
name="context"
eval="{'active_model': 'report.stock.inventory.valuation.report'}"
/>
</record>
<record id="action_stock_inventory_valuation_report_pdf" model="ir.actions.report">
<field name="name">Stock Inventory Valuation Report PDF</field>
<field name="model">report.stock.inventory.valuation.report</field>
<field name="report_type">qweb-pdf</field>
<field
name="report_name"
>stock_inventory_valuation_report.report_stock_inventory_valuation_report_pdf</field>
<field
name="report_file"
>stock_inventory_valuation_report.report_stock_inventory_valuation_report_pdf</field>
<field
name="print_report_name"
>'Inventory Valuation Report - [%s]' % object.inventory_datetime</field>
<field
name="binding_model_id"
ref="model_report_stock_inventory_valuation_report"
/>
<field name="binding_type">report</field>
<field
name="paperformat_id"
ref="stock_inventory_valuation_report.paperformat_inventory_valuation_report"
/>
</record>
<record id="action_stock_inventory_valuation_report_xlsx" model="ir.actions.report">
<field name="name">Stock Inventory Valuation Report XLSX</field>
<field name="model">report.stock.inventory.valuation.report</field>
<field name="report_type">xlsx</field>
<field
name="report_name"
>s_i_v_r.report_stock_inventory_valuation_report_xlsx</field>
<field name="report_file">Inventory Valuation Report</field>
<field
name="binding_model_id"
ref="model_report_stock_inventory_valuation_report"
/>
<field name="binding_type">report</field>
<field name="attachment_use">False</field>
</record>
<template
id="assets_backend"
name="stock_inventory_valuation_report assets"
@@ -120,7 +171,7 @@
</div>
<div class="act_as_row">
<div class="act_as_cell">
<span t-esc="o.date.strftime('%Y-%m-%d')" />
<span t-esc="o.inventory_datetime.strftime('%Y-%m-%d')" />
</div>
<div class="act_as_cell">
<span t-field='o.company_id.name' />

View File

@@ -1,19 +1,20 @@
# Copyright 2019 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import models
_logger = logging.getLogger(__name__)
from odoo.addons.report_xlsx_helper.report.report_xlsx_format import (
FORMATS,
XLS_HEADERS,
)
class ReportStockInventoryValuationReportXlsx(models.TransientModel):
_name = "report.s_i_v_r.report_stock_inventory_valuation_report_xlsx"
_description = "Report Stock Inventory Valuation xlsx"
_inherit = "report.report_xlsx.abstract"
def _get_ws_params(self, wb, data, objects):
stock_inventory_valuation_template = {
"1_number": {
"header": {
@@ -57,7 +58,7 @@ class ReportStockInventoryValuationReportXlsx(models.TransientModel):
},
"data": {
"value": self._render("qty_at_date"),
"format": self.format_tcell_amount_conditional_right,
"format": FORMATS["format_tcell_amount_conditional_right"],
},
"width": 18,
},
@@ -67,7 +68,7 @@ class ReportStockInventoryValuationReportXlsx(models.TransientModel):
},
"data": {
"value": self._render("standard_price"),
"format": self.format_tcell_amount_conditional_right,
"format": FORMATS["format_tcell_amount_conditional_right"],
},
"width": 18,
},
@@ -77,7 +78,7 @@ class ReportStockInventoryValuationReportXlsx(models.TransientModel):
},
"data": {
"value": self._render("stock_value"),
"format": self.format_tcell_amount_conditional_right,
"format": FORMATS["format_tcell_amount_conditional_right"],
},
"width": 18,
},
@@ -95,11 +96,10 @@ class ReportStockInventoryValuationReportXlsx(models.TransientModel):
return [ws_params]
def _inventory_valuation_report(self, wb, ws, ws_params, data, objects):
ws.set_portrait()
ws.fit_to_pages(1, 0)
ws.set_header(self.xls_headers["standard"])
ws.set_footer(self.xls_footers["standard"])
ws.set_header(XLS_HEADERS["xls_headers"]["standard"])
ws.set_footer(XLS_HEADERS["xls_footers"]["standard"])
self._set_column_width(ws, ws_params)
@@ -111,14 +111,19 @@ class ReportStockInventoryValuationReportXlsx(models.TransientModel):
row_pos,
0,
["Date", "Partner", "Tax ID"],
self.format_theader_blue_center,
FORMATS["format_theader_blue_center"],
)
ws.write_row(
row_pos + 1,
0,
[o.inventory_datetime or ""],
FORMATS["format_tcell_date_center"],
)
ws.write_row(row_pos + 1, 0, [o.date or ""], self.format_tcell_date_center)
ws.write_row(
row_pos + 1,
1,
[o.company_id.name or "", o.company_id.vat or ""],
self.format_tcell_center,
FORMATS["format_tcell_center"],
)
row_pos += 3
@@ -127,7 +132,7 @@ class ReportStockInventoryValuationReportXlsx(models.TransientModel):
row_pos,
ws_params,
col_specs_section="header",
default_format=self.format_theader_blue_center,
default_format=FORMATS["format_theader_blue_center"],
)
ws.freeze_panes(row_pos, 0)
@@ -147,8 +152,8 @@ class ReportStockInventoryValuationReportXlsx(models.TransientModel):
"standard_price": line.standard_price or 0.00,
"stock_value": line.stock_value or 0.00,
},
default_format=self.format_tcell_left,
default_format=FORMATS["format_tcell_left"],
)
total += line.stock_value
ws.write(row_pos, 6, total, self.format_theader_blue_amount_right)
ws.write(row_pos, 6, total, FORMATS["format_theader_blue_amount_right"])

View File

@@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_report_stock_inventory_valuation_report,report.stock.inventory.valuation.report,model_report_stock_inventory_valuation_report,stock.group_stock_user,1,1,1,1
access_stock_inventory_valuation_view,stock_inventory_valuation_view,model_stock_inventory_valuation_view,stock.group_stock_user,1,1,1,1
access_report_s_i_v_r_report_stock_inventory_valuation_report_xlsx,report.s_i_v_r.report_stock_inventory_valuation_report_xlsx,model_report_s_i_v_r_report_stock_inventory_valuation_report_xlsx,stock.group_stock_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_report_stock_inventory_valuation_report report.stock.inventory.valuation.report model_report_stock_inventory_valuation_report stock.group_stock_user 1 1 1 1
3 access_stock_inventory_valuation_view stock_inventory_valuation_view model_stock_inventory_valuation_view stock.group_stock_user 1 1 1 1
4 access_report_s_i_v_r_report_stock_inventory_valuation_report_xlsx report.s_i_v_r.report_stock_inventory_valuation_report_xlsx model_report_s_i_v_r_report_stock_inventory_valuation_report_xlsx stock.group_stock_user 1 1 1 1

View File

@@ -367,9 +367,9 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f52dbe5b051ec99d9ee7a63c214cf404ccafa168d8be97ae1d9af05ce83951f2
!! source digest: sha256:7e81cc55bfaa7140318103e270fb5e41e7ee0ab5c82d8ce7ae587f6586adafa0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<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-reporting/tree/12.0/stock_inventory_valuation_report"><img alt="OCA/stock-logistics-reporting" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--reporting-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-reporting-12-0/stock-logistics-reporting-12-0-stock_inventory_valuation_report"><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-reporting&amp;target_branch=12.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-reporting/tree/14.0/stock_inventory_valuation_report"><img alt="OCA/stock-logistics-reporting" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--reporting-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-reporting-14-0/stock-logistics-reporting-14-0-stock_inventory_valuation_report"><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-reporting&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Stock Inventory Valuation Report is the report that display value of all products in internal location.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
@@ -389,8 +389,8 @@ ul.auto-toc {
<p>To use this module, you need to:</p>
<ol class="arabic simple">
<li>Go to Inventory &gt; Reporting &gt; Inventory Valuation.</li>
<li>Select Compute (Current Inventory or At a Specific Date).</li>
<li>Choose Retrieve the inventory valuation or View report or Export PDF or Export XLSX or Cancel.</li>
<li>Select Inventory At Date.</li>
<li>You can now choose a few additional options: “View report”, “Export PDF” and “Export XLSX.</li>
</ol>
</div>
<div class="section" id="bug-tracker">
@@ -398,7 +398,7 @@ ul.auto-toc {
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-reporting/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-reporting/issues/new?body=module:%20stock_inventory_valuation_report%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<a class="reference external" href="https://github.com/OCA/stock-logistics-reporting/issues/new?body=module:%20stock_inventory_valuation_report%0Aversion:%2014.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">
@@ -412,7 +412,31 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li>Pimolnat Suntian &lt;<a class="reference external" href="mailto:pimolnats&#64;ecosoft.co.th">pimolnats&#64;ecosoft.co.th</a>&gt;</li>
<li><a class="reference external" href="mailto:pimolnats&#64;ecosoft.co.th">Pimolnat Suntian</a></li>
<li><dl class="first docutils">
<dt><a class="reference external" href="https://ooops404.com">Ooops404</a></dt>
<dd><ul class="first last">
<li><a class="reference external" href="mailto:francesco.foresti&#64;ooops404.com">Francesco Foresti</a></li>
</ul>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt><a class="reference external" href="https://cetmix.com">Cetmix</a></dt>
<dd><ul class="first last">
<li><a class="reference external" href="mailto:andrejsolodovnikov&#64;gmail.com">Andrey Solodovnikov</a></li>
</ul>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt><a class="reference external" href="https://www.pytech.it">PyTech SRL</a></dt>
<dd><ul class="first last">
<li><a class="reference external" href="mailto:alessandro.uffreduzzi&#64;pytech.it">Alessandro Uffreduzzi</a></li>
</ul>
</dd>
</dl>
</li>
</ul>
</div>
<div class="section" id="maintainers">
@@ -422,7 +446,7 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<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/stock-logistics-reporting/tree/12.0/stock_inventory_valuation_report">OCA/stock-logistics-reporting</a> project on GitHub.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/stock-logistics-reporting/tree/14.0/stock_inventory_valuation_report">OCA/stock-logistics-reporting</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>

View File

@@ -4,17 +4,18 @@ odoo.define(
"use strict";
var core = require("web.core");
var Widget = require("web.Widget");
var ControlPanelMixin = require("web.ControlPanelMixin");
var AbstractAction = require("web.AbstractAction");
var ReportWidget = require("web.Widget");
var report_backend = Widget.extend(ControlPanelMixin, {
var report_backend = AbstractAction.extend({
hasControlPanel: true,
// Stores all the parameters of the action.
events: {
"click .o_stock_inventory_valuation_report_print": "print",
"click .o_stock_inventory_valuation_report_export": "export",
},
init: function (parent, action) {
this._super.apply(this, arguments);
this.actionManager = parent;
this.given_context = {};
this.odoo_context = action.context;
@@ -26,17 +27,19 @@ odoo.define(
action.context.active_id || action.params.active_id;
this.given_context.model = action.context.active_model || false;
this.given_context.ttype = action.context.ttype || false;
return this._super.apply(this, arguments);
},
willStart: function () {
return $.when(this.get_html());
return Promise.all([
this._super.apply(this, arguments),
this.get_html(),
]);
},
set_html: function () {
var self = this;
var def = $.when();
if (!this.report_widget) {
this.report_widget = new ReportWidget(this, this.given_context);
def = this.report_widget.appendTo(this.$el);
const self = this;
var def = Promise.resolve();
if (!self.report_widget) {
self.report_widget = new ReportWidget(self, self.given_context);
def = self.report_widget.appendTo(self.$(".o_content"));
}
def.then(function () {
self.report_widget.$el.html(self.html);
@@ -59,7 +62,7 @@ odoo.define(
}).then(function (result) {
self.html = result.html;
defs.push(self.update_cp());
return $.when.apply($, defs);
return Promise.all(defs);
});
},
// Updates the control panel and render the elements that have yet
@@ -100,7 +103,7 @@ odoo.define(
});
},
canBeRemoved: function () {
return $.when();
return Promise.resolve();
},
});

View File

@@ -2,32 +2,40 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime
import logging
from dateutil.relativedelta import relativedelta
from odoo.tests import common
from odoo.tools import test_reports
_logger = logging.getLogger(__name__)
class TestStockInventoryValuation(common.SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
class TestStockInventoryValuation(common.TransactionCase):
def setUp(cls):
super(TestStockInventoryValuation, cls).setUp()
cls.inv_valuation_report_model = cls.env[
"report.stock.inventory.valuation.report"
]
cls.model = cls._getReportModel()
cls.qweb_report_name = (
"stock_inventory_valuation_report."
"report_stock_inventory_valuation_report_pdf"
)
cls.xlsx_report_name = "s_i_v_r.report_stock_inventory_valuation_report_xlsx"
cls.xlsx_action_name = (
"stock_inventory_valuation_report."
"action_stock_inventory_valuation_report_xlsx"
)
cls.qweb_report_name = cls._getQwebReportName()
cls.xlsx_report_name = cls._getXlsxReportName()
cls.xlsx_action_name = cls._getXlsxReportActionName()
cls.report_title = "Inventory Valuation Report"
cls.report_title = cls._getReportTitle()
cls.base_filters = {
"company_id": cls.env.user.company_id.id,
}
cls.base_filters = cls._getBaseFilters()
cls.report = cls.model.create(cls.base_filters)
cls.report._compute_results()
cls.report = cls.inv_valuation_report_model.create(cls.base_filters)
def test_html(self):
test_reports.try_report(
@@ -60,60 +68,35 @@ class TestStockInventoryValuation(common.TransactionCase):
self.report.print_report("qweb")
self.report.print_report("xlsx")
def _getReportModel(self):
return self.env["report.stock.inventory.valuation.report"]
def _getQwebReportName(self):
return (
"stock_inventory_valuation_report."
"report_stock_inventory_valuation_report_pdf"
)
class TestStockInventoryValuationReport(common.SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.company_id = cls.env.ref("base.main_company")
cls.date = datetime.datetime.now()
def _getXlsxReportName(self):
return "s_i_v_r.report_stock_inventory_valuation_report_xlsx"
cls.location_stock_id = cls.env.ref("stock.stock_location_stock")
cls.location_customers_id = cls.env.ref("stock.stock_location_customers")
cls.location_suppliers_id = cls.env.ref("stock.stock_location_suppliers")
def _getXlsxReportActionName(self):
return (
"stock_inventory_valuation_report."
"action_stock_inventory_valuation_report_xlsx"
)
def _getReportTitle(self):
return "Inventory Valuation Report"
def _getBaseFilters(self):
return {
"company_id": self.env.user.company_id.id,
"compute_at_date": 0,
"date": datetime.datetime.now(),
}
class TestStockInventoryValuationReport(common.TransactionCase):
def setUp(self):
super(TestStockInventoryValuationReport, self).setUp()
self.company_id = self.env.ref("base.main_company")
self.compute_at_date = 0
self.date = datetime.datetime.now()
cls.picking_type_in_id = cls.env.ref("stock.picking_type_in")
cls.picking_type_out_id = cls.env.ref("stock.picking_type_out")
cls.product_category_all = cls.env.ref("product.product_category_all")
def test_get_report_html(self):
report = self.env["report.stock.inventory.valuation.report"].create(
{
"company_id": self.company_id.id,
"compute_at_date": self.compute_at_date,
"date": self.date,
"inventory_datetime": self.date,
}
)
report._compute_results()
report.get_html(given_context={"active_id": report.id})
def test_wizard(self):
wizard = self.env["stock.quantity.history"].create(
{
"compute_at_date": 0,
"date": datetime.datetime.now(),
}
)
wizard = self.env["stock.quantity.history"].create({})
wizard._export("qweb-pdf")
wizard.button_export_html()
wizard.button_export_pdf()
@@ -128,21 +111,23 @@ class TestStockInventoryValuationReport(common.TransactionCase):
{
"name": "test valuation report date",
"type": "product",
"categ_id": self.env.ref("product.product_category_all").id,
"company_id": self.company_id.id,
"categ_id": self.product_category_all.id,
}
)
stock_location_id = self.ref("stock.stock_location_stock")
partner_id = self.ref("base.res_partner_4")
partner_id = self.env.ref("base.res_partner_4")
product_qty = 100
date_with_stock = datetime.datetime.now() + relativedelta(days=-1)
date_with_stock = self.date + relativedelta(days=-1)
# Receive the product
receipt = self.env["stock.picking"].create(
{
"location_id": self.ref("stock.stock_location_suppliers"),
"location_dest_id": stock_location_id,
"partner_id": partner_id,
"picking_type_id": self.ref("stock.picking_type_in"),
"location_id": self.location_suppliers_id.id,
"location_dest_id": self.location_stock_id.id,
"picking_type_id": self.picking_type_in_id.id,
"partner_id": partner_id.id,
"company_id": self.company_id.id,
"move_lines": [
(
0,
@@ -159,31 +144,47 @@ class TestStockInventoryValuationReport(common.TransactionCase):
}
)
receipt.action_confirm()
receipt.action_done()
receipt.move_lines.date = date_with_stock
receipt.button_validate()
move = receipt.move_lines
move.date = date_with_stock
move.stock_valuation_layer_ids._write({"create_date": date_with_stock})
self.assertEqual(
product.with_context(to_date=date_with_stock).qty_available, product_qty
product.with_context(to_date=date_with_stock).quantity_svl,
product_qty,
msg="Product should be present in stock at this date",
)
self.assertEqual(
product.quantity_svl,
product_qty,
msg="Product should be present in stock at this date",
)
self.assertEqual(product.qty_available, product_qty)
# Report should have a line with the product and its quantity
report = self.env["report.stock.inventory.valuation.report"].create(
{
"company_id": self.company_id.id,
"compute_at_date": 0,
}
)
product_row = report.results.filtered(lambda r: r.name == product.name)
self.assertEqual(len(product_row), 1)
self.assertEqual(product_row.qty_at_date, product_qty)
self.assertEqual(
len(product_row),
1,
msg="There should be one line for this produce in the report",
)
self.assertEqual(
product_row.qty_at_date,
product_qty,
msg="The product should have full quantity",
)
# Delivery the product
# Deliver the product
delivery = self.env["stock.picking"].create(
{
"location_id": stock_location_id,
"location_dest_id": self.ref("stock.stock_location_customers"),
"partner_id": partner_id,
"picking_type_id": self.ref("stock.picking_type_out"),
"location_id": self.location_stock_id.id,
"location_dest_id": self.location_customers_id.id,
"partner_id": partner_id.id,
"company_id": self.company_id.id,
"picking_type_id": self.picking_type_out_id.id,
"move_lines": [
(
0,
@@ -200,32 +201,49 @@ class TestStockInventoryValuationReport(common.TransactionCase):
}
)
delivery.action_confirm()
delivery.action_done()
delivery.button_validate()
date_no_stock = self.date + relativedelta(hours=-6)
move = delivery.move_lines
move.date = date_no_stock
move.stock_valuation_layer_ids._write({"create_date": date_no_stock})
self.assertEqual(
product.with_context(to_date=date_with_stock).qty_available, product_qty
product.with_context(to_date=date_with_stock).quantity_svl,
product_qty,
msg="The product should have full quantity at this date.",
)
self.assertEqual(
product.with_context(to_date=self.date).quantity_svl,
0,
msg="The product should not be present at this date.",
)
self.assertEqual(product.qty_available, 0)
# Report should not have a line with the product
# because it is not available
report = self.env["report.stock.inventory.valuation.report"].create(
{
"company_id": self.company_id.id,
"compute_at_date": 0,
"inventory_datetime": date_no_stock,
}
)
product_row = report.results.filtered(lambda r: r.name == product.name)
self.assertFalse(product_row)
self.assertFalse(
product_row,
msg="Product should not be present in this report "
"for this date, because it was delivered.",
)
# Report computed specifying the date
# when there was stock should have the product and its quantity
report = self.env["report.stock.inventory.valuation.report"].create(
{
"company_id": self.company_id.id,
"compute_at_date": 1,
"date": date_with_stock,
"inventory_datetime": date_with_stock,
}
)
product_row = report.results.filtered(lambda r: r.name == product.name)
self.assertEqual(len(product_row), 1)
self.assertEqual(product_row.qty_at_date, product_qty)
self.assertEqual(
len(product_row),
1,
msg="Report for this date should have one line for the product.",
)
self.assertEqual(
product_row.qty_at_date,
product_qty,
msg="Report for this date should show full quantity for the product",
)

View File

@@ -1,15 +1,16 @@
# Copyright 2019 Ecosoft Co., Ltd. (http://ecosoft.co.th)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import api, models
from odoo.tools import pycompat
from odoo import _, models
from odoo.tools.safe_eval import safe_eval
_logger = logging.getLogger(__name__)
class StockQuantityHistory(models.TransientModel):
_inherit = "stock.quantity.history"
@api.multi
def button_export_html(self):
self.ensure_one()
action = self.env.ref(
@@ -17,35 +18,37 @@ class StockQuantityHistory(models.TransientModel):
"action_stock_inventory_valuation_report_html"
)
vals = action.read()[0]
context1 = vals.get("context", {})
if isinstance(context1, pycompat.string_types):
context1 = safe_eval(context1)
new_context = vals.get("context", {})
if isinstance(new_context, str):
try:
new_context = safe_eval(new_context)
except (TypeError, SyntaxError, NameError, ValueError):
_logger.warning(
_("Failed context evaluation: %(context)s", context=new_context)
)
new_context = {}
model = self.env["report.stock.inventory.valuation.report"]
report = model.create(self._prepare_stock_inventory_valuation_report())
context1["active_id"] = report.id
context1["active_ids"] = report.ids
vals["context"] = context1
new_context.update(active_id=report.id, active_ids=report.ids)
vals["context"] = new_context
return vals
@api.multi
def button_export_pdf(self):
self.ensure_one()
report_type = "qweb-pdf"
return self._export(report_type)
return self._export(report_type="qweb-pdf")
@api.multi
def button_export_xlsx(self):
self.ensure_one()
report_type = "xlsx"
return self._export(report_type)
return self._export(report_type="xlsx")
def _prepare_stock_inventory_valuation_report(self):
self.ensure_one()
return {
vals = {
"company_id": self.env.user.company_id.id,
"compute_at_date": self.compute_at_date,
"date": self.date,
}
if self.inventory_datetime:
vals["inventory_datetime"] = self.inventory_datetime
return vals
def _export(self, report_type):
model = self.env["report.stock.inventory.valuation.report"]

View File

@@ -1,15 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_stock_quantity_history_inherit" model="ir.ui.view">
<field name="name">view_stock_quantity_history_inherit</field>
<record id="view_stock_valuation_quantity_history" model="ir.ui.view">
<field name="name">Valuation Report</field>
<field name="model">stock.quantity.history</field>
<field name="inherit_id" ref="stock_account.view_stock_quantity_history" />
<field name="inherit_id" ref="stock.view_stock_quantity_history" />
<field name="arch" type="xml">
<xpath expr="//button[@name='open_table']" position="after">
<button name="open_at_date" position="attributes">
<!-- Restoring v12 button name, to differentiate from other buttons -->
<attribute name="string">Retrieve the Inventory Quantities</attribute>
</button>
<button name="open_at_date" position="after">
<button name="button_export_html" string="View report" type="object" />
<button name="button_export_pdf" string="Export PDF" type="object" />
<button name="button_export_xlsx" string="Export XLSX" type="object" />
</xpath>
</button>
</field>
</record>